summaryrefslogtreecommitdiffhomepage
path: root/packages/kernel/src/runtime/run-turn.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-12 00:43:55 +0900
committerAdam Malczewski <[email protected]>2026-06-12 00:43:55 +0900
commite2646ad2b0c28bd64ad4efd6b154f97f8a35e0ad (patch)
tree0f739576bbabf19ebb0e254776188b0950c4f489 /packages/kernel/src/runtime/run-turn.ts
parente7eada4802ceebd86c83bcd6e3eca70152e7f331 (diff)
downloaddispatch-e2646ad2b0c28bd64ad4efd6b154f97f8a35e0ad.tar.gz
dispatch-e2646ad2b0c28bd64ad4efd6b154f97f8a35e0ad.zip
feat(metrics): expose current context size to the frontend
contextSize = the turn's FINAL step inputTokens+outputTokens (true context occupancy; NOT the aggregate usage, which sums per-step prompts and overcounts multi-step turns). Stamped on both the live done event (kernel) and persisted TurnMetrics (session-orchestrator); a client reads the latest turn's value. - @dispatch/wire 0.4.0->0.5.0: optional contextSize on TurnDoneEvent + TurnMetrics - @dispatch/transport-contract 0.5.0->0.6.0 (re-export only) - glossary: context size (reserve 'context window' for the model limit, later) - FE courier: frontend-context-size-handoff.md 881 vitest pass; tsc -b EXIT 0; biome clean.
Diffstat (limited to 'packages/kernel/src/runtime/run-turn.ts')
-rw-r--r--packages/kernel/src/runtime/run-turn.ts7
1 files changed, 7 insertions, 0 deletions
diff --git a/packages/kernel/src/runtime/run-turn.ts b/packages/kernel/src/runtime/run-turn.ts
index b50e8ee..bf57854 100644
--- a/packages/kernel/src/runtime/run-turn.ts
+++ b/packages/kernel/src/runtime/run-turn.ts
@@ -449,6 +449,7 @@ export async function runTurn(input: RunTurnInput): Promise<RunTurnResult> {
const messages: ChatMessage[] = [...input.messages];
const resultMessages: ChatMessage[] = [];
let totalUsage = zeroUsage();
+ let lastStepUsage: Usage | undefined;
let finishReason = "stop";
const toolMap = new Map<string, ToolContract>();
@@ -513,6 +514,7 @@ export async function runTurn(input: RunTurnInput): Promise<RunTurnResult> {
});
totalUsage = addUsage(totalUsage, stepResult.usage);
+ lastStepUsage = stepResult.usage;
if (stepResult.assistantMessage !== undefined) {
messages.push(stepResult.assistantMessage);
@@ -571,6 +573,10 @@ export async function runTurn(input: RunTurnInput): Promise<RunTurnResult> {
totalUsage.outputTokens > 0 ||
totalUsage.cacheReadTokens !== undefined ||
totalUsage.cacheWriteTokens !== undefined;
+ const contextSize =
+ hasUsage && lastStepUsage !== undefined
+ ? lastStepUsage.inputTokens + lastStepUsage.outputTokens
+ : undefined;
input.emit(
doneEvent(
conversationId,
@@ -578,6 +584,7 @@ export async function runTurn(input: RunTurnInput): Promise<RunTurnResult> {
finishReason,
turnDurationMs,
hasUsage ? totalUsage : undefined,
+ contextSize,
),
);