diff options
| author | Adam Malczewski <[email protected]> | 2026-06-04 22:59:57 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-04 22:59:57 +0900 |
| commit | 974ce6f46c25a522a42c6bd04fd62ce2d031aad5 (patch) | |
| tree | 79564a1e5c4265c07e0a313a12ee385155635b1a /packages/kernel | |
| parent | ae22da591474d4be7daf16be552ad7437ef1828b (diff) | |
| download | dispatch-974ce6f46c25a522a42c6bd04fd62ce2d031aad5.tar.gz dispatch-974ce6f46c25a522a42c6bd04fd62ce2d031aad5.zip | |
feat(contracts): RunTurnInput gains tabId/turnId/providerOpts; FinishReason union (resolves runtime CR-1/2/3)
Diffstat (limited to 'packages/kernel')
| -rw-r--r-- | packages/kernel/src/contracts/index.ts | 1 | ||||
| -rw-r--r-- | packages/kernel/src/contracts/runtime.ts | 37 | ||||
| -rw-r--r-- | packages/kernel/src/runtime/run-turn.test.ts | 32 |
3 files changed, 67 insertions, 3 deletions
diff --git a/packages/kernel/src/contracts/index.ts b/packages/kernel/src/contracts/index.ts index 1c3393f..0b578cb 100644 --- a/packages/kernel/src/contracts/index.ts +++ b/packages/kernel/src/contracts/index.ts @@ -82,6 +82,7 @@ export type { } from "./provider.js"; export type { EventEmitter, + FinishReason, RunTurnInput, RunTurnResult, } from "./runtime.js"; diff --git a/packages/kernel/src/contracts/runtime.ts b/packages/kernel/src/contracts/runtime.ts index 15f4869..ff994af 100644 --- a/packages/kernel/src/contracts/runtime.ts +++ b/packages/kernel/src/contracts/runtime.ts @@ -10,7 +10,7 @@ import type { ChatMessage } from "./conversation.js"; import type { ToolDispatchPolicy } from "./dispatch.js"; import type { AgentEvent } from "./events.js"; -import type { ProviderContract, Usage } from "./provider.js"; +import type { ProviderContract, ProviderStreamOptions, Usage } from "./provider.js"; import type { ToolContract } from "./tool.js"; /** @@ -20,6 +20,21 @@ import type { ToolContract } from "./tool.js"; export type EventEmitter = (event: AgentEvent) => void; /** + * Why a turn ended. Known kernel/provider reasons are enumerated for ergonomics; + * the trailing `(string & {})` keeps the type open for provider-specific reasons + * passed through verbatim without losing autocomplete on the known values. + */ +export type FinishReason = + | "stop" + | "tool-calls" + | "length" + | "content-filter" + | "max-steps" + | "error" + | "aborted" + | (string & {}); + +/** * Input to `runTurn` — everything the kernel needs to execute one turn. * All fields are resolved by the session-orchestrator before calling; * the kernel never reads config or resolves providers/tools itself. @@ -40,6 +55,22 @@ export interface RunTurnInput { /** The emitter the kernel calls for each outward event. */ readonly emit: EventEmitter; + /** + * Identifiers used to attribute every emitted `AgentEvent`. The kernel does + * not generate these — the session-orchestrator owns turn/tab identity and + * passes them in, so events are traceable to their conversation. + */ + readonly tabId: string; + readonly turnId: string; + + /** + * Optional per-turn provider options (model, temperature, maxTokens, + * systemPrompt). The orchestrator resolves these; the kernel forwards them + * verbatim to `provider.stream` and never interprets them. A provider may + * also be pre-configured at construction and ignore these. + */ + readonly providerOpts?: ProviderStreamOptions; + /** Cancellation signal for the entire turn. */ readonly signal?: AbortSignal; } @@ -55,6 +86,6 @@ export interface RunTurnResult { /** Aggregated token usage across all steps in the turn. */ readonly usage: Usage; - /** Why the turn ended (e.g. "stop", "max-steps", "error", "aborted"). */ - readonly finishReason: string; + /** Why the turn ended. */ + readonly finishReason: FinishReason; } diff --git a/packages/kernel/src/runtime/run-turn.test.ts b/packages/kernel/src/runtime/run-turn.test.ts index eba05e6..f63a0a8 100644 --- a/packages/kernel/src/runtime/run-turn.test.ts +++ b/packages/kernel/src/runtime/run-turn.test.ts @@ -70,6 +70,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); @@ -111,6 +113,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); @@ -167,6 +171,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -214,6 +220,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [toolA, toolB], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -256,6 +264,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [toolA, toolB], dispatch: { maxConcurrent: 2, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -312,6 +322,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [toolA, toolB, toolC], dispatch: { maxConcurrent: 0, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -371,6 +383,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: true }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -420,6 +434,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -467,6 +483,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, signal: ac.signal, }); @@ -497,6 +515,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, signal: ac.signal, }); @@ -533,6 +553,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); @@ -605,6 +627,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [unsafeTool, safeTool], dispatch: { maxConcurrent: 5, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -637,6 +661,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); @@ -668,6 +694,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); @@ -701,6 +729,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit: () => {}, }); @@ -737,6 +767,8 @@ describe("runTurn", () => { messages: [userMessage], tools: [tool], dispatch: { maxConcurrent: 1, eager: false }, + tabId: "tab-test", + turnId: "turn-test", emit, }); |
