fix: integrate audit findings round 1 - tools, worker, scheduler, main agent

- Unify ToolResultEnvelope (output vs content) for built-in tools
- Fix shell.run AsyncGenerator consumption in ToolRegistry.call/streaming
- Scheduler: consume WorkerResult.status instead of marking all running tasks completed
- WorkerProcess/WorkerManager: surface exit events and generate failed/cancelled result
- MainAgent: integrate ContextAssembler, Chinese destructive regex, ArchitectureDesigner impact gate
- run.ts: pendingConfirmation flow, dispatch extracted, .air files filtered from /results
- CapabilityRegistry wired into RuntimeApp and ServiceRegistry; DoctorService uses it
- release.ts: findRepoRoot/findBun, run air e2e + depcruise + runtime regression
- New gates: release-critical-gates, CLI run command regression
- 14/14 e2e gates pass; 3/3 release dry-run pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
AirCoding
2026-06-05 18:39:10 +08:00
parent a2d7aa0339
commit ddefcbb2b1
24 changed files with 1992 additions and 186 deletions

View File

@@ -133,13 +133,17 @@ After completing ALL required files, write: DONE`
}
}
// After executing, check if LLM indicated completion
if (text.includes('DONE') || text.includes('TASK_COMPLETE')) {
if (this.is_done_signal(text)) {
if (!allSucceeded) {
messages.push({ role: 'assistant', content: text })
messages.push({ role: 'user', content: 'You signaled DONE, but one or more tool actions failed. Fix the failed actions before signaling DONE.' })
continue
}
await this.runtime.checkpoint('task_completed', { task_id: task_spec.id })
return {
status: 'completed',
changes,
verification: { passed: allSucceeded, output: `${changes.length} files: ${changes.map(c => c.file).join(', ')}` },
verification: { passed: true, output: `${changes.length} files: ${changes.map(c => c.file).join(', ')}` },
evidence_refs: []
}
}
@@ -153,7 +157,7 @@ After completing ALL required files, write: DONE`
})
} else {
// No code blocks, no tool calls — LLM is just talking
if (text.includes('DONE') || text.includes('TASK_COMPLETE')) {
if (this.is_done_signal(text)) {
if (changes.length === 0) {
messages.push({ role: 'assistant', content: text })
messages.push({ role: 'user', content: 'You said DONE but no files were created. Please create the required files first.' })
@@ -189,6 +193,13 @@ After completing ALL required files, write: DONE`
}
}
private is_done_signal(text: string): boolean {
return text
.split(/\r?\n/)
.map(line => line.trim())
.some(line => line === 'DONE' || line === 'TASK_COMPLETE')
}
/**
* Parse ALL actions from LLM response: code blocks and tool calls.
*/
@@ -219,7 +230,7 @@ After completing ALL required files, write: DONE`
filename = extMap[lang] || `${lang}_output.${lang === 'cmake' ? 'txt' : lang}`
}
actions.push({ type: 'code_block', filename, content: match[4].trim() })
actions.push({ type: 'code_block', filename, content: match[4] })
}
// ── Pattern 2: Explicit tool calls ──