feat(server): pi module with upstream CRUD, server-side OAuth and token refresh

- /pi/providers, /pi/upstreams CRUD, test (auth-only by default, no cost), models
- subscription login via pi models.login with a suspended interaction: browser mode
  waits for the pasted redirect URL, device mode polls server-side; per-provider
  login lock, readable callback-port-in-use errors
- credential store locks the pi_upstream row (select for update) so api and worker
  refreshes never double-write a rotated refresh token
- refreshPiTokens task: refresh before expiry; failure marks expired and opens a
  relogin decision, closed again after a successful login
- runAgent picks upstreamId > agent_run.upstream_id > default upstream > legacy
  settings; credentials injected by the server, never logged

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 02:23:22 +08:00
1 parent 743fe2486d
commit fd3ffe5a8d
13 files changed
+1617 -26

No files matched your search

+4
View File
@@ -2,6 +2,8 @@ import { acquisitionOrganizeModule } from "./acquisition-organize/index.ts";
import { agentModule } from "./agent/index.ts";
import { authSettingsModule } from "./auth-settings/index.ts";
import { fileManagerModule } from "./file-manager/index.ts";
import { piModule } from "./pi/index.ts";
import { schedulesModule } from "./schedules/index.ts";
import { sourcesIdentityModule } from "./sources-identity/index.ts";
import type { ServerModule } from "./types.ts";
@@ -17,4 +19,6 @@ export const SERVER_MODULES: readonly ServerModule[] = [
acquisitionOrganizeModule,
agentModule,
fileManagerModule,
piModule,
schedulesModule,
];