Class: TurnRunner
Executes a single agent turn through paired input and output middleware pipelines.
Remarks
Construction validates config eagerly and throws @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG if it does not satisfy the schema — fail-fast so misconfiguration surfaces before any turn runs.
Each call to TurnRunner.run threads a @nhtio/adk!TurnContext through the input pipeline, invokes the model, then threads the result through the output pipeline. Middleware on each side can read and mutate the context for pre- and post-processing (e.g. message normalisation, tool call dispatch, response filtering).
Two event buses:
- Functional bus (
on/off/once):message,thought,toolCall— pipeline-affecting events that middleware raises throughout turn execution. - Observability bus (
observe/unobserve/observeOnce):turnStart,turnEnd,turnGateOpen,turnGateClosed,error— instrumentation-only events that monitor execution without participating in it.
Streaming content is surfaced via message and thought events; tool call lifecycle via toolCall; non-fatal pipeline errors via the observability error event; gate lifecycle via turnGateOpen and turnGateClosed — all throughout execution.
Example
const runner = new TurnRunner({
fetchMemoriesCallback: async (ctx) => memoryStore.query(ctx),
fetchMessagesCallback: async (ctx) => messageStore.history(ctx),
fetchThoughtsCallback: async (ctx) => thoughtStore.history(ctx),
fetchToolCallsCallback: async (ctx) => toolCallStore.history(ctx),
});
// Functional bus — pipeline events
runner.on("message", (chunk) => process.stdout.write(chunk.aDelta));
// Observability bus — instrumentation
runner.observe("error", (err) => console.error(err.toString()));
runner.observe("turnStart", ({ turnId }) =>
console.log("turn started", turnId),
);
runner.observe("turnGateOpen", (gate) => {
if (gate.reason === "tool_approval") {
gate.resolve(true); // approve immediately for this example
}
});
await runner.run({
turnAbortController: new AbortController(),
systemPrompt: "You are a helpful assistant.",
standingInstructions: [],
});Constructors
Constructor
new TurnRunner(config: TurnRunnerConfig): TurnRunner;Parameters
| Parameter | Type | Description |
|---|---|---|
config | TurnRunnerConfig | Construction-time configuration validated against turnRunnerConfigSchema. |
Returns
TurnRunner
Throws
@nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG when config does not satisfy the schema.
Methods
observe()
observe<K>(event: TurnObservabilityEvent<K>, listener: TurnObservabilityEventListener<K>): this;Registers a persistent observability listener for event.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnObservabilityEvent<K> | The event to observe. |
listener | TurnObservabilityEventListener<K> | The function to call on each emission. |
Returns
this
this for chaining.
Remarks
Use the observability bus (observe / unobserve / observeOnce) for instrumentation: turn lifecycle, gate lifecycle, and non-fatal errors. Use the functional bus (on / off / once) for pipeline-affecting events: message, thought, toolCall.
observeOnce()
observeOnce<K>(event: TurnObservabilityEvent<K>, listener: TurnObservabilityEventListener<K>): this;Registers a one-time observability listener for event that is automatically removed after the first emission.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnObservabilityEvent<K> | The event to observe once. |
listener | TurnObservabilityEventListener<K> | The function to call on the next emission. |
Returns
this
this for chaining.
off()
off<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this;Removes a previously registered functional listener for event.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnEvent<K> | The event to stop listening to. |
listener | TurnEventListener<K> | The listener function to remove. |
Returns
this
this for chaining.
on()
on<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this;Registers a persistent functional listener for event.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnEvent<K> | The event to listen to. |
listener | TurnEventListener<K> | The function to call on each emission. |
Returns
this
this for chaining.
once()
once<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this;Registers a one-time functional listener for event that is automatically removed after the first emission.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnEvent<K> | The event to listen to. |
listener | TurnEventListener<K> | The function to call on the next emission. |
Returns
this
this for chaining.
run()
run(context: RawTurnContext): Promise<void>;Executes a single agent turn against the provided raw context.
Parameters
| Parameter | Type | Description |
|---|---|---|
context | RawTurnContext | Raw input validated and wrapped into a @nhtio/adk!TurnContext before execution. |
Returns
Promise<void>
Remarks
Returns Promise<void> intentionally — all meaningful output surfaces via events, not return values. Register listeners before calling run: observability events (turnStart, turnEnd) bracket execution; functional events (message, thought, toolCall) fire throughout; observability error carries non-fatal pipeline failures; turnGateOpen and turnGateClosed fire when middleware suspends via ctx.waitFor(). Awaiting this method only tells you the pipeline has finished, not what it produced.
Constructs a validated @nhtio/adk!TurnContext from context (throwing @nhtio/adk!E_INVALID_TURN_CONTEXT on failure), then runs the input middleware pipeline. Abort signals are silently swallowed.
Throws
@nhtio/adk!E_INVALID_TURN_CONTEXT when context does not satisfy the schema.
unobserve()
unobserve<K>(event: TurnObservabilityEvent<K>, listener: TurnObservabilityEventListener<K>): this;Removes a previously registered observability listener for event.
Type Parameters
| Type Parameter |
|---|
K |
Parameters
| Parameter | Type | Description |
|---|---|---|
event | TurnObservabilityEvent<K> | The event to stop observing. |
listener | TurnObservabilityEventListener<K> | The listener function to remove. |
Returns
this
this for chaining.
isTurnRunner()
static isTurnRunner(value: unknown): value is TurnRunner;Returns true if value is a TurnRunner instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
value | unknown | The value to test. |
Returns
value is TurnRunner
true when value is a TurnRunner instance.
Remarks
Uses @nhtio/adk!isInstanceOf for cross-realm safety.