@minpeter/pss-runtime 0.1.0-next.3 → 0.1.0-next.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,19 +50,18 @@ consume the events for the run to progress. This is what lets code react to
50
50
  created.
51
51
 
52
52
  `model` is the single public constructor key for model execution. Pass an AI SDK
53
- `LanguageModel` for the managed runtime path with `instructions` and `tools`, or
54
- pass a custom `RuntimeLlm` function when you want to own the model
55
- adapter yourself:
53
+ `LanguageModel` object and configure runtime-owned prompting through
54
+ `instructions`, `tools`, and `toolChoice`:
56
55
 
57
56
  ```ts
58
- import { Agent, type RuntimeLlm } from "@minpeter/pss-runtime";
57
+ import { openai } from "@ai-sdk/openai";
58
+ import { Agent } from "@minpeter/pss-runtime";
59
59
 
60
- const runtimeModel: RuntimeLlm = async ({ history }) => [
61
- { role: "assistant", content: `Seen ${history.length} messages.` },
62
- ];
60
+ const model = openai("gpt-4.1-mini");
63
61
 
64
62
  const agent = new Agent({
65
- model: runtimeModel,
63
+ instructions: "Answer with concise operational notes.",
64
+ model,
66
65
  });
67
66
  ```
68
67
 
@@ -457,7 +456,7 @@ calls. Tools are checkpointed before and after execution and receive stable
457
456
  `attempt`, `idempotencyKey`, `retryPolicy`, `signal`, and public `toolCallId`
458
457
  values. The `@minpeter/pss-runtime/execution` entrypoint also exposes the same
459
458
  low-level tool execution checkpoint types for custom resume runners built
460
- directly on `createLlm`.
459
+ directly on AI SDK `LanguageModel` objects.
461
460
 
462
461
  These checkpoints are rollback boundaries, not a complete host adapter by
463
462
  themselves. Edge hosts still need durable scheduling, leases, resume workers,
@@ -1,6 +1,7 @@
1
1
  import { modelMessageToAgentEvents } from "./session/mapping.js";
2
+ import { generateModelStep } from "./llm.js";
2
3
  //#region src/agent-loop.ts
