feat(agent): per-upstream pi Models with isolated credential stores

- PiUpstreamClient: one Models per upstream holding only its provider; credential
  store adapter maps to that upstream's secret, so several accounts of one provider
  coexist; host env is only read for authKind none (ambient cloud creds)
- provider catalog from builtinProviders() plus static oauth modes, env fields and
  subscription terms notes; openai-compatible custom endpoints
- fake upstream provider with mock OAuth (browser paste / device approval)
- PiAgentRuntime accepts an upstream; thinking level clamped to the model

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 02:23:09 +08:00
1 parent b9dbd54e37
commit 743fe2486d
8 files changed
+1085 -5

No files matched your search

+8 -2
View File
@@ -8,10 +8,15 @@ export type AgentThinkingLevel = (typeof THINKING_LEVELS)[number];
* 只在请求时经 provider auth.resolve 交给 SDK,不进入事件、日志、错误信息。
*/
export const AgentSettingsSchema = z.object({
provider: z.enum(["anthropic", "openai-compatible"]),
/**
* pi provider id。按上游运行(PiAgentRuntimeOptions.upstream)时只作记录;
* 没有上游时只支持旧的 anthropic / openai-compatible(apiKey 必填)
*/
provider: z.string().min(1),
/** Anthropic 写不带 /v1 的根地址;OpenAI 兼容写带 /v1 的地址 */
baseUrl: z.string().url().optional(),
apiKey: z.string().min(1),
/** 旧的单上游密钥;按上游运行时由凭据存储提供,这里留空 */
apiKey: z.string().min(1).optional(),
model: z.string().min(1),
thinkingLevel: z.enum(THINKING_LEVELS).default("off"),
/** 上下文预算 = 模型 contextWindow(可以比上游真实窗口小) */
@@ -54,5 +59,6 @@ export function resolveAgentSettings(settings: AgentSettings): ResolvedAgentSett
export function describeSettings(settings: ResolvedAgentSettings): Omit<ResolvedAgentSettings, "apiKey"> & {
apiKey: "[REDACTED]";
} {
// apiKey 可能为空(按上游运行),展示时一律打码
return { ...settings, apiKey: "[REDACTED]" };
}