feat(core): add agent execution context

This commit is contained in:
Yichen Jiang
2026-07-16 16:29:46 +08:00
parent 04df615dd6
commit 7bcae0cd64
93 changed files with 1272 additions and 462 deletions

View File

@@ -351,6 +351,50 @@ interface Agent {
The [event taxonomy](../architecture.md#event) owns the `agent/*` lifecycle, checkpoint, and waterfall contracts. Turn and step boundaries are durable session events rather than agent emits.
## Agent execution context
`AgentExecution` is the process-local ambient frame established around a concrete driver's lifetime. It holds the exact Agent rather than duplicating Session or step state; ambient presence is neither liveness proof nor authorization.
Source: [`packages/core/agent-execution/src/types.ts`](../../packages/core/agent-execution/src/types.ts)
```ts type-equiv
interface AgentExecution {
readonly agent: Agent
}
```
The mandatory service reads, requires, establishes, or explicitly clears that frame. `run()` preserves the operation's exact synchronous value or Promise.
Source: [`packages/core/agent-execution/src/index.ts`](../../packages/core/agent-execution/src/index.ts)
```ts type-equiv
interface AgentExecutionService {
/**
* Read the active execution without requiring one.
* @returns the inherited execution, or `undefined` outside/inside a cleared boundary.
* @throws when this service instance has been disposed.
*/
current(): AgentExecution | undefined
/**
* Read the active execution and fail when no boundary is active.
* @returns the inherited execution.
* @throws when no execution is active or this service instance has been disposed.
*/
require(): AgentExecution
/**
* Run an operation inside an execution boundary. Passing `undefined` clears
* an inherited execution; the exact synchronous value or Promise is returned.
* @param execution - execution to inherit, or `undefined` for a clearing boundary.
* @param operation - synchronous or asynchronous operation to invoke.
* @returns the exact value returned by `operation`.
* @throws when this service is closing/disposed, or when `operation` throws.
*/
run<T>(execution: AgentExecution | undefined, operation: () => T): T
}
```
## Interception decisions
Each `agent/*` interception waterfall returns a small, seam-specific typed union — the unified Decision idiom (the tool seams' `PreToolDecision`/`PostToolDecision` in [tools.md](tools.md) follow the same shape). A CC/Codex hook bridge maps its `permissionDecision`/`decision`/`continue`/`additionalContext` fields onto these; a native plugin returns them directly. They share one envelope for model-facing context, `HookContext`, which is `inject()`ed as a `context/message` and so carries a REQUIRED `source` (a missing source would default to `{kind:'user'}` and mislabel plugin context as a user prompt).