3
- async function runAgentLoop({ captureObserverEvents = captureNoObserverEvents, emit, history, llm, signal = new AbortController().signal, toolExecution }) {
4
+ async function runAgentLoop({ captureObserverEvents = captureNoObserverEvents, emit, history, model, signal = new AbortController().signal, toolExecution }) {
4
5
  while (true) {
5
6
  if (signal.aborted) return "aborted";
6
7
  if (await emitBoundary({
@@ -8,9 +9,9 @@ async function runAgentLoop({ captureObserverEvents = captureNoObserverEvents, e
8
9
  event: { type: "step-start" },
9
10
  signal
10
11
  }) === "aborted") return "aborted";
11
- const capturedOutput = await captureObserverEvents(() => readLlmOutput({
12
+ const capturedOutput = await captureObserverEvents(() => readModelOutput({
12
13
  history,
13
- llm,
14
+ model,
14
15
  signal,
15
16
  toolExecution
16
17
  }));
@@ -65,10 +66,11 @@ async function captureNoObserverEvents(callback) {
65
66
  };
66
67
  }
67
68
  function releaseNoObserverEvents() {}
68
- async function readLlmOutput({ history, llm, signal, toolExecution }) {
69
+ async function readModelOutput({ history, model, signal, toolExecution }) {
69
70
  try {
70
- return await llm({
71
+ return await generateModelStep({
71
72
  history: history.modelSnapshot(),
73
+ ...model,
72
74
  signal,
73
75
  toolExecution
74
76
  });
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.js","names":[],"sources":["../src/agent-loop.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport type { RuntimeLlm, RuntimeLlmOutput } from \"./llm\";\nimport type { RuntimeToolExecutionContext } from \"./llm-tool-execution\";\nimport type { AgentEvent } from \"./session/events\";\nimport { modelMessageToAgentEvents } from \"./session/mapping\";\n\ninterface ModelHistory {\n appendModelMessage(message: ModelMessage): void;\n modelSnapshot(): ModelMessage[];\n}\n\ninterface RunAgentLoopOptions {\n captureObserverEvents?: ObserverEventCapture;\n emit: AgentLoopEventListener;\n history: ModelHistory;\n llm: RuntimeLlm;\n signal?: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}\n\ntype AgentLoopResult = \"completed\" | \"aborted\";\ntype AgentLoopBoundaryEvent = Extract<\n AgentEvent,\n { type: \"step-end\" } | { type: \"step-start\" }\n>;\ninterface AgentLoopBoundaryDecision {\n readonly runtimeInputAdded?: boolean;\n}\ntype AgentLoopEventListener = (\n event: AgentEvent\n) =>\n | AgentLoopBoundaryDecision\n | Promise<AgentLoopBoundaryDecision | undefined>\n | undefined;\ntype StepOutputResult = \"aborted\" | \"completed\" | \"continue\";\ninterface ObserverEventCaptureResult<T> {\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n}\ntype ObserverEventCapture = <T>(\n callback: () => Promise<T>\n) => Promise<ObserverEventCaptureResult<T>>;\n\nexport async function runAgentLoop({\n captureObserverEvents = captureNoObserverEvents,\n emit,\n history,\n llm,\n signal = new AbortController().signal,\n toolExecution,\n}: RunAgentLoopOptions): Promise<AgentLoopResult> {\n while (true) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n const stepStartDecision = await emitBoundary({\n emit,\n event: { type: \"step-start\" },\n signal,\n });\n\n if (stepStartDecision === \"aborted\") {\n return \"aborted\";\n }\n\n const capturedOutput = await captureObserverEvents(() =>\n readLlmOutput({ history, llm, signal, toolExecution })\n );\n const output = capturedOutput.value;\n\n if (output === \"aborted\") {\n return \"aborted\";\n }\n\n const result = await appendCapturedStepOutput({\n capturedOutput,\n emit,\n history,\n output,\n signal,\n });\n\n if (result === \"aborted\") {\n return \"aborted\";\n }\n\n const stepEndDecision = await emitBoundary({\n emit,\n event: { type: \"step-end\" },\n signal,\n });\n\n if (stepEndDecision === \"aborted\") {\n return \"aborted\";\n }\n\n // Runtime input after step-end intentionally forces another inference step,\n // even after final-looking assistant text. Unconditional insertion on every\n // step-end can create an unbounded loop.\n if (result === \"completed\" && !stepEndDecision?.runtimeInputAdded) {\n return \"completed\";\n }\n }\n}\n\nasync function emitBoundary({\n emit,\n event,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & {\n event: AgentLoopBoundaryEvent;\n signal: AbortSignal;\n}): Promise<AgentLoopBoundaryDecision | \"aborted\" | undefined> {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n const abort = createAbortBoundary(signal);\n try {\n return await Promise.race([Promise.resolve(emit(event)), abort.promise]);\n } catch (error) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n throw error;\n } finally {\n abort.dispose();\n }\n}\n\nfunction createAbortBoundary(signal: AbortSignal): {\n dispose: () => void;\n promise: Promise<\"aborted\">;\n} {\n let dispose: () => void = () => undefined;\n\n const promise = new Promise<\"aborted\">((resolve) => {\n const onAbort = () => resolve(\"aborted\");\n dispose = () => signal.removeEventListener(\"abort\", onAbort);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n return { dispose, promise };\n}\n\nasync function captureNoObserverEvents<T>(callback: () => Promise<T>): Promise<{\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n}> {\n return {\n events: [],\n release: releaseNoObserverEvents,\n value: await callback(),\n };\n}\n\nfunction releaseNoObserverEvents(): void {\n return;\n}\n\nasync function readLlmOutput({\n history,\n llm,\n signal,\n toolExecution,\n}: Pick<RunAgentLoopOptions, \"history\" | \"llm\"> & {\n signal: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}): Promise<RuntimeLlmOutput | \"aborted\"> {\n try {\n return await llm({\n history: history.modelSnapshot(),\n signal,\n toolExecution,\n });\n } catch (error) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n throw error;\n }\n}\n\nasync function appendCapturedStepOutput({\n capturedOutput,\n emit,\n history,\n output,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & { history: ModelHistory } & {\n capturedOutput: ObserverEventCaptureResult<RuntimeLlmOutput | \"aborted\">;\n output: RuntimeLlmOutput;\n signal: AbortSignal;\n}): Promise<StepOutputResult> {\n try {\n return await appendStepOutput({\n emit,\n history,\n observerEvents: capturedOutput.events,\n output,\n signal,\n });\n } finally {\n capturedOutput.release();\n }\n}\n\nasync function appendStepOutput({\n emit,\n history,\n observerEvents,\n output,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & { history: ModelHistory } & {\n observerEvents: AgentEvent[];\n output: RuntimeLlmOutput;\n signal: AbortSignal;\n}): Promise<StepOutputResult> {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n let shouldContinue = false;\n const pendingObserverEvents = observerEvents;\n const flushObserverEvents = async (\n shouldFlush: (event: AgentEvent) => boolean = () => true\n ) => {\n for (let index = 0; index < pendingObserverEvents.length; ) {\n const event = pendingObserverEvents[index];\n if (!(event && shouldFlush(event))) {\n index += 1;\n continue;\n }\n pendingObserverEvents.splice(index, 1);\n await emit(event);\n }\n };\n\n for (const message of output) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n history.appendModelMessage(message);\n const events = modelMessageToAgentEvents(message);\n const hasToolResult = events.some((event) => event.type === \"tool-result\");\n\n for (const event of events) {\n await emit(event);\n if (event.type === \"tool-call\") {\n shouldContinue = true;\n await flushObserverEvents(isLaunchOrBlockingObserverEvent);\n }\n }\n\n if (hasToolResult) {\n await flushObserverEvents();\n }\n }\n\n await flushObserverEvents();\n\n return shouldContinue ? \"continue\" : \"completed\";\n}\n\nfunction isLaunchOrBlockingObserverEvent(_event: AgentEvent): boolean {\n return true;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-loop.js","names":[],"sources":["../src/agent-loop.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport {\n generateModelStep,\n type ModelGenerationOptions,\n type ModelStepOutput,\n} from \"./llm\";\nimport type { RuntimeToolExecutionContext } from \"./llm-tool-execution\";\nimport type { AgentEvent } from \"./session/events\";\nimport { modelMessageToAgentEvents } from \"./session/mapping\";\n\ninterface ModelHistory {\n appendModelMessage(message: ModelMessage): void;\n modelSnapshot(): ModelMessage[];\n}\n\ninterface RunAgentLoopOptions {\n captureObserverEvents?: ObserverEventCapture;\n emit: AgentLoopEventListener;\n history: ModelHistory;\n model: ModelGenerationOptions;\n signal?: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}\n\ntype AgentLoopResult = \"completed\" | \"aborted\";\ntype AgentLoopBoundaryEvent = Extract<\n AgentEvent,\n { type: \"step-end\" } | { type: \"step-start\" }\n>;\ninterface AgentLoopBoundaryDecision {\n readonly runtimeInputAdded?: boolean;\n}\ntype AgentLoopEventListener = (\n event: AgentEvent\n) =>\n | AgentLoopBoundaryDecision\n | Promise<AgentLoopBoundaryDecision | undefined>\n | undefined;\ntype StepOutputResult = \"aborted\" | \"completed\" | \"continue\";\ninterface ObserverEventCaptureResult<T> {\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n}\ntype ObserverEventCapture = <T>(\n callback: () => Promise<T>\n) => Promise<ObserverEventCaptureResult<T>>;\n\nexport async function runAgentLoop({\n captureObserverEvents = captureNoObserverEvents,\n emit,\n history,\n model,\n signal = new AbortController().signal,\n toolExecution,\n}: RunAgentLoopOptions): Promise<AgentLoopResult> {\n while (true) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n const stepStartDecision = await emitBoundary({\n emit,\n event: { type: \"step-start\" },\n signal,\n });\n\n if (stepStartDecision === \"aborted\") {\n return \"aborted\";\n }\n\n const capturedOutput = await captureObserverEvents(() =>\n readModelOutput({ history, model, signal, toolExecution })\n );\n const output = capturedOutput.value;\n\n if (output === \"aborted\") {\n return \"aborted\";\n }\n\n const result = await appendCapturedStepOutput({\n capturedOutput,\n emit,\n history,\n output,\n signal,\n });\n\n if (result === \"aborted\") {\n return \"aborted\";\n }\n\n const stepEndDecision = await emitBoundary({\n emit,\n event: { type: \"step-end\" },\n signal,\n });\n\n if (stepEndDecision === \"aborted\") {\n return \"aborted\";\n }\n\n // Runtime input after step-end intentionally forces another inference step,\n // even after final-looking assistant text. Unconditional insertion on every\n // step-end can create an unbounded loop.\n if (result === \"completed\" && !stepEndDecision?.runtimeInputAdded) {\n return \"completed\";\n }\n }\n}\n\nasync function emitBoundary({\n emit,\n event,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & {\n event: AgentLoopBoundaryEvent;\n signal: AbortSignal;\n}): Promise<AgentLoopBoundaryDecision | \"aborted\" | undefined> {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n const abort = createAbortBoundary(signal);\n try {\n return await Promise.race([Promise.resolve(emit(event)), abort.promise]);\n } catch (error) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n throw error;\n } finally {\n abort.dispose();\n }\n}\n\nfunction createAbortBoundary(signal: AbortSignal): {\n dispose: () => void;\n promise: Promise<\"aborted\">;\n} {\n let dispose: () => void = () => undefined;\n\n const promise = new Promise<\"aborted\">((resolve) => {\n const onAbort = () => resolve(\"aborted\");\n dispose = () => signal.removeEventListener(\"abort\", onAbort);\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n return { dispose, promise };\n}\n\nasync function captureNoObserverEvents<T>(callback: () => Promise<T>): Promise<{\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n}> {\n return {\n events: [],\n release: releaseNoObserverEvents,\n value: await callback(),\n };\n}\n\nfunction releaseNoObserverEvents(): void {\n return;\n}\n\nasync function readModelOutput({\n history,\n model,\n signal,\n toolExecution,\n}: Pick<RunAgentLoopOptions, \"history\" | \"model\"> & {\n signal: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}): Promise<ModelStepOutput | \"aborted\"> {\n try {\n return await generateModelStep({\n history: history.modelSnapshot(),\n ...model,\n signal,\n toolExecution,\n });\n } catch (error) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n throw error;\n }\n}\n\nasync function appendCapturedStepOutput({\n capturedOutput,\n emit,\n history,\n output,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & { history: ModelHistory } & {\n capturedOutput: ObserverEventCaptureResult<ModelStepOutput | \"aborted\">;\n output: ModelStepOutput;\n signal: AbortSignal;\n}): Promise<StepOutputResult> {\n try {\n return await appendStepOutput({\n emit,\n history,\n observerEvents: capturedOutput.events,\n output,\n signal,\n });\n } finally {\n capturedOutput.release();\n }\n}\n\nasync function appendStepOutput({\n emit,\n history,\n observerEvents,\n output,\n signal,\n}: Pick<RunAgentLoopOptions, \"emit\"> & { history: ModelHistory } & {\n observerEvents: AgentEvent[];\n output: ModelStepOutput;\n signal: AbortSignal;\n}): Promise<StepOutputResult> {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n let shouldContinue = false;\n const pendingObserverEvents = observerEvents;\n const flushObserverEvents = async (\n shouldFlush: (event: AgentEvent) => boolean = () => true\n ) => {\n for (let index = 0; index < pendingObserverEvents.length; ) {\n const event = pendingObserverEvents[index];\n if (!(event && shouldFlush(event))) {\n index += 1;\n continue;\n }\n pendingObserverEvents.splice(index, 1);\n await emit(event);\n }\n };\n\n for (const message of output) {\n if (signal.aborted) {\n return \"aborted\";\n }\n\n history.appendModelMessage(message);\n const events = modelMessageToAgentEvents(message);\n const hasToolResult = events.some((event) => event.type === \"tool-result\");\n\n for (const event of events) {\n await emit(event);\n if (event.type === \"tool-call\") {\n shouldContinue = true;\n await flushObserverEvents(isLaunchOrBlockingObserverEvent);\n }\n }\n\n if (hasToolResult) {\n await flushObserverEvents();\n }\n }\n\n await flushObserverEvents();\n\n return shouldContinue ? \"continue\" : \"completed\";\n}\n\nfunction isLaunchOrBlockingObserverEvent(_event: AgentEvent): boolean {\n return true;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AgentToolChoice, RuntimeLlm } from "./llm.js";
1
+ import { AgentToolChoice } from "./llm.js";
2
2
  import { AgentHost } from "./execution/types.js";
3
3
  import { AgentPlugin } from "./plugins.js";
4
4
  import { LanguageModel, ToolSet } from "ai";
@@ -13,16 +13,7 @@ interface AgentLanguageModelOptions {
13
13
  readonly toolChoice?: AgentToolChoice;
14
14
  readonly tools?: ToolSet;
15
15
  }
16
- interface AgentRuntimeModelOptions {
17
- readonly host?: AgentHost;
18
- readonly instructions?: never;
19
- readonly model: RuntimeLlm;
20
- readonly namespace?: string;
21
- readonly plugins?: readonly AgentPlugin[];
22
- readonly toolChoice?: never;
23
- readonly tools?: never;
24
- }
25
- type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;
16
+ type AgentOptions = AgentLanguageModelOptions;
26
17
  type AgentConstructionOptions = AgentOptions;
27
18
  //#endregion
28
19
  export { AgentConstructionOptions, AgentOptions };
@@ -2,15 +2,9 @@
2
2
  function assertAgentOptions(options) {
3
3
  if (options === null || typeof options !== "object") throw new TypeError("Agent options are required. Provide { model }.");
4
4
  if (!("model" in options && options.model != null)) throw new TypeError("Agent: missing options.model.");
5
- if (typeof options.model !== "function" && (typeof options.model !== "object" || options.model === null)) throw new TypeError("Agent: invalid options.model.");
6
- }
7
- function hasRuntimeModel(options) {
8
- return typeof options.model === "function";
9
- }
10
- function hasLanguageModel(options) {
11
- return typeof options.model !== "function";
5
+ if (typeof options.model !== "object" || options.model === null) throw new TypeError("Agent: invalid options.model.");
12
6
  }
13
7
  //#endregion
14
- export { assertAgentOptions, hasLanguageModel, hasRuntimeModel };
8
+ export { assertAgentOptions };
15
9
 
16
10
  //# sourceMappingURL=agent-options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-options.js","names":[],"sources":["../src/agent-options.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport type { AgentHost } from \"./execution/types\";\nimport type { AgentToolChoice, RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\n\ninterface AgentLanguageModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: string;\n readonly model: LanguageModel;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: AgentToolChoice;\n readonly tools?: ToolSet;\n}\n\ninterface AgentRuntimeModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: never;\n readonly model: RuntimeLlm;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: never;\n readonly tools?: never;\n}\n\nexport type AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\"\n>;\nexport type AgentOptions = AgentLanguageModelOptions | AgentRuntimeModelOptions;\n\nexport type AgentConstructionOptions = AgentOptions;\n\nexport function assertAgentOptions(\n options: unknown\n): asserts options is AgentConstructionOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"Agent options are required. Provide { model }.\");\n }\n\n const hasModel = \"model\" in options && options.model != null;\n\n if (!hasModel) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n\n if (\n typeof options.model !== \"function\" &&\n (typeof options.model !== \"object\" || options.model === null)\n ) {\n throw new TypeError(\"Agent: invalid options.model.\");\n }\n}\n\nexport function hasRuntimeModel(\n options: AgentConstructionOptions\n): options is AgentRuntimeModelOptions {\n return typeof options.model === \"function\";\n}\n\nexport function hasLanguageModel(\n options: AgentConstructionOptions\n): options is AgentLanguageModelOptions {\n return typeof options.model !== \"function\";\n}\n"],"mappings":";AAiCA,SAAgB,mBACd,SAC6C;CAC7C,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UAAU,gDAAgD;CAKtE,IAAI,EAFa,WAAW,WAAW,QAAQ,SAAS,OAGtD,MAAM,IAAI,UAAU,+BAA+B;CAGrD,IACE,OAAO,QAAQ,UAAU,eACxB,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,OAExD,MAAM,IAAI,UAAU,+BAA+B;AAEvD;AAEA,SAAgB,gBACd,SACqC;CACrC,OAAO,OAAO,QAAQ,UAAU;AAClC;AAEA,SAAgB,iBACd,SACsC;CACtC,OAAO,OAAO,QAAQ,UAAU;AAClC"}
1
+ {"version":3,"file":"agent-options.js","names":[],"sources":["../src/agent-options.ts"],"sourcesContent":["import type { LanguageModel, ToolSet } from \"ai\";\nimport type { AgentHost } from \"./execution/types\";\nimport type { AgentToolChoice } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\n\nexport interface AgentLanguageModelOptions {\n readonly host?: AgentHost;\n readonly instructions?: string;\n readonly model: LanguageModel;\n readonly namespace?: string;\n readonly plugins?: readonly AgentPlugin[];\n readonly toolChoice?: AgentToolChoice;\n readonly tools?: ToolSet;\n}\n\nexport type AgentModelOptions = Pick<\n AgentLanguageModelOptions,\n \"instructions\" | \"model\" | \"toolChoice\" | \"tools\"\n>;\nexport type AgentOptions = AgentLanguageModelOptions;\n\nexport type AgentConstructionOptions = AgentOptions;\n\nexport function assertAgentOptions(\n options: unknown\n): asserts options is AgentConstructionOptions {\n if (options === null || typeof options !== \"object\") {\n throw new TypeError(\"Agent options are required. Provide { model }.\");\n }\n\n const hasModel = \"model\" in options && options.model != null;\n\n if (!hasModel) {\n throw new TypeError(\"Agent: missing options.model.\");\n }\n\n if (typeof options.model !== \"object\" || options.model === null) {\n throw new TypeError(\"Agent: invalid options.model.\");\n }\n}\n"],"mappings":";AAuBA,SAAgB,mBACd,SAC6C;CAC7C,IAAI,YAAY,QAAQ,OAAO,YAAY,UACzC,MAAM,IAAI,UAAU,gDAAgD;CAKtE,IAAI,EAFa,WAAW,WAAW,QAAQ,SAAS,OAGtD,MAAM,IAAI,UAAU,+BAA+B;CAGrD,IAAI,OAAO,QAAQ,UAAU,YAAY,QAAQ,UAAU,MACzD,MAAM,IAAI,UAAU,+BAA+B;AAEvD"}
package/dist/agent.js CHANGED
@@ -1,15 +1,12 @@
1
1
  import { executionHost } from "./execution/host.js";
2
2
  import { sessionStoreForHost } from "./agent-host-session-store.js";
3
3
  import { stableAgentNamespace } from "./agent-namespace.js";
4
- import { assertAgentOptions, hasLanguageModel, hasRuntimeModel } from "./agent-options.js";
4
+ import { assertAgentOptions } from "./agent-options.js";
5
5
  import { resumeAgentRun } from "./agent-resume.js";
6
6
  import { createInMemoryExecutionHost } from "./execution/memory.js";
7
- import { createLlm } from "./llm.js";
8
7
  import { AgentSession } from "./session/session.js";
9
8
  //#region src/agent.ts
10
9
  var Agent = class {
11
- #baseTools;
12
- #llm;
13
10
  #modelOptions;
14
11
  #sessions = /* @__PURE__ */ new Map();
15
12
  #sessionNamespace;
@@ -26,15 +23,12 @@ var Agent = class {
26
23
  this.host = this.#host;
27
24
  this.#store = sessionStoreForHost(this.#host);
28
25
  this.#plugins = options.plugins ?? [];
29
- if (hasRuntimeModel(options)) this.#llm = options.model;
30
- else if (hasLanguageModel(options)) {
31
- this.#baseTools = options.tools;
32
- this.#modelOptions = {
33
- instructions: options.instructions,
34
- model: options.model,
35
- toolChoice: options.toolChoice
36
- };
37
- }
26
+ this.#modelOptions = {
27
+ instructions: options.instructions,
28
+ model: options.model,
29
+ toolChoice: options.toolChoice,
30
+ tools: options.tools
31
+ };
38
32
  }
39
33
  send(input) {
40
34
  return this.session("default").send(input);
@@ -56,7 +50,7 @@ var Agent = class {
56
50
  const existing = this.#sessions.get(key);
57
51
  if (existing) return existing;
58
52
  let session;
59
- session = new AgentSession(this.#llm ?? createLlm(this.#createLlmOptionsForSession()), {
53
+ session = new AgentSession(this.#modelOptions, {
60
54
  key,
61
55
  store: this.#store
62
56
  }, this.#plugins, { executionHost: executionHost(this.#host) });
@@ -87,16 +81,6 @@ var Agent = class {
87
81
  #resumeNotification(notification) {
88
82
  return this.#sessionEntry(notification.sessionKey).notify(notification.input, { observerEvents: notification.observerEvents });
89
83
  }
90
- #createLlmOptionsForSession() {
91
- const modelOptions = this.#modelOptions;
92
- if (!modelOptions) throw new Error("Agent: missing model options.");
93
- return {
94
- instructions: modelOptions.instructions,
95
- model: modelOptions.model,
96
- toolChoice: modelOptions.toolChoice,
97
- tools: this.#baseTools
98
- };
99
- }
100
84
  };
101
85
  //#endregion
102
86
  export { Agent };
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","names":["#baseTools","#llm","#modelOptions","#sessions","#sessionNamespace","#store","#host","#plugins","#resumeNotification","#sessionEntry","#createLlmOptionsForSession","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import type { ToolSet } from \"ai\";\nimport { sessionStoreForHost } from \"./agent-host-session-store\";\nimport { stableAgentNamespace } from \"./agent-namespace\";\nimport {\n type AgentConstructionOptions,\n type AgentModelOptions,\n assertAgentOptions,\n hasLanguageModel,\n hasRuntimeModel,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport { createLlm, type RuntimeLlm } from \"./llm\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #baseTools?: ToolSet;\n readonly #llm?: RuntimeLlm;\n readonly #modelOptions?: AgentModelOptions;\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly host: AgentHost;\n readonly namespace?: string;\n constructor(options: AgentConstructionOptions) {\n assertAgentOptions(options);\n\n this.namespace = options.namespace;\n this.#sessionNamespace = stableAgentNamespace({\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.host = this.#host;\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n if (hasRuntimeModel(options)) {\n this.#llm = options.model;\n } else if (hasLanguageModel(options)) {\n this.#baseTools = options.tools;\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n };\n }\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n const llm = this.#llm ?? createLlm(this.#createLlmOptionsForSession());\n session = new AgentSession(\n llm,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n this.#evictSessionHandle(key);\n await session.delete();\n },\n dispose: () => {\n session.kill();\n this.#evictSessionHandle(key);\n return Promise.resolve();\n },\n interrupt: () => session.interrupt(),\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n\n #createLlmOptionsForSession(): Parameters<typeof createLlm>[0] {\n const modelOptions = this.#modelOptions;\n if (!modelOptions) {\n throw new Error(\"Agent: missing model options.\");\n }\n\n return {\n instructions: modelOptions.instructions,\n model: modelOptions.model,\n toolChoice: modelOptions.toolChoice,\n tools: this.#baseTools,\n };\n }\n}\n"],"mappings":";;;;;;;;;AAyBA,IAAa,QAAb,MAAmB;CACjB;CACA;CACA;CACA,4BAAqB,IAAI,IAA+B;CACxD;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,SAAmC;EAC7C,mBAAmB,OAAO;EAE1B,KAAK,YAAY,QAAQ;EACzB,KAAKI,oBAAoB,qBAAqB,EAC5C,WAAW,QAAQ,UACrB,CAAC;EACD,KAAKE,QAAQ,QAAQ,QAAQ,4BAA4B;EACzD,KAAK,OAAO,KAAKA;EACjB,KAAKD,SAAS,oBAAoB,KAAKC,KAAK;EAC5C,KAAKC,WAAW,QAAQ,WAAW,CAAC;EACpC,IAAI,gBAAgB,OAAO,GACzB,KAAKN,OAAO,QAAQ;OACf,IAAI,iBAAiB,OAAO,GAAG;GACpC,KAAKD,aAAa,QAAQ;GAC1B,KAAKE,gBAAgB;IACnB,cAAc,QAAQ;IACtB,OAAO,QAAQ;IACf,YAAY,QAAQ;GACtB;EACF;CACF;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,MAAM,OAAO,OAAyC;EACpD,MAAM,OAAO,cAAc,KAAKI,KAAK;EACrC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iDAAiD;EAGnE,OAAO,MAAM,eAAe;GAC1B;GACA,gBAAgB,KAAKF;GACrB,qBAAqB,iBACnB,KAAKI,oBAAoB,YAAY;GACvC;EACF,CAAC;CACH;CAEA,QAAQ,KAA4B;EAClC,OAAO,KAAKC,cAAc,GAAG,EAAE;CACjC;CAEA,cAAc,KAAgC;EAC5C,MAAM,WAAW,KAAKN,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EAEJ,UAAU,IAAI,aADF,KAAKF,QAAQ,UAAU,KAAKS,4BAA4B,CAAC,GAGnE;GAAE;GAAK,OAAO,KAAKL;EAAO,GAC1B,KAAKE,UACL,EACE,eAAe,cAAc,KAAKD,KAAK,EACzC,CACF;EAgBA,MAAM,QAA2B;GAC/B,SAAS,OAAO,YAAY,QAAQ,OAAO,OAAO,OAAO;GACzD,cAAA;IAhBA,QAAQ,YAAY;KAClB,QAAQ,KAAK;KACb,KAAKK,oBAAoB,GAAG;KAC5B,MAAM,QAAQ,OAAO;IACvB;IACA,eAAe;KACb,QAAQ,KAAK;KACb,KAAKA,oBAAoB,GAAG;KAC5B,OAAO,QAAQ,QAAQ;IACzB;IACA,iBAAiB,QAAQ,UAAU;IACnC,OAAO,UAAU,QAAQ,KAAK,KAAK;IACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;GAI1B;EACb;EACA,KAAKR,UAAU,IAAI,KAAK,KAAK;EAC7B,OAAO;CACT;CAEA,oBAAoB,KAAmB;EACrC,KAAKA,UAAU,OAAO,GAAG;CAC3B;CAEA,oBAAoB,cAAqD;EACvE,OAAO,KAAKM,cAAc,aAAa,UAAU,EAAE,OACjD,aAAa,OACb,EAAE,gBAAgB,aAAa,eAAe,CAChD;CACF;CAEA,8BAA+D;EAC7D,MAAM,eAAe,KAAKP;EAC1B,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+BAA+B;EAGjD,OAAO;GACL,cAAc,aAAa;GAC3B,OAAO,aAAa;GACpB,YAAY,aAAa;GACzB,OAAO,KAAKF;EACd;CACF;AACF"}
1
+ {"version":3,"file":"agent.js","names":["#modelOptions","#sessions","#sessionNamespace","#store","#host","#plugins","#resumeNotification","#sessionEntry","#evictSessionHandle"],"sources":["../src/agent.ts"],"sourcesContent":["import { sessionStoreForHost } from \"./agent-host-session-store\";\nimport { stableAgentNamespace } from \"./agent-namespace\";\nimport {\n type AgentConstructionOptions,\n type AgentModelOptions,\n assertAgentOptions,\n} from \"./agent-options\";\nimport { resumeAgentRun } from \"./agent-resume\";\nimport type { AgentSessionEntry, SessionHandle } from \"./agent-session-entry\";\nimport { executionHost } from \"./execution/host\";\nimport { createInMemoryExecutionHost } from \"./execution/memory\";\nimport type { AgentHost, NotificationRecord } from \"./execution/types\";\nimport type { AgentPlugin } from \"./plugins\";\nimport type { AgentRun } from \"./session/run\";\nimport { type AgentInput, AgentSession } from \"./session/session\";\nimport type { SessionStore } from \"./session/store/types\";\n\nexport type { AgentOptions } from \"./agent-options\";\nexport type { SessionHandle } from \"./agent-session-entry\";\nexport type { AgentHost } from \"./execution/types\";\n\nexport class Agent {\n readonly #modelOptions: AgentModelOptions;\n readonly #sessions = new Map<string, AgentSessionEntry>();\n readonly #sessionNamespace: string;\n readonly #store: SessionStore;\n readonly #host: AgentHost;\n readonly #plugins: readonly AgentPlugin[];\n readonly host: AgentHost;\n readonly namespace?: string;\n constructor(options: AgentConstructionOptions) {\n assertAgentOptions(options);\n\n this.namespace = options.namespace;\n this.#sessionNamespace = stableAgentNamespace({\n namespace: options.namespace,\n });\n this.#host = options.host ?? createInMemoryExecutionHost();\n this.host = this.#host;\n this.#store = sessionStoreForHost(this.#host);\n this.#plugins = options.plugins ?? [];\n this.#modelOptions = {\n instructions: options.instructions,\n model: options.model,\n toolChoice: options.toolChoice,\n tools: options.tools,\n };\n }\n\n send(input: AgentInput): Promise<AgentRun> {\n return this.session(\"default\").send(input);\n }\n\n async resume(runId: string): Promise<AgentRun | null> {\n const host = executionHost(this.#host);\n if (!host) {\n throw new Error(\"Agent host does not support durable run resume.\");\n }\n\n return await resumeAgentRun({\n host,\n ownerNamespace: this.#sessionNamespace,\n resumeNotification: (notification) =>\n this.#resumeNotification(notification),\n runId,\n });\n }\n\n session(key: string): SessionHandle {\n return this.#sessionEntry(key).publicHandle;\n }\n\n #sessionEntry(key: string): AgentSessionEntry {\n const existing = this.#sessions.get(key);\n if (existing) {\n return existing;\n }\n\n let session: AgentSession | undefined;\n session = new AgentSession(\n this.#modelOptions,\n { key, store: this.#store },\n this.#plugins,\n {\n executionHost: executionHost(this.#host),\n }\n );\n const publicHandle: SessionHandle = {\n delete: async () => {\n session.kill();\n this.#evictSessionHandle(key);\n await session.delete();\n },\n dispose: () => {\n session.kill();\n this.#evictSessionHandle(key);\n return Promise.resolve();\n },\n interrupt: () => session.interrupt(),\n send: (input) => session.send(input),\n steer: (input) => session.steer(input),\n };\n const entry: AgentSessionEntry = {\n notify: (input, options) => session.notify(input, options),\n publicHandle,\n };\n this.#sessions.set(key, entry);\n return entry;\n }\n\n #evictSessionHandle(key: string): void {\n this.#sessions.delete(key);\n }\n\n #resumeNotification(notification: NotificationRecord): Promise<AgentRun> {\n return this.#sessionEntry(notification.sessionKey).notify(\n notification.input,\n { observerEvents: notification.observerEvents }\n );\n }\n}\n"],"mappings":";;;;;;;;AAqBA,IAAa,QAAb,MAAmB;CACjB;CACA,4BAAqB,IAAI,IAA+B;CACxD;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,SAAmC;EAC7C,mBAAmB,OAAO;EAE1B,KAAK,YAAY,QAAQ;EACzB,KAAKE,oBAAoB,qBAAqB,EAC5C,WAAW,QAAQ,UACrB,CAAC;EACD,KAAKE,QAAQ,QAAQ,QAAQ,4BAA4B;EACzD,KAAK,OAAO,KAAKA;EACjB,KAAKD,SAAS,oBAAoB,KAAKC,KAAK;EAC5C,KAAKC,WAAW,QAAQ,WAAW,CAAC;EACpC,KAAKL,gBAAgB;GACnB,cAAc,QAAQ;GACtB,OAAO,QAAQ;GACf,YAAY,QAAQ;GACpB,OAAO,QAAQ;EACjB;CACF;CAEA,KAAK,OAAsC;EACzC,OAAO,KAAK,QAAQ,SAAS,EAAE,KAAK,KAAK;CAC3C;CAEA,MAAM,OAAO,OAAyC;EACpD,MAAM,OAAO,cAAc,KAAKI,KAAK;EACrC,IAAI,CAAC,MACH,MAAM,IAAI,MAAM,iDAAiD;EAGnE,OAAO,MAAM,eAAe;GAC1B;GACA,gBAAgB,KAAKF;GACrB,qBAAqB,iBACnB,KAAKI,oBAAoB,YAAY;GACvC;EACF,CAAC;CACH;CAEA,QAAQ,KAA4B;EAClC,OAAO,KAAKC,cAAc,GAAG,EAAE;CACjC;CAEA,cAAc,KAAgC;EAC5C,MAAM,WAAW,KAAKN,UAAU,IAAI,GAAG;EACvC,IAAI,UACF,OAAO;EAGT,IAAI;EACJ,UAAU,IAAI,aACZ,KAAKD,eACL;GAAE;GAAK,OAAO,KAAKG;EAAO,GAC1B,KAAKE,UACL,EACE,eAAe,cAAc,KAAKD,KAAK,EACzC,CACF;EAgBA,MAAM,QAA2B;GAC/B,SAAS,OAAO,YAAY,QAAQ,OAAO,OAAO,OAAO;GACzD,cAAA;IAhBA,QAAQ,YAAY;KAClB,QAAQ,KAAK;KACb,KAAKI,oBAAoB,GAAG;KAC5B,MAAM,QAAQ,OAAO;IACvB;IACA,eAAe;KACb,QAAQ,KAAK;KACb,KAAKA,oBAAoB,GAAG;KAC5B,OAAO,QAAQ,QAAQ;IACzB;IACA,iBAAiB,QAAQ,UAAU;IACnC,OAAO,UAAU,QAAQ,KAAK,KAAK;IACnC,QAAQ,UAAU,QAAQ,MAAM,KAAK;GAI1B;EACb;EACA,KAAKP,UAAU,IAAI,KAAK,KAAK;EAC7B,OAAO;CACT;CAEA,oBAAoB,KAAmB;EACrC,KAAKA,UAAU,OAAO,GAAG;CAC3B;CAEA,oBAAoB,cAAqD;EACvE,OAAO,KAAKM,cAAc,aAAa,UAAU,EAAE,OACjD,aAAa,OACb,EAAE,gBAAgB,aAAa,eAAe,CAChD;CACF;AACF"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AgentToolChoice, RuntimeCreateLlmOptions, RuntimeLlm, RuntimeLlmContext, RuntimeLlmOutput, RuntimeLlmOutputPart, createLlm } from "./llm.js";
1
+ import { AgentToolChoice } from "./llm.js";
2
2
  import { CommitResult, ExpectedSessionVersion, SessionStore, SessionStoreCommit, StoredSession } from "./session/store/types.js";
3
3
  import { InputEventMeta, InputSource } from "./session/input-meta-types.js";
4
4
  import { AgentInput, SessionInput, UserInput, UserMessage, UserMessageContent, UserMessageContentPart, UserMessageFileData, UserMessageFilePart, UserMessageImagePart, UserMessageTextPart, UserText, UserTextContent } from "./session/input.js";
@@ -12,4 +12,4 @@ import { SessionHandle } from "./agent-session-entry.js";
12
12
  import { Agent } from "./agent.js";
13
13
  import { delegateUserInput } from "./session/delegate-input.js";
14
14
  import { attachInputMeta, attachRuntimeInputMeta, stripEventMeta, stripInputMeta, userInputFromEvent } from "./session/input-meta.js";
15
- export { Agent, type AgentEvent, type AgentEventContext, type AgentEventListener, type AgentHost, type AgentInput, type AgentOptions, type AgentPlugin, type AgentPluginInterceptResult, type AgentPluginResult, type AgentRun, type AgentToolChoice, type AssistantReasoning, type AssistantText, type CommitResult, type ControlAgentEvent, type ExpectedSessionVersion, type InputEventMeta, type InputSource, type InterceptableAgentEvent, type LifecycleAgentEvent, type PluginPipelineResult, type RuntimeCreateLlmOptions, type RuntimeInput, type RuntimeLlm, type RuntimeLlmContext, type RuntimeLlmOutput, type RuntimeLlmOutputPart, type SessionHandle, type SessionInput, type SessionStore, type SessionStoreCommit, type StoredSession, type TelemetryAgentEvent, type ToolAgentEvent, type ToolCall, type ToolResult, type UserInput, type UserMessage, type UserMessageContent, type UserMessageContentPart, type UserMessageFileData, type UserMessageFilePart, type UserMessageImagePart, type UserMessageTextPart, type UserText, type UserTextContent, type VisibleAgentEvent, attachInputMeta, attachRuntimeInputMeta, createLlm, delegateUserInput, executionHost, isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent, runPluginsForEvent, stripEventMeta, stripInputMeta, userInputFromEvent };
15
+ export { Agent, type AgentEvent, type AgentEventContext, type AgentEventListener, type AgentHost, type AgentInput, type AgentOptions, type AgentPlugin, type AgentPluginInterceptResult, type AgentPluginResult, type AgentRun, type AgentToolChoice, type AssistantReasoning, type AssistantText, type CommitResult, type ControlAgentEvent, type ExpectedSessionVersion, type InputEventMeta, type InputSource, type InterceptableAgentEvent, type LifecycleAgentEvent, type PluginPipelineResult, type RuntimeInput, type SessionHandle, type SessionInput, type SessionStore, type SessionStoreCommit, type StoredSession, type TelemetryAgentEvent, type ToolAgentEvent, type ToolCall, type ToolResult, type UserInput, type UserMessage, type UserMessageContent, type UserMessageContentPart, type UserMessageFileData, type UserMessageFilePart, type UserMessageImagePart, type UserMessageTextPart, type UserText, type UserTextContent, type VisibleAgentEvent, attachInputMeta, attachRuntimeInputMeta, delegateUserInput, executionHost, isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent, runPluginsForEvent, stripEventMeta, stripInputMeta, userInputFromEvent };
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { executionHost } from "./execution/host.js";
2
- import { createLlm } from "./llm.js";
3
2
  import { attachInputMeta, attachRuntimeInputMeta, stripEventMeta, stripInputMeta, userInputFromEvent } from "./session/input-meta.js";
4
3
  import { runPluginsForEvent } from "./plugins.js";
5
4
  import { Agent } from "./agent.js";
6
5
  import { delegateUserInput } from "./session/delegate-input.js";
7
6
  import { isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent } from "./session/events.js";
8
- export { Agent, attachInputMeta, attachRuntimeInputMeta, createLlm, delegateUserInput, executionHost, isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent, runPluginsForEvent, stripEventMeta, stripInputMeta, userInputFromEvent };
7
+ export { Agent, attachInputMeta, attachRuntimeInputMeta, delegateUserInput, executionHost, isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent, runPluginsForEvent, stripEventMeta, stripInputMeta, userInputFromEvent };
@@ -1 +1 @@
1
- {"version":3,"file":"llm-tool-execution.js","names":[],"sources":["../src/llm-tool-execution.ts"],"sourcesContent":["import type { AssistantModelMessage, ToolModelMessage, ToolSet } from \"ai\";\nimport type { RuntimeLlmOutput } from \"./llm\";\n\nconst toolCallIdPrefix = \"call_\";\nconst publicToolCallIdPattern = /^call[-_]/;\n\ntype RuntimeLlmMessage = RuntimeLlmOutput[number];\n\nexport type RuntimeToolRetryPolicy = \"idempotent\" | \"manual-recovery\" | \"pure\";\n\nexport interface RuntimeToolExecutionCheckpointMetadata {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\nexport interface RuntimeToolExecutionCheckpoint\n extends RuntimeToolExecutionCheckpointMetadata {\n readonly input: unknown;\n}\n\nexport type RuntimePersistedToolExecutionCheckpoint =\n RuntimeToolExecutionCheckpointMetadata;\n\nexport type RuntimeToolExecutionDecision =\n | { readonly status: \"needs-recovery\" }\n | undefined;\n\nexport interface RuntimeToolExecutionContext {\n readonly afterTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint & { readonly output: unknown }\n ) => Promise<void> | void;\n readonly attempt: number;\n readonly beforeTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint\n ) => Promise<RuntimeToolExecutionDecision> | RuntimeToolExecutionDecision;\n readonly runId: string;\n}\n\nexport class ToolExecutionNeedsRecoveryError extends Error {\n readonly idempotencyKey: string;\n readonly status = \"needs-recovery\";\n readonly toolCallId: string;\n readonly toolName: string;\n\n constructor(checkpoint: RuntimeToolExecutionCheckpointMetadata) {\n super(\n `Tool ${checkpoint.toolName} requires manual recovery for ${checkpoint.idempotencyKey}`\n );\n this.idempotencyKey = checkpoint.idempotencyKey;\n this.name = \"ToolExecutionNeedsRecoveryError\";\n this.toolCallId = checkpoint.toolCallId;\n this.toolName = checkpoint.toolName;\n }\n}\n\nexport function persistedToolExecutionCheckpoint(\n checkpoint: RuntimeToolExecutionCheckpointMetadata\n): RuntimePersistedToolExecutionCheckpoint {\n return {\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n policy: checkpoint.policy,\n toolCallId: checkpoint.toolCallId,\n toolName: checkpoint.toolName,\n };\n}\n\nexport function normalizeToolCallIds(\n tools: ToolSet | undefined,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): ToolSet | undefined {\n if (!tools) {\n return;\n }\n\n return Object.fromEntries(\n Object.entries(tools).map(([name, candidate]) => [\n name,\n wrapToolExecute(name, candidate, toolCallIds, toolExecution),\n ])\n ) as ToolSet;\n}\n\nexport function rewriteMessageToolCallIds(\n message: RuntimeLlmMessage,\n toolCallIds: Map<string, string>\n): RuntimeLlmMessage {\n if (message.role === \"assistant\") {\n return rewriteAssistantToolCallIds(message, toolCallIds);\n }\n\n if (message.role === \"tool\") {\n return rewriteToolResultCallIds(message, toolCallIds);\n }\n\n return message;\n}\n\nfunction wrapToolExecute(\n toolName: string,\n toolDefinition: unknown,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): unknown {\n if (!isExecutableToolDefinition(toolDefinition)) {\n return toolDefinition;\n }\n\n const { execute } = toolDefinition;\n if (!toolExecution) {\n return {\n ...toolDefinition,\n execute: (input: unknown, options: ToolExecutionOptionsLike) =>\n execute(input, {\n ...options,\n toolCallId: publicToolCallId(options.toolCallId, toolCallIds),\n }),\n };\n }\n\n return {\n ...toolDefinition,\n execute: async (input: unknown, options: ToolExecutionOptionsLike) => {\n const toolCallId = publicToolCallId(options.toolCallId, toolCallIds);\n const checkpoint = toolCheckpoint({\n input,\n policy: toolRetryPolicy(toolDefinition),\n toolCallId,\n toolExecution,\n toolName,\n });\n const decision = await toolExecution.beforeTool?.(checkpoint);\n if (decision?.status === \"needs-recovery\") {\n throw new ToolExecutionNeedsRecoveryError(checkpoint);\n }\n\n const output = await execute(input, {\n ...options,\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n retryPolicy: checkpoint.policy,\n ...(options.abortSignal === undefined\n ? {}\n : { signal: options.abortSignal }),\n toolCallId,\n });\n await toolExecution.afterTool?.({ ...checkpoint, output });\n return output;\n },\n };\n}\n\nfunction isExecutableToolDefinition(value: unknown): value is {\n readonly execute: (\n input: unknown,\n options: RuntimeToolExecutionOptionsLike | ToolExecutionOptionsLike\n ) => unknown;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof value.execute === \"function\"\n );\n}\n\ninterface ToolExecutionOptionsLike {\n readonly abortSignal?: AbortSignal;\n readonly toolCallId: string;\n}\n\ninterface RuntimeToolExecutionOptionsLike extends ToolExecutionOptionsLike {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly retryPolicy: RuntimeToolRetryPolicy;\n readonly signal?: AbortSignal;\n}\n\nfunction toolCheckpoint({\n input,\n policy,\n toolCallId,\n toolExecution,\n toolName,\n}: {\n readonly input: unknown;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolExecution: RuntimeToolExecutionContext;\n readonly toolName: string;\n}): RuntimeToolExecutionCheckpoint {\n return {\n attempt: toolExecution.attempt,\n idempotencyKey: `${toolExecution.runId}:${toolCallId}`,\n input,\n policy,\n toolCallId,\n toolName,\n };\n}\n\nfunction toolRetryPolicy(toolDefinition: unknown): RuntimeToolRetryPolicy {\n if (\n typeof toolDefinition === \"object\" &&\n toolDefinition !== null &&\n \"retryPolicy\" in toolDefinition &&\n isToolRetryPolicy(toolDefinition.retryPolicy)\n ) {\n return toolDefinition.retryPolicy;\n }\n\n return \"manual-recovery\";\n}\n\nfunction isToolRetryPolicy(value: unknown): value is RuntimeToolRetryPolicy {\n return (\n value === \"idempotent\" || value === \"manual-recovery\" || value === \"pure\"\n );\n}\n\nfunction rewriteAssistantToolCallIds(\n message: AssistantModelMessage,\n toolCallIds: Map<string, string>\n): AssistantModelMessage {\n if (typeof message.content === \"string\") {\n return message;\n }\n\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction rewriteToolResultCallIds(\n message: ToolModelMessage,\n toolCallIds: Map<string, string>\n): ToolModelMessage {\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction publicToolCallId(\n toolCallId: string,\n toolCallIds: Map<string, string>\n): string {\n if (publicToolCallIdPattern.test(toolCallId)) {\n return toolCallId;\n }\n\n const existing = toolCallIds.get(toolCallId);\n if (existing) {\n return existing;\n }\n\n const generated = createToolCallId();\n toolCallIds.set(toolCallId, generated);\n return generated;\n}\n\nfunction createToolCallId(): string {\n return `${toolCallIdPrefix}${crypto.randomUUID().replaceAll(\"-\", \"\")}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"llm-tool-execution.js","names":[],"sources":["../src/llm-tool-execution.ts"],"sourcesContent":["import type { AssistantModelMessage, ToolModelMessage, ToolSet } from \"ai\";\nimport type { ModelStepOutput } from \"./llm\";\n\nconst toolCallIdPrefix = \"call_\";\nconst publicToolCallIdPattern = /^call[-_]/;\n\ntype ModelStepMessage = ModelStepOutput[number];\n\nexport type RuntimeToolRetryPolicy = \"idempotent\" | \"manual-recovery\" | \"pure\";\n\nexport interface RuntimeToolExecutionCheckpointMetadata {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\nexport interface RuntimeToolExecutionCheckpoint\n extends RuntimeToolExecutionCheckpointMetadata {\n readonly input: unknown;\n}\n\nexport type RuntimePersistedToolExecutionCheckpoint =\n RuntimeToolExecutionCheckpointMetadata;\n\nexport type RuntimeToolExecutionDecision =\n | { readonly status: \"needs-recovery\" }\n | undefined;\n\nexport interface RuntimeToolExecutionContext {\n readonly afterTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint & { readonly output: unknown }\n ) => Promise<void> | void;\n readonly attempt: number;\n readonly beforeTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint\n ) => Promise<RuntimeToolExecutionDecision> | RuntimeToolExecutionDecision;\n readonly runId: string;\n}\n\nexport class ToolExecutionNeedsRecoveryError extends Error {\n readonly idempotencyKey: string;\n readonly status = \"needs-recovery\";\n readonly toolCallId: string;\n readonly toolName: string;\n\n constructor(checkpoint: RuntimeToolExecutionCheckpointMetadata) {\n super(\n `Tool ${checkpoint.toolName} requires manual recovery for ${checkpoint.idempotencyKey}`\n );\n this.idempotencyKey = checkpoint.idempotencyKey;\n this.name = \"ToolExecutionNeedsRecoveryError\";\n this.toolCallId = checkpoint.toolCallId;\n this.toolName = checkpoint.toolName;\n }\n}\n\nexport function persistedToolExecutionCheckpoint(\n checkpoint: RuntimeToolExecutionCheckpointMetadata\n): RuntimePersistedToolExecutionCheckpoint {\n return {\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n policy: checkpoint.policy,\n toolCallId: checkpoint.toolCallId,\n toolName: checkpoint.toolName,\n };\n}\n\nexport function normalizeToolCallIds(\n tools: ToolSet | undefined,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): ToolSet | undefined {\n if (!tools) {\n return;\n }\n\n return Object.fromEntries(\n Object.entries(tools).map(([name, candidate]) => [\n name,\n wrapToolExecute(name, candidate, toolCallIds, toolExecution),\n ])\n ) as ToolSet;\n}\n\nexport function rewriteMessageToolCallIds(\n message: ModelStepMessage,\n toolCallIds: Map<string, string>\n): ModelStepMessage {\n if (message.role === \"assistant\") {\n return rewriteAssistantToolCallIds(message, toolCallIds);\n }\n\n if (message.role === \"tool\") {\n return rewriteToolResultCallIds(message, toolCallIds);\n }\n\n return message;\n}\n\nfunction wrapToolExecute(\n toolName: string,\n toolDefinition: unknown,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): unknown {\n if (!isExecutableToolDefinition(toolDefinition)) {\n return toolDefinition;\n }\n\n const { execute } = toolDefinition;\n if (!toolExecution) {\n return {\n ...toolDefinition,\n execute: (input: unknown, options: ToolExecutionOptionsLike) =>\n execute(input, {\n ...options,\n toolCallId: publicToolCallId(options.toolCallId, toolCallIds),\n }),\n };\n }\n\n return {\n ...toolDefinition,\n execute: async (input: unknown, options: ToolExecutionOptionsLike) => {\n const toolCallId = publicToolCallId(options.toolCallId, toolCallIds);\n const checkpoint = toolCheckpoint({\n input,\n policy: toolRetryPolicy(toolDefinition),\n toolCallId,\n toolExecution,\n toolName,\n });\n const decision = await toolExecution.beforeTool?.(checkpoint);\n if (decision?.status === \"needs-recovery\") {\n throw new ToolExecutionNeedsRecoveryError(checkpoint);\n }\n\n const output = await execute(input, {\n ...options,\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n retryPolicy: checkpoint.policy,\n ...(options.abortSignal === undefined\n ? {}\n : { signal: options.abortSignal }),\n toolCallId,\n });\n await toolExecution.afterTool?.({ ...checkpoint, output });\n return output;\n },\n };\n}\n\nfunction isExecutableToolDefinition(value: unknown): value is {\n readonly execute: (\n input: unknown,\n options: RuntimeToolExecutionOptionsLike | ToolExecutionOptionsLike\n ) => unknown;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof value.execute === \"function\"\n );\n}\n\ninterface ToolExecutionOptionsLike {\n readonly abortSignal?: AbortSignal;\n readonly toolCallId: string;\n}\n\ninterface RuntimeToolExecutionOptionsLike extends ToolExecutionOptionsLike {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly retryPolicy: RuntimeToolRetryPolicy;\n readonly signal?: AbortSignal;\n}\n\nfunction toolCheckpoint({\n input,\n policy,\n toolCallId,\n toolExecution,\n toolName,\n}: {\n readonly input: unknown;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolExecution: RuntimeToolExecutionContext;\n readonly toolName: string;\n}): RuntimeToolExecutionCheckpoint {\n return {\n attempt: toolExecution.attempt,\n idempotencyKey: `${toolExecution.runId}:${toolCallId}`,\n input,\n policy,\n toolCallId,\n toolName,\n };\n}\n\nfunction toolRetryPolicy(toolDefinition: unknown): RuntimeToolRetryPolicy {\n if (\n typeof toolDefinition === \"object\" &&\n toolDefinition !== null &&\n \"retryPolicy\" in toolDefinition &&\n isToolRetryPolicy(toolDefinition.retryPolicy)\n ) {\n return toolDefinition.retryPolicy;\n }\n\n return \"manual-recovery\";\n}\n\nfunction isToolRetryPolicy(value: unknown): value is RuntimeToolRetryPolicy {\n return (\n value === \"idempotent\" || value === \"manual-recovery\" || value === \"pure\"\n );\n}\n\nfunction rewriteAssistantToolCallIds(\n message: AssistantModelMessage,\n toolCallIds: Map<string, string>\n): AssistantModelMessage {\n if (typeof message.content === \"string\") {\n return message;\n }\n\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction rewriteToolResultCallIds(\n message: ToolModelMessage,\n toolCallIds: Map<string, string>\n): ToolModelMessage {\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction publicToolCallId(\n toolCallId: string,\n toolCallIds: Map<string, string>\n): string {\n if (publicToolCallIdPattern.test(toolCallId)) {\n return toolCallId;\n }\n\n const existing = toolCallIds.get(toolCallId);\n if (existing) {\n return existing;\n }\n\n const generated = createToolCallId();\n toolCallIds.set(toolCallId, generated);\n return generated;\n}\n\nfunction createToolCallId(): string {\n return `${toolCallIdPrefix}${crypto.randomUUID().replaceAll(\"-\", \"\")}`;\n}\n"],"mappings":"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"}
package/dist/llm.d.ts CHANGED
@@ -3,26 +3,6 @@ import { LanguageModel, ModelMessage, ToolChoice, ToolSet, generateText } from "
3
3
 
4
4
  //#region src/llm.d.ts
5
5
  type AgentToolChoice = ToolChoice<ToolSet>;
6
- type RuntimeLlmOutput = Awaited<ReturnType<typeof generateText>>["responseMessages"];
7
- type RuntimeLlmOutputPart = RuntimeLlmOutput[number];
8
- interface RuntimeLlmContext {
9
- history: readonly ModelMessage[];
10
- signal: AbortSignal;
11
- toolExecution?: RuntimeToolExecutionContext;
12
- }
13
- type RuntimeLlm = (context: RuntimeLlmContext) => Promise<RuntimeLlmOutput>;
14
- interface RuntimeCreateLlmOptions {
15
- instructions?: string;
16
- model: LanguageModel;
17
- toolChoice?: AgentToolChoice;
18
- tools?: ToolSet;
19
- }
20
- declare function createLlm({
21
- model,
22
- instructions,
23
- toolChoice,
24
- tools
25
- }: RuntimeCreateLlmOptions): RuntimeLlm;
26
6
  //#endregion
27
- export { AgentToolChoice, RuntimeCreateLlmOptions, RuntimeLlm, RuntimeLlmContext, RuntimeLlmOutput, RuntimeLlmOutputPart, createLlm };
7
+ export { AgentToolChoice };
28
8
  //# sourceMappingURL=llm.d.ts.map
package/dist/llm.js CHANGED
@@ -1,21 +1,19 @@
1
1
  import { normalizeToolCallIds, rewriteMessageToolCallIds } from "./llm-tool-execution.js";
2
2
  import { generateText } from "ai";
3
3
  //#region src/llm.ts
4
- function createLlm({ model, instructions, toolChoice, tools }) {
5
- return async ({ history, signal, toolExecution }) => {
6
- const toolCallIds = /* @__PURE__ */ new Map();
7
- const { responseMessages } = await generateText({
8
- abortSignal: signal,
9
- instructions,
10
- messages: [...history],
11
- model,
12
- toolChoice,
13
- tools: normalizeToolCallIds(tools, toolCallIds, toolExecution)
14
- });
15
- return responseMessages.map((message) => rewriteMessageToolCallIds(message, toolCallIds));
16
- };
4
+ async function generateModelStep({ history, model, instructions, signal, toolChoice, toolExecution, tools }) {
5
+ const toolCallIds = /* @__PURE__ */ new Map();
6
+ const { responseMessages } = await generateText({
7
+ abortSignal: signal,
8
+ instructions,
9
+ messages: [...history],
10
+ model,
11
+ toolChoice,
12
+ tools: normalizeToolCallIds(tools, toolCallIds, toolExecution)
13
+ });
14
+ return responseMessages.map((message) => rewriteMessageToolCallIds(message, toolCallIds));
17
15
  }
18
16
  //#endregion
19
- export { createLlm };
17
+ export { generateModelStep };
20
18
 
21
19
  //# sourceMappingURL=llm.js.map
package/dist/llm.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"llm.js","names":[],"sources":["../src/llm.ts"],"sourcesContent":["import type { LanguageModel, ModelMessage, ToolChoice, ToolSet } from \"ai\";\nimport { generateText } from \"ai\";\nimport type { RuntimeToolExecutionContext } from \"./llm-tool-execution\";\nimport {\n normalizeToolCallIds,\n rewriteMessageToolCallIds,\n} from \"./llm-tool-execution\";\n\nexport type {\n RuntimePersistedToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpointMetadata,\n RuntimeToolExecutionContext,\n RuntimeToolExecutionDecision,\n RuntimeToolRetryPolicy,\n} from \"./llm-tool-execution\";\n\nexport type AgentToolChoice = ToolChoice<ToolSet>;\nexport type RuntimeLlmOutput = Awaited<\n ReturnType<typeof generateText>\n>[\"responseMessages\"];\nexport type RuntimeLlmOutputPart = RuntimeLlmOutput[number];\n\nexport interface RuntimeLlmContext {\n history: readonly ModelMessage[];\n signal: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}\n\nexport type RuntimeLlm = (\n context: RuntimeLlmContext\n) => Promise<RuntimeLlmOutput>;\n\nexport interface RuntimeCreateLlmOptions {\n instructions?: string;\n model: LanguageModel;\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\nexport function createLlm({\n model,\n instructions,\n toolChoice,\n tools,\n}: RuntimeCreateLlmOptions): RuntimeLlm {\n return async ({ history, signal, toolExecution }) => {\n const toolCallIds = new Map<string, string>();\n const { responseMessages } = await generateText({\n abortSignal: signal,\n instructions,\n messages: [...history],\n model,\n toolChoice,\n tools: normalizeToolCallIds(tools, toolCallIds, toolExecution),\n });\n\n return responseMessages.map((message) =>\n rewriteMessageToolCallIds(message, toolCallIds)\n );\n };\n}\n"],"mappings":";;;AAwCA,SAAgB,UAAU,EACxB,OACA,cACA,YACA,SACsC;CACtC,OAAO,OAAO,EAAE,SAAS,QAAQ,oBAAoB;EACnD,MAAM,8BAAc,IAAI,IAAoB;EAC5C,MAAM,EAAE,qBAAqB,MAAM,aAAa;GAC9C,aAAa;GACb;GACA,UAAU,CAAC,GAAG,OAAO;GACrB;GACA;GACA,OAAO,qBAAqB,OAAO,aAAa,aAAa;EAC/D,CAAC;EAED,OAAO,iBAAiB,KAAK,YAC3B,0BAA0B,SAAS,WAAW,CAChD;CACF;AACF"}
1
+ {"version":3,"file":"llm.js","names":[],"sources":["../src/llm.ts"],"sourcesContent":["import type { LanguageModel, ModelMessage, ToolChoice, ToolSet } from \"ai\";\nimport { generateText } from \"ai\";\nimport type { RuntimeToolExecutionContext } from \"./llm-tool-execution\";\nimport {\n normalizeToolCallIds,\n rewriteMessageToolCallIds,\n} from \"./llm-tool-execution\";\n\nexport type {\n RuntimePersistedToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpointMetadata,\n RuntimeToolExecutionContext,\n RuntimeToolExecutionDecision,\n RuntimeToolRetryPolicy,\n} from \"./llm-tool-execution\";\n\nexport type AgentToolChoice = ToolChoice<ToolSet>;\nexport type ModelStepOutput = Awaited<\n ReturnType<typeof generateText>\n>[\"responseMessages\"];\nexport type ModelStepOutputPart = ModelStepOutput[number];\n\nexport interface ModelGenerationOptions {\n instructions?: string;\n model: LanguageModel;\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\nexport interface ModelStepOptions extends ModelGenerationOptions {\n history: readonly ModelMessage[];\n signal: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}\n\nexport async function generateModelStep({\n history,\n model,\n instructions,\n signal,\n toolChoice,\n toolExecution,\n tools,\n}: ModelStepOptions): Promise<ModelStepOutput> {\n const toolCallIds = new Map<string, string>();\n const { responseMessages } = await generateText({\n abortSignal: signal,\n instructions,\n messages: [...history],\n model,\n toolChoice,\n tools: normalizeToolCallIds(tools, toolCallIds, toolExecution),\n });\n\n return responseMessages.map((message) =>\n rewriteMessageToolCallIds(message, toolCallIds)\n );\n}\n"],"mappings":";;;AAoCA,eAAsB,kBAAkB,EACtC,SACA,OACA,cACA,QACA,YACA,eACA,SAC6C;CAC7C,MAAM,8BAAc,IAAI,IAAoB;CAC5C,MAAM,EAAE,qBAAqB,MAAM,aAAa;EAC9C,aAAa;EACb;EACA,UAAU,CAAC,GAAG,OAAO;EACrB;EACA;EACA,OAAO,qBAAqB,OAAO,aAAa,aAAa;CAC/D,CAAC;CAED,OAAO,iBAAiB,KAAK,YAC3B,0BAA0B,SAAS,WAAW,CAChD;AACF"}
package/dist/plugins.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { RuntimeLlmContext } from "./llm.js";
2
1
  import { InputEventMeta, InputSource } from "./session/input-meta-types.js";
3
2
  import { UserMessage, UserText } from "./session/input.js";
4
3
  import { AgentEvent, RuntimeInput } from "./session/events.js";
4
+ import { ModelMessage } from "ai";
5
5
 
6
6
  //#region src/plugins.d.ts
7
7
  type MaybePromise<T> = PromiseLike<T> | T;
8
- type AgentEventHistory = RuntimeLlmContext["history"];
8
+ type AgentEventHistory = readonly ModelMessage[];
9
9
  type InterceptableAgentEvent = RuntimeInput | UserMessage | UserText;
10
10
  type AgentPluginInterceptResult = {
11
11
  readonly action: "continue";
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","names":[],"sources":["../src/plugins.ts"],"sourcesContent":["import type { RuntimeLlmContext } from \"./llm\";\nimport type {\n AgentEvent,\n RuntimeInput,\n UserMessage,\n UserText,\n} from \"./session/events\";\n\nexport type { InputEventMeta, InputSource } from \"./session/input-meta-types\";\n\ntype MaybePromise<T> = PromiseLike<T> | T;\ntype AgentEventHistory = RuntimeLlmContext[\"history\"];\n\nexport type InterceptableAgentEvent = RuntimeInput | UserMessage | UserText;\n\nexport type AgentPluginInterceptResult =\n | { readonly action: \"continue\" }\n | { readonly action: \"handled\" }\n | { readonly action: \"transform\"; readonly event: InterceptableAgentEvent };\n\nexport type AgentPluginResult = AgentPluginInterceptResult | undefined;\n\nexport interface AgentEventContext {\n readonly event: AgentEvent;\n readonly history: AgentEventHistory;\n readonly signal?: AbortSignal;\n}\n\nexport interface AgentPlugin {\n readonly events?: {\n /** @deprecated Use top-level `on`. */\n readonly on?: (context: AgentEventContext) => MaybePromise<void>;\n };\n readonly name?: string;\n readonly on?: (context: AgentEventContext) => MaybePromise<AgentPluginResult>;\n}\n\nexport type PluginPipelineResult =\n | { readonly event: AgentEvent; readonly kind: \"emit\" }\n | { readonly kind: \"handled\" };\n\nexport function runEventPlugins(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext\n): Promise<void> {\n return runPluginsForEvent(plugins, context, { observeOnly: true }).then(\n () => undefined\n );\n}\n\nexport function runPluginsForEvent(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext,\n options: { readonly observeOnly?: boolean } = {}\n): Promise<PluginPipelineResult> {\n return runPluginPipeline(plugins, context, options.observeOnly === true);\n}\n\nfunction isInterceptableEvent(\n event: AgentEvent\n): event is InterceptableAgentEvent {\n return (\n event.type === \"user-text\" ||\n event.type === \"user-message\" ||\n event.type === \"runtime-input\"\n );\n}\n\nfunction resolvePluginHandler(\n plugin: AgentPlugin\n):\n | ((context: AgentEventContext) => MaybePromise<AgentPluginResult>)\n | undefined {\n if (plugin.on) {\n return plugin.on;\n }\n\n const legacyHandler = plugin.events?.on;\n if (!legacyHandler) {\n return;\n }\n\n return (legacyContext) =>\n Promise.resolve(legacyHandler(legacyContext)).then(() => undefined);\n}\n\nfunction normalizeInterceptResult(\n result: AgentPluginResult | undefined\n): AgentPluginInterceptResult | undefined {\n if (result === undefined) {\n return;\n }\n\n if (result.action === \"continue\") {\n return result;\n }\n\n if (result.action === \"handled\") {\n return result;\n }\n\n if (result.action === \"transform\") {\n return result;\n }\n\n return;\n}\n\nasync function runPluginPipeline(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext,\n observeOnly: boolean\n): Promise<PluginPipelineResult> {\n let currentEvent = context.event;\n\n for (const plugin of plugins) {\n const handler = resolvePluginHandler(plugin);\n if (!handler) {\n continue;\n }\n\n const result = await handler({ ...context, event: currentEvent });\n if (observeOnly || !isInterceptableEvent(currentEvent)) {\n continue;\n }\n\n const intercept = normalizeInterceptResult(result);\n if (!intercept || intercept.action === \"continue\") {\n continue;\n }\n\n if (intercept.action === \"handled\") {\n return { kind: \"handled\" };\n }\n\n currentEvent = intercept.event;\n }\n\n return { kind: \"emit\", event: currentEvent };\n}\n"],"mappings":";AAkDA,SAAgB,mBACd,SACA,SACA,UAA8C,CAAC,GAChB;CAC/B,OAAO,kBAAkB,SAAS,SAAS,QAAQ,gBAAgB,IAAI;AACzE;AAEA,SAAS,qBACP,OACkC;CAClC,OACE,MAAM,SAAS,eACf,MAAM,SAAS,kBACf,MAAM,SAAS;AAEnB;AAEA,SAAS,qBACP,QAGY;CACZ,IAAI,OAAO,IACT,OAAO,OAAO;CAGhB,MAAM,gBAAgB,OAAO,QAAQ;CACrC,IAAI,CAAC,eACH;CAGF,QAAQ,kBACN,QAAQ,QAAQ,cAAc,aAAa,CAAC,EAAE,WAAW,KAAA,CAAS;AACtE;AAEA,SAAS,yBACP,QACwC;CACxC,IAAI,WAAW,KAAA,GACb;CAGF,IAAI,OAAO,WAAW,YACpB,OAAO;CAGT,IAAI,OAAO,WAAW,WACpB,OAAO;CAGT,IAAI,OAAO,WAAW,aACpB,OAAO;AAIX;AAEA,eAAe,kBACb,SACA,SACA,aAC+B;CAC/B,IAAI,eAAe,QAAQ;CAE3B,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,qBAAqB,MAAM;EAC3C,IAAI,CAAC,SACH;EAGF,MAAM,SAAS,MAAM,QAAQ;GAAE,GAAG;GAAS,OAAO;EAAa,CAAC;EAChE,IAAI,eAAe,CAAC,qBAAqB,YAAY,GACnD;EAGF,MAAM,YAAY,yBAAyB,MAAM;EACjD,IAAI,CAAC,aAAa,UAAU,WAAW,YACrC;EAGF,IAAI,UAAU,WAAW,WACvB,OAAO,EAAE,MAAM,UAAU;EAG3B,eAAe,UAAU;CAC3B;CAEA,OAAO;EAAE,MAAM;EAAQ,OAAO;CAAa;AAC7C"}
1
+ {"version":3,"file":"plugins.js","names":[],"sources":["../src/plugins.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport type {\n AgentEvent,\n RuntimeInput,\n UserMessage,\n UserText,\n} from \"./session/events\";\n\nexport type { InputEventMeta, InputSource } from \"./session/input-meta-types\";\n\ntype MaybePromise<T> = PromiseLike<T> | T;\ntype AgentEventHistory = readonly ModelMessage[];\n\nexport type InterceptableAgentEvent = RuntimeInput | UserMessage | UserText;\n\nexport type AgentPluginInterceptResult =\n | { readonly action: \"continue\" }\n | { readonly action: \"handled\" }\n | { readonly action: \"transform\"; readonly event: InterceptableAgentEvent };\n\nexport type AgentPluginResult = AgentPluginInterceptResult | undefined;\n\nexport interface AgentEventContext {\n readonly event: AgentEvent;\n readonly history: AgentEventHistory;\n readonly signal?: AbortSignal;\n}\n\nexport interface AgentPlugin {\n readonly events?: {\n /** @deprecated Use top-level `on`. */\n readonly on?: (context: AgentEventContext) => MaybePromise<void>;\n };\n readonly name?: string;\n readonly on?: (context: AgentEventContext) => MaybePromise<AgentPluginResult>;\n}\n\nexport type PluginPipelineResult =\n | { readonly event: AgentEvent; readonly kind: \"emit\" }\n | { readonly kind: \"handled\" };\n\nexport function runEventPlugins(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext\n): Promise<void> {\n return runPluginsForEvent(plugins, context, { observeOnly: true }).then(\n () => undefined\n );\n}\n\nexport function runPluginsForEvent(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext,\n options: { readonly observeOnly?: boolean } = {}\n): Promise<PluginPipelineResult> {\n return runPluginPipeline(plugins, context, options.observeOnly === true);\n}\n\nfunction isInterceptableEvent(\n event: AgentEvent\n): event is InterceptableAgentEvent {\n return (\n event.type === \"user-text\" ||\n event.type === \"user-message\" ||\n event.type === \"runtime-input\"\n );\n}\n\nfunction resolvePluginHandler(\n plugin: AgentPlugin\n):\n | ((context: AgentEventContext) => MaybePromise<AgentPluginResult>)\n | undefined {\n if (plugin.on) {\n return plugin.on;\n }\n\n const legacyHandler = plugin.events?.on;\n if (!legacyHandler) {\n return;\n }\n\n return (legacyContext) =>\n Promise.resolve(legacyHandler(legacyContext)).then(() => undefined);\n}\n\nfunction normalizeInterceptResult(\n result: AgentPluginResult | undefined\n): AgentPluginInterceptResult | undefined {\n if (result === undefined) {\n return;\n }\n\n if (result.action === \"continue\") {\n return result;\n }\n\n if (result.action === \"handled\") {\n return result;\n }\n\n if (result.action === \"transform\") {\n return result;\n }\n\n return;\n}\n\nasync function runPluginPipeline(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext,\n observeOnly: boolean\n): Promise<PluginPipelineResult> {\n let currentEvent = context.event;\n\n for (const plugin of plugins) {\n const handler = resolvePluginHandler(plugin);\n if (!handler) {\n continue;\n }\n\n const result = await handler({ ...context, event: currentEvent });\n if (observeOnly || !isInterceptableEvent(currentEvent)) {\n continue;\n }\n\n const intercept = normalizeInterceptResult(result);\n if (!intercept || intercept.action === \"continue\") {\n continue;\n }\n\n if (intercept.action === \"handled\") {\n return { kind: \"handled\" };\n }\n\n currentEvent = intercept.event;\n }\n\n return { kind: \"emit\", event: currentEvent };\n}\n"],"mappings":";AAkDA,SAAgB,mBACd,SACA,SACA,UAA8C,CAAC,GAChB;CAC/B,OAAO,kBAAkB,SAAS,SAAS,QAAQ,gBAAgB,IAAI;AACzE;AAEA,SAAS,qBACP,OACkC;CAClC,OACE,MAAM,SAAS,eACf,MAAM,SAAS,kBACf,MAAM,SAAS;AAEnB;AAEA,SAAS,qBACP,QAGY;CACZ,IAAI,OAAO,IACT,OAAO,OAAO;CAGhB,MAAM,gBAAgB,OAAO,QAAQ;CACrC,IAAI,CAAC,eACH;CAGF,QAAQ,kBACN,QAAQ,QAAQ,cAAc,aAAa,CAAC,EAAE,WAAW,KAAA,CAAS;AACtE;AAEA,SAAS,yBACP,QACwC;CACxC,IAAI,WAAW,KAAA,GACb;CAGF,IAAI,OAAO,WAAW,YACpB,OAAO;CAGT,IAAI,OAAO,WAAW,WACpB,OAAO;CAGT,IAAI,OAAO,WAAW,aACpB,OAAO;AAIX;AAEA,eAAe,kBACb,SACA,SACA,aAC+B;CAC/B,IAAI,eAAe,QAAQ;CAE3B,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,qBAAqB,MAAM;EAC3C,IAAI,CAAC,SACH;EAGF,MAAM,SAAS,MAAM,QAAQ;GAAE,GAAG;GAAS,OAAO;EAAa,CAAC;EAChE,IAAI,eAAe,CAAC,qBAAqB,YAAY,GACnD;EAGF,MAAM,YAAY,yBAAyB,MAAM;EACjD,IAAI,CAAC,aAAa,UAAU,WAAW,YACrC;EAGF,IAAI,UAAU,WAAW,WACvB,OAAO,EAAE,MAAM,UAAU;EAG3B,eAAe,UAAU;CAC3B;CAEA,OAAO;EAAE,MAAM;EAAQ,OAAO;CAAa;AAC7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.js","names":["#history","#plugins","#signal","#observerEventBuffer","#runInterceptPipeline"],"sources":["../../src/session/session-events.ts"],"sourcesContent":["import type { RuntimeLlmContext } from \"../llm\";\nimport {\n type AgentPlugin,\n type PluginPipelineResult,\n runPluginsForEvent,\n} from \"../plugins\";\nimport type { AgentEvent } from \"./events\";\nimport type { BufferedAgentRun } from \"./run\";\n\ninterface SessionEventDispatcherOptions {\n readonly history: () => RuntimeLlmContext[\"history\"];\n readonly plugins: readonly AgentPlugin[];\n readonly signal: () => AbortSignal | undefined;\n}\n\nexport class SessionEventDispatcher {\n readonly #history: () => RuntimeLlmContext[\"history\"];\n #observerEventBuffer?: AgentEvent[];\n readonly #plugins: readonly AgentPlugin[];\n readonly #signal: () => AbortSignal | undefined;\n\n constructor(options: SessionEventDispatcherOptions) {\n this.#history = options.history;\n this.#plugins = options.plugins;\n this.#signal = options.signal;\n }\n\n async captureObserverEvents<T>(\n run: BufferedAgentRun,\n callback: () => Promise<T>\n ): Promise<{\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n }> {\n const previousBuffer = this.#observerEventBuffer;\n const buffer: AgentEvent[] = [];\n this.#observerEventBuffer = buffer;\n try {\n const value = await callback();\n return {\n events: buffer,\n release: () => {\n if (this.#observerEventBuffer === buffer) {\n this.#observerEventBuffer = previousBuffer;\n }\n },\n value,\n };\n } catch (error) {\n for (const event of buffer.splice(0)) {\n await this.emitRunEvent(run, event);\n }\n this.#observerEventBuffer = previousBuffer;\n throw error;\n }\n }\n\n emitObserverEvent(\n activeRun: BufferedAgentRun | undefined,\n event: AgentEvent\n ): Promise<void> {\n const observerEventBuffer = this.#observerEventBuffer;\n if (observerEventBuffer) {\n observerEventBuffer.push(structuredClone(event));\n return Promise.resolve();\n }\n\n if (!activeRun) {\n return Promise.resolve();\n }\n\n return this.emitRunEvent(activeRun, event).then(() => undefined);\n }\n\n async emitRunBoundaryEvent(\n run: BufferedAgentRun,\n event: AgentEvent\n ): Promise<void> {\n await runPluginsForEvent(\n this.#plugins,\n {\n event,\n history: this.#history(),\n signal: this.#signal(),\n },\n { observeOnly: true }\n );\n await run.emitBoundary(event);\n }\n\n async emitRunEvent(\n run: BufferedAgentRun,\n event: AgentEvent\n ): Promise<AgentEvent | \"handled\"> {\n const processed = await this.interceptEvent(event);\n if (processed === \"handled\") {\n return \"handled\";\n }\n\n run.emit(processed);\n return processed;\n }\n\n async interceptEvent(event: AgentEvent): Promise<AgentEvent | \"handled\"> {\n const pipeline = await this.#runInterceptPipeline(event);\n if (pipeline.kind === \"handled\") {\n return \"handled\";\n }\n\n return pipeline.event;\n }\n\n emitProcessedEvent(run: BufferedAgentRun, event: AgentEvent): void {\n run.emit(event);\n }\n\n #runInterceptPipeline(event: AgentEvent): Promise<PluginPipelineResult> {\n return runPluginsForEvent(this.#plugins, {\n event,\n history: this.#history(),\n signal: this.#signal(),\n });\n }\n}\n"],"mappings":";;AAeA,IAAa,yBAAb,MAAoC;CAClC;CACA;CACA;CACA;CAEA,YAAY,SAAwC;EAClD,KAAKA,WAAW,QAAQ;EACxB,KAAKC,WAAW,QAAQ;EACxB,KAAKC,UAAU,QAAQ;CACzB;CAEA,MAAM,sBACJ,KACA,UAKC;EACD,MAAM,iBAAiB,KAAKC;EAC5B,MAAM,SAAuB,CAAC;EAC9B,KAAKA,uBAAuB;EAC5B,IAAI;GAEF,OAAO;IACL,QAAQ;IACR,eAAe;KACb,IAAI,KAAKA,yBAAyB,QAChC,KAAKA,uBAAuB;IAEhC;IACA,OAAA,MARkB,SAAS;GAS7B;EACF,SAAS,OAAO;GACd,KAAK,MAAM,SAAS,OAAO,OAAO,CAAC,GACjC,MAAM,KAAK,aAAa,KAAK,KAAK;GAEpC,KAAKA,uBAAuB;GAC5B,MAAM;EACR;CACF;CAEA,kBACE,WACA,OACe;EACf,MAAM,sBAAsB,KAAKA;EACjC,IAAI,qBAAqB;GACvB,oBAAoB,KAAK,gBAAgB,KAAK,CAAC;GAC/C,OAAO,QAAQ,QAAQ;EACzB;EAEA,IAAI,CAAC,WACH,OAAO,QAAQ,QAAQ;EAGzB,OAAO,KAAK,aAAa,WAAW,KAAK,EAAE,WAAW,KAAA,CAAS;CACjE;CAEA,MAAM,qBACJ,KACA,OACe;EACf,MAAM,mBACJ,KAAKF,UACL;GACE;GACA,SAAS,KAAKD,SAAS;GACvB,QAAQ,KAAKE,QAAQ;EACvB,GACA,EAAE,aAAa,KAAK,CACtB;EACA,MAAM,IAAI,aAAa,KAAK;CAC9B;CAEA,MAAM,aACJ,KACA,OACiC;EACjC,MAAM,YAAY,MAAM,KAAK,eAAe,KAAK;EACjD,IAAI,cAAc,WAChB,OAAO;EAGT,IAAI,KAAK,SAAS;EAClB,OAAO;CACT;CAEA,MAAM,eAAe,OAAoD;EACvE,MAAM,WAAW,MAAM,KAAKE,sBAAsB,KAAK;EACvD,IAAI,SAAS,SAAS,WACpB,OAAO;EAGT,OAAO,SAAS;CAClB;CAEA,mBAAmB,KAAuB,OAAyB;EACjE,IAAI,KAAK,KAAK;CAChB;CAEA,sBAAsB,OAAkD;EACtE,OAAO,mBAAmB,KAAKH,UAAU;GACvC;GACA,SAAS,KAAKD,SAAS;GACvB,QAAQ,KAAKE,QAAQ;EACvB,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"session-events.js","names":["#history","#plugins","#signal","#observerEventBuffer","#runInterceptPipeline"],"sources":["../../src/session/session-events.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport {\n type AgentPlugin,\n type PluginPipelineResult,\n runPluginsForEvent,\n} from \"../plugins\";\nimport type { AgentEvent } from \"./events\";\nimport type { BufferedAgentRun } from \"./run\";\n\ninterface SessionEventDispatcherOptions {\n readonly history: () => readonly ModelMessage[];\n readonly plugins: readonly AgentPlugin[];\n readonly signal: () => AbortSignal | undefined;\n}\n\nexport class SessionEventDispatcher {\n readonly #history: () => readonly ModelMessage[];\n #observerEventBuffer?: AgentEvent[];\n readonly #plugins: readonly AgentPlugin[];\n readonly #signal: () => AbortSignal | undefined;\n\n constructor(options: SessionEventDispatcherOptions) {\n this.#history = options.history;\n this.#plugins = options.plugins;\n this.#signal = options.signal;\n }\n\n async captureObserverEvents<T>(\n run: BufferedAgentRun,\n callback: () => Promise<T>\n ): Promise<{\n readonly events: AgentEvent[];\n readonly release: () => void;\n readonly value: T;\n }> {\n const previousBuffer = this.#observerEventBuffer;\n const buffer: AgentEvent[] = [];\n this.#observerEventBuffer = buffer;\n try {\n const value = await callback();\n return {\n events: buffer,\n release: () => {\n if (this.#observerEventBuffer === buffer) {\n this.#observerEventBuffer = previousBuffer;\n }\n },\n value,\n };\n } catch (error) {\n for (const event of buffer.splice(0)) {\n await this.emitRunEvent(run, event);\n }\n this.#observerEventBuffer = previousBuffer;\n throw error;\n }\n }\n\n emitObserverEvent(\n activeRun: BufferedAgentRun | undefined,\n event: AgentEvent\n ): Promise<void> {\n const observerEventBuffer = this.#observerEventBuffer;\n if (observerEventBuffer) {\n observerEventBuffer.push(structuredClone(event));\n return Promise.resolve();\n }\n\n if (!activeRun) {\n return Promise.resolve();\n }\n\n return this.emitRunEvent(activeRun, event).then(() => undefined);\n }\n\n async emitRunBoundaryEvent(\n run: BufferedAgentRun,\n event: AgentEvent\n ): Promise<void> {\n await runPluginsForEvent(\n this.#plugins,\n {\n event,\n history: this.#history(),\n signal: this.#signal(),\n },\n { observeOnly: true }\n );\n await run.emitBoundary(event);\n }\n\n async emitRunEvent(\n run: BufferedAgentRun,\n event: AgentEvent\n ): Promise<AgentEvent | \"handled\"> {\n const processed = await this.interceptEvent(event);\n if (processed === \"handled\") {\n return \"handled\";\n }\n\n run.emit(processed);\n return processed;\n }\n\n async interceptEvent(event: AgentEvent): Promise<AgentEvent | \"handled\"> {\n const pipeline = await this.#runInterceptPipeline(event);\n if (pipeline.kind === \"handled\") {\n return \"handled\";\n }\n\n return pipeline.event;\n }\n\n emitProcessedEvent(run: BufferedAgentRun, event: AgentEvent): void {\n run.emit(event);\n }\n\n #runInterceptPipeline(event: AgentEvent): Promise<PluginPipelineResult> {\n return runPluginsForEvent(this.#plugins, {\n event,\n history: this.#history(),\n signal: this.#signal(),\n });\n }\n}\n"],"mappings":";;AAeA,IAAa,yBAAb,MAAoC;CAClC;CACA;CACA;CACA;CAEA,YAAY,SAAwC;EAClD,KAAKA,WAAW,QAAQ;EACxB,KAAKC,WAAW,QAAQ;EACxB,KAAKC,UAAU,QAAQ;CACzB;CAEA,MAAM,sBACJ,KACA,UAKC;EACD,MAAM,iBAAiB,KAAKC;EAC5B,MAAM,SAAuB,CAAC;EAC9B,KAAKA,uBAAuB;EAC5B,IAAI;GAEF,OAAO;IACL,QAAQ;IACR,eAAe;KACb,IAAI,KAAKA,yBAAyB,QAChC,KAAKA,uBAAuB;IAEhC;IACA,OAAA,MARkB,SAAS;GAS7B;EACF,SAAS,OAAO;GACd,KAAK,MAAM,SAAS,OAAO,OAAO,CAAC,GACjC,MAAM,KAAK,aAAa,KAAK,KAAK;GAEpC,KAAKA,uBAAuB;GAC5B,MAAM;EACR;CACF;CAEA,kBACE,WACA,OACe;EACf,MAAM,sBAAsB,KAAKA;EACjC,IAAI,qBAAqB;GACvB,oBAAoB,KAAK,gBAAgB,KAAK,CAAC;GAC/C,OAAO,QAAQ,QAAQ;EACzB;EAEA,IAAI,CAAC,WACH,OAAO,QAAQ,QAAQ;EAGzB,OAAO,KAAK,aAAa,WAAW,KAAK,EAAE,WAAW,KAAA,CAAS;CACjE;CAEA,MAAM,qBACJ,KACA,OACe;EACf,MAAM,mBACJ,KAAKF,UACL;GACE;GACA,SAAS,KAAKD,SAAS;GACvB,QAAQ,KAAKE,QAAQ;EACvB,GACA,EAAE,aAAa,KAAK,CACtB;EACA,MAAM,IAAI,aAAa,KAAK;CAC9B;CAEA,MAAM,aACJ,KACA,OACiC;EACjC,MAAM,YAAY,MAAM,KAAK,eAAe,KAAK;EACjD,IAAI,cAAc,WAChB,OAAO;EAGT,IAAI,KAAK,SAAS;EAClB,OAAO;CACT;CAEA,MAAM,eAAe,OAAoD;EACvE,MAAM,WAAW,MAAM,KAAKE,sBAAsB,KAAK;EACvD,IAAI,SAAS,SAAS,WACpB,OAAO;EAGT,OAAO,SAAS;CAClB;CAEA,mBAAmB,KAAuB,OAAyB;EACjE,IAAI,KAAK,KAAK;CAChB;CAEA,sBAAsB,OAAkD;EACtE,OAAO,mBAAmB,KAAKH,UAAU;GACvC;GACA,SAAS,KAAKD,SAAS;GACvB,QAAQ,KAAKE,QAAQ;EACvB,CAAC;CACH;AACF"}
@@ -1,13 +1,13 @@
1
- import { ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
2
1
  import { closeRuntimeInput, withRuntimeInputWindow } from "./runtime-input.js";
3
2
  import { errorMessage } from "./session-errors.js";
3
+ import { ToolExecutionNeedsRecoveryError } from "../llm-tool-execution.js";
4
4
  import { runAgentLoop } from "../agent-loop.js";
5
5
  import { commitPreUserRuntimeInputs, emitCommittedRuntimeInputs } from "./runtime-input-emit.js";
6
6
  import { startSessionExecutionRun } from "./session-execution.js";
7
7
  import { drainRuntimeInput } from "./session-runtime-drain.js";
8
8
  import { emitTurnErrorAfterRecovery } from "./session-turn-error.js";
9
9
  //#region src/session/session-turn-processor.ts
10
- async function processQueuedInput({ activate, deactivateRun, events, execution, item, llm, release, sessionKey, state }) {
10
+ async function processQueuedInput({ activate, deactivateRun, events, execution, item, model, release, sessionKey, state }) {
11
11
  const activeAbort = new AbortController();
12
12
  const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } = item;
13
13
  const turnId = crypto.randomUUID();
@@ -52,7 +52,7 @@ async function processQueuedInput({ activate, deactivateRun, events, execution,
52
52
  state
53
53
  }),
54
54
  history: state.history,
55
- llm,
55
+ model,
56
56
  captureObserverEvents: (callback) => events.captureObserverEvents(run, callback),
57
57
  signal: activeAbort.signal,
58
58
  toolExecution: executionRun?.toolExecution
@@ -1 +1 @@
1
- {"version":3,"file":"session-turn-processor.js","names":[],"sources":["../../src/session/session-turn-processor.ts"],"sourcesContent":["import { runAgentLoop } from \"../agent-loop\";\nimport type { RuntimeLlm } from \"../llm\";\nimport { ToolExecutionNeedsRecoveryError } from \"../llm-tool-execution\";\nimport type { AgentEvent } from \"./events\";\nimport type { BufferedAgentRun } from \"./run\";\nimport {\n closeRuntimeInput,\n type QueuedInput,\n type RuntimeInputState,\n withRuntimeInputWindow,\n} from \"./runtime-input\";\nimport {\n commitPreUserRuntimeInputs,\n emitCommittedRuntimeInputs,\n} from \"./runtime-input-emit\";\nimport { errorMessage } from \"./session-errors\";\nimport type { SessionEventDispatcher } from \"./session-events\";\nimport {\n type SessionExecutionOptions,\n type SessionExecutionRun,\n type SessionExecutionTerminalStatus,\n startSessionExecutionRun,\n} from \"./session-execution\";\nimport { drainRuntimeInput } from \"./session-runtime-drain\";\n\nimport type { SessionState } from \"./session-state\";\nimport { emitTurnErrorAfterRecovery } from \"./session-turn-error\";\n\ninterface ActiveTurn {\n readonly abort: AbortController;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly turnId: string;\n}\n\ninterface ProcessQueuedInputOptions {\n readonly activate: (turn: ActiveTurn) => void;\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly execution: SessionExecutionOptions;\n readonly item: QueuedInput;\n readonly llm: RuntimeLlm;\n readonly release: () => void;\n readonly sessionKey: string;\n readonly state: SessionState;\n}\n\nexport async function processQueuedInput({\n activate,\n deactivateRun,\n events,\n execution,\n item,\n llm,\n release,\n sessionKey,\n state,\n}: ProcessQueuedInputOptions): Promise<void> {\n const activeAbort = new AbortController();\n const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } =\n item;\n const turnId = crypto.randomUUID();\n activate({\n abort: activeAbort,\n run,\n runtimeInput,\n turnId,\n });\n const historySnapshot = state.modelSnapshot();\n let executionRun: SessionExecutionRun | undefined;\n\n try {\n executionRun = await startSessionExecutionRun({\n executionHost: execution.executionHost,\n sessionKey,\n state,\n turnId,\n });\n for (const event of initialEvents) {\n await events.emitRunEvent(run, event);\n }\n const committedPreUser = await commitPreUserRuntimeInputs(\n events,\n state,\n preUserRuntimeInputs\n );\n if (input) {\n state.appendUserInput(input);\n await state.commit();\n }\n await withRuntimeInputWindow(runtimeInput, \"turn-start\", async () => {\n await events.emitRunBoundaryEvent(run, { type: \"turn-start\" });\n });\n await emitCommittedRuntimeInputs(events, run, committedPreUser);\n await drainRuntimeInput({\n events,\n placement: \"turn-start\",\n run,\n runtimeInput,\n state,\n });\n\n const result = await runAgentLoop({\n emit: async (event) =>\n emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n }),\n history: state.history,\n llm,\n captureObserverEvents: (callback) =>\n events.captureObserverEvents(run, callback),\n signal: activeAbort.signal,\n toolExecution: executionRun?.toolExecution,\n });\n\n await state.commit();\n await executionRun?.complete(executionStatusForResult(result));\n await closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n });\n } catch (error) {\n const turnError = error instanceof Error ? error : new Error(String(error));\n await executionRun?.complete(executionStatusForError(turnError));\n await emitTurnErrorAfterRecovery({\n error: turnError,\n historySnapshot,\n run,\n runtimeInput,\n state,\n });\n } finally {\n closeRuntimeInput(runtimeInput);\n release();\n run.close(undefined, runtimeInput.closedReason);\n }\n}\n\nfunction executionStatusForResult(\n result: \"aborted\" | \"completed\"\n): SessionExecutionTerminalStatus {\n return result === \"aborted\" ? \"cancelled\" : \"completed\";\n}\n\nfunction executionStatusForError(error: Error): SessionExecutionTerminalStatus {\n return error instanceof ToolExecutionNeedsRecoveryError\n ? \"needs-recovery\"\n : \"error\";\n}\n\nasync function closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n}: {\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly result: \"aborted\" | \"completed\";\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n}): Promise<void> {\n const terminalEvent = result === \"aborted\" ? \"turn-abort\" : \"turn-end\";\n closeRuntimeInput(runtimeInput, terminalEvent);\n deactivateRun();\n try {\n await events.emitRunEvent(run, { type: terminalEvent });\n } catch (terminalError) {\n run.emit({ type: \"turn-error\", message: errorMessage(terminalError) });\n closeRuntimeInput(runtimeInput, \"turn-error\");\n }\n}\n\nasync function emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n}: {\n readonly event: AgentEvent;\n readonly events: SessionEventDispatcher;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<{ readonly runtimeInputAdded: boolean } | undefined> {\n if (event.type !== \"step-start\" && event.type !== \"step-end\") {\n await events.emitRunEvent(run, event);\n return;\n }\n\n await withRuntimeInputWindow(runtimeInput, event.type, async () => {\n await events.emitRunBoundaryEvent(run, event);\n });\n const runtimeInputAdded = await drainRuntimeInput({\n events,\n placement: event.type,\n run,\n runtimeInput,\n state,\n });\n return event.type === \"step-end\" ? { runtimeInputAdded } : undefined;\n}\n"],"mappings":";;;;;;;;;AA+CA,eAAsB,mBAAmB,EACvC,UACA,eACA,QACA,WACA,MACA,KACA,SACA,YACA,SAC2C;CAC3C,MAAM,cAAc,IAAI,gBAAgB;CACxC,MAAM,EAAE,eAAe,OAAO,sBAAsB,KAAK,iBACvD;CACF,MAAM,SAAS,OAAO,WAAW;CACjC,SAAS;EACP,OAAO;EACP;EACA;EACA;CACF,CAAC;CACD,MAAM,kBAAkB,MAAM,cAAc;CAC5C,IAAI;CAEJ,IAAI;EACF,eAAe,MAAM,yBAAyB;GAC5C,eAAe,UAAU;GACzB;GACA;GACA;EACF,CAAC;EACD,KAAK,MAAM,SAAS,eAClB,MAAM,OAAO,aAAa,KAAK,KAAK;EAEtC,MAAM,mBAAmB,MAAM,2BAC7B,QACA,OACA,oBACF;EACA,IAAI,OAAO;GACT,MAAM,gBAAgB,KAAK;GAC3B,MAAM,MAAM,OAAO;EACrB;EACA,MAAM,uBAAuB,cAAc,cAAc,YAAY;GACnE,MAAM,OAAO,qBAAqB,KAAK,EAAE,MAAM,aAAa,CAAC;EAC/D,CAAC;EACD,MAAM,2BAA2B,QAAQ,KAAK,gBAAgB;EAC9D,MAAM,kBAAkB;GACtB;GACA,WAAW;GACX;GACA;GACA;EACF,CAAC;EAED,MAAM,SAAS,MAAM,aAAa;GAChC,MAAM,OAAO,UACX,cAAc;IACZ;IACA;IACA;IACA;IACA;GACF,CAAC;GACH,SAAS,MAAM;GACf;GACA,wBAAwB,aACtB,OAAO,sBAAsB,KAAK,QAAQ;GAC5C,QAAQ,YAAY;GACpB,eAAe,cAAc;EAC/B,CAAC;EAED,MAAM,MAAM,OAAO;EACnB,MAAM,cAAc,SAAS,yBAAyB,MAAM,CAAC;EAC7D,MAAM,oBAAoB;GACxB;GACA;GACA;GACA;GACA;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,YAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EAC1E,MAAM,cAAc,SAAS,wBAAwB,SAAS,CAAC;EAC/D,MAAM,2BAA2B;GAC/B,OAAO;GACP;GACA;GACA;GACA;EACF,CAAC;CACH,UAAU;EACR,kBAAkB,YAAY;EAC9B,QAAQ;EACR,IAAI,MAAM,KAAA,GAAW,aAAa,YAAY;CAChD;AACF;AAEA,SAAS,yBACP,QACgC;CAChC,OAAO,WAAW,YAAY,cAAc;AAC9C;AAEA,SAAS,wBAAwB,OAA8C;CAC7E,OAAO,iBAAiB,kCACpB,mBACA;AACN;AAEA,eAAe,oBAAoB,EACjC,eACA,QACA,QACA,KACA,gBAOgB;CAChB,MAAM,gBAAgB,WAAW,YAAY,eAAe;CAC5D,kBAAkB,cAAc,aAAa;CAC7C,cAAc;CACd,IAAI;EACF,MAAM,OAAO,aAAa,KAAK,EAAE,MAAM,cAAc,CAAC;CACxD,SAAS,eAAe;EACtB,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,aAAa,aAAa;EAAE,CAAC;EACrE,kBAAkB,cAAc,YAAY;CAC9C;AACF;AAEA,eAAe,cAAc,EAC3B,OACA,QACA,KACA,cACA,SAO+D;CAC/D,IAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,YAAY;EAC5D,MAAM,OAAO,aAAa,KAAK,KAAK;EACpC;CACF;CAEA,MAAM,uBAAuB,cAAc,MAAM,MAAM,YAAY;EACjE,MAAM,OAAO,qBAAqB,KAAK,KAAK;CAC9C,CAAC;CACD,MAAM,oBAAoB,MAAM,kBAAkB;EAChD;EACA,WAAW,MAAM;EACjB;EACA;EACA;CACF,CAAC;CACD,OAAO,MAAM,SAAS,aAAa,EAAE,kBAAkB,IAAI,KAAA;AAC7D"}
1
+ {"version":3,"file":"session-turn-processor.js","names":[],"sources":["../../src/session/session-turn-processor.ts"],"sourcesContent":["import { runAgentLoop } from \"../agent-loop\";\nimport type { ModelGenerationOptions } from \"../llm\";\nimport { ToolExecutionNeedsRecoveryError } from \"../llm-tool-execution\";\nimport type { AgentEvent } from \"./events\";\nimport type { BufferedAgentRun } from \"./run\";\nimport {\n closeRuntimeInput,\n type QueuedInput,\n type RuntimeInputState,\n withRuntimeInputWindow,\n} from \"./runtime-input\";\nimport {\n commitPreUserRuntimeInputs,\n emitCommittedRuntimeInputs,\n} from \"./runtime-input-emit\";\nimport { errorMessage } from \"./session-errors\";\nimport type { SessionEventDispatcher } from \"./session-events\";\nimport {\n type SessionExecutionOptions,\n type SessionExecutionRun,\n type SessionExecutionTerminalStatus,\n startSessionExecutionRun,\n} from \"./session-execution\";\nimport { drainRuntimeInput } from \"./session-runtime-drain\";\n\nimport type { SessionState } from \"./session-state\";\nimport { emitTurnErrorAfterRecovery } from \"./session-turn-error\";\n\ninterface ActiveTurn {\n readonly abort: AbortController;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly turnId: string;\n}\n\ninterface ProcessQueuedInputOptions {\n readonly activate: (turn: ActiveTurn) => void;\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly execution: SessionExecutionOptions;\n readonly item: QueuedInput;\n readonly model: ModelGenerationOptions;\n readonly release: () => void;\n readonly sessionKey: string;\n readonly state: SessionState;\n}\n\nexport async function processQueuedInput({\n activate,\n deactivateRun,\n events,\n execution,\n item,\n model,\n release,\n sessionKey,\n state,\n}: ProcessQueuedInputOptions): Promise<void> {\n const activeAbort = new AbortController();\n const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } =\n item;\n const turnId = crypto.randomUUID();\n activate({\n abort: activeAbort,\n run,\n runtimeInput,\n turnId,\n });\n const historySnapshot = state.modelSnapshot();\n let executionRun: SessionExecutionRun | undefined;\n\n try {\n executionRun = await startSessionExecutionRun({\n executionHost: execution.executionHost,\n sessionKey,\n state,\n turnId,\n });\n for (const event of initialEvents) {\n await events.emitRunEvent(run, event);\n }\n const committedPreUser = await commitPreUserRuntimeInputs(\n events,\n state,\n preUserRuntimeInputs\n );\n if (input) {\n state.appendUserInput(input);\n await state.commit();\n }\n await withRuntimeInputWindow(runtimeInput, \"turn-start\", async () => {\n await events.emitRunBoundaryEvent(run, { type: \"turn-start\" });\n });\n await emitCommittedRuntimeInputs(events, run, committedPreUser);\n await drainRuntimeInput({\n events,\n placement: \"turn-start\",\n run,\n runtimeInput,\n state,\n });\n\n const result = await runAgentLoop({\n emit: async (event) =>\n emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n }),\n history: state.history,\n model,\n captureObserverEvents: (callback) =>\n events.captureObserverEvents(run, callback),\n signal: activeAbort.signal,\n toolExecution: executionRun?.toolExecution,\n });\n\n await state.commit();\n await executionRun?.complete(executionStatusForResult(result));\n await closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n });\n } catch (error) {\n const turnError = error instanceof Error ? error : new Error(String(error));\n await executionRun?.complete(executionStatusForError(turnError));\n await emitTurnErrorAfterRecovery({\n error: turnError,\n historySnapshot,\n run,\n runtimeInput,\n state,\n });\n } finally {\n closeRuntimeInput(runtimeInput);\n release();\n run.close(undefined, runtimeInput.closedReason);\n }\n}\n\nfunction executionStatusForResult(\n result: \"aborted\" | \"completed\"\n): SessionExecutionTerminalStatus {\n return result === \"aborted\" ? \"cancelled\" : \"completed\";\n}\n\nfunction executionStatusForError(error: Error): SessionExecutionTerminalStatus {\n return error instanceof ToolExecutionNeedsRecoveryError\n ? \"needs-recovery\"\n : \"error\";\n}\n\nasync function closeSuccessfulTurn({\n deactivateRun,\n events,\n result,\n run,\n runtimeInput,\n}: {\n readonly deactivateRun: () => void;\n readonly events: SessionEventDispatcher;\n readonly result: \"aborted\" | \"completed\";\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n}): Promise<void> {\n const terminalEvent = result === \"aborted\" ? \"turn-abort\" : \"turn-end\";\n closeRuntimeInput(runtimeInput, terminalEvent);\n deactivateRun();\n try {\n await events.emitRunEvent(run, { type: terminalEvent });\n } catch (terminalError) {\n run.emit({ type: \"turn-error\", message: errorMessage(terminalError) });\n closeRuntimeInput(runtimeInput, \"turn-error\");\n }\n}\n\nasync function emitTurnEvent({\n event,\n events,\n run,\n runtimeInput,\n state,\n}: {\n readonly event: AgentEvent;\n readonly events: SessionEventDispatcher;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<{ readonly runtimeInputAdded: boolean } | undefined> {\n if (event.type !== \"step-start\" && event.type !== \"step-end\") {\n await events.emitRunEvent(run, event);\n return;\n }\n\n await withRuntimeInputWindow(runtimeInput, event.type, async () => {\n await events.emitRunBoundaryEvent(run, event);\n });\n const runtimeInputAdded = await drainRuntimeInput({\n events,\n placement: event.type,\n run,\n runtimeInput,\n state,\n });\n return event.type === \"step-end\" ? { runtimeInputAdded } : undefined;\n}\n"],"mappings":";;;;;;;;;AA+CA,eAAsB,mBAAmB,EACvC,UACA,eACA,QACA,WACA,MACA,OACA,SACA,YACA,SAC2C;CAC3C,MAAM,cAAc,IAAI,gBAAgB;CACxC,MAAM,EAAE,eAAe,OAAO,sBAAsB,KAAK,iBACvD;CACF,MAAM,SAAS,OAAO,WAAW;CACjC,SAAS;EACP,OAAO;EACP;EACA;EACA;CACF,CAAC;CACD,MAAM,kBAAkB,MAAM,cAAc;CAC5C,IAAI;CAEJ,IAAI;EACF,eAAe,MAAM,yBAAyB;GAC5C,eAAe,UAAU;GACzB;GACA;GACA;EACF,CAAC;EACD,KAAK,MAAM,SAAS,eAClB,MAAM,OAAO,aAAa,KAAK,KAAK;EAEtC,MAAM,mBAAmB,MAAM,2BAC7B,QACA,OACA,oBACF;EACA,IAAI,OAAO;GACT,MAAM,gBAAgB,KAAK;GAC3B,MAAM,MAAM,OAAO;EACrB;EACA,MAAM,uBAAuB,cAAc,cAAc,YAAY;GACnE,MAAM,OAAO,qBAAqB,KAAK,EAAE,MAAM,aAAa,CAAC;EAC/D,CAAC;EACD,MAAM,2BAA2B,QAAQ,KAAK,gBAAgB;EAC9D,MAAM,kBAAkB;GACtB;GACA,WAAW;GACX;GACA;GACA;EACF,CAAC;EAED,MAAM,SAAS,MAAM,aAAa;GAChC,MAAM,OAAO,UACX,cAAc;IACZ;IACA;IACA;IACA;IACA;GACF,CAAC;GACH,SAAS,MAAM;GACf;GACA,wBAAwB,aACtB,OAAO,sBAAsB,KAAK,QAAQ;GAC5C,QAAQ,YAAY;GACpB,eAAe,cAAc;EAC/B,CAAC;EAED,MAAM,MAAM,OAAO;EACnB,MAAM,cAAc,SAAS,yBAAyB,MAAM,CAAC;EAC7D,MAAM,oBAAoB;GACxB;GACA;GACA;GACA;GACA;EACF,CAAC;CACH,SAAS,OAAO;EACd,MAAM,YAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EAC1E,MAAM,cAAc,SAAS,wBAAwB,SAAS,CAAC;EAC/D,MAAM,2BAA2B;GAC/B,OAAO;GACP;GACA;GACA;GACA;EACF,CAAC;CACH,UAAU;EACR,kBAAkB,YAAY;EAC9B,QAAQ;EACR,IAAI,MAAM,KAAA,GAAW,aAAa,YAAY;CAChD;AACF;AAEA,SAAS,yBACP,QACgC;CAChC,OAAO,WAAW,YAAY,cAAc;AAC9C;AAEA,SAAS,wBAAwB,OAA8C;CAC7E,OAAO,iBAAiB,kCACpB,mBACA;AACN;AAEA,eAAe,oBAAoB,EACjC,eACA,QACA,QACA,KACA,gBAOgB;CAChB,MAAM,gBAAgB,WAAW,YAAY,eAAe;CAC5D,kBAAkB,cAAc,aAAa;CAC7C,cAAc;CACd,IAAI;EACF,MAAM,OAAO,aAAa,KAAK,EAAE,MAAM,cAAc,CAAC;CACxD,SAAS,eAAe;EACtB,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,aAAa,aAAa;EAAE,CAAC;EACrE,kBAAkB,cAAc,YAAY;CAC9C;AACF;AAEA,eAAe,cAAc,EAC3B,OACA,QACA,KACA,cACA,SAO+D;CAC/D,IAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,YAAY;EAC5D,MAAM,OAAO,aAAa,KAAK,KAAK;EACpC;CACF;CAEA,MAAM,uBAAuB,cAAc,MAAM,MAAM,YAAY;EACjE,MAAM,OAAO,qBAAqB,KAAK,KAAK;CAC9C,CAAC;CACD,MAAM,oBAAoB,MAAM,kBAAkB;EAChD;EACA,WAAW,MAAM;EACjB;EACA;EACA;CACF,CAAC;CACD,OAAO,MAAM,SAAS,aAAa,EAAE,kBAAkB,IAAI,KAAA;AAC7D"}
@@ -13,7 +13,7 @@ var AgentSession = class {
13
13
  #events;
14
14
  #execution;
15
15
  #inputQueue = [];
16
- #llm;
16
+ #model;
17
17
  #pendingRuntimeInputs = [];
18
18
  #sessionKey;
19
19
  #state;
@@ -25,8 +25,8 @@ var AgentSession = class {
25
25
  #killed = false;
26
26
  #running = false;
27
27
  #runToCloseOnKill;
28
- constructor(llm, persistence, plugins = [], execution = {}) {
29
- this.#llm = llm;
28
+ constructor(model, persistence, plugins = [], execution = {}) {
29
+ this.#model = model;
30
30
  this.#execution = execution;
31
31
  this.#sessionKey = persistence.key;
32
32
  this.#state = new SessionState(persistence);
@@ -163,7 +163,7 @@ var AgentSession = class {
163
163
  events: this.#events,
164
164
  execution: this.#execution,
165
165
  item,
166
- llm: this.#llm,
166
+ model: this.#model,
167
167
  release: () => {
168
168
  this.#activeAbort = void 0;
169
169
  this.#activeRun = void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","names":["#events","#execution","#inputQueue","#llm","#pendingRuntimeInputs","#sessionKey","#state","#activeAbort","#killed","#deletePromise","#drainInputQueue","#activeRun","#activeRuntimeInput","#activeTurnId","#enqueuePendingRuntimeInput","#runToCloseOnKill","#running"],"sources":["../../src/session/session.ts"],"sourcesContent":["import type { RuntimeLlm } from \"../llm\";\nimport type { AgentPlugin } from \"../plugins\";\nimport type { AgentEvent } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { attachInputMeta, userInputFromEvent } from \"./input-meta\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n addSteeringInput,\n createRuntimeInputState,\n type QueuedInput,\n type QueuedRuntimeInput,\n queueRuntimeInput,\n type RuntimeInputPlacement,\n type RuntimeInputState,\n} from \"./runtime-input\";\nimport { sessionKilledError, sessionTerminalError } from \"./session-errors\";\nimport { SessionEventDispatcher } from \"./session-events\";\nimport type { SessionExecutionOptions } from \"./session-execution\";\nimport { closeKilledRuntimeInputs } from \"./session-kill\";\nimport {\n type NotifyOptions,\n queueSessionNotification,\n startSessionQueueDrain,\n} from \"./session-notification\";\nimport { type SessionPersistenceOptions, SessionState } from \"./session-state\";\nimport { processQueuedInput } from \"./session-turn-processor\";\n\nexport type { AgentInput, SessionInput, UserInput } from \"./input\";\nexport type { AgentRun } from \"./run\";\nexport type { NotifyOptions } from \"./session-notification\";\n\nexport class AgentSession {\n readonly #events: SessionEventDispatcher;\n readonly #execution: SessionExecutionOptions;\n readonly #inputQueue: QueuedInput[] = [];\n readonly #llm: RuntimeLlm;\n readonly #pendingRuntimeInputs: QueuedRuntimeInput[] = [];\n readonly #sessionKey: string;\n readonly #state: SessionState;\n #activeAbort?: AbortController;\n #activeRun?: BufferedAgentRun;\n #activeRuntimeInput?: RuntimeInputState;\n #activeTurnId?: string;\n #deletePromise?: Promise<void>;\n #killed = false;\n #running = false;\n #runToCloseOnKill?: BufferedAgentRun;\n\n constructor(\n llm: RuntimeLlm,\n persistence: SessionPersistenceOptions,\n plugins: readonly AgentPlugin[] = [],\n execution: SessionExecutionOptions = {}\n ) {\n this.#llm = llm;\n this.#execution = execution;\n this.#sessionKey = persistence.key;\n this.#state = new SessionState(persistence);\n this.#events = new SessionEventDispatcher({\n history: () => this.#state.modelSnapshot(),\n plugins,\n signal: () => this.#activeAbort?.signal,\n });\n }\n\n async send(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = createRuntimeInputState(\n this.#pendingRuntimeInputs.splice(0)\n );\n const normalized = normalizeAgentInput(input);\n const acceptedInput =\n normalized.meta === undefined\n ? attachInputMeta(normalized, { source: \"send\" })\n : normalized;\n const run = new BufferedAgentRun();\n const emitted = await this.#events.emitRunEvent(run, acceptedInput);\n if (emitted === \"handled\") {\n run.close();\n return run;\n }\n\n const queuedInput = userInputFromEvent(\n emitted.type === \"user-text\" || emitted.type === \"user-message\"\n ? emitted\n : acceptedInput\n );\n this.#inputQueue.push({\n initialEvents: [],\n input: structuredClone(queuedInput),\n preUserRuntimeInputs: [],\n run,\n runtimeInput,\n });\n startSessionQueueDrain(run, () => this.#drainInputQueue());\n return run;\n }\n\n async notify(\n input: AgentInput,\n options: NotifyOptions = {}\n ): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n return queueSessionNotification(input, options, {\n activeRun: this.#activeRun,\n activeRuntimeInput: this.#activeRuntimeInput,\n drain: () => this.#drainInputQueue(),\n inputQueue: this.#inputQueue,\n pendingRuntimeInputs: this.#pendingRuntimeInputs,\n });\n }\n\n async steer(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n const run = this.#activeRun;\n if (!(runtimeInput && run)) {\n return this.send(input);\n }\n\n await addSteeringInput(runtimeInput, input);\n return run;\n }\n\n interrupt(): void {\n this.#activeAbort?.abort();\n }\n\n currentTurnId(): string | undefined {\n return this.#activeTurnId;\n }\n\n delete(): Promise<void> {\n if (!this.#deletePromise) {\n this.kill();\n this.#deletePromise = this.#state.delete().catch((error: unknown) => {\n this.#deletePromise = undefined;\n throw error;\n });\n }\n return this.#deletePromise;\n }\n\n enqueueRuntimeInput(\n input: UserInput,\n placement: RuntimeInputPlacement = \"turn-start\"\n ): void {\n if (this.#killed) {\n return;\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n if (runtimeInput && !runtimeInput.closedReason) {\n if (placement === \"turn-start\" && runtimeInput.placement !== placement) {\n this.#enqueuePendingRuntimeInput({ input, placement });\n return;\n }\n\n queueRuntimeInput(runtimeInput, { input, placement });\n return;\n }\n\n this.#enqueuePendingRuntimeInput({ input, placement });\n }\n\n emitObserverEvent(event: AgentEvent): Promise<void> {\n return this.#events.emitObserverEvent(this.#activeRun, event);\n }\n\n #enqueuePendingRuntimeInput(input: QueuedRuntimeInput): void {\n const queuedTurn = this.#inputQueue[0];\n if (input.placement === \"turn-start\" && queuedTurn) {\n queueRuntimeInput(queuedTurn.runtimeInput, input);\n return;\n }\n\n this.#pendingRuntimeInputs.push(input);\n }\n\n kill(): void {\n if (this.#killed) {\n return;\n }\n\n this.#killed = true;\n const killedError = sessionKilledError();\n this.#pendingRuntimeInputs.length = 0;\n this.#activeAbort?.abort();\n closeKilledRuntimeInputs({\n activeRuntimeInput: this.#activeRuntimeInput,\n inputQueue: this.#inputQueue,\n message: killedError.message,\n runToClose: this.#runToCloseOnKill ?? this.#activeRun,\n });\n }\n\n async #drainInputQueue(): Promise<void> {\n if (this.#running) {\n return;\n }\n\n this.#running = true;\n try {\n while (!this.#killed && this.#inputQueue.length > 0) {\n const item = this.#inputQueue.shift();\n if (item) {\n await processQueuedInput({\n activate: ({ abort, run, runtimeInput, turnId }) => {\n this.#activeAbort = abort;\n this.#activeRun = run;\n this.#activeRuntimeInput = runtimeInput;\n this.#activeTurnId = turnId;\n this.#runToCloseOnKill = run;\n },\n deactivateRun: () => {\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n },\n events: this.#events,\n execution: this.#execution,\n item,\n llm: this.#llm,\n release: () => {\n this.#activeAbort = undefined;\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n this.#activeTurnId = undefined;\n this.#runToCloseOnKill = undefined;\n },\n sessionKey: this.#sessionKey,\n state: this.#state,\n });\n }\n }\n } finally {\n this.#running = false;\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"session.js","names":["#events","#execution","#inputQueue","#model","#pendingRuntimeInputs","#sessionKey","#state","#activeAbort","#killed","#deletePromise","#drainInputQueue","#activeRun","#activeRuntimeInput","#activeTurnId","#enqueuePendingRuntimeInput","#runToCloseOnKill","#running"],"sources":["../../src/session/session.ts"],"sourcesContent":["import type { ModelGenerationOptions } from \"../llm\";\nimport type { AgentPlugin } from \"../plugins\";\nimport type { AgentEvent } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { attachInputMeta, userInputFromEvent } from \"./input-meta\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n addSteeringInput,\n createRuntimeInputState,\n type QueuedInput,\n type QueuedRuntimeInput,\n queueRuntimeInput,\n type RuntimeInputPlacement,\n type RuntimeInputState,\n} from \"./runtime-input\";\nimport { sessionKilledError, sessionTerminalError } from \"./session-errors\";\nimport { SessionEventDispatcher } from \"./session-events\";\nimport type { SessionExecutionOptions } from \"./session-execution\";\nimport { closeKilledRuntimeInputs } from \"./session-kill\";\nimport {\n type NotifyOptions,\n queueSessionNotification,\n startSessionQueueDrain,\n} from \"./session-notification\";\nimport { type SessionPersistenceOptions, SessionState } from \"./session-state\";\nimport { processQueuedInput } from \"./session-turn-processor\";\n\nexport type { AgentInput, SessionInput, UserInput } from \"./input\";\nexport type { AgentRun } from \"./run\";\nexport type { NotifyOptions } from \"./session-notification\";\n\nexport class AgentSession {\n readonly #events: SessionEventDispatcher;\n readonly #execution: SessionExecutionOptions;\n readonly #inputQueue: QueuedInput[] = [];\n readonly #model: ModelGenerationOptions;\n readonly #pendingRuntimeInputs: QueuedRuntimeInput[] = [];\n readonly #sessionKey: string;\n readonly #state: SessionState;\n #activeAbort?: AbortController;\n #activeRun?: BufferedAgentRun;\n #activeRuntimeInput?: RuntimeInputState;\n #activeTurnId?: string;\n #deletePromise?: Promise<void>;\n #killed = false;\n #running = false;\n #runToCloseOnKill?: BufferedAgentRun;\n\n constructor(\n model: ModelGenerationOptions,\n persistence: SessionPersistenceOptions,\n plugins: readonly AgentPlugin[] = [],\n execution: SessionExecutionOptions = {}\n ) {\n this.#model = model;\n this.#execution = execution;\n this.#sessionKey = persistence.key;\n this.#state = new SessionState(persistence);\n this.#events = new SessionEventDispatcher({\n history: () => this.#state.modelSnapshot(),\n plugins,\n signal: () => this.#activeAbort?.signal,\n });\n }\n\n async send(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = createRuntimeInputState(\n this.#pendingRuntimeInputs.splice(0)\n );\n const normalized = normalizeAgentInput(input);\n const acceptedInput =\n normalized.meta === undefined\n ? attachInputMeta(normalized, { source: \"send\" })\n : normalized;\n const run = new BufferedAgentRun();\n const emitted = await this.#events.emitRunEvent(run, acceptedInput);\n if (emitted === \"handled\") {\n run.close();\n return run;\n }\n\n const queuedInput = userInputFromEvent(\n emitted.type === \"user-text\" || emitted.type === \"user-message\"\n ? emitted\n : acceptedInput\n );\n this.#inputQueue.push({\n initialEvents: [],\n input: structuredClone(queuedInput),\n preUserRuntimeInputs: [],\n run,\n runtimeInput,\n });\n startSessionQueueDrain(run, () => this.#drainInputQueue());\n return run;\n }\n\n async notify(\n input: AgentInput,\n options: NotifyOptions = {}\n ): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n await this.#state.ensureLoaded();\n\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n return queueSessionNotification(input, options, {\n activeRun: this.#activeRun,\n activeRuntimeInput: this.#activeRuntimeInput,\n drain: () => this.#drainInputQueue(),\n inputQueue: this.#inputQueue,\n pendingRuntimeInputs: this.#pendingRuntimeInputs,\n });\n }\n\n async steer(input: AgentInput): Promise<AgentRun> {\n if (this.#killed || this.#deletePromise) {\n throw sessionTerminalError(this.#killed);\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n const run = this.#activeRun;\n if (!(runtimeInput && run)) {\n return this.send(input);\n }\n\n await addSteeringInput(runtimeInput, input);\n return run;\n }\n\n interrupt(): void {\n this.#activeAbort?.abort();\n }\n\n currentTurnId(): string | undefined {\n return this.#activeTurnId;\n }\n\n delete(): Promise<void> {\n if (!this.#deletePromise) {\n this.kill();\n this.#deletePromise = this.#state.delete().catch((error: unknown) => {\n this.#deletePromise = undefined;\n throw error;\n });\n }\n return this.#deletePromise;\n }\n\n enqueueRuntimeInput(\n input: UserInput,\n placement: RuntimeInputPlacement = \"turn-start\"\n ): void {\n if (this.#killed) {\n return;\n }\n\n const runtimeInput = this.#activeRuntimeInput;\n if (runtimeInput && !runtimeInput.closedReason) {\n if (placement === \"turn-start\" && runtimeInput.placement !== placement) {\n this.#enqueuePendingRuntimeInput({ input, placement });\n return;\n }\n\n queueRuntimeInput(runtimeInput, { input, placement });\n return;\n }\n\n this.#enqueuePendingRuntimeInput({ input, placement });\n }\n\n emitObserverEvent(event: AgentEvent): Promise<void> {\n return this.#events.emitObserverEvent(this.#activeRun, event);\n }\n\n #enqueuePendingRuntimeInput(input: QueuedRuntimeInput): void {\n const queuedTurn = this.#inputQueue[0];\n if (input.placement === \"turn-start\" && queuedTurn) {\n queueRuntimeInput(queuedTurn.runtimeInput, input);\n return;\n }\n\n this.#pendingRuntimeInputs.push(input);\n }\n\n kill(): void {\n if (this.#killed) {\n return;\n }\n\n this.#killed = true;\n const killedError = sessionKilledError();\n this.#pendingRuntimeInputs.length = 0;\n this.#activeAbort?.abort();\n closeKilledRuntimeInputs({\n activeRuntimeInput: this.#activeRuntimeInput,\n inputQueue: this.#inputQueue,\n message: killedError.message,\n runToClose: this.#runToCloseOnKill ?? this.#activeRun,\n });\n }\n\n async #drainInputQueue(): Promise<void> {\n if (this.#running) {\n return;\n }\n\n this.#running = true;\n try {\n while (!this.#killed && this.#inputQueue.length > 0) {\n const item = this.#inputQueue.shift();\n if (item) {\n await processQueuedInput({\n activate: ({ abort, run, runtimeInput, turnId }) => {\n this.#activeAbort = abort;\n this.#activeRun = run;\n this.#activeRuntimeInput = runtimeInput;\n this.#activeTurnId = turnId;\n this.#runToCloseOnKill = run;\n },\n deactivateRun: () => {\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n },\n events: this.#events,\n execution: this.#execution,\n item,\n model: this.#model,\n release: () => {\n this.#activeAbort = undefined;\n this.#activeRun = undefined;\n this.#activeRuntimeInput = undefined;\n this.#activeTurnId = undefined;\n this.#runToCloseOnKill = undefined;\n },\n sessionKey: this.#sessionKey,\n state: this.#state,\n });\n }\n }\n } finally {\n this.#running = false;\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minpeter/pss-runtime",
3
- "version": "0.1.0-next.3",
3
+ "version": "0.1.0-next.4",
4
4
  "description": "Generic agent runtime for sessions, model loops, and synchronized run events.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",