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

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.
Files changed (141) hide show
  1. package/README.md +166 -78
  2. package/dist/agent-host-session-store.js +2 -4
  3. package/dist/agent-host-session-store.js.map +1 -1
  4. package/dist/agent-loop.js +2 -3
  5. package/dist/agent-loop.js.map +1 -1
  6. package/dist/agent-namespace.js +3 -7
  7. package/dist/agent-namespace.js.map +1 -1
  8. package/dist/agent-options.d.ts +2 -8
  9. package/dist/agent-options.js +4 -4
  10. package/dist/agent-options.js.map +1 -1
  11. package/dist/agent-resume.js +2 -82
  12. package/dist/agent-resume.js.map +1 -1
  13. package/dist/agent-session-entry.d.ts +1 -1
  14. package/dist/agent.d.ts +4 -4
  15. package/dist/agent.js +16 -70
  16. package/dist/agent.js.map +1 -1
  17. package/dist/cloudflare/cloudflare-agent-context.d.ts +40 -0
  18. package/dist/cloudflare/cloudflare-agent-context.js +37 -0
  19. package/dist/cloudflare/cloudflare-agent-context.js.map +1 -0
  20. package/dist/cloudflare/cloudflare-alarm-budget.d.ts +18 -0
  21. package/dist/cloudflare/cloudflare-alarm-budget.js +77 -0
  22. package/dist/cloudflare/cloudflare-alarm-budget.js.map +1 -0
  23. package/dist/cloudflare/cloudflare-alarm-drainer.d.ts +45 -0
  24. package/dist/cloudflare/cloudflare-alarm-drainer.js +103 -0
  25. package/dist/cloudflare/cloudflare-alarm-drainer.js.map +1 -0
  26. package/dist/cloudflare/cloudflare-alarm-run-drain.d.ts +13 -0
  27. package/dist/cloudflare/cloudflare-alarm-run-drain.js +81 -0
  28. package/dist/cloudflare/cloudflare-alarm-run-drain.js.map +1 -0
  29. package/dist/cloudflare/cloudflare-alarm-work.js +110 -0
  30. package/dist/cloudflare/cloudflare-alarm-work.js.map +1 -0
  31. package/dist/cloudflare/cloudflare-checkpoint-store.js +39 -0
  32. package/dist/cloudflare/cloudflare-checkpoint-store.js.map +1 -0
  33. package/dist/cloudflare/cloudflare-durable-object-fetch.d.ts +21 -0
  34. package/dist/cloudflare/cloudflare-durable-object-fetch.js +11 -0
  35. package/dist/cloudflare/cloudflare-durable-object-fetch.js.map +1 -0
  36. package/dist/cloudflare/cloudflare-event-store.js +33 -0
  37. package/dist/cloudflare/cloudflare-event-store.js.map +1 -0
  38. package/dist/cloudflare/cloudflare-execution-session-store.js +40 -0
  39. package/dist/cloudflare/cloudflare-execution-session-store.js.map +1 -0
  40. package/dist/cloudflare/cloudflare-execution-store.js +35 -0
  41. package/dist/cloudflare/cloudflare-execution-store.js.map +1 -0
  42. package/dist/cloudflare/cloudflare-host.d.ts +61 -0
  43. package/dist/cloudflare/cloudflare-host.js +113 -0
  44. package/dist/cloudflare/cloudflare-host.js.map +1 -0
  45. package/dist/cloudflare/cloudflare-notification-store.js +59 -0
  46. package/dist/cloudflare/cloudflare-notification-store.js.map +1 -0
  47. package/dist/cloudflare/cloudflare-run-store.js +81 -0
  48. package/dist/cloudflare/cloudflare-run-store.js.map +1 -0
  49. package/dist/cloudflare/cloudflare-store-utils.js +43 -0
  50. package/dist/cloudflare/cloudflare-store-utils.js.map +1 -0
  51. package/dist/cloudflare/durable-object-storage.d.ts +20 -0
  52. package/dist/cloudflare/durable-object-storage.js +76 -0
  53. package/dist/cloudflare/durable-object-storage.js.map +1 -0
  54. package/dist/cloudflare/index.d.ts +7 -0
  55. package/dist/cloudflare/index.js +6 -0
  56. package/dist/execution/capabilities.d.ts +40 -0
  57. package/dist/execution/host.d.ts +9 -0
  58. package/dist/execution/host.js +49 -1
  59. package/dist/execution/host.js.map +1 -1
  60. package/dist/execution/index.d.ts +3 -1
  61. package/dist/execution/index.js +2 -1
  62. package/dist/execution/memory.js +1 -1
  63. package/dist/execution/memory.js.map +1 -1
  64. package/dist/execution/types.d.ts +5 -10
  65. package/dist/index.d.ts +8 -4
  66. package/dist/index.js +6 -1
  67. package/dist/plugins.d.ts +25 -3
  68. package/dist/plugins.js +35 -6
  69. package/dist/plugins.js.map +1 -1
  70. package/dist/session/delegate-input.d.ts +9 -0
  71. package/dist/session/delegate-input.js +16 -0
  72. package/dist/session/delegate-input.js.map +1 -0
  73. package/dist/session/events.d.ts +43 -25
  74. package/dist/session/events.js +41 -0
  75. package/dist/session/events.js.map +1 -0
  76. package/dist/session/input-meta-types.d.ts +10 -0
  77. package/dist/session/input-meta.d.ts +13 -0
  78. package/dist/session/input-meta.js +45 -0
  79. package/dist/session/input-meta.js.map +1 -0
  80. package/dist/session/input.d.ts +4 -0
  81. package/dist/session/mapping.js +4 -2
  82. package/dist/session/mapping.js.map +1 -1
  83. package/dist/session/runtime-input-emit.js +41 -0
  84. package/dist/session/runtime-input-emit.js.map +1 -0
  85. package/dist/session/runtime-input.js +5 -1
  86. package/dist/session/runtime-input.js.map +1 -1
  87. package/dist/session/session-events.js +20 -6
  88. package/dist/session/session-events.js.map +1 -1
  89. package/dist/session/session-notification.js +3 -2
  90. package/dist/session/session-notification.js.map +1 -1
  91. package/dist/session/session-runtime-drain.js +3 -9
  92. package/dist/session/session-runtime-drain.js.map +1 -1
  93. package/dist/session/session-turn-processor.js +7 -17
  94. package/dist/session/session-turn-processor.js.map +1 -1
  95. package/dist/session/session.js +11 -4
  96. package/dist/session/session.js.map +1 -1
  97. package/package.json +6 -1
  98. package/dist/agent-child-runs.js +0 -16
  99. package/dist/agent-child-runs.js.map +0 -1
  100. package/dist/agent-host-capabilities.js +0 -9
  101. package/dist/agent-host-capabilities.js.map +0 -1
  102. package/dist/agent-validation.js +0 -35
  103. package/dist/agent-validation.js.map +0 -1
  104. package/dist/child-session-cleanups.js +0 -61
  105. package/dist/child-session-cleanups.js.map +0 -1
  106. package/dist/execution/run.js +0 -55
  107. package/dist/execution/run.js.map +0 -1
  108. package/dist/subagent-background-child-run-state.js +0 -51
  109. package/dist/subagent-background-child-run-state.js.map +0 -1
  110. package/dist/subagent-background-child-run.js +0 -103
  111. package/dist/subagent-background-child-run.js.map +0 -1
  112. package/dist/subagent-background-in-process.js +0 -98
  113. package/dist/subagent-background-in-process.js.map +0 -1
  114. package/dist/subagent-background-notification-inbox.js +0 -106
  115. package/dist/subagent-background-notification-inbox.js.map +0 -1
  116. package/dist/subagent-background-notify.js +0 -136
  117. package/dist/subagent-background-notify.js.map +0 -1
  118. package/dist/subagent-background-resume-group.js +0 -99
  119. package/dist/subagent-background-resume-group.js.map +0 -1
  120. package/dist/subagent-background-runner.js +0 -115
  121. package/dist/subagent-background-runner.js.map +0 -1
  122. package/dist/subagent-background-schedule.js +0 -43
  123. package/dist/subagent-background-schedule.js.map +0 -1
  124. package/dist/subagent-child-run.js +0 -68
  125. package/dist/subagent-child-run.js.map +0 -1
  126. package/dist/subagent-job-cancel.js +0 -84
  127. package/dist/subagent-job-cancel.js.map +0 -1
  128. package/dist/subagent-job-observer.js +0 -19
  129. package/dist/subagent-job-observer.js.map +0 -1
  130. package/dist/subagent-job-output.js +0 -87
  131. package/dist/subagent-job-output.js.map +0 -1
  132. package/dist/subagent-job-state.js +0 -66
  133. package/dist/subagent-job-state.js.map +0 -1
  134. package/dist/subagent-jobs.js +0 -96
  135. package/dist/subagent-jobs.js.map +0 -1
  136. package/dist/subagent-prompt-schema.js +0 -114
  137. package/dist/subagent-prompt-schema.js.map +0 -1
  138. package/dist/subagent-run.js +0 -111
  139. package/dist/subagent-run.js.map +0 -1
  140. package/dist/subagents.js +0 -125
  141. package/dist/subagents.js.map +0 -1
package/dist/plugins.d.ts CHANGED
@@ -1,9 +1,21 @@
1
1
  import { RuntimeLlmContext } from "./llm.js";
2
- import { AgentEvent } from "./session/events.js";
2
+ import { InputEventMeta, InputSource } from "./session/input-meta-types.js";
3
+ import { UserMessage, UserText } from "./session/input.js";
4
+ import { AgentEvent, RuntimeInput } from "./session/events.js";
3
5
 
