Files
UHD_Media_Tool/packages/agent/src/settings.ts
T
rootandClaude Opus 5.5 459991421e feat(agent): Pi subagents via agent.spawn / agent.await
- agent_run gains depth / spawn_reason (0029); agent_run_event types
  subagent_spawned / subagent_event / subagent_completed
- agent.spawn (propose, medium, replay never): allowlist ⊆ parent, mode not
  above parent, budget carved from parent's remainder, idempotent per run+input;
  settings.pi.subagents {enabled, maxConcurrent, maxDepth} (subagentsEnabled kept as alias)
- child runs claim a concurrency slot under an advisory lock (waitForFact while
  queued); agent.await polls business tables without calling the model
- parent abort cascades to all descendants; parent runtime budget counts
  descendant usage; child events mirrored into the parent stream by parent seq
- authorize caps every child call by all ancestors' allowlists/kinds
- session page shows parent link, inherited info and the subagent tree
- e2e E11; runbook section on subagents

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-28 02:49:37 +08:00

65 lines
2.6 KiB
TypeScript

import { z } from "zod";
export const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
export type AgentThinkingLevel = (typeof THINKING_LEVELS)[number];
/**
* 设置页 → Agent 运行参数。apiKey 为调用方从 secret store 解密后的明文,
* 只在请求时经 provider auth.resolve 交给 SDK,不进入事件、日志、错误信息。
*/
export const AgentSettingsSchema = z.object({
/**
* 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).optional(),
model: z.string().min(1),
thinkingLevel: z.enum(THINKING_LEVELS).default("off"),
/** 上下文预算 = 模型 contextWindow(可以比上游真实窗口小) */
contextBudgetTokens: z.number().int().min(1024).default(128_000),
/** 单次回复最大输出 token */
maxOutputTokens: z.number().int().min(256).default(8192),
compaction: z
.object({
mode: z.enum(["threshold", "manual"]),
/** 上下文占用达到预算的该比例时自动压缩(0.5~0.95) */
threshold: z.number().min(0.5).max(0.95).default(0.8),
})
.default({ mode: "threshold", threshold: 0.8 }),
/** 子代理开关(仅记录);派生由服务端 agent.spawn 能力实现,开关与并发/深度上限在服务端校验 */
subagentsEnabled: z.boolean().default(false),
maxToolCalls: z.number().int().min(1).default(40),
maxDurationMs: z
.number()
.int()
.min(1000)
.default(15 * 60_000),
costBudget: z
.object({
maxTotalTokens: z.number().int().positive().optional(),
maxCostUsd: z.number().positive().optional(),
})
.optional(),
/** 单次请求超时 */
requestTimeoutMs: z.number().int().positive().default(120_000),
maxRetries: z.number().int().min(0).max(10).default(2),
});
export type AgentSettings = z.input<typeof AgentSettingsSchema>;
export type ResolvedAgentSettings = z.output<typeof AgentSettingsSchema>;
export function resolveAgentSettings(settings: AgentSettings): ResolvedAgentSettings {
return AgentSettingsSchema.parse(settings);
}
/** 用于日志/展示:去掉 apiKey */
export function describeSettings(settings: ResolvedAgentSettings): Omit<ResolvedAgentSettings, "apiKey"> & {
apiKey: "[REDACTED]";
} {
// apiKey 可能为空(按上游运行),展示时一律打码
return { ...settings, apiKey: "[REDACTED]" };
}