Skip to content
4 min read · 790 words

Interface: DispatchExecutorHelpers

Per-dispatch helpers passed to DispatchExecutorFn alongside the active @nhtio/adk!DispatchContext.

Remarks

DispatchRunner constructs a fresh helpers instance for every dispatch and threads it through every iteration of that dispatch. Per-id stream state is scoped to the dispatch — helpers are garbage-collected with the runner, so cross-dispatch state cannot leak.

Helpers are emit-only: they call ctx.emitMessage / ctx.emitThought / ctx.emitToolCall to surface streaming content. They do not persist Message / Thought / ToolCall records, because building those records requires implementation-specific fields (role, identity, SpooledArtifact for results) that the wire payload doesn't carry. The executor calls ctx.storeMessage(...) / ctx.storeThought(...) / ctx.storeToolCall(...) itself when it has the full record assembled.

The value the helpers add is per-id accumulation state. Without them, every executor reimplements a per-id Map<id, { full, createdAt, ... }> to track streaming chunks across SDK callbacks.

Properties

PropertyTypeDescription
logDispatchExecutorLogChannelEmit a structured log event for the current dispatch. Remarks trace / debug / info / warn / error mirror the standard syslog severity levels. Each call routes through the runner's observability bus as a log event so middleware, tests, and consumer observability stacks can subscribe without monkey-patching the executor. The runner enriches every emission with the active dispatchId and 0-based iteration index — call sites only need to supply a kind discriminator, a human-readable message, and an optional structured payload. The log channel is the canonical egress for executor-side diagnostics — retry decisions, idle / request-timeout fires, HTTP error bodies, SSE chunk anomalies, provider-quirk warnings, context-window perBucket breakdowns. Use it instead of console.*.

Methods

reportMessage()

ts
reportMessage(
   id: string,
   deltaText: string,
   opts?: {
  isComplete?: boolean;
}): void;

Append a delta to the message stream for id and emit a @nhtio/adk!TurnStreamableContent.

Parameters

ParameterTypeDescription
idstringStable identifier for this message stream.
deltaTextstringThe new chunk to append.
opts?{ isComplete?: boolean; }-
opts.isComplete?booleanWhen true, this is the final chunk for id.

Returns

void

Remarks

On the first call for id, creates the stream with createdAt / updatedAt set to now and full equal to deltaText. On subsequent calls, appends deltaText to the accumulated full and updates updatedAt. When opts.isComplete is true, sets completedAt and seals the stream — subsequent calls for the same id will throw.


reportThought()

ts
reportThought(
   id: string,
   deltaText: string,
   opts?: {
  isComplete?: boolean;
}): void;

Append a delta to the thought stream for id and emit a @nhtio/adk!TurnStreamableContent.

Parameters

ParameterTypeDescription
idstringStable identifier for this thought stream.
deltaTextstringThe new chunk to append.
opts?{ isComplete?: boolean; }-
opts.isComplete?booleanWhen true, this is the final chunk for id.

Returns

void

Remarks

Same accumulation semantics as DispatchExecutorHelpers.reportMessage but emits via ctx.emitThought. Used for reasoning trace chunks that the executor wants to surface but not show to the end user.


reportToolCall()

ts
reportToolCall(id: string, partial: {
  args?: unknown;
  isComplete?: boolean;
  isError?: boolean;
  results?: unknown;
  tool?: string;
}): void;

Update tool call state for id and emit a @nhtio/adk!TurnToolCallContent.

Parameters

ParameterTypeDescription
idstringStable identifier for this tool call (correlates request with result).
partial{ args?: unknown; isComplete?: boolean; isError?: boolean; results?: unknown; tool?: string; }Fields to merge into the tool call state.
partial.args?unknown-
partial.isComplete?boolean-
partial.isError?boolean-
partial.results?unknownShape depends on the tool kind backing this call. Remarks For a normal @nhtio/adk!Tool call, this is typically a @nhtio/adk!SpooledArtifact (single or array — a tool may legitimately spool multiple bounded artifacts in a single call) wrapping the bytes returned by the handler, or one or more @nhtio/adk!Media instances when the handler chose the explicit-modality return path. For an @nhtio/adk!ArtifactTool call, this should be the raw string the handler emitted (Tokenizable.toString()-equivalent — already the model-visible answer). Type stays unknown to keep the wire-side payload narrow.
partial.tool?string-

Returns

void

Remarks

Accepts a partial of the tool call fields; the helper merges into the per-id state and emits the merged view. Typical usage is two calls: one with { tool, args } to announce the requested call (helper auto-computes checksum via SHA-256 of JSON.stringify({tool, args})), and one with { results, isComplete: true, isError? } after the tool runs.

Calls after isComplete: true will throw — the per-id state is sealed.