4
6
  //#region src/plugins.d.ts
5
7
  type MaybePromise<T> = PromiseLike<T> | T;
6
8
  type AgentEventHistory = RuntimeLlmContext["history"];
9
+ type InterceptableAgentEvent = RuntimeInput | UserMessage | UserText;
10
+ type AgentPluginInterceptResult = {
11
+ readonly action: "continue";
12
+ } | {
13
+ readonly action: "handled";
14
+ } | {
15
+ readonly action: "transform";
16
+ readonly event: InterceptableAgentEvent;
17
+ };
18
+ type AgentPluginResult = AgentPluginInterceptResult | undefined;
7
19
  interface AgentEventContext {
8
20
  readonly event: AgentEvent;
9
21
  readonly history: AgentEventHistory;
@@ -11,10 +23,20 @@ interface AgentEventContext {
11
23
  }
12
24
  interface AgentPlugin {
13
25
  readonly events?: {
14
- readonly on?: (context: AgentEventContext) => MaybePromise<void>;
26
+ /** @deprecated Use top-level `on`. */readonly on?: (context: AgentEventContext) => MaybePromise<void>;
15
27
  };
16
28
  readonly name?: string;
29
+ readonly on?: (context: AgentEventContext) => MaybePromise<AgentPluginResult>;
17
30
  }
31
+ type PluginPipelineResult = {
32
+ readonly event: AgentEvent;
33
+ readonly kind: "emit";
34
+ } | {
35
+ readonly kind: "handled";
36
+ };
37
+ declare function runPluginsForEvent(plugins: readonly AgentPlugin[], context: AgentEventContext, options?: {
38
+ readonly observeOnly?: boolean;
39
+ }): Promise<PluginPipelineResult>;
18
40
  //#endregion
19
- export { AgentEventContext, AgentPlugin };
41
+ export { AgentEventContext, AgentPlugin, AgentPluginInterceptResult, AgentPluginResult, InterceptableAgentEvent, PluginPipelineResult, runPluginsForEvent };
20
42
  //# sourceMappingURL=plugins.d.ts.map
package/dist/plugins.js CHANGED
@@ -1,14 +1,43 @@
1
1
  //#region src/plugins.ts
2
- function runEventPlugins(plugins, context) {
3
- return runPluginHandlers(plugins, (plugin) => plugin.events?.on, context);
2
+ function runPluginsForEvent(plugins, context, options = {}) {
3
+ return runPluginPipeline(plugins, context, options.observeOnly === true);
4
4
  }
5
- async function runPluginHandlers(plugins, handlerFor, context) {
5
+ function isInterceptableEvent(event) {
6
+ return event.type === "user-text" || event.type === "user-message" || event.type === "runtime-input";
7
+ }
8
+ function resolvePluginHandler(plugin) {
9
+ if (plugin.on) return plugin.on;
10
+ const legacyHandler = plugin.events?.on;
11
+ if (!legacyHandler) return;
12
+ return (legacyContext) => Promise.resolve(legacyHandler(legacyContext)).then(() => void 0);
13
+ }
14
+ function normalizeInterceptResult(result) {
15
+ if (result === void 0) return;
16
+ if (result.action === "continue") return result;
17
+ if (result.action === "handled") return result;
18
+ if (result.action === "transform") return result;
19
+ }
20
+ async function runPluginPipeline(plugins, context, observeOnly) {
21
+ let currentEvent = context.event;
6
22
  for (const plugin of plugins) {
7
- const handler = handlerFor(plugin);
8
- if (handler) await handler(context);
23
+ const handler = resolvePluginHandler(plugin);
24
+ if (!handler) continue;
25
+ const result = await handler({
26
+ ...context,
27
+ event: currentEvent
28
+ });
29
+ if (observeOnly || !isInterceptableEvent(currentEvent)) continue;
30
+ const intercept = normalizeInterceptResult(result);
31
+ if (!intercept || intercept.action === "continue") continue;
32
+ if (intercept.action === "handled") return { kind: "handled" };
33
+ currentEvent = intercept.event;
9
34
  }
35
+ return {
36
+ kind: "emit",
37
+ event: currentEvent
38
+ };
10
39
  }
11
40
  //#endregion
12
- export { runEventPlugins };
41
+ export { runPluginsForEvent };
13
42
 
14
43
  //# sourceMappingURL=plugins.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","names":[],"sources":["../src/plugins.ts"],"sourcesContent":["import type { RuntimeLlmContext } from \"./llm\";\nimport type { AgentEvent } from \"./session/events\";\n\ntype MaybePromise<T> = PromiseLike<T> | T;\ntype AgentEventHistory = RuntimeLlmContext[\"history\"];\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 readonly on?: (context: AgentEventContext) => MaybePromise<void>;\n };\n readonly name?: string;\n}\n\nexport function runEventPlugins(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext\n): Promise<void> {\n return runPluginHandlers(plugins, (plugin) => plugin.events?.on, context);\n}\n\nasync function runPluginHandlers<Context>(\n plugins: readonly AgentPlugin[],\n handlerFor: (\n plugin: AgentPlugin\n ) => ((context: Context) => MaybePromise<void>) | undefined,\n context: Context\n): Promise<void> {\n for (const plugin of plugins) {\n const handler = handlerFor(plugin);\n if (handler) {\n await handler(context);\n }\n }\n}\n"],"mappings":";AAmBA,SAAgB,gBACd,SACA,SACe;CACf,OAAO,kBAAkB,UAAU,WAAW,OAAO,QAAQ,IAAI,OAAO;AAC1E;AAEA,eAAe,kBACb,SACA,YAGA,SACe;CACf,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,WAAW,MAAM;EACjC,IAAI,SACF,MAAM,QAAQ,OAAO;CAEzB;AACF"}
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"}
@@ -0,0 +1,9 @@
1
+ import { UserInput } from "./input.js";
2
+
3
+ //#region src/session/delegate-input.d.ts
4
+ declare function delegateUserInput(prompt: unknown, options?: {
5
+ readonly delegateToolName?: string;
6
+ }): UserInput;
7
+ //#endregion
8
+ export { delegateUserInput };
9
+ //# sourceMappingURL=delegate-input.d.ts.map
@@ -0,0 +1,16 @@
1
+ import { attachInputMeta } from "./input-meta.js";
2
+ //#region src/session/delegate-input.ts
3
+ function delegateUserInput(prompt, options = {}) {
4
+ if (typeof prompt !== "string") throw new TypeError("Delegate prompt must be a plain string.");
5
+ return attachInputMeta({
6
+ type: "user-text",
7
+ text: prompt
8
+ }, {
9
+ delegateToolName: options.delegateToolName,
10
+ source: "delegate"
11
+ });
12
+ }
13
+ //#endregion
14
+ export { delegateUserInput };
15
+
16
+ //# sourceMappingURL=delegate-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegate-input.js","names":[],"sources":["../../src/session/delegate-input.ts"],"sourcesContent":["import type { UserInput } from \"./input\";\nimport { attachInputMeta } from \"./input-meta\";\n\nexport function delegateUserInput(\n prompt: unknown,\n options: { readonly delegateToolName?: string } = {}\n): UserInput {\n if (typeof prompt !== \"string\") {\n throw new TypeError(\"Delegate prompt must be a plain string.\");\n }\n\n return attachInputMeta(\n {\n type: \"user-text\",\n text: prompt,\n },\n {\n delegateToolName: options.delegateToolName,\n source: \"delegate\",\n }\n );\n}\n"],"mappings":";;AAGA,SAAgB,kBACd,QACA,UAAkD,CAAC,GACxC;CACX,IAAI,OAAO,WAAW,UACpB,MAAM,IAAI,UAAU,yCAAyC;CAG/D,OAAO,gBACL;EACE,MAAM;EACN,MAAM;CACR,GACA;EACE,kBAAkB,QAAQ;EAC1B,QAAQ;CACV,CACF;AACF"}
@@ -1,3 +1,4 @@
1
+ import { InputEventMeta, InputSource } from "./input-meta-types.js";
1
2
  import { UserInput, UserMessage, UserMessageContent, UserMessageContentPart, UserMessageFileData, UserMessageFilePart, UserMessageImagePart, UserMessageTextPart, UserText, UserTextContent } from "./input.js";
2
3
 
3
4
  //#region src/session/events.d.ts
@@ -7,6 +8,7 @@ interface RuntimeInput {
7
8
  * This is distinct from human-originated user-text and user-message input.
8
9
  */
9
10
  input: UserInput;
11
+ meta?: InputEventMeta;
10
12
  placement: "turn-start" | "step-start" | "step-end";
11
13
  type: "runtime-input";
12
14
  }
@@ -30,7 +32,6 @@ interface ToolResult {
30
32
  toolName: string;
31
33
  type: "tool-result";
32
34
  }
33
- type SubagentJobStatus = "aborted" | "cancelled" | "completed" | "error" | "pending" | "running";
34
35
  type AgentEvent = /** User input was accepted into the session queue. */UserText /** User multipart input was accepted into the session queue. */ | UserMessage /** Runtime/API-originated input inserted into the current turn, not human input. */ | RuntimeInput /** A queued user input started running as a turn. */ | {
35
36
  type: "turn-start";
36
37
  } /** The active turn was interrupted before normal completion. */ | {
@@ -42,32 +43,49 @@ type AgentEvent = /** User input was accepted into the session queue. */UserText
42
43
  type: "turn-end";
43
44
  } /** One model/tool-loop iteration started within the active turn. */ | {
44
45
  type: "step-start";
45
- } /** The model produced reasoning content. */ | AssistantReasoning /** The model produced visible assistant text. */ | AssistantText /** The model requested a tool call. */ | ToolCall /** A tool call returned a result. */ | ToolResult | {
46
- description?: string;
47
- delegateToolCallId?: string;
48
- run_in_background: boolean;
49
- subagent: string;
50
- task_id?: string;
51
- type: "subagent-job-start";
52
- } | {
53
- eventType?: AgentEvent["type"];
54
- delegateToolCallId?: string;
55
- status: SubagentJobStatus;
56
- subagent: string;
57
- task_id: string;
58
- type: "subagent-job-update";
59
- } | {
60
- error?: string;
61
- eventCount: number;
62
- delegateToolCallId?: string;
63
- status: Exclude<SubagentJobStatus, "pending" | "running">;
64
- subagent: string;
65
- task_id?: string;
66
- type: "subagent-job-end";
67
- } /** One model/tool-loop iteration finished within the active turn. */ | {
46
+ } /** The model produced reasoning content. */ | AssistantReasoning /** The model produced visible assistant text. */ | AssistantText /** The model requested a tool call. */ | ToolCall /** A tool call returned a result. */ | ToolResult /** One model/tool-loop iteration finished within the active turn. */ | {
68
47
  type: "step-end";
69
48
  };
70
49
  type AgentEventListener = (event: AgentEvent) => void;
50
+ declare const visibleAgentEventTypes: {
51
+ "assistant-text": true;
52
+ "user-message": true;
53
+ "user-text": true;
54
+ };
55
+ declare const lifecycleAgentEventTypes: {
56
+ "step-end": true;
57
+ "step-start": true;
58
+ "turn-abort": true;
59
+ "turn-end": true;
60
+ "turn-error": true;
61
+ "turn-start": true;
62
+ };
63
+ declare const toolAgentEventTypes: {
64
+ "tool-call": true;
65
+ "tool-result": true;
66
+ };
67
+ declare const telemetryAgentEventTypes: {
68
+ "assistant-reasoning": true;
69
+ "runtime-input": true;
70
+ };
71
+ type VisibleAgentEvent = Extract<AgentEvent, {
72
+ type: keyof typeof visibleAgentEventTypes;
73
+ }>;
74
+ type LifecycleAgentEvent = Extract<AgentEvent, {
75
+ type: keyof typeof lifecycleAgentEventTypes;
76
+ }>;
77
+ type ToolAgentEvent = Extract<AgentEvent, {
78
+ type: keyof typeof toolAgentEventTypes;
79
+ }>;
80
+ type TelemetryAgentEvent = Extract<AgentEvent, {
81
+ type: keyof typeof telemetryAgentEventTypes;
82
+ }>;
83
+ type ControlAgentEvent = Exclude<AgentEvent, VisibleAgentEvent>;
84
+ declare function isVisibleAgentEvent(event: AgentEvent): event is VisibleAgentEvent;
85
+ declare function isLifecycleAgentEvent(event: AgentEvent): event is LifecycleAgentEvent;
86
+ declare function isToolAgentEvent(event: AgentEvent): event is ToolAgentEvent;
87
+ declare function isTelemetryAgentEvent(event: AgentEvent): event is TelemetryAgentEvent;
88
+ declare function isControlAgentEvent(event: AgentEvent): event is ControlAgentEvent;
71
89
  //#endregion
72
- export { AgentEvent, AgentEventListener, AssistantReasoning, AssistantText, RuntimeInput, ToolCall, ToolResult };
90
+ export { AgentEvent, AgentEventListener, AssistantReasoning, AssistantText, ControlAgentEvent, LifecycleAgentEvent, RuntimeInput, TelemetryAgentEvent, ToolAgentEvent, ToolCall, ToolResult, VisibleAgentEvent, isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent };
73
91
  //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1,41 @@
1
+ //#region src/session/events.ts
2
+ const visibleAgentEventTypes = {
3
+ "assistant-text": true,
4
+ "user-message": true,
5
+ "user-text": true
6
+ };
7
+ const lifecycleAgentEventTypes = {
8
+ "step-end": true,
9
+ "step-start": true,
10
+ "turn-abort": true,
11
+ "turn-end": true,
12
+ "turn-error": true,
13
+ "turn-start": true
14
+ };
15
+ const toolAgentEventTypes = {
16
+ "tool-call": true,
17
+ "tool-result": true
18
+ };
19
+ const telemetryAgentEventTypes = {
20
+ "assistant-reasoning": true,
21
+ "runtime-input": true
22
+ };
23
+ function isVisibleAgentEvent(event) {
24
+ return event.type in visibleAgentEventTypes;
25
+ }
26
+ function isLifecycleAgentEvent(event) {
27
+ return event.type in lifecycleAgentEventTypes;
28
+ }
29
+ function isToolAgentEvent(event) {
30
+ return event.type in toolAgentEventTypes;
31
+ }
32
+ function isTelemetryAgentEvent(event) {
33
+ return event.type in telemetryAgentEventTypes;
34
+ }
35
+ function isControlAgentEvent(event) {
36
+ return !isVisibleAgentEvent(event);
37
+ }
38
+ //#endregion
39
+ export { isControlAgentEvent, isLifecycleAgentEvent, isTelemetryAgentEvent, isToolAgentEvent, isVisibleAgentEvent };
40
+
41
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../src/session/events.ts"],"sourcesContent":["import type { UserInput, UserMessage, UserText } from \"./input\";\nimport type { InputEventMeta } from \"./input-meta-types\";\n\nexport type {\n UserInput,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserMessageFilePart,\n UserMessageImagePart,\n UserMessageTextPart,\n UserText,\n UserTextContent,\n} from \"./input\";\nexport type { InputEventMeta, InputSource } from \"./input-meta-types\";\n\nexport interface RuntimeInput {\n /**\n * Runtime/API-originated model input inserted into the current turn.\n * This is distinct from human-originated user-text and user-message input.\n */\n input: UserInput;\n meta?: InputEventMeta;\n placement: \"turn-start\" | \"step-start\" | \"step-end\";\n type: \"runtime-input\";\n}\n\nexport interface AssistantText {\n text: string;\n type: \"assistant-text\";\n}\nexport interface AssistantReasoning {\n text: string;\n type: \"assistant-reasoning\";\n}\nexport interface ToolCall {\n input: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-call\";\n}\nexport interface ToolResult {\n output: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-result\";\n}\n\nexport type AgentEvent =\n /** User input was accepted into the session queue. */\n | UserText\n /** User multipart input was accepted into the session queue. */\n | UserMessage\n /** Runtime/API-originated input inserted into the current turn, not human input. */\n | RuntimeInput\n /** A queued user input started running as a turn. */\n | { type: \"turn-start\" }\n /** The active turn was interrupted before normal completion. */\n | { type: \"turn-abort\" }\n /** The active turn hit an unrecoverable runtime failure. */\n | { type: \"turn-error\"; message: string }\n /** The active turn completed normally. */\n | { type: \"turn-end\" }\n /** One model/tool-loop iteration started within the active turn. */\n | { type: \"step-start\" }\n /** The model produced reasoning content. */\n | AssistantReasoning\n /** The model produced visible assistant text. */\n | AssistantText\n /** The model requested a tool call. */\n | ToolCall\n /** A tool call returned a result. */\n | ToolResult\n /** One model/tool-loop iteration finished within the active turn. */\n | { type: \"step-end\" };\n\nexport type AgentEventListener = (event: AgentEvent) => void;\n\nconst visibleAgentEventTypes = {\n \"assistant-text\": true,\n \"user-message\": true,\n \"user-text\": true,\n} satisfies Partial<Record<AgentEvent[\"type\"], true>>;\n\nconst lifecycleAgentEventTypes = {\n \"step-end\": true,\n \"step-start\": true,\n \"turn-abort\": true,\n \"turn-end\": true,\n \"turn-error\": true,\n \"turn-start\": true,\n} satisfies Partial<Record<AgentEvent[\"type\"], true>>;\n\nconst toolAgentEventTypes = {\n \"tool-call\": true,\n \"tool-result\": true,\n} satisfies Partial<Record<AgentEvent[\"type\"], true>>;\n\nconst telemetryAgentEventTypes = {\n \"assistant-reasoning\": true,\n \"runtime-input\": true,\n} satisfies Partial<Record<AgentEvent[\"type\"], true>>;\n\nexport type VisibleAgentEvent = Extract<\n AgentEvent,\n { type: keyof typeof visibleAgentEventTypes }\n>;\nexport type LifecycleAgentEvent = Extract<\n AgentEvent,\n { type: keyof typeof lifecycleAgentEventTypes }\n>;\nexport type ToolAgentEvent = Extract<\n AgentEvent,\n { type: keyof typeof toolAgentEventTypes }\n>;\nexport type TelemetryAgentEvent = Extract<\n AgentEvent,\n { type: keyof typeof telemetryAgentEventTypes }\n>;\nexport type ControlAgentEvent = Exclude<AgentEvent, VisibleAgentEvent>;\n\nexport function isVisibleAgentEvent(\n event: AgentEvent\n): event is VisibleAgentEvent {\n return event.type in visibleAgentEventTypes;\n}\n\nexport function isLifecycleAgentEvent(\n event: AgentEvent\n): event is LifecycleAgentEvent {\n return event.type in lifecycleAgentEventTypes;\n}\n\nexport function isToolAgentEvent(event: AgentEvent): event is ToolAgentEvent {\n return event.type in toolAgentEventTypes;\n}\n\nexport function isTelemetryAgentEvent(\n event: AgentEvent\n): event is TelemetryAgentEvent {\n return event.type in telemetryAgentEventTypes;\n}\n\nexport function isControlAgentEvent(\n event: AgentEvent\n): event is ControlAgentEvent {\n return !isVisibleAgentEvent(event);\n}\n"],"mappings":";AA+EA,MAAM,yBAAyB;CAC7B,kBAAkB;CAClB,gBAAgB;CAChB,aAAa;AACf;AAEA,MAAM,2BAA2B;CAC/B,YAAY;CACZ,cAAc;CACd,cAAc;CACd,YAAY;CACZ,cAAc;CACd,cAAc;AAChB;AAEA,MAAM,sBAAsB;CAC1B,aAAa;CACb,eAAe;AACjB;AAEA,MAAM,2BAA2B;CAC/B,uBAAuB;CACvB,iBAAiB;AACnB;AAoBA,SAAgB,oBACd,OAC4B;CAC5B,OAAO,MAAM,QAAQ;AACvB;AAEA,SAAgB,sBACd,OAC8B;CAC9B,OAAO,MAAM,QAAQ;AACvB;AAEA,SAAgB,iBAAiB,OAA4C;CAC3E,OAAO,MAAM,QAAQ;AACvB;AAEA,SAAgB,sBACd,OAC8B;CAC9B,OAAO,MAAM,QAAQ;AACvB;AAEA,SAAgB,oBACd,OAC4B;CAC5B,OAAO,CAAC,oBAAoB,KAAK;AACnC"}
@@ -0,0 +1,10 @@
1
+ //#region src/session/input-meta-types.d.ts
2
+ type InputSource = "delegate" | "notify" | "send" | "steer";
3
+ interface InputEventMeta {
4
+ readonly delegateToolName?: string;
5
+ readonly source: InputSource;
6
+ readonly streaming?: "follow-up" | "steer";
7
+ }
8
+ //#endregion
9
+ export { InputEventMeta, InputSource };
10
+ //# sourceMappingURL=input-meta-types.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { InputEventMeta, InputSource } from "./input-meta-types.js";
2
+ import { UserInput, UserMessage, UserText } from "./input.js";
3
+ import { AgentEvent, RuntimeInput } from "./events.js";
4
+
5
+ //#region src/session/input-meta.d.ts
6
+ declare function attachInputMeta(input: UserInput, meta: InputEventMeta): UserText | UserMessage;
7
+ declare function attachRuntimeInputMeta(input: UserInput, placement: RuntimeInput["placement"], meta: InputEventMeta): RuntimeInput;
8
+ declare function stripInputMeta(input: UserInput): UserInput;
9
+ declare function stripEventMeta(event: AgentEvent): AgentEvent;
10
+ declare function userInputFromEvent(event: UserText | UserMessage): UserInput;
11
+ //#endregion
12
+ export { attachInputMeta, attachRuntimeInputMeta, stripEventMeta, stripInputMeta, userInputFromEvent };
13
+ //# sourceMappingURL=input-meta.d.ts.map
@@ -0,0 +1,45 @@
1
+ //#region src/session/input-meta.ts
2
+ function attachInputMeta(input, meta) {
3
+ if (input.type === "user-text") return {
4
+ ...input,
5
+ meta
6
+ };
7
+ return {
8
+ ...input,
9
+ meta
10
+ };
11
+ }
12
+ function attachRuntimeInputMeta(input, placement, meta) {
13
+ return {
14
+ input: attachInputMeta(input, meta),
15
+ meta,
16
+ placement,
17
+ type: "runtime-input"
18
+ };
19
+ }
20
+ function stripInputMeta(input) {
21
+ if (input.type === "user-text") {
22
+ const { meta: _meta, ...rest } = input;
23
+ return rest;
24
+ }
25
+ const { meta: _meta, ...rest } = input;
26
+ return rest;
27
+ }
28
+ function stripEventMeta(event) {
29
+ if (event.type === "user-text" || event.type === "user-message") return stripInputMeta(event);
30
+ if (event.type === "runtime-input") {
31
+ const { meta: _meta, ...rest } = event;
32
+ return {
33
+ ...rest,
34
+ input: stripInputMeta(event.input)
35
+ };
36
+ }
37
+ return event;
38
+ }
39
+ function userInputFromEvent(event) {
40
+ return stripInputMeta(event);
41
+ }
42
+ //#endregion
43
+ export { attachInputMeta, attachRuntimeInputMeta, stripEventMeta, stripInputMeta, userInputFromEvent };
44
+
45
+ //# sourceMappingURL=input-meta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-meta.js","names":[],"sources":["../../src/session/input-meta.ts"],"sourcesContent":["import type { AgentEvent, RuntimeInput } from \"./events\";\nimport type { UserInput, UserMessage, UserText } from \"./input\";\nimport type { InputEventMeta } from \"./input-meta-types\";\n\nexport type { InputEventMeta, InputSource } from \"./input-meta-types\";\n\nexport function attachInputMeta(\n input: UserInput,\n meta: InputEventMeta\n): UserText | UserMessage {\n if (input.type === \"user-text\") {\n return { ...input, meta };\n }\n\n return { ...input, meta };\n}\n\nexport function attachRuntimeInputMeta(\n input: UserInput,\n placement: RuntimeInput[\"placement\"],\n meta: InputEventMeta\n): RuntimeInput {\n return {\n input: attachInputMeta(input, meta),\n meta,\n placement,\n type: \"runtime-input\",\n };\n}\n\nexport function stripInputMeta(input: UserInput): UserInput {\n if (input.type === \"user-text\") {\n const { meta: _meta, ...rest } = input;\n return rest;\n }\n\n const { meta: _meta, ...rest } = input;\n return rest;\n}\n\nexport function stripEventMeta(event: AgentEvent): AgentEvent {\n if (event.type === \"user-text\" || event.type === \"user-message\") {\n return stripInputMeta(event);\n }\n\n if (event.type === \"runtime-input\") {\n const { meta: _meta, ...rest } = event;\n return {\n ...rest,\n input: stripInputMeta(event.input),\n };\n }\n\n return event;\n}\n\nexport function userInputFromEvent(event: UserText | UserMessage): UserInput {\n return stripInputMeta(event);\n}\n"],"mappings":";AAMA,SAAgB,gBACd,OACA,MACwB;CACxB,IAAI,MAAM,SAAS,aACjB,OAAO;EAAE,GAAG;EAAO;CAAK;CAG1B,OAAO;EAAE,GAAG;EAAO;CAAK;AAC1B;AAEA,SAAgB,uBACd,OACA,WACA,MACc;CACd,OAAO;EACL,OAAO,gBAAgB,OAAO,IAAI;EAClC;EACA;EACA,MAAM;CACR;AACF;AAEA,SAAgB,eAAe,OAA6B;CAC1D,IAAI,MAAM,SAAS,aAAa;EAC9B,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;EACjC,OAAO;CACT;CAEA,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;CACjC,OAAO;AACT;AAEA,SAAgB,eAAe,OAA+B;CAC5D,IAAI,MAAM,SAAS,eAAe,MAAM,SAAS,gBAC/C,OAAO,eAAe,KAAK;CAG7B,IAAI,MAAM,SAAS,iBAAiB;EAClC,MAAM,EAAE,MAAM,OAAO,GAAG,SAAS;EACjC,OAAO;GACL,GAAG;GACH,OAAO,eAAe,MAAM,KAAK;EACnC;CACF;CAEA,OAAO;AACT;AAEA,SAAgB,mBAAmB,OAA0C;CAC3E,OAAO,eAAe,KAAK;AAC7B"}
@@ -1,6 +1,9 @@
1
+ import { InputEventMeta } from "./input-meta-types.js";
2
+
1
3
  //#region src/session/input.d.ts
2
4
  type UserTextContent = string | readonly string[];
3
5
  interface UserText {
6
+ meta?: InputEventMeta;
4
7
  text: UserTextContent;
5
8
  type: "user-text";
6
9
  }
@@ -36,6 +39,7 @@ type UserMessageContentPart = UserMessageFilePart | UserMessageImagePart | UserM
36
39
  type UserMessageContent = readonly UserMessageContentPart[];
37
40
  interface UserMessage {
38
41
  content: UserMessageContent;
42
+ meta?: InputEventMeta;
39
43
  type: "user-message";
40
44
  }
41
45
  type UserInput = UserMessage | UserText;
@@ -1,7 +1,9 @@
1
+ import { stripInputMeta } from "./input-meta.js";
1
2
  //#region src/session/mapping.ts
2
3
  function userInputToModelMessage(input) {
3
- if (input.type === "user-message") return userMessageToModelMessage(input);
4
- return userTextToModelMessage(input);
4
+ const stripped = stripInputMeta(input);
5
+ if (stripped.type === "user-message") return userMessageToModelMessage(stripped);
6
+ return userTextToModelMessage(stripped);
5
7
  }
6
8
  function userTextToModelMessage(input) {
7
9
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"mapping.js","names":[],"sources":["../../src/session/mapping.ts"],"sourcesContent":["import type {\n AssistantContent,\n AssistantModelMessage,\n ModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from \"ai\";\nimport type {\n AssistantReasoning,\n AssistantText,\n ToolCall,\n ToolResult,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserText,\n UserTextContent,\n} from \"./events\";\nimport type { UserInput } from \"./input\";\n\ntype AssistantContentPart = Exclude<AssistantContent, string>[number];\ntype ToolContentPart = ToolModelMessage[\"content\"][number];\ntype ModelEvent = AssistantReasoning | AssistantText | ToolCall | ToolResult;\n\n// UserInput -> AI SDK UserModelMessage\nexport function userInputToModelMessage(input: UserInput): UserModelMessage {\n if (input.type === \"user-message\") {\n return userMessageToModelMessage(input);\n }\n\n return userTextToModelMessage(input);\n}\n\nexport function userTextToModelMessage(input: UserText): UserModelMessage {\n return { role: \"user\", content: userTextContentToUserContent(input.text) };\n}\n\nfunction userTextContentToUserContent(\n text: UserTextContent\n): UserModelMessage[\"content\"] {\n if (typeof text === \"string\") {\n return text;\n }\n\n return text.map((part) => ({ type: \"text\", text: part }));\n}\n\nexport function userMessageToModelMessage(\n input: UserMessage\n): UserModelMessage {\n return {\n role: \"user\",\n content: userMessageContentToUserContent(input.content),\n };\n}\n\nfunction userMessageContentToUserContent(\n content: UserMessageContent\n): Exclude<UserModelMessage[\"content\"], string> {\n return content.map(userMessageContentPartToUserContentPart);\n}\n\nfunction userMessageContentPartToUserContentPart(\n part: UserMessageContentPart\n): Exclude<UserModelMessage[\"content\"], string>[number] {\n if (part.type === \"text\") {\n return { type: \"text\", text: part.text };\n }\n\n if (part.type === \"image\") {\n return {\n type: \"file\",\n data: part.image,\n mediaType: part.mediaType ?? \"image\",\n };\n }\n\n return {\n type: \"file\",\n data: userMessageFileDataToFileData(part.data),\n mediaType: part.mediaType,\n ...(part.filename === undefined ? {} : { filename: part.filename }),\n };\n}\n\nfunction userMessageFileDataToFileData(\n data: UserMessageFileData\n): Extract<\n Exclude<UserModelMessage[\"content\"], string>[number],\n { type: \"file\" }\n>[\"data\"] {\n if (typeof data === \"string\") {\n return data;\n }\n\n if (data.type === \"url\") {\n return data.url;\n }\n\n if (data.type === \"data\") {\n return { type: \"data\", data: data.data };\n }\n\n if (data.type === \"reference\") {\n return { type: \"reference\", reference: { ...data.reference } };\n }\n\n return { type: \"text\", text: data.text };\n}\n\n// AI SDK ModelMessage -> public agent events\nexport function modelMessageToAgentEvents(message: ModelMessage): ModelEvent[] {\n if (message.role === \"assistant\") {\n return assistantReasoningFirstParts(assistantContentParts(message)).flatMap(\n assistantContentPartToEvents\n );\n }\n\n if (message.role === \"tool\") {\n return message.content.flatMap(toolContentPartToEvents);\n }\n\n return [];\n}\n\nfunction assistantContentParts(\n message: AssistantModelMessage\n): AssistantContentPart[] {\n return typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content;\n}\n\nfunction assistantReasoningFirstParts(\n parts: AssistantContentPart[]\n): AssistantContentPart[] {\n return [\n ...parts.filter((part) => part.type === \"reasoning\"),\n ...parts.filter((part) => part.type !== \"reasoning\"),\n ];\n}\n\nfunction assistantContentPartToEvents(\n part: AssistantContentPart\n): ModelEvent[] {\n if (part.type === \"text\") {\n return part.text ? [{ type: \"assistant-text\", text: part.text }] : [];\n }\n\n if (part.type === \"reasoning\") {\n return part.text ? [{ type: \"assistant-reasoning\", text: part.text }] : [];\n }\n\n if (part.type === \"tool-call\") {\n return [\n {\n type: \"tool-call\",\n input: part.input,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n }\n\n return [];\n}\n\nfunction toolContentPartToEvents(part: ToolContentPart): ModelEvent[] {\n if (part.type === \"tool-result\") {\n return toolResultPartToEvents(part);\n }\n\n return [];\n}\n\nfunction toolResultPartToEvents(part: {\n output: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-result\";\n}): ModelEvent[] {\n return [\n {\n type: \"tool-result\",\n output: part.output,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n}\n"],"mappings":";AA0BA,SAAgB,wBAAwB,OAAoC;CAC1E,IAAI,MAAM,SAAS,gBACjB,OAAO,0BAA0B,KAAK;CAGxC,OAAO,uBAAuB,KAAK;AACrC;AAEA,SAAgB,uBAAuB,OAAmC;CACxE,OAAO;EAAE,MAAM;EAAQ,SAAS,6BAA6B,MAAM,IAAI;CAAE;AAC3E;AAEA,SAAS,6BACP,MAC6B;CAC7B,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,OAAO,KAAK,KAAK,UAAU;EAAE,MAAM;EAAQ,MAAM;CAAK,EAAE;AAC1D;AAEA,SAAgB,0BACd,OACkB;CAClB,OAAO;EACL,MAAM;EACN,SAAS,gCAAgC,MAAM,OAAO;CACxD;AACF;AAEA,SAAS,gCACP,SAC8C;CAC9C,OAAO,QAAQ,IAAI,uCAAuC;AAC5D;AAEA,SAAS,wCACP,MACsD;CACtD,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,SAChB,OAAO;EACL,MAAM;EACN,MAAM,KAAK;EACX,WAAW,KAAK,aAAa;CAC/B;CAGF,OAAO;EACL,MAAM;EACN,MAAM,8BAA8B,KAAK,IAAI;EAC7C,WAAW,KAAK;EAChB,GAAI,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;CACnE;AACF;AAEA,SAAS,8BACP,MAIQ;CACR,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,KAAK,SAAS,OAChB,OAAO,KAAK;CAGd,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,aAChB,OAAO;EAAE,MAAM;EAAa,WAAW,EAAE,GAAG,KAAK,UAAU;CAAE;CAG/D,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;AACzC;AAGA,SAAgB,0BAA0B,SAAqC;CAC7E,IAAI,QAAQ,SAAS,aACnB,OAAO,6BAA6B,sBAAsB,OAAO,CAAC,EAAE,QAClE,4BACF;CAGF,IAAI,QAAQ,SAAS,QACnB,OAAO,QAAQ,QAAQ,QAAQ,uBAAuB;CAGxD,OAAO,CAAC;AACV;AAEA,SAAS,sBACP,SACwB;CACxB,OAAO,OAAO,QAAQ,YAAY,WAC9B,CAAC;EAAE,MAAM;EAAQ,MAAM,QAAQ;CAAQ,CAAC,IACxC,QAAQ;AACd;AAEA,SAAS,6BACP,OACwB;CACxB,OAAO,CACL,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,GACnD,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,CACrD;AACF;AAEA,SAAS,6BACP,MACc;CACd,IAAI,KAAK,SAAS,QAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAkB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAGtE,IAAI,KAAK,SAAS,aAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAuB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAG3E,IAAI,KAAK,SAAS,aAChB,OAAO,CACL;EACE,MAAM;EACN,OAAO,KAAK;EACZ,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;CAGF,OAAO,CAAC;AACV;AAEA,SAAS,wBAAwB,MAAqC;CACpE,IAAI,KAAK,SAAS,eAChB,OAAO,uBAAuB,IAAI;CAGpC,OAAO,CAAC;AACV;AAEA,SAAS,uBAAuB,MAKf;CACf,OAAO,CACL;EACE,MAAM;EACN,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;AACF"}
1
+ {"version":3,"file":"mapping.js","names":[],"sources":["../../src/session/mapping.ts"],"sourcesContent":["import type {\n AssistantContent,\n AssistantModelMessage,\n ModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from \"ai\";\nimport type {\n AssistantReasoning,\n AssistantText,\n ToolCall,\n ToolResult,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserText,\n UserTextContent,\n} from \"./events\";\nimport type { UserInput } from \"./input\";\nimport { stripInputMeta } from \"./input-meta\";\n\ntype AssistantContentPart = Exclude<AssistantContent, string>[number];\ntype ToolContentPart = ToolModelMessage[\"content\"][number];\ntype ModelEvent = AssistantReasoning | AssistantText | ToolCall | ToolResult;\n\n// UserInput -> AI SDK UserModelMessage\nexport function userInputToModelMessage(input: UserInput): UserModelMessage {\n const stripped = stripInputMeta(input);\n if (stripped.type === \"user-message\") {\n return userMessageToModelMessage(stripped);\n }\n\n return userTextToModelMessage(stripped);\n}\n\nexport function userTextToModelMessage(input: UserText): UserModelMessage {\n return { role: \"user\", content: userTextContentToUserContent(input.text) };\n}\n\nfunction userTextContentToUserContent(\n text: UserTextContent\n): UserModelMessage[\"content\"] {\n if (typeof text === \"string\") {\n return text;\n }\n\n return text.map((part) => ({ type: \"text\", text: part }));\n}\n\nexport function userMessageToModelMessage(\n input: UserMessage\n): UserModelMessage {\n return {\n role: \"user\",\n content: userMessageContentToUserContent(input.content),\n };\n}\n\nfunction userMessageContentToUserContent(\n content: UserMessageContent\n): Exclude<UserModelMessage[\"content\"], string> {\n return content.map(userMessageContentPartToUserContentPart);\n}\n\nfunction userMessageContentPartToUserContentPart(\n part: UserMessageContentPart\n): Exclude<UserModelMessage[\"content\"], string>[number] {\n if (part.type === \"text\") {\n return { type: \"text\", text: part.text };\n }\n\n if (part.type === \"image\") {\n return {\n type: \"file\",\n data: part.image,\n mediaType: part.mediaType ?? \"image\",\n };\n }\n\n return {\n type: \"file\",\n data: userMessageFileDataToFileData(part.data),\n mediaType: part.mediaType,\n ...(part.filename === undefined ? {} : { filename: part.filename }),\n };\n}\n\nfunction userMessageFileDataToFileData(\n data: UserMessageFileData\n): Extract<\n Exclude<UserModelMessage[\"content\"], string>[number],\n { type: \"file\" }\n>[\"data\"] {\n if (typeof data === \"string\") {\n return data;\n }\n\n if (data.type === \"url\") {\n return data.url;\n }\n\n if (data.type === \"data\") {\n return { type: \"data\", data: data.data };\n }\n\n if (data.type === \"reference\") {\n return { type: \"reference\", reference: { ...data.reference } };\n }\n\n return { type: \"text\", text: data.text };\n}\n\n// AI SDK ModelMessage -> public agent events\nexport function modelMessageToAgentEvents(message: ModelMessage): ModelEvent[] {\n if (message.role === \"assistant\") {\n return assistantReasoningFirstParts(assistantContentParts(message)).flatMap(\n assistantContentPartToEvents\n );\n }\n\n if (message.role === \"tool\") {\n return message.content.flatMap(toolContentPartToEvents);\n }\n\n return [];\n}\n\nfunction assistantContentParts(\n message: AssistantModelMessage\n): AssistantContentPart[] {\n return typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content;\n}\n\nfunction assistantReasoningFirstParts(\n parts: AssistantContentPart[]\n): AssistantContentPart[] {\n return [\n ...parts.filter((part) => part.type === \"reasoning\"),\n ...parts.filter((part) => part.type !== \"reasoning\"),\n ];\n}\n\nfunction assistantContentPartToEvents(\n part: AssistantContentPart\n): ModelEvent[] {\n if (part.type === \"text\") {\n return part.text ? [{ type: \"assistant-text\", text: part.text }] : [];\n }\n\n if (part.type === \"reasoning\") {\n return part.text ? [{ type: \"assistant-reasoning\", text: part.text }] : [];\n }\n\n if (part.type === \"tool-call\") {\n return [\n {\n type: \"tool-call\",\n input: part.input,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n }\n\n return [];\n}\n\nfunction toolContentPartToEvents(part: ToolContentPart): ModelEvent[] {\n if (part.type === \"tool-result\") {\n return toolResultPartToEvents(part);\n }\n\n return [];\n}\n\nfunction toolResultPartToEvents(part: {\n output: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-result\";\n}): ModelEvent[] {\n return [\n {\n type: \"tool-result\",\n output: part.output,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n}\n"],"mappings":";;AA2BA,SAAgB,wBAAwB,OAAoC;CAC1E,MAAM,WAAW,eAAe,KAAK;CACrC,IAAI,SAAS,SAAS,gBACpB,OAAO,0BAA0B,QAAQ;CAG3C,OAAO,uBAAuB,QAAQ;AACxC;AAEA,SAAgB,uBAAuB,OAAmC;CACxE,OAAO;EAAE,MAAM;EAAQ,SAAS,6BAA6B,MAAM,IAAI;CAAE;AAC3E;AAEA,SAAS,6BACP,MAC6B;CAC7B,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,OAAO,KAAK,KAAK,UAAU;EAAE,MAAM;EAAQ,MAAM;CAAK,EAAE;AAC1D;AAEA,SAAgB,0BACd,OACkB;CAClB,OAAO;EACL,MAAM;EACN,SAAS,gCAAgC,MAAM,OAAO;CACxD;AACF;AAEA,SAAS,gCACP,SAC8C;CAC9C,OAAO,QAAQ,IAAI,uCAAuC;AAC5D;AAEA,SAAS,wCACP,MACsD;CACtD,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,SAChB,OAAO;EACL,MAAM;EACN,MAAM,KAAK;EACX,WAAW,KAAK,aAAa;CAC/B;CAGF,OAAO;EACL,MAAM;EACN,MAAM,8BAA8B,KAAK,IAAI;EAC7C,WAAW,KAAK;EAChB,GAAI,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;CACnE;AACF;AAEA,SAAS,8BACP,MAIQ;CACR,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,KAAK,SAAS,OAChB,OAAO,KAAK;CAGd,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,aAChB,OAAO;EAAE,MAAM;EAAa,WAAW,EAAE,GAAG,KAAK,UAAU;CAAE;CAG/D,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;AACzC;AAGA,SAAgB,0BAA0B,SAAqC;CAC7E,IAAI,QAAQ,SAAS,aACnB,OAAO,6BAA6B,sBAAsB,OAAO,CAAC,EAAE,QAClE,4BACF;CAGF,IAAI,QAAQ,SAAS,QACnB,OAAO,QAAQ,QAAQ,QAAQ,uBAAuB;CAGxD,OAAO,CAAC;AACV;AAEA,SAAS,sBACP,SACwB;CACxB,OAAO,OAAO,QAAQ,YAAY,WAC9B,CAAC;EAAE,MAAM;EAAQ,MAAM,QAAQ;CAAQ,CAAC,IACxC,QAAQ;AACd;AAEA,SAAS,6BACP,OACwB;CACxB,OAAO,CACL,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,GACnD,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,CACrD;AACF;AAEA,SAAS,6BACP,MACc;CACd,IAAI,KAAK,SAAS,QAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAkB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAGtE,IAAI,KAAK,SAAS,aAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAuB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAG3E,IAAI,KAAK,SAAS,aAChB,OAAO,CACL;EACE,MAAM;EACN,OAAO,KAAK;EACZ,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;CAGF,OAAO,CAAC;AACV;AAEA,SAAS,wBAAwB,MAAqC;CACpE,IAAI,KAAK,SAAS,eAChB,OAAO,uBAAuB,IAAI;CAGpC,OAAO,CAAC;AACV;AAEA,SAAS,uBAAuB,MAKf;CACf,OAAO,CACL;EACE,MAAM;EACN,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;AACF"}
@@ -0,0 +1,41 @@
1
+ import { stripInputMeta } from "./input-meta.js";
2
+ //#region src/session/runtime-input-emit.ts
3
+ function runtimeInputEventFromQueued(queued) {
4
+ return {
5
+ input: queued.input,
6
+ meta: queued.input.meta,
7
+ placement: queued.placement,
8
+ type: "runtime-input"
9
+ };
10
+ }
11
+ async function commitPreUserRuntimeInputs(events, state, runtimeInputs) {
12
+ const committed = [];
13
+ for (const queued of runtimeInputs) {
14
+ const processed = await events.interceptEvent(runtimeInputEventFromQueued(queued));
15
+ if (processed === "handled") continue;
16
+ committed.push(processed);
17
+ const input = runtimeInputHistoryFromEvent(processed, queued);
18
+ state.appendUserInput(input);
19
+ await state.commit();
20
+ }
21
+ return committed;
22
+ }
23
+ function emitCommittedRuntimeInputs(events, run, committed) {
24
+ for (const event of committed) events.emitProcessedEvent(run, event);
25
+ }
26
+ async function emitRuntimeInputEvent(events, run, state, queued) {
27
+ const processed = await events.interceptEvent(runtimeInputEventFromQueued(queued));
28
+ if (processed === "handled") return false;
29
+ events.emitProcessedEvent(run, processed);
30
+ state.appendUserInput(runtimeInputHistoryFromEvent(processed, queued));
31
+ await state.commit();
32
+ return true;
33
+ }
34
+ function runtimeInputHistoryFromEvent(processed, queued) {
35
+ if (processed.type === "runtime-input") return stripInputMeta(processed.input);
36
+ return stripInputMeta(queued.input);
37
+ }
38
+ //#endregion
39
+ export { commitPreUserRuntimeInputs, emitCommittedRuntimeInputs, emitRuntimeInputEvent };
40
+
41
+ //# sourceMappingURL=runtime-input-emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-input-emit.js","names":[],"sources":["../../src/session/runtime-input-emit.ts"],"sourcesContent":["import type { AgentEvent, RuntimeInput } from \"./events\";\nimport type { UserInput } from \"./input\";\nimport { stripInputMeta } from \"./input-meta\";\nimport type { BufferedAgentRun } from \"./run\";\nimport type { QueuedRuntimeInput } from \"./runtime-input\";\nimport type { SessionEventDispatcher } from \"./session-events\";\nimport type { SessionState } from \"./session-state\";\n\nexport function runtimeInputEventFromQueued(\n queued: QueuedRuntimeInput\n): RuntimeInput {\n return {\n input: queued.input,\n meta: queued.input.meta,\n placement: queued.placement,\n type: \"runtime-input\",\n };\n}\n\nexport async function commitPreUserRuntimeInputs(\n events: SessionEventDispatcher,\n state: SessionState,\n runtimeInputs: readonly QueuedRuntimeInput[]\n): Promise<readonly AgentEvent[]> {\n const committed: AgentEvent[] = [];\n for (const queued of runtimeInputs) {\n const processed = await events.interceptEvent(\n runtimeInputEventFromQueued(queued)\n );\n if (processed === \"handled\") {\n continue;\n }\n\n committed.push(processed);\n const input = runtimeInputHistoryFromEvent(processed, queued);\n state.appendUserInput(input);\n await state.commit();\n }\n\n return committed;\n}\n\nexport function emitCommittedRuntimeInputs(\n events: SessionEventDispatcher,\n run: BufferedAgentRun,\n committed: readonly AgentEvent[]\n): void {\n for (const event of committed) {\n events.emitProcessedEvent(run, event);\n }\n}\n\nexport async function emitRuntimeInputEvent(\n events: SessionEventDispatcher,\n run: BufferedAgentRun,\n state: SessionState,\n queued: QueuedRuntimeInput\n): Promise<boolean> {\n const processed = await events.interceptEvent(\n runtimeInputEventFromQueued(queued)\n );\n if (processed === \"handled\") {\n return false;\n }\n\n events.emitProcessedEvent(run, processed);\n state.appendUserInput(runtimeInputHistoryFromEvent(processed, queued));\n await state.commit();\n return true;\n}\n\nfunction runtimeInputHistoryFromEvent(\n processed: AgentEvent,\n queued: QueuedRuntimeInput\n): UserInput {\n if (processed.type === \"runtime-input\") {\n return stripInputMeta(processed.input);\n }\n\n return stripInputMeta(queued.input);\n}\n"],"mappings":";;AAQA,SAAgB,4BACd,QACc;CACd,OAAO;EACL,OAAO,OAAO;EACd,MAAM,OAAO,MAAM;EACnB,WAAW,OAAO;EAClB,MAAM;CACR;AACF;AAEA,eAAsB,2BACpB,QACA,OACA,eACgC;CAChC,MAAM,YAA0B,CAAC;CACjC,KAAK,MAAM,UAAU,eAAe;EAClC,MAAM,YAAY,MAAM,OAAO,eAC7B,4BAA4B,MAAM,CACpC;EACA,IAAI,cAAc,WAChB;EAGF,UAAU,KAAK,SAAS;EACxB,MAAM,QAAQ,6BAA6B,WAAW,MAAM;EAC5D,MAAM,gBAAgB,KAAK;EAC3B,MAAM,MAAM,OAAO;CACrB;CAEA,OAAO;AACT;AAEA,SAAgB,2BACd,QACA,KACA,WACM;CACN,KAAK,MAAM,SAAS,WAClB,OAAO,mBAAmB,KAAK,KAAK;AAExC;AAEA,eAAsB,sBACpB,QACA,KACA,OACA,QACkB;CAClB,MAAM,YAAY,MAAM,OAAO,eAC7B,4BAA4B,MAAM,CACpC;CACA,IAAI,cAAc,WAChB,OAAO;CAGT,OAAO,mBAAmB,KAAK,SAAS;CACxC,MAAM,gBAAgB,6BAA6B,WAAW,MAAM,CAAC;CACrE,MAAM,MAAM,OAAO;CACnB,OAAO;AACT;AAEA,SAAS,6BACP,WACA,QACW;CACX,IAAI,UAAU,SAAS,iBACrB,OAAO,eAAe,UAAU,KAAK;CAGvC,OAAO,eAAe,OAAO,KAAK;AACpC"}
@@ -1,3 +1,4 @@
1
+ import { attachInputMeta } from "./input-meta.js";
1
2
  import { normalizeAgentInput } from "./input-normalization.js";
2
3
  //#region src/session/runtime-input.ts
3
4
  function createRuntimeInputState(queue) {
@@ -10,7 +11,10 @@ function addSteeringInput(runtimeInput, input) {
10
11
  const next = runtimeInput.pending.then(() => {
11
12
  if (runtimeInput.closedReason) throw runtimeInputClosedError(runtimeInput.closedReason);
12
13
  queueRuntimeInput(runtimeInput, {
13
- input: normalizeAgentInput(input),
14
+ input: attachInputMeta(normalizeAgentInput(input), {
15
+ source: "steer",
16
+ streaming: "steer"
17
+ }),
14
18
  placement: runtimeInput.steerPlacement ?? runtimeInput.placement ?? "step-end"
15
19
  });
16
20
  });
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-input.js","names":[],"sources":["../../src/session/runtime-input.ts"],"sourcesContent":["import type { AgentEvent, RuntimeInput } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport type { BufferedAgentRun } from \"./run\";\n\nexport type RuntimeInputPlacement = RuntimeInput[\"placement\"];\n\nexport interface QueuedRuntimeInput {\n readonly input: UserInput;\n readonly placement: RuntimeInputPlacement;\n}\n\nexport interface RuntimeInputState {\n closedReason?: string;\n pending: Promise<void>;\n placement?: RuntimeInputPlacement;\n readonly queue: QueuedRuntimeInput[];\n steerPlacement?: RuntimeInputPlacement;\n}\n\nexport interface QueuedInput {\n readonly initialEvents: AgentEvent[];\n readonly input?: UserInput;\n readonly preUserRuntimeInputs: QueuedRuntimeInput[];\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n}\n\nexport function createRuntimeInputState(\n queue: QueuedRuntimeInput[]\n): RuntimeInputState {\n return {\n pending: Promise.resolve(),\n queue,\n };\n}\n\nexport function addSteeringInput(\n runtimeInput: RuntimeInputState,\n input: AgentInput\n): Promise<void> {\n const next = runtimeInput.pending.then(() => {\n if (runtimeInput.closedReason) {\n throw runtimeInputClosedError(runtimeInput.closedReason);\n }\n\n queueRuntimeInput(runtimeInput, {\n input: normalizeAgentInput(input),\n placement:\n runtimeInput.steerPlacement ?? runtimeInput.placement ?? \"step-end\",\n });\n });\n runtimeInput.pending = next.catch(() => undefined);\n return next;\n}\n\nexport function closeRuntimeInput(\n runtimeInput: RuntimeInputState | undefined,\n reason = \"the run reached a terminal state\"\n): void {\n if (runtimeInput && !runtimeInput.closedReason) {\n runtimeInput.closedReason = reason;\n runtimeInput.placement = undefined;\n }\n}\n\nexport async function withRuntimeInputWindow<T>(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement,\n callback: () => Promise<T>\n): Promise<T> {\n const previousSteerPlacement = runtimeInput.steerPlacement;\n runtimeInput.placement = placement;\n runtimeInput.steerPlacement = placement;\n try {\n return await callback();\n } finally {\n runtimeInput.placement = undefined;\n runtimeInput.steerPlacement = previousSteerPlacement;\n }\n}\n\nexport async function withSteeringPlacement<T>(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement,\n callback: () => Promise<T>\n): Promise<T> {\n const previousSteerPlacement = runtimeInput.steerPlacement;\n runtimeInput.steerPlacement = placement;\n try {\n return await callback();\n } finally {\n runtimeInput.steerPlacement = previousSteerPlacement;\n }\n}\n\nexport function shiftRuntimeInput(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement\n): QueuedRuntimeInput | undefined {\n const index = runtimeInput.queue.findIndex(\n (input) => input.placement === placement\n );\n if (index === -1) {\n return;\n }\n\n return runtimeInput.queue.splice(index, 1)[0];\n}\n\nexport function queueRuntimeInput(\n runtimeInput: RuntimeInputState,\n input: QueuedRuntimeInput\n): void {\n runtimeInput.queue.push(input);\n}\n\nfunction runtimeInputClosedError(reason: string): Error {\n return new Error(`session.steer() cannot be used after ${reason}`);\n}\n"],"mappings":";;AA4BA,SAAgB,wBACd,OACmB;CACnB,OAAO;EACL,SAAS,QAAQ,QAAQ;EACzB;CACF;AACF;AAEA,SAAgB,iBACd,cACA,OACe;CACf,MAAM,OAAO,aAAa,QAAQ,WAAW;EAC3C,IAAI,aAAa,cACf,MAAM,wBAAwB,aAAa,YAAY;EAGzD,kBAAkB,cAAc;GAC9B,OAAO,oBAAoB,KAAK;GAChC,WACE,aAAa,kBAAkB,aAAa,aAAa;EAC7D,CAAC;CACH,CAAC;CACD,aAAa,UAAU,KAAK,YAAY,KAAA,CAAS;CACjD,OAAO;AACT;AAEA,SAAgB,kBACd,cACA,SAAS,oCACH;CACN,IAAI,gBAAgB,CAAC,aAAa,cAAc;EAC9C,aAAa,eAAe;EAC5B,aAAa,YAAY,KAAA;CAC3B;AACF;AAEA,eAAsB,uBACpB,cACA,WACA,UACY;CACZ,MAAM,yBAAyB,aAAa;CAC5C,aAAa,YAAY;CACzB,aAAa,iBAAiB;CAC9B,IAAI;EACF,OAAO,MAAM,SAAS;CACxB,UAAU;EACR,aAAa,YAAY,KAAA;EACzB,aAAa,iBAAiB;CAChC;AACF;AAgBA,SAAgB,kBACd,cACA,WACgC;CAChC,MAAM,QAAQ,aAAa,MAAM,WAC9B,UAAU,MAAM,cAAc,SACjC;CACA,IAAI,UAAU,IACZ;CAGF,OAAO,aAAa,MAAM,OAAO,OAAO,CAAC,EAAE;AAC7C;AAEA,SAAgB,kBACd,cACA,OACM;CACN,aAAa,MAAM,KAAK,KAAK;AAC/B;AAEA,SAAS,wBAAwB,QAAuB;CACtD,uBAAO,IAAI,MAAM,wCAAwC,QAAQ;AACnE"}
1
+ {"version":3,"file":"runtime-input.js","names":[],"sources":["../../src/session/runtime-input.ts"],"sourcesContent":["import type { AgentEvent, RuntimeInput } from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\nimport { attachInputMeta } from \"./input-meta\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport type { BufferedAgentRun } from \"./run\";\n\nexport type RuntimeInputPlacement = RuntimeInput[\"placement\"];\n\nexport interface QueuedRuntimeInput {\n readonly input: UserInput;\n readonly placement: RuntimeInputPlacement;\n}\n\nexport interface RuntimeInputState {\n closedReason?: string;\n pending: Promise<void>;\n placement?: RuntimeInputPlacement;\n readonly queue: QueuedRuntimeInput[];\n steerPlacement?: RuntimeInputPlacement;\n}\n\nexport interface QueuedInput {\n readonly initialEvents: AgentEvent[];\n readonly input?: UserInput;\n readonly preUserRuntimeInputs: QueuedRuntimeInput[];\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n}\n\nexport function createRuntimeInputState(\n queue: QueuedRuntimeInput[]\n): RuntimeInputState {\n return {\n pending: Promise.resolve(),\n queue,\n };\n}\n\nexport function addSteeringInput(\n runtimeInput: RuntimeInputState,\n input: AgentInput\n): Promise<void> {\n const next = runtimeInput.pending.then(() => {\n if (runtimeInput.closedReason) {\n throw runtimeInputClosedError(runtimeInput.closedReason);\n }\n\n queueRuntimeInput(runtimeInput, {\n input: attachInputMeta(normalizeAgentInput(input), {\n source: \"steer\",\n streaming: \"steer\",\n }),\n placement:\n runtimeInput.steerPlacement ?? runtimeInput.placement ?? \"step-end\",\n });\n });\n runtimeInput.pending = next.catch(() => undefined);\n return next;\n}\n\nexport function closeRuntimeInput(\n runtimeInput: RuntimeInputState | undefined,\n reason = \"the run reached a terminal state\"\n): void {\n if (runtimeInput && !runtimeInput.closedReason) {\n runtimeInput.closedReason = reason;\n runtimeInput.placement = undefined;\n }\n}\n\nexport async function withRuntimeInputWindow<T>(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement,\n callback: () => Promise<T>\n): Promise<T> {\n const previousSteerPlacement = runtimeInput.steerPlacement;\n runtimeInput.placement = placement;\n runtimeInput.steerPlacement = placement;\n try {\n return await callback();\n } finally {\n runtimeInput.placement = undefined;\n runtimeInput.steerPlacement = previousSteerPlacement;\n }\n}\n\nexport async function withSteeringPlacement<T>(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement,\n callback: () => Promise<T>\n): Promise<T> {\n const previousSteerPlacement = runtimeInput.steerPlacement;\n runtimeInput.steerPlacement = placement;\n try {\n return await callback();\n } finally {\n runtimeInput.steerPlacement = previousSteerPlacement;\n }\n}\n\nexport function shiftRuntimeInput(\n runtimeInput: RuntimeInputState,\n placement: RuntimeInputPlacement\n): QueuedRuntimeInput | undefined {\n const index = runtimeInput.queue.findIndex(\n (input) => input.placement === placement\n );\n if (index === -1) {\n return;\n }\n\n return runtimeInput.queue.splice(index, 1)[0];\n}\n\nexport function queueRuntimeInput(\n runtimeInput: RuntimeInputState,\n input: QueuedRuntimeInput\n): void {\n runtimeInput.queue.push(input);\n}\n\nfunction runtimeInputClosedError(reason: string): Error {\n return new Error(`session.steer() cannot be used after ${reason}`);\n}\n"],"mappings":";;;AA6BA,SAAgB,wBACd,OACmB;CACnB,OAAO;EACL,SAAS,QAAQ,QAAQ;EACzB;CACF;AACF;AAEA,SAAgB,iBACd,cACA,OACe;CACf,MAAM,OAAO,aAAa,QAAQ,WAAW;EAC3C,IAAI,aAAa,cACf,MAAM,wBAAwB,aAAa,YAAY;EAGzD,kBAAkB,cAAc;GAC9B,OAAO,gBAAgB,oBAAoB,KAAK,GAAG;IACjD,QAAQ;IACR,WAAW;GACb,CAAC;GACD,WACE,aAAa,kBAAkB,aAAa,aAAa;EAC7D,CAAC;CACH,CAAC;CACD,aAAa,UAAU,KAAK,YAAY,KAAA,CAAS;CACjD,OAAO;AACT;AAEA,SAAgB,kBACd,cACA,SAAS,oCACH;CACN,IAAI,gBAAgB,CAAC,aAAa,cAAc;EAC9C,aAAa,eAAe;EAC5B,aAAa,YAAY,KAAA;CAC3B;AACF;AAEA,eAAsB,uBACpB,cACA,WACA,UACY;CACZ,MAAM,yBAAyB,aAAa;CAC5C,aAAa,YAAY;CACzB,aAAa,iBAAiB;CAC9B,IAAI;EACF,OAAO,MAAM,SAAS;CACxB,UAAU;EACR,aAAa,YAAY,KAAA;EACzB,aAAa,iBAAiB;CAChC;AACF;AAgBA,SAAgB,kBACd,cACA,WACgC;CAChC,MAAM,QAAQ,aAAa,MAAM,WAC9B,UAAU,MAAM,cAAc,SACjC;CACA,IAAI,UAAU,IACZ;CAGF,OAAO,aAAa,MAAM,OAAO,OAAO,CAAC,EAAE;AAC7C;AAEA,SAAgB,kBACd,cACA,OACM;CACN,aAAa,MAAM,KAAK,KAAK;AAC/B;AAEA,SAAS,wBAAwB,QAAuB;CACtD,uBAAO,IAAI,MAAM,wCAAwC,QAAQ;AACnE"}
@@ -1,4 +1,4 @@
1
- import { runEventPlugins } from "../plugins.js";
1
+ import { runPluginsForEvent } from "../plugins.js";
2
2
  //#region src/session/session-events.ts
3
3
  var SessionEventDispatcher = class {
4
4
  #history;
@@ -35,18 +35,32 @@ var SessionEventDispatcher = class {
35
35
  return Promise.resolve();
36
36
  }
37
37
  if (!activeRun) return Promise.resolve();
38
- return this.emitRunEvent(activeRun, event);
38
+ return this.emitRunEvent(activeRun, event).then(() => void 0);
39
39
  }
40
40
  async emitRunBoundaryEvent(run, event) {
41
- await this.#runPlugins(event);
41
+ await runPluginsForEvent(this.#plugins, {
42
+ event,
43
+ history: this.#history(),
44
+ signal: this.#signal()
45
+ }, { observeOnly: true });
42
46
  await run.emitBoundary(event);
43
47
  }
44
48
  async emitRunEvent(run, event) {
45
- await this.#runPlugins(event);
49
+ const processed = await this.interceptEvent(event);
50
+ if (processed === "handled") return "handled";
51
+ run.emit(processed);
52
+ return processed;
53
+ }
54
+ async interceptEvent(event) {
55
+ const pipeline = await this.#runInterceptPipeline(event);
56
+ if (pipeline.kind === "handled") return "handled";
57
+ return pipeline.event;
58
+ }
59
+ emitProcessedEvent(run, event) {
46
60
  run.emit(event);
47
61
  }
48
- #runPlugins(event) {
49
- return runEventPlugins(this.#plugins, {
62
+ #runInterceptPipeline(event) {
63
+ return runPluginsForEvent(this.#plugins, {
50
64
  event,
51
65
  history: this.#history(),
52
66
  signal: this.#signal()
@@ -1 +1 @@
1
- {"version":3,"file":"session-events.js","names":["#history","#plugins","#signal","#observerEventBuffer","#runPlugins"],"sources":["../../src/session/session-events.ts"],"sourcesContent":["import type { RuntimeLlmContext } from \"../llm\";\nimport { type AgentPlugin, runEventPlugins } 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);\n }\n\n async emitRunBoundaryEvent(\n run: BufferedAgentRun,\n event: AgentEvent\n ): Promise<void> {\n await this.#runPlugins(event);\n await run.emitBoundary(event);\n }\n\n async emitRunEvent(run: BufferedAgentRun, event: AgentEvent): Promise<void> {\n await this.#runPlugins(event);\n run.emit(event);\n }\n\n #runPlugins(event: AgentEvent): Promise<void> {\n return runEventPlugins(this.#plugins, {\n event,\n history: this.#history(),\n signal: this.#signal(),\n });\n }\n}\n"],"mappings":";;AAWA,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;CAC3C;CAEA,MAAM,qBACJ,KACA,OACe;EACf,MAAM,KAAKC,YAAY,KAAK;EAC5B,MAAM,IAAI,aAAa,KAAK;CAC9B;CAEA,MAAM,aAAa,KAAuB,OAAkC;EAC1E,MAAM,KAAKA,YAAY,KAAK;EAC5B,IAAI,KAAK,KAAK;CAChB;CAEA,YAAY,OAAkC;EAC5C,OAAO,gBAAgB,KAAKH,UAAU;GACpC;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 { 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,11 +1,12 @@
1
- import { BufferedAgentRun } from "./run.js";
1
+ import { attachInputMeta } from "./input-meta.js";
2
2
  import { normalizeAgentInput } from "./input-normalization.js";
3
+ import { BufferedAgentRun } from "./run.js";
3
4
  import { createRuntimeInputState, queueRuntimeInput } from "./runtime-input.js";
4
5
  import { errorMessage } from "./session-errors.js";
5
6
  //#region src/session/session-notification.ts
6
7
  function queueSessionNotification(input, options, state) {
7
8
  const queuedRuntimeInput = {
8
- input: normalizeAgentInput(input),
9
+ input: attachInputMeta(normalizeAgentInput(input), { source: "notify" }),
9
10
  placement: "turn-start"
10
11
  };
11
12
  const observerEvents = cloneObserverEvents(options.observerEvents ?? []);