Merge current master into debug-pangwenjie

# Conflicts:
#	docs/cordis-catalog/events.md
#	docs/core-data-structures/core.md
#	docs/core-data-structures/tools.md
#	docs/event-producer-consumer.md
#	docs/rfc/implemented/feature/2026-06-30-interception-seams.md
#	docs/tool-execution-pipeline.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/loop.ts
#	packages/core/agent-loop/tests/loop.spec.ts
#	packages/core/agent/README.md
#	packages/core/tools/src/index.ts
#	scripts/gen-doc-graphs.ts
This commit is contained in:
Tianyi Cui
2026-07-18 13:39:12 +08:00
701 changed files with 38518 additions and 8779 deletions

View File

@@ -10,7 +10,7 @@ A `ToolSchema` (the model-facing fields) plus the `execute` function and optiona
```ts type-equiv
interface ToolDefinition extends ToolSchema {
execute(args: unknown, exec: ToolExecution): Promise<ToolExecuteReturn>
execute(args: unknown, exec: ToolRunContext): Promise<ToolExecuteReturn>
/**
* Cooperative tool-call timeout budget in milliseconds. Omit for no deadline.
* Enforced by `@deepseek-ai/dsh-timeout-policy` (a `tools/execute` wrapper); it
@@ -120,6 +120,19 @@ interface ToolExecutionInput {
}
```
A tool body receives the runtime extension. `deferContext()` is the composite-tool channel: it records nested-dispatch context without injecting inside the still-open outer call.
```ts type-equiv
interface ToolRunContext extends ToolExecution {
/**
* Defer one nested-dispatch context until this tool's final result reaches
* the agent loop. Contexts retain their individual source, envelope, and
* metadata and are emitted in call order.
*/
deferContext(context: HookContext): void
}
```
```ts type-equiv
interface ToolExecution extends ToolExecutionInput {
/** Registry-assigned identity shared with nested calls only as their opaque `parent` token. */
@@ -146,17 +159,16 @@ interface ToolExecutionResult {
*/
error?: ToolErrorInfo
/**
* Extra model-facing context a `tools/post-execute` listener attached for the
* NEXT request (Claude Code's PostToolUse `additionalContext`). It is NOT part
* of this call's `content` — `content`/`feedback` shape the tool RESULT, but
* `additionalContext` is a SEPARATE `context/message`. A step can carry
* multiple tool calls, so the loop accepts every call's `additionalContext`
* into the active-batch FIFO and appends it only when that batch settles. A
* successful batch places context AFTER all its `tool/result`s; an interrupted
* batch places it after every recorded result and before turn close. Carried
* on the result purely to ferry it from `execute()` up to that FIFO.
* Extra model-facing contexts deferred by a composite tool or attached by
* `tools/post-execute` listeners for the NEXT request. They are not part of
* this call's `content`: the loop accepts them into the active-batch FIFO and
* appends them after every recorded `tool/result` when the batch settles, even
* when execution is interrupted. The array preserves each context's source,
* envelope, metadata, and production order. An accepted outer call keeps
* deferred contexts before decision contexts; a block retains only contexts
* supplied by the blocking decision.
*/
additionalContext?: HookContext
additionalContexts?: HookContext[]
/**
* The tool-private presentation payload from a successful `execute` (the object
* return form). Threaded onto the `tool/result` session event and back into
@@ -182,8 +194,8 @@ type PreToolDecision =
```ts type-equiv
type PostToolDecision =
| { kind: 'accept'; content?: ContentBlock[]; additionalContext?: HookContext }
| { kind: 'block'; feedback: ContentBlock[]; additionalContext?: HookContext }
| { kind: 'accept'; content?: ContentBlock[]; additionalContexts?: HookContext[] }
| { kind: 'block'; feedback: ContentBlock[]; additionalContexts?: HookContext[] }
```
Call `next()` for the default or return a decision to short-circuit. Pre-policy may deny or ask; only `allowed-once` proceeds, while a non-grant, missing approval channel or service, or agent-less request becomes a denial. Guards may still impose a final denial. Arguments cannot be rewritten because history, audit, UI, and execution must agree.