fix(system-prompt): reject a toolOrder that names an unregistered tool

Review follow-up (#196): a listed name with no registered tool was silently
ignored; misconfiguration must block work instead. The check lives in the
assembly — the earliest moment the registered tool set exists (tool plugins
register after the service constructs) and the only universal one (cordis has
no "all plugins loaded" event; registrations change at any time). assemble()
is now async so the throw surfaces as a rejection rather than a synchronous
escape from a Promise-returning method.

Blast radius, pinned by a loop-level test: the rejection reaches the turn's
outer catch — the turn closes balanced with an `error` reason, agent/error
mirrors it, no step opens, no request/header is logged, no request reaches
the adapter, and the agent returns to idle; every turn fails identically
until the config is fixed. A boot-time validation pass was considered and
rejected (recorded in the RFC). The general principle — misconfiguration
fails loud, never a silent skip — is added to AGENTS.md.
This commit is contained in:
imccyu
2026-07-07 20:20:56 +08:00
parent 72933ec558
commit adbba0deb2
10 changed files with 106 additions and 35 deletions
+1 -1
View File
@@ -190,7 +190,7 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
assemble(context: AssembleContext = {}): Promise<PromptAssembly>
```
Source: [`packages/core/system-prompt/src/index.ts:262`](../../packages/core/system-prompt/src/index.ts)
Source: [`packages/core/system-prompt/src/index.ts:279`](../../packages/core/system-prompt/src/index.ts)
## `ctx.tools` — `ToolRegistry`