diff --git a/packages/agent/src/types.ts b/packages/agent/src/types.ts index 0ebf582bda..d6b35b97a1 100644 --- a/packages/agent/src/types.ts +++ b/packages/agent/src/types.ts @@ -132,48 +132,94 @@ export interface Agent { declare module 'cordis' { interface Events { // ---- lifecycle (emit) ---- - /** An agent was registered. */ + /** + * An agent was registered in the {@link AgentRegistry} and is ready to + * receive messages. + * @mode emit + */ 'agent/created'(agent: Agent): void - /** An agent was disposed. */ + /** + * An agent was disposed and removed from the registry; its fiber and any + * in-flight turn have been torn down. + * @mode emit + */ 'agent/disposed'(agent: Agent): void - /** Agent status changed (idle/running/disposed). */ + /** + * Agent status changed (`idle` ⇄ `running`, or → `disposed`). Drive + * lifecycle off this transition, never off a status you just requested — + * `send()` does not flip status to `running` before it returns. + * @mode emit + */ 'agent/status'(agent: Agent, status: AgentStatus): void /** * A message entered the agent's inbox (queued or steering). `source` is * the resolved source (defaults applied), not the caller's raw options. + * @mode emit */ 'agent/queued'(agent: Agent, content: ContentBlock[], info: { source: MessageSource; steering: boolean }): void // ---- turn/step boundaries (emit) ---- + /** + * A turn began. `turn` is the 1-based turn number within the session. + * @mode emit + */ 'agent/turn-start'(agent: Agent, turn: number): void + /** + * A turn ended. `reason` distinguishes a clean stop from a truncated or + * aborted one (`completed` | `aborted` | `error` | `disposed` | `max-tokens`). + * @mode emit + */ 'agent/turn-end'(agent: Agent, turn: number, reason: TurnEndReason): void + /** + * A step (one model call plus its tool dispatch) began. `step` is 1-based + * within the turn; a turn runs one or more steps. + * @mode emit + */ 'agent/step-start'(agent: Agent, turn: number, step: number): void + /** + * A step ended. + * @mode emit + */ 'agent/step-end'(agent: Agent, turn: number, step: number): void // ---- interception seams (waterfall) ---- /** - * Waterfall: mutate the fully-assembled GenerateOptions before the model - * call (hooks, compaction, model switching, tool filtering, …). + * Waterfall: mutate the fully-assembled {@link GenerateOptions} before the + * model call (hooks, compaction, model switching, tool filtering, …). Call + * `next()` to delegate, or return without it to short-circuit. + * @mode waterfall */ 'agent/request'(agent: Agent, turn: number, step: number, options: GenerateOptions, next: () => Promise): Promise /** - * Waterfall: post-process the assembled assistant message before tool - * dispatch (validation, content rewriting, …). + * Waterfall: post-process the assembled assistant {@link Message} before + * tool dispatch (validation, content rewriting, …). + * @mode waterfall */ 'agent/step-result'(agent: Agent, turn: number, step: number, message: Message, next: () => Promise): Promise /** * Waterfall: override the turn-continuation decision. The default * (computed by the loop) is `hadToolCalls || steeringInjected`. Listeners * can force-continue (/goal, /loop) or force-stop (budget guards). + * @mode waterfall */ 'agent/turn-continuation'(agent: Agent, turn: number, defaultDecision: boolean, next: () => Promise): Promise // ---- streaming + tool notifications (emit) ---- - /** A raw stream chunk arrived (token-level UI/log feed). */ + /** + * A raw {@link StreamChunk} arrived from the model (token-level UI/log feed). + * @mode emit + */ 'agent/stream-chunk'(agent: Agent, turn: number, step: number, chunk: StreamChunk): void - /** Steering content was injected into a running turn. */ + /** + * Steering content was injected into a running turn. + * @mode emit + */ 'agent/steering'(agent: Agent, turn: number, content: ContentBlock[], source: MessageSource): void - /** A step or turn errored. */ + /** + * A step or turn errored. The loop reports a failure here (plus the logger) + * even when the error has no in-turn position for a session `error` event. + * @mode emit + */ 'agent/error'(agent: Agent, turn: number, step: number, error: Error): void } } diff --git a/packages/llm/src/index.ts b/packages/llm/src/index.ts index 460316ea50..aaa0f66460 100644 --- a/packages/llm/src/index.ts +++ b/packages/llm/src/index.ts @@ -23,11 +23,23 @@ declare module 'cordis' { } interface Events { - /** Waterfall around every streaming model call (retry, caching, routing). */ + /** + * Waterfall around every streaming model call (retry, caching, routing). + * Bound to the {@link LlmService}; call `next()` to reach the resolved + * adapter's stream, or yield your own chunks to short-circuit. + * @mode waterfall + */ 'llm/stream'(this: LlmService, options: GenerateOptions, next: () => AsyncIterable): AsyncIterable - /** Waterfall around every non-streaming model call. */ + /** + * Waterfall around every non-streaming model call. Bound to the + * {@link LlmService}; call `next()` to delegate to the adapter. + * @mode waterfall + */ 'llm/generate'(this: LlmService, options: GenerateOptions, next: () => Promise): Promise - /** An adapter was registered or unregistered. */ + /** + * An adapter was registered or unregistered (the model→adapter map changed). + * @mode emit + */ 'llm/adapter-change'(): void } } diff --git a/packages/session/src/index.ts b/packages/session/src/index.ts index 57210c3431..65fbe01015 100644 --- a/packages/session/src/index.ts +++ b/packages/session/src/index.ts @@ -23,15 +23,24 @@ declare module 'cordis' { } interface Events { - /** A session was created in the store. */ + /** + * A session was created in the store. + * @mode emit + */ 'session/created'(session: Session): void - /** An event was appended to a session log (sync, fire-and-forget). */ + /** + * An event was appended to a session log (sync, fire-and-forget). This is + * the per-append feed a UI or invariant plugin tails. + * @mode emit + */ 'session/event'(session: Session, event: SessionEvent): void /** * Awaited durability checkpoint. The agent loop awaits * `ctx.parallel('session/flush', session)` at every turn end; persistence - * plugins (JSONL, SQLite) drain their write-behind - * buffers here and on fiber dispose. + * plugins (JSONL, SQLite) drain their write-behind buffers here and on + * fiber dispose. Awaited (parallel), not a waterfall: every listener runs + * and the loop waits for all of them, but none can veto. + * @mode parallel */ 'session/flush'(session: Session): Promise | void } diff --git a/packages/system-prompt/src/index.ts b/packages/system-prompt/src/index.ts index 25d87d2194..a5e6e4ed78 100644 --- a/packages/system-prompt/src/index.ts +++ b/packages/system-prompt/src/index.ts @@ -15,9 +15,18 @@ declare module 'cordis' { } interface Events { - /** Waterfall around prompt assembly — mutate/extend the assembly. */ + /** + * Waterfall around prompt assembly — mutate or extend the + * {@link PromptAssembly} (sections + tool schemas) before it is rendered. + * Bound to the {@link SystemPrompt} service; call `next()` to delegate. + * @mode waterfall + */ 'system-prompt/assemble'(this: SystemPrompt, assembly: PromptAssembly, next: () => Promise): Promise - /** A section or tool provider was registered or unregistered. */ + /** + * A section or tool provider was registered or unregistered (the assembly + * inputs changed). + * @mode emit + */ 'system-prompt/change'(): void } } diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index eee77445eb..5a17aa2b0c 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -36,11 +36,15 @@ declare module 'cordis' { * Waterfall around every tool execution — the single seam where sandbox, * permission, hook, and plan-mode plugins wrap or veto a call. Listeners * receive `(exec, next)`: call `next()` to proceed (possibly around your - * own logic), or return a ToolExecutionResult without calling `next()` - * to short-circuit (veto). + * own logic), or return a {@link ToolExecutionResult} without calling + * `next()` to short-circuit (veto). + * @mode waterfall */ 'tools/execute'(this: ToolRegistry, exec: ToolExecution, next: () => Promise): Promise - /** A tool was registered or unregistered. */ + /** + * A tool was registered or unregistered (the available tool set changed). + * @mode emit + */ 'tools/change'(): void } }