feat(v3): T26 两级智能体(大模型规划/审查 + 本地小模型执行,D7)

- run_dual 编排:规划者两阶段 JSON(plan/review,失败回喂重试一次再降级),
  redo 时裁决意见回喂执行者,交接上限 agent.max_handoffs(默认 2)
- 交接文档 agent_runs/{id}/handoff.json(智能体版交流文本:instructions/acceptance/exchanges)
- /agent 新增 executor_pool_id;规划者==执行者条目拒绝;整体 token_cap 覆盖两级调用
- ToolLoop 增 emit_final 开关(内层循环不发终态,防前端 SSE 提前收口)
- 前端:执行者选择器 + phase/message 事件渲染(阶段徽标 + 双色消息卡)
- 测试 +3(done/redo/执行者故障),全量 277 passed
- fix(tests): test_config_get_put_reset 增加设置备份/恢复隔离,防止清掉用户真实配置
This commit is contained in:
tzt
2026-09-01 11:45:33 +08:00
parent 8e2123343c
commit 43e2bceae7
20 changed files with 568 additions and 59 deletions
+20 -5
View File
@@ -311,7 +311,7 @@ export async function listPoolModels(id: string) {
// ── 智能体(工具调用) ───────────────────────────────────────────────────────
export interface AgentEvent {
type: 'round' | 'tool_call' | 'tool_result' | 'usage' | 'final'
type: 'round' | 'tool_call' | 'tool_result' | 'usage' | 'final' | 'phase' | 'message'
ts?: number
round?: number
name?: string
@@ -322,6 +322,12 @@ export interface AgentEvent {
completion_tokens?: number
reason?: string
error?: string
// 两级模式(D7
phase?: 'plan' | 'execute' | 'review'
handoff?: number
model?: string
role?: 'planner' | 'executor'
content?: string
}
export interface AgentStatus {
@@ -337,12 +343,21 @@ export interface AgentStatus {
started_at?: number
finished_at?: number
workspace?: string
executor_model?: string
mode?: 'single' | 'dual'
}
/** POST /agent:提交智能体任务(workspace 可选:选中工作目录 */
export async function startAgent(task: string, poolId?: string, workspace?: string) {
const { data } = await http.post<{ request_id: string; status: string; model: string; workspace?: string }>(
'/agent', { task, pool_id: poolId || undefined, workspace: workspace || undefined })
/** POST /agent:提交智能体任务(executorPoolId 可选:两级模式的执行者/本地小模型 */
export async function startAgent(task: string, poolId?: string, workspace?: string, executorPoolId?: string) {
const { data } = await http.post<{
request_id: string; status: string; model: string
workspace?: string; mode?: 'single' | 'dual'; executor_model?: string
}>('/agent', {
task,
pool_id: poolId || undefined,
workspace: workspace || undefined,
executor_pool_id: executorPoolId || undefined,
})
return data
}