agentworkshop 0.7.33 → 0.7.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/adc365b6-f636-4a2b-9527-79819c1e874b.json +1 -0
- package/.output/server/chunks/_/nitro.mjs +699 -670
- package/.output/server/package.json +1 -1
- package/package.json +1 -1
- package/scripts/_dbg-harness-cancel-repro.mjs +81 -0
- package/scripts/_dbg-opslog-agent-e2e.mjs +5 -2
- package/scripts/production-closed-loop-e2e.mjs +7 -4
- package/server/services/workshop/agents/base-agent.ts +9 -0
- package/server/services/workshop/agents/codex-agent.ts +746 -729
- package/server/services/workshop/plugins/host.mjs +4 -7
- package/server/services/workshop/runtime/agent-runtime.ts +32 -3
- package/.output/public/_nuxt/builds/meta/291ef3e6-fa6a-4dee-8f46-05da1aeab815.json +0 -1
|
@@ -688,14 +688,11 @@ async function doReload(host) {
|
|
|
688
688
|
}
|
|
689
689
|
}
|
|
690
690
|
const prevNames = [...host.plugins.keys()]
|
|
691
|
-
//
|
|
691
|
+
// 工具注销延后:先装载新集、后清「本轮未再装载」的旧插件工具。
|
|
692
|
+
// 原先在装载前就全部注销 → 重载窗口内(秒级~数十秒)所有插件工具"未知工具",
|
|
693
|
+
// 期间到达的 Agent 工具调用(daq:sample 自动诊断/kb_store 等)被误拒
|
|
694
|
+
// (实测生产闭环 Stage D 撞窗失败)。同名工具装载时按"后注册者胜"覆盖,无残留。
|
|
692
695
|
const ompTools = await import('@/server/services/workshop/agents/plugin-tools').catch(() => null)
|
|
693
|
-
for (const prev of prevNames) {
|
|
694
|
-
try {
|
|
695
|
-
ompTools?.unregisterPluginTools(prev)
|
|
696
|
-
}
|
|
697
|
-
catch { /* 注销失败不阻断重载 */ }
|
|
698
|
-
}
|
|
699
696
|
host.plugins.clear()
|
|
700
697
|
host.routes = createRouteTable()
|
|
701
698
|
host.failures = []
|
|
@@ -197,6 +197,11 @@ export class AgentRuntime {
|
|
|
197
197
|
this.role = agent.role
|
|
198
198
|
this.channelId = agent.channelId
|
|
199
199
|
this.name = agent.name
|
|
200
|
+
// 工作区即时可用:impl 的 workspace 原本在首个 run() 才注入,此前 REST 直调
|
|
201
|
+
// host 工具(agent-tools/invoke)会拿到 null →「workspace 未就绪」。
|
|
202
|
+
// 装配期即绑定(与 run() 注入的是同一对象,语义等价)。
|
|
203
|
+
const attach = (this.impl as { attachWorkspace?: (ws: AgentWorkspace) => void }).attachWorkspace
|
|
204
|
+
if (typeof attach === 'function') attach.call(this.impl, deps.workspace)
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
/** 投递消息;idle 时立即唤醒消费 */
|
|
@@ -582,6 +587,13 @@ export class AgentRuntime {
|
|
|
582
587
|
// LLM 流式增量:只走事件流(AEP agent.delta),不进任务引擎/交付兜底管道
|
|
583
588
|
if (event.kind === 'delta') continue
|
|
584
589
|
if (event.kind === 'error') sawRunError = true
|
|
590
|
+
// 无原生工具面的 harness(codex/dsh 等)以 shell/文本方式作业:回合 error 收束
|
|
591
|
+
// 但已有实质输出时,不落入 FAILED(交由回合结束后的交付兜底按最终输出隐式收口)——
|
|
592
|
+
// 否则「工作已做完、流断在收尾」的任务全部 FAILED→重试→CANCELED(实测 dsh)。
|
|
593
|
+
if (event.kind === 'error' && taskId && replyText.trim().length >= 40) {
|
|
594
|
+
const cur = this.deps.taskEngine.get(taskId)
|
|
595
|
+
if (cur && cur.state === 'WORKING') continue
|
|
596
|
+
}
|
|
585
597
|
if (taskId) await this.deps.taskEngine.applyEvent(taskId, event)
|
|
586
598
|
if (event.kind === 'message') cap(partsToText(event.message.parts))
|
|
587
599
|
else if (event.kind === 'status' && event.status.message) cap(partsToText(event.status.message.parts))
|
|
@@ -618,13 +630,30 @@ export class AgentRuntime {
|
|
|
618
630
|
// 交付兜底(harness 回合结束 ≠ 任务完成):
|
|
619
631
|
// - 回合产出过实质 artifact(LLM 完成了工作但跳过 complete_task 工具)→ 隐式完成,
|
|
620
632
|
// 交付物即回合规避的输出,平台代为收口(进度 100)。
|
|
621
|
-
// -
|
|
633
|
+
// - 无 artifact 但回合有最终文本输出(部分 harness 不支持回合内调工具,只能把
|
|
634
|
+
// 结果写在答复里,如 codex/dsh 的 MCP 桥未就绪/未被模型使用)→ 同样隐式完成,
|
|
635
|
+
// 最终文本作为交付物;否则这类引擎的所有任务都会「工作做完了却停滞被回收」。
|
|
636
|
+
// - 两者皆无(LLM 空转)→ FAILED 交给调度器 retry/reassign。
|
|
622
637
|
// 仅 worker 的 assign 执行消息生效:lead 由 supervise 协调;WAITING 父任务不属此列。
|
|
623
638
|
if (taskId && this.role === 'worker' && msg.metadata?.['x-aw-task-kind'] === 'assign') {
|
|
624
639
|
const after = this.deps.taskEngine.get(taskId)
|
|
625
640
|
if (after && after.assigneeId === this.agentId && after.state === 'WORKING') {
|
|
626
641
|
const deliverable = after.artifacts.find(a => a.name !== 'input' && a.parts.some(p => ('text' in p ? p.text.trim().length : 1) > 0))
|
|
627
|
-
|
|
642
|
+
const fallbackText = deliverable ? '' : replyText.trim()
|
|
643
|
+
if (deliverable || fallbackText) {
|
|
644
|
+
if (!deliverable) {
|
|
645
|
+
// 回合最终文本 → 平台代录交付物(与 complete_task 的 deliverable 同构)
|
|
646
|
+
await this.deps.taskEngine.applyEvent(taskId, {
|
|
647
|
+
kind: 'artifact',
|
|
648
|
+
artifact: {
|
|
649
|
+
artifactId: randomUUID(),
|
|
650
|
+
name: 'deliverable',
|
|
651
|
+
parts: [{ text: fallbackText.slice(0, 20_000) }],
|
|
652
|
+
},
|
|
653
|
+
lastChunk: true,
|
|
654
|
+
totalChunks: 1,
|
|
655
|
+
})
|
|
656
|
+
}
|
|
628
657
|
const completed = await this.deps.taskEngine.complete(taskId)
|
|
629
658
|
this.emitExternal({
|
|
630
659
|
kind: 'status',
|
|
@@ -634,7 +663,7 @@ export class AgentRuntime {
|
|
|
634
663
|
messageId: randomUUID(),
|
|
635
664
|
contextId: this.channelId,
|
|
636
665
|
role: 'ROLE_AGENT',
|
|
637
|
-
parts: [{ text: `任务 ${taskId} 回合已产出交付物但未调用完成工具,平台隐式收口为 COMPLETED` }],
|
|
666
|
+
parts: [{ text: `任务 ${taskId} 回合已产出交付物但未调用完成工具,平台隐式收口为 COMPLETED${deliverable ? '' : '(交付物取自回合最终输出)'}` }],
|
|
638
667
|
},
|
|
639
668
|
timestamp: new Date().toISOString(),
|
|
640
669
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"291ef3e6-fa6a-4dee-8f46-05da1aeab815","timestamp":1789115705165,"prerendered":[]}
|