@minpeter/pss-runtime 0.1.0-next.2 → 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.
Files changed (145) hide show
  1. package/README.md +172 -85
  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 +9 -8
  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 +4 -19
  9. package/dist/agent-options.js +2 -8
  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 +19 -89
  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 +9 -5
  66. package/dist/index.js +6 -2
  67. package/dist/llm-tool-execution.js.map +1 -1
  68. package/dist/llm.d.ts +1 -21
  69. package/dist/llm.js +12 -14
  70. package/dist/llm.js.map +1 -1
  71. package/dist/plugins.d.ts +27 -5
  72. package/dist/plugins.js +35 -6
  73. package/dist/plugins.js.map +1 -1
  74. package/dist/session/delegate-input.d.ts +9 -0
  75. package/dist/session/delegate-input.js +16 -0
  76. package/dist/session/delegate-input.js.map +1 -0
  77. package/dist/session/events.d.ts +43 -25
  78. package/dist/session/events.js +41 -0
  79. package/dist/session/events.js.map +1 -0
  80. package/dist/session/input-meta-types.d.ts +10 -0
  81. package/dist/session/input-meta.d.ts +13 -0
  82. package/dist/session/input-meta.js +45 -0
  83. package/dist/session/input-meta.js.map +1 -0
  84. package/dist/session/input.d.ts +4 -0
  85. package/dist/session/mapping.js +4 -2
  86. package/dist/session/mapping.js.map +1 -1
  87. package/dist/session/runtime-input-emit.js +41 -0
  88. package/dist/session/runtime-input-emit.js.map +1 -0
  89. package/dist/session/runtime-input.js +5 -1
  90. package/dist/session/runtime-input.js.map +1 -1
  91. package/dist/session/session-events.js +20 -6
  92. package/dist/session/session-events.js.map +1 -1
  93. package/dist/session/session-notification.js +3 -2
  94. package/dist/session/session-notification.js.map +1 -1
  95. package/dist/session/session-runtime-drain.js +3 -9
  96. package/dist/session/session-runtime-drain.js.map +1 -1
  97. package/dist/session/session-turn-processor.js +10 -20
  98. package/dist/session/session-turn-processor.js.map +1 -1
  99. package/dist/session/session.js +15 -8
  100. package/dist/session/session.js.map +1 -1
  101. package/package.json +6 -1
  102. package/dist/agent-child-runs.js +0 -16
  103. package/dist/agent-child-runs.js.map +0 -1
  104. package/dist/agent-host-capabilities.js +0 -9
  105. package/dist/agent-host-capabilities.js.map +0 -1
  106. package/dist/agent-validation.js +0 -35
  107. package/dist/agent-validation.js.map +0 -1
  108. package/dist/child-session-cleanups.js +0 -61
  109. package/dist/child-session-cleanups.js.map +0 -1
  110. package/dist/execution/run.js +0 -55
  111. package/dist/execution/run.js.map +0 -1
  112. package/dist/subagent-background-child-run-state.js +0 -51
  113. package/dist/subagent-background-child-run-state.js.map +0 -1
  114. package/dist/subagent-background-child-run.js +0 -103
  115. package/dist/subagent-background-child-run.js.map +0 -1
  116. package/dist/subagent-background-in-process.js +0 -98
  117. package/dist/subagent-background-in-process.js.map +0 -1
  118. package/dist/subagent-background-notification-inbox.js +0 -106
  119. package/dist/subagent-background-notification-inbox.js.map +0 -1
  120. package/dist/subagent-background-notify.js +0 -136
  121. package/dist/subagent-background-notify.js.map +0 -1
  122. package/dist/subagent-background-resume-group.js +0 -99
  123. package/dist/subagent-background-resume-group.js.map +0 -1
  124. package/dist/subagent-background-runner.js +0 -115
  125. package/dist/subagent-background-runner.js.map +0 -1
  126. package/dist/subagent-background-schedule.js +0 -43
  127. package/dist/subagent-background-schedule.js.map +0 -1
  128. package/dist/subagent-child-run.js +0 -68
  129. package/dist/subagent-child-run.js.map +0 -1
  130. package/dist/subagent-job-cancel.js +0 -84
  131. package/dist/subagent-job-cancel.js.map +0 -1
  132. package/dist/subagent-job-observer.js +0 -19
  133. package/dist/subagent-job-observer.js.map +0 -1
  134. package/dist/subagent-job-output.js +0 -87
  135. package/dist/subagent-job-output.js.map +0 -1
  136. package/dist/subagent-job-state.js +0 -66
  137. package/dist/subagent-job-state.js.map +0 -1
  138. package/dist/subagent-jobs.js +0 -96
  139. package/dist/subagent-jobs.js.map +0 -1
  140. package/dist/subagent-prompt-schema.js +0 -114
  141. package/dist/subagent-prompt-schema.js.map +0 -1
  142. package/dist/subagent-run.js +0 -111
  143. package/dist/subagent-run.js.map +0 -1
  144. package/dist/subagents.js +0 -125
  145. package/dist/subagents.js.map +0 -1
@@ -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 { 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,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 ?? []);
@@ -1 +1 @@
1
- {"version":3,"file":"session-notification.js","names":[],"sources":["../../src/session/session-notification.ts"],"sourcesContent":["import type { AgentEvent } from \"./events\";\nimport type { AgentInput } from \"./input\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n createRuntimeInputState,\n type QueuedInput,\n type QueuedRuntimeInput,\n queueRuntimeInput,\n type RuntimeInputState,\n} from \"./runtime-input\";\nimport { errorMessage } from \"./session-errors\";\n\nexport interface NotifyOptions {\n readonly deferWhenUnobserved?: boolean;\n readonly observerEvents?: readonly AgentEvent[];\n}\n\ninterface QueueSessionNotificationOptions {\n readonly activeRun: BufferedAgentRun | undefined;\n readonly activeRuntimeInput: RuntimeInputState | undefined;\n readonly drain: () => Promise<void>;\n readonly inputQueue: QueuedInput[];\n readonly pendingRuntimeInputs: QueuedRuntimeInput[];\n}\n\nexport function queueSessionNotification(\n input: AgentInput,\n options: NotifyOptions,\n state: QueueSessionNotificationOptions\n): AgentRun {\n const queuedRuntimeInput: QueuedRuntimeInput = {\n input: normalizeAgentInput(input),\n placement: \"turn-start\",\n };\n const observerEvents = cloneObserverEvents(options.observerEvents ?? []);\n const queuedTurn = state.inputQueue[0];\n if (queuedTurn) {\n queuedTurn.initialEvents.push(...observerEvents);\n queuedTurn.preUserRuntimeInputs.push(queuedRuntimeInput);\n return queuedTurn.run;\n }\n\n const activeRun = state.activeRun;\n const runtimeInput = state.activeRuntimeInput;\n if (runtimeInput && activeRun && !runtimeInput.closedReason) {\n queueRuntimeInput(runtimeInput, {\n input: structuredClone(queuedRuntimeInput.input),\n placement: \"step-end\",\n });\n return activeRun;\n }\n\n if (options.deferWhenUnobserved === true) {\n state.pendingRuntimeInputs.push(queuedRuntimeInput);\n const deferredRun = new BufferedAgentRun();\n deferredRun.close();\n return deferredRun;\n }\n\n const run = new BufferedAgentRun();\n state.inputQueue.push({\n initialEvents: observerEvents,\n preUserRuntimeInputs: [],\n run,\n runtimeInput: createRuntimeInputState([queuedRuntimeInput]),\n });\n startSessionQueueDrain(run, state.drain);\n return run;\n}\n\nexport function startSessionQueueDrain(\n run: BufferedAgentRun,\n drain: () => Promise<void>\n): void {\n drain().catch((error: unknown) => {\n run.emit({ type: \"turn-error\", message: errorMessage(error) });\n run.close();\n });\n}\n\nfunction cloneObserverEvents(events: readonly AgentEvent[]): AgentEvent[] {\n return events.map((event) => structuredClone(event));\n}\n"],"mappings":";;;;;AA0BA,SAAgB,yBACd,OACA,SACA,OACU;CACV,MAAM,qBAAyC;EAC7C,OAAO,oBAAoB,KAAK;EAChC,WAAW;CACb;CACA,MAAM,iBAAiB,oBAAoB,QAAQ,kBAAkB,CAAC,CAAC;CACvE,MAAM,aAAa,MAAM,WAAW;CACpC,IAAI,YAAY;EACd,WAAW,cAAc,KAAK,GAAG,cAAc;EAC/C,WAAW,qBAAqB,KAAK,kBAAkB;EACvD,OAAO,WAAW;CACpB;CAEA,MAAM,YAAY,MAAM;CACxB,MAAM,eAAe,MAAM;CAC3B,IAAI,gBAAgB,aAAa,CAAC,aAAa,cAAc;EAC3D,kBAAkB,cAAc;GAC9B,OAAO,gBAAgB,mBAAmB,KAAK;GAC/C,WAAW;EACb,CAAC;EACD,OAAO;CACT;CAEA,IAAI,QAAQ,wBAAwB,MAAM;EACxC,MAAM,qBAAqB,KAAK,kBAAkB;EAClD,MAAM,cAAc,IAAI,iBAAiB;EACzC,YAAY,MAAM;EAClB,OAAO;CACT;CAEA,MAAM,MAAM,IAAI,iBAAiB;CACjC,MAAM,WAAW,KAAK;EACpB,eAAe;EACf,sBAAsB,CAAC;EACvB;EACA,cAAc,wBAAwB,CAAC,kBAAkB,CAAC;CAC5D,CAAC;CACD,uBAAuB,KAAK,MAAM,KAAK;CACvC,OAAO;AACT;AAEA,SAAgB,uBACd,KACA,OACM;CACN,MAAM,EAAE,OAAO,UAAmB;EAChC,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,aAAa,KAAK;EAAE,CAAC;EAC7D,IAAI,MAAM;CACZ,CAAC;AACH;AAEA,SAAS,oBAAoB,QAA6C;CACxE,OAAO,OAAO,KAAK,UAAU,gBAAgB,KAAK,CAAC;AACrD"}
1
+ {"version":3,"file":"session-notification.js","names":[],"sources":["../../src/session/session-notification.ts"],"sourcesContent":["import type { AgentEvent } from \"./events\";\nimport type { AgentInput } from \"./input\";\nimport { attachInputMeta } from \"./input-meta\";\nimport { normalizeAgentInput } from \"./input-normalization\";\nimport { type AgentRun, BufferedAgentRun } from \"./run\";\nimport {\n createRuntimeInputState,\n type QueuedInput,\n type QueuedRuntimeInput,\n queueRuntimeInput,\n type RuntimeInputState,\n} from \"./runtime-input\";\nimport { errorMessage } from \"./session-errors\";\n\nexport interface NotifyOptions {\n readonly deferWhenUnobserved?: boolean;\n readonly observerEvents?: readonly AgentEvent[];\n}\n\ninterface QueueSessionNotificationOptions {\n readonly activeRun: BufferedAgentRun | undefined;\n readonly activeRuntimeInput: RuntimeInputState | undefined;\n readonly drain: () => Promise<void>;\n readonly inputQueue: QueuedInput[];\n readonly pendingRuntimeInputs: QueuedRuntimeInput[];\n}\n\nexport function queueSessionNotification(\n input: AgentInput,\n options: NotifyOptions,\n state: QueueSessionNotificationOptions\n): AgentRun {\n const queuedRuntimeInput: QueuedRuntimeInput = {\n input: attachInputMeta(normalizeAgentInput(input), { source: \"notify\" }),\n placement: \"turn-start\",\n };\n const observerEvents = cloneObserverEvents(options.observerEvents ?? []);\n const queuedTurn = state.inputQueue[0];\n if (queuedTurn) {\n queuedTurn.initialEvents.push(...observerEvents);\n queuedTurn.preUserRuntimeInputs.push(queuedRuntimeInput);\n return queuedTurn.run;\n }\n\n const activeRun = state.activeRun;\n const runtimeInput = state.activeRuntimeInput;\n if (runtimeInput && activeRun && !runtimeInput.closedReason) {\n queueRuntimeInput(runtimeInput, {\n input: structuredClone(queuedRuntimeInput.input),\n placement: \"step-end\",\n });\n return activeRun;\n }\n\n if (options.deferWhenUnobserved === true) {\n state.pendingRuntimeInputs.push(queuedRuntimeInput);\n const deferredRun = new BufferedAgentRun();\n deferredRun.close();\n return deferredRun;\n }\n\n const run = new BufferedAgentRun();\n state.inputQueue.push({\n initialEvents: observerEvents,\n preUserRuntimeInputs: [],\n run,\n runtimeInput: createRuntimeInputState([queuedRuntimeInput]),\n });\n startSessionQueueDrain(run, state.drain);\n return run;\n}\n\nexport function startSessionQueueDrain(\n run: BufferedAgentRun,\n drain: () => Promise<void>\n): void {\n drain().catch((error: unknown) => {\n run.emit({ type: \"turn-error\", message: errorMessage(error) });\n run.close();\n });\n}\n\nfunction cloneObserverEvents(events: readonly AgentEvent[]): AgentEvent[] {\n return events.map((event) => structuredClone(event));\n}\n"],"mappings":";;;;;;AA2BA,SAAgB,yBACd,OACA,SACA,OACU;CACV,MAAM,qBAAyC;EAC7C,OAAO,gBAAgB,oBAAoB,KAAK,GAAG,EAAE,QAAQ,SAAS,CAAC;EACvE,WAAW;CACb;CACA,MAAM,iBAAiB,oBAAoB,QAAQ,kBAAkB,CAAC,CAAC;CACvE,MAAM,aAAa,MAAM,WAAW;CACpC,IAAI,YAAY;EACd,WAAW,cAAc,KAAK,GAAG,cAAc;EAC/C,WAAW,qBAAqB,KAAK,kBAAkB;EACvD,OAAO,WAAW;CACpB;CAEA,MAAM,YAAY,MAAM;CACxB,MAAM,eAAe,MAAM;CAC3B,IAAI,gBAAgB,aAAa,CAAC,aAAa,cAAc;EAC3D,kBAAkB,cAAc;GAC9B,OAAO,gBAAgB,mBAAmB,KAAK;GAC/C,WAAW;EACb,CAAC;EACD,OAAO;CACT;CAEA,IAAI,QAAQ,wBAAwB,MAAM;EACxC,MAAM,qBAAqB,KAAK,kBAAkB;EAClD,MAAM,cAAc,IAAI,iBAAiB;EACzC,YAAY,MAAM;EAClB,OAAO;CACT;CAEA,MAAM,MAAM,IAAI,iBAAiB;CACjC,MAAM,WAAW,KAAK;EACpB,eAAe;EACf,sBAAsB,CAAC;EACvB;EACA,cAAc,wBAAwB,CAAC,kBAAkB,CAAC;CAC5D,CAAC;CACD,uBAAuB,KAAK,MAAM,KAAK;CACvC,OAAO;AACT;AAEA,SAAgB,uBACd,KACA,OACM;CACN,MAAM,EAAE,OAAO,UAAmB;EAChC,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,aAAa,KAAK;EAAE,CAAC;EAC7D,IAAI,MAAM;CACZ,CAAC;AACH;AAEA,SAAS,oBAAoB,QAA6C;CACxE,OAAO,OAAO,KAAK,UAAU,gBAAgB,KAAK,CAAC;AACrD"}
@@ -1,17 +1,11 @@
1
1
  import { shiftRuntimeInput } from "./runtime-input.js";
2
+ import { emitRuntimeInputEvent } from "./runtime-input-emit.js";
2
3
  //#region src/session/session-runtime-drain.ts
3
- async function drainRuntimeInput({ emit, placement, runtimeInput, state }) {
4
+ async function drainRuntimeInput({ events, placement, run, runtimeInput, state }) {
4
5
  let added = false;
5
6
  let next = shiftRuntimeInput(runtimeInput, placement);
6
7
  while (next) {
7
- added = true;
8
- await emit({
9
- type: "runtime-input",
10
- input: next.input,
11
- placement
12
- });
13
- state.appendUserInput(next.input);
14
- await state.commit();
8
+ if (await emitRuntimeInputEvent(events, run, state, next)) added = true;
15
9
  next = shiftRuntimeInput(runtimeInput, placement);
16
10
  }
17
11
  return added;
@@ -1 +1 @@
1
- {"version":3,"file":"session-runtime-drain.js","names":[],"sources":["../../src/session/session-runtime-drain.ts"],"sourcesContent":["import type { RuntimeInput } from \"./events\";\nimport {\n type RuntimeInputPlacement,\n type RuntimeInputState,\n shiftRuntimeInput,\n} from \"./runtime-input\";\nimport type { SessionState } from \"./session-state\";\n\nexport async function drainRuntimeInput({\n emit,\n placement,\n runtimeInput,\n state,\n}: {\n readonly emit: (event: RuntimeInput) => Promise<void>;\n readonly placement: RuntimeInputPlacement;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<boolean> {\n let added = false;\n let next = shiftRuntimeInput(runtimeInput, placement);\n while (next) {\n added = true;\n await emit({ type: \"runtime-input\", input: next.input, placement });\n state.appendUserInput(next.input);\n await state.commit();\n next = shiftRuntimeInput(runtimeInput, placement);\n }\n\n return added;\n}\n"],"mappings":";;AAQA,eAAsB,kBAAkB,EACtC,MACA,WACA,cACA,SAMmB;CACnB,IAAI,QAAQ;CACZ,IAAI,OAAO,kBAAkB,cAAc,SAAS;CACpD,OAAO,MAAM;EACX,QAAQ;EACR,MAAM,KAAK;GAAE,MAAM;GAAiB,OAAO,KAAK;GAAO;EAAU,CAAC;EAClE,MAAM,gBAAgB,KAAK,KAAK;EAChC,MAAM,MAAM,OAAO;EACnB,OAAO,kBAAkB,cAAc,SAAS;CAClD;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"session-runtime-drain.js","names":[],"sources":["../../src/session/session-runtime-drain.ts"],"sourcesContent":["import type { BufferedAgentRun } from \"./run\";\nimport {\n type RuntimeInputPlacement,\n type RuntimeInputState,\n shiftRuntimeInput,\n} from \"./runtime-input\";\nimport { emitRuntimeInputEvent } from \"./runtime-input-emit\";\nimport type { SessionEventDispatcher } from \"./session-events\";\nimport type { SessionState } from \"./session-state\";\n\nexport async function drainRuntimeInput({\n events,\n placement,\n run,\n runtimeInput,\n state,\n}: {\n readonly events: SessionEventDispatcher;\n readonly placement: RuntimeInputPlacement;\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<boolean> {\n let added = false;\n let next = shiftRuntimeInput(runtimeInput, placement);\n while (next) {\n if (await emitRuntimeInputEvent(events, run, state, next)) {\n added = true;\n }\n next = shiftRuntimeInput(runtimeInput, placement);\n }\n\n return added;\n}\n"],"mappings":";;;AAUA,eAAsB,kBAAkB,EACtC,QACA,WACA,KACA,cACA,SAOmB;CACnB,IAAI,QAAQ;CACZ,IAAI,OAAO,kBAAkB,cAAc,SAAS;CACpD,OAAO,MAAM;EACX,IAAI,MAAM,sBAAsB,QAAQ,KAAK,OAAO,IAAI,GACtD,QAAQ;EAEV,OAAO,kBAAkB,cAAc,SAAS;CAClD;CAEA,OAAO;AACT"}
@@ -1,12 +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
+ import { commitPreUserRuntimeInputs, emitCommittedRuntimeInputs } from "./runtime-input-emit.js";
5
6
  import { startSessionExecutionRun } from "./session-execution.js";
6
7
  import { drainRuntimeInput } from "./session-runtime-drain.js";
7
8
  import { emitTurnErrorAfterRecovery } from "./session-turn-error.js";
8
9
  //#region src/session/session-turn-processor.ts
9
- 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 }) {
10
11
  const activeAbort = new AbortController();
11
12
  const { initialEvents, input, preUserRuntimeInputs, run, runtimeInput } = item;
12
13
  const turnId = crypto.randomUUID();
@@ -26,7 +27,7 @@ async function processQueuedInput({ activate, deactivateRun, events, execution,
26
27
  turnId
27
28
  });
28
29
  for (const event of initialEvents) await events.emitRunEvent(run, event);
29
- await appendRuntimeInputsToHistory(state, preUserRuntimeInputs);
30
+ const committedPreUser = await commitPreUserRuntimeInputs(events, state, preUserRuntimeInputs);
30
31
  if (input) {
31
32
  state.appendUserInput(input);
32
33
  await state.commit();
@@ -34,10 +35,11 @@ async function processQueuedInput({ activate, deactivateRun, events, execution,
34
35
  await withRuntimeInputWindow(runtimeInput, "turn-start", async () => {
35
36
  await events.emitRunBoundaryEvent(run, { type: "turn-start" });
36
37
  });
37
- await emitPreUserRuntimeInputs(events, run, preUserRuntimeInputs);
38
+ await emitCommittedRuntimeInputs(events, run, committedPreUser);
38
39
  await drainRuntimeInput({
39
- emit: (event) => events.emitRunEvent(run, event),
40
+ events,
40
41
  placement: "turn-start",
42
+ run,
41
43
  runtimeInput,
42
44
  state
43
45
  });
@@ -50,7 +52,7 @@ async function processQueuedInput({ activate, deactivateRun, events, execution,
50
52
  state
51
53
  }),
52
54
  history: state.history,
53
- llm,
55
+ model,
54
56
  captureObserverEvents: (callback) => events.captureObserverEvents(run, callback),
55
57
  signal: activeAbort.signal,
56
58
  toolExecution: executionRun?.toolExecution
@@ -86,12 +88,6 @@ function executionStatusForResult(result) {
86
88
  function executionStatusForError(error) {
87
89
  return error instanceof ToolExecutionNeedsRecoveryError ? "needs-recovery" : "error";
88
90
  }
89
- async function appendRuntimeInputsToHistory(state, runtimeInputs) {
90
- for (const runtimeInput of runtimeInputs) {
91
- state.appendUserInput(runtimeInput.input);
92
- await state.commit();
93
- }
94
- }
95
91
  async function closeSuccessfulTurn({ deactivateRun, events, result, run, runtimeInput }) {
96
92
  const terminalEvent = result === "aborted" ? "turn-abort" : "turn-end";
97
93
  closeRuntimeInput(runtimeInput, terminalEvent);
@@ -106,13 +102,6 @@ async function closeSuccessfulTurn({ deactivateRun, events, result, run, runtime
106
102
  closeRuntimeInput(runtimeInput, "turn-error");
107
103
  }
108
104
  }
109
- async function emitPreUserRuntimeInputs(events, run, runtimeInputs) {
110
- for (const runtimeInput of runtimeInputs) await events.emitRunEvent(run, {
111
- input: runtimeInput.input,
112
- placement: runtimeInput.placement,
113
- type: "runtime-input"
114
- });
115
- }
116
105
  async function emitTurnEvent({ event, events, run, runtimeInput, state }) {
117
106
  if (event.type !== "step-start" && event.type !== "step-end") {
118
107
  await events.emitRunEvent(run, event);
@@ -122,8 +111,9 @@ async function emitTurnEvent({ event, events, run, runtimeInput, state }) {
122
111
  await events.emitRunBoundaryEvent(run, event);
123
112
  });
124
113
  const runtimeInputAdded = await drainRuntimeInput({
125
- emit: (runtimeInputEvent) => events.emitRunEvent(run, runtimeInputEvent),
114
+ events,
126
115
  placement: event.type,
116
+ run,
127
117
  runtimeInput,
128
118
  state
129
119
  });
@@ -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 QueuedRuntimeInput,\n type RuntimeInputState,\n withRuntimeInputWindow,\n} from \"./runtime-input\";\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\";\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 await appendRuntimeInputsToHistory(state, preUserRuntimeInputs);\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 emitPreUserRuntimeInputs(events, run, preUserRuntimeInputs);\n await drainRuntimeInput({\n emit: (event) => events.emitRunEvent(run, event),\n placement: \"turn-start\",\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 appendRuntimeInputsToHistory(\n state: SessionState,\n runtimeInputs: readonly QueuedRuntimeInput[]\n): Promise<void> {\n for (const runtimeInput of runtimeInputs) {\n state.appendUserInput(runtimeInput.input);\n await state.commit();\n }\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 emitPreUserRuntimeInputs(\n events: SessionEventDispatcher,\n run: BufferedAgentRun,\n runtimeInputs: readonly QueuedRuntimeInput[]\n): Promise<void> {\n for (const runtimeInput of runtimeInputs) {\n await events.emitRunEvent(run, {\n input: runtimeInput.input,\n placement: runtimeInput.placement,\n type: \"runtime-input\",\n });\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 emit: (runtimeInputEvent) => events.emitRunEvent(run, runtimeInputEvent),\n placement: event.type,\n runtimeInput,\n state,\n });\n return event.type === \"step-end\" ? { runtimeInputAdded } : undefined;\n}\n"],"mappings":"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"}
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"}
@@ -1,5 +1,6 @@
1
- import { BufferedAgentRun } from "./run.js";
1
+ import { attachInputMeta, userInputFromEvent } from "./input-meta.js";
2
2
  import { normalizeAgentInput } from "./input-normalization.js";
3
+ import { BufferedAgentRun } from "./run.js";
3
4
  import { addSteeringInput, createRuntimeInputState, queueRuntimeInput } from "./runtime-input.js";
4
5
  import { sessionKilledError, sessionTerminalError } from "./session-errors.js";
5
6
  import { SessionEventDispatcher } from "./session-events.js";
@@ -12,7 +13,7 @@ var AgentSession = class {
12
13
  #events;
13
14
  #execution;
14
15
  #inputQueue = [];
15
- #llm;
16
+ #model;
16
17
  #pendingRuntimeInputs = [];
17
18
  #sessionKey;
18
19
  #state;
@@ -24,8 +25,8 @@ var AgentSession = class {
24
25
  #killed = false;
25
26
  #running = false;
26
27
  #runToCloseOnKill;
27
- constructor(llm, persistence, plugins = [], execution = {}) {
28
- this.#llm = llm;
28
+ constructor(model, persistence, plugins = [], execution = {}) {
29
+ this.#model = model;
29
30
  this.#execution = execution;
30
31
  this.#sessionKey = persistence.key;
31
32
  this.#state = new SessionState(persistence);
@@ -40,12 +41,18 @@ var AgentSession = class {
40
41
  await this.#state.ensureLoaded();
41
42
  if (this.#killed || this.#deletePromise) throw sessionTerminalError(this.#killed);
42
43
  const runtimeInput = createRuntimeInputState(this.#pendingRuntimeInputs.splice(0));
43
- const acceptedInput = normalizeAgentInput(input);
44
+ const normalized = normalizeAgentInput(input);
45
+ const acceptedInput = normalized.meta === void 0 ? attachInputMeta(normalized, { source: "send" }) : normalized;
44
46
  const run = new BufferedAgentRun();
45
- await this.#events.emitRunEvent(run, acceptedInput);
47
+ const emitted = await this.#events.emitRunEvent(run, acceptedInput);
48
+ if (emitted === "handled") {
49
+ run.close();
50
+ return run;
51
+ }
52
+ const queuedInput = userInputFromEvent(emitted.type === "user-text" || emitted.type === "user-message" ? emitted : acceptedInput);
46
53
  this.#inputQueue.push({
47
54
  initialEvents: [],
48
- input: structuredClone(acceptedInput),
55
+ input: structuredClone(queuedInput),
49
56
  preUserRuntimeInputs: [],
50
57
  run,
51
58
  runtimeInput
@@ -156,7 +163,7 @@ var AgentSession = class {
156
163
  events: this.#events,
157
164
  execution: this.#execution,
158
165
  item,
159
- llm: this.#llm,
166
+ model: this.#model,
160
167
  release: () => {
161
168
  this.#activeAbort = void 0;
162
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 { 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 acceptedInput = normalizeAgentInput(input);\n const run = new BufferedAgentRun();\n await this.#events.emitRunEvent(run, acceptedInput);\n this.#inputQueue.push({\n initialEvents: [],\n input: structuredClone(acceptedInput),\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":";;;;;;;;;;;AAgCA,IAAa,eAAb,MAA0B;CACxB;CACA;CACA,cAAsC,CAAC;CACvC;CACA,wBAAuD,CAAC;CACxD;CACA;CACA;CACA;CACA;CACA;CACA;CACA,UAAU;CACV,WAAW;CACX;CAEA,YACE,OACA,aACA,UAAkC,CAAC,GACnC,YAAqC,CAAC,GACtC;EACA,KAAKG,SAAS;EACd,KAAKF,aAAa;EAClB,KAAKI,cAAc,YAAY;EAC/B,KAAKC,SAAS,IAAI,aAAa,WAAW;EAC1C,KAAKN,UAAU,IAAI,uBAAuB;GACxC,eAAe,KAAKM,OAAO,cAAc;GACzC;GACA,cAAc,KAAKC,cAAc;EACnC,CAAC;CACH;CAEA,MAAM,KAAK,OAAsC;EAC/C,IAAI,KAAKC,WAAW,KAAKC,gBACvB,MAAM,qBAAqB,KAAKD,OAAO;EAGzC,MAAM,KAAKF,OAAO,aAAa;EAE/B,IAAI,KAAKE,WAAW,KAAKC,gBACvB,MAAM,qBAAqB,KAAKD,OAAO;EAGzC,MAAM,eAAe,wBACnB,KAAKJ,sBAAsB,OAAO,CAAC,CACrC;EACA,MAAM,aAAa,oBAAoB,KAAK;EAC5C,MAAM,gBACJ,WAAW,SAAS,KAAA,IAChB,gBAAgB,YAAY,EAAE,QAAQ,OAAO,CAAC,IAC9C;EACN,MAAM,MAAM,IAAI,iBAAiB;EACjC,MAAM,UAAU,MAAM,KAAKJ,QAAQ,aAAa,KAAK,aAAa;EAClE,IAAI,YAAY,WAAW;GACzB,IAAI,MAAM;GACV,OAAO;EACT;EAEA,MAAM,cAAc,mBAClB,QAAQ,SAAS,eAAe,QAAQ,SAAS,iBAC7C,UACA,aACN;EACA,KAAKE,YAAY,KAAK;GACpB,eAAe,CAAC;GAChB,OAAO,gBAAgB,WAAW;GAClC,sBAAsB,CAAC;GACvB;GACA;EACF,CAAC;EACD,uBAAuB,WAAW,KAAKQ,iBAAiB,CAAC;EACzD,OAAO;CACT;CAEA,MAAM,OACJ,OACA,UAAyB,CAAC,GACP;EACnB,IAAI,KAAKF,WAAW,KAAKC,gBACvB,MAAM,qBAAqB,KAAKD,OAAO;EAGzC,MAAM,KAAKF,OAAO,aAAa;EAE/B,IAAI,KAAKE,WAAW,KAAKC,gBACvB,MAAM,qBAAqB,KAAKD,OAAO;EAGzC,OAAO,yBAAyB,OAAO,SAAS;GAC9C,WAAW,KAAKG;GAChB,oBAAoB,KAAKC;GACzB,aAAa,KAAKF,iBAAiB;GACnC,YAAY,KAAKR;GACjB,sBAAsB,KAAKE;EAC7B,CAAC;CACH;CAEA,MAAM,MAAM,OAAsC;EAChD,IAAI,KAAKI,WAAW,KAAKC,gBACvB,MAAM,qBAAqB,KAAKD,OAAO;EAGzC,MAAM,eAAe,KAAKI;EAC1B,MAAM,MAAM,KAAKD;EACjB,IAAI,EAAE,gBAAgB,MACpB,OAAO,KAAK,KAAK,KAAK;EAGxB,MAAM,iBAAiB,cAAc,KAAK;EAC1C,OAAO;CACT;CAEA,YAAkB;EAChB,KAAKJ,cAAc,MAAM;CAC3B;CAEA,gBAAoC;EAClC,OAAO,KAAKM;CACd;CAEA,SAAwB;EACtB,IAAI,CAAC,KAAKJ,gBAAgB;GACxB,KAAK,KAAK;GACV,KAAKA,iBAAiB,KAAKH,OAAO,OAAO,EAAE,OAAO,UAAmB;IACnE,KAAKG,iBAAiB,KAAA;IACtB,MAAM;GACR,CAAC;EACH;EACA,OAAO,KAAKA;CACd;CAEA,oBACE,OACA,YAAmC,cAC7B;EACN,IAAI,KAAKD,SACP;EAGF,MAAM,eAAe,KAAKI;EAC1B,IAAI,gBAAgB,CAAC,aAAa,cAAc;GAC9C,IAAI,cAAc,gBAAgB,aAAa,cAAc,WAAW;IACtE,KAAKE,4BAA4B;KAAE;KAAO;IAAU,CAAC;IACrD;GACF;GAEA,kBAAkB,cAAc;IAAE;IAAO;GAAU,CAAC;GACpD;EACF;EAEA,KAAKA,4BAA4B;GAAE;GAAO;EAAU,CAAC;CACvD;CAEA,kBAAkB,OAAkC;EAClD,OAAO,KAAKd,QAAQ,kBAAkB,KAAKW,YAAY,KAAK;CAC9D;CAEA,4BAA4B,OAAiC;EAC3D,MAAM,aAAa,KAAKT,YAAY;EACpC,IAAI,MAAM,cAAc,gBAAgB,YAAY;GAClD,kBAAkB,WAAW,cAAc,KAAK;GAChD;EACF;EAEA,KAAKE,sBAAsB,KAAK,KAAK;CACvC;CAEA,OAAa;EACX,IAAI,KAAKI,SACP;EAGF,KAAKA,UAAU;EACf,MAAM,cAAc,mBAAmB;EACvC,KAAKJ,sBAAsB,SAAS;EACpC,KAAKG,cAAc,MAAM;EACzB,yBAAyB;GACvB,oBAAoB,KAAKK;GACzB,YAAY,KAAKV;GACjB,SAAS,YAAY;GACrB,YAAY,KAAKa,qBAAqB,KAAKJ;EAC7C,CAAC;CACH;CAEA,MAAMD,mBAAkC;EACtC,IAAI,KAAKM,UACP;EAGF,KAAKA,WAAW;EAChB,IAAI;GACF,OAAO,CAAC,KAAKR,WAAW,KAAKN,YAAY,SAAS,GAAG;IACnD,MAAM,OAAO,KAAKA,YAAY,MAAM;IACpC,IAAI,MACF,MAAM,mBAAmB;KACvB,WAAW,EAAE,OAAO,KAAK,cAAc,aAAa;MAClD,KAAKK,eAAe;MACpB,KAAKI,aAAa;MAClB,KAAKC,sBAAsB;MAC3B,KAAKC,gBAAgB;MACrB,KAAKE,oBAAoB;KAC3B;KACA,qBAAqB;MACnB,KAAKJ,aAAa,KAAA;MAClB,KAAKC,sBAAsB,KAAA;KAC7B;KACA,QAAQ,KAAKZ;KACb,WAAW,KAAKC;KAChB;KACA,OAAO,KAAKE;KACZ,eAAe;MACb,KAAKI,eAAe,KAAA;MACpB,KAAKI,aAAa,KAAA;MAClB,KAAKC,sBAAsB,KAAA;MAC3B,KAAKC,gBAAgB,KAAA;MACrB,KAAKE,oBAAoB,KAAA;KAC3B;KACA,YAAY,KAAKV;KACjB,OAAO,KAAKC;IACd,CAAC;GAEL;EACF,UAAU;GACR,KAAKU,WAAW;EAClB;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minpeter/pss-runtime",
3
- "version": "0.1.0-next.2",
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",
@@ -21,6 +21,11 @@
21
21
  "types": "./dist/session/store/file.d.ts",
22
22
  "import": "./dist/session/store/file.js"
23
23
  },
24
+ "./cloudflare": {
25
+ "@minpeter/pss-source": "./src/cloudflare/index.ts",
26
+ "types": "./dist/cloudflare/index.d.ts",
27
+ "import": "./dist/cloudflare/index.js"
28
+ },
24
29
  "./execution": {
25
30
  "@minpeter/pss-source": "./src/execution/index.ts",
26
31
  "types": "./dist/execution/index.d.ts",
@@ -1,16 +0,0 @@
1
- import { executionHost } from "./execution/host.js";
2
- import { cancelBackgroundChildRun } from "./subagent-background-child-run.js";
3
- //#region src/agent-child-runs.ts
4
- async function cancelDurableChildRuns(host, parentRunId) {
5
- const durableHost = executionHost(host);
6
- if (!durableHost) return;
7
- const childRuns = await durableHost.store.runs.listByParentRunId(parentRunId);
8
- await Promise.all(childRuns.map((run) => cancelBackgroundChildRun({
9
- executionHost: durableHost,
10
- runId: run.runId
11
- })));
12
- }
13
- //#endregion
14
- export { cancelDurableChildRuns };
15
-
16
- //# sourceMappingURL=agent-child-runs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-child-runs.js","names":[],"sources":["../src/agent-child-runs.ts"],"sourcesContent":["import { executionHost } from \"./execution/host\";\nimport type { AgentHost } from \"./execution/types\";\nimport { cancelBackgroundChildRun } from \"./subagent-background-child-run\";\n\nexport async function cancelDurableChildRuns(\n host: AgentHost,\n parentRunId: string\n): Promise<void> {\n const durableHost = executionHost(host);\n if (!durableHost) {\n return;\n }\n\n const childRuns = await durableHost.store.runs.listByParentRunId(parentRunId);\n await Promise.all(\n childRuns.map((run) =>\n cancelBackgroundChildRun({\n executionHost: durableHost,\n runId: run.runId,\n })\n )\n );\n}\n"],"mappings":";;;AAIA,eAAsB,uBACpB,MACA,aACe;CACf,MAAM,cAAc,cAAc,IAAI;CACtC,IAAI,CAAC,aACH;CAGF,MAAM,YAAY,MAAM,YAAY,MAAM,KAAK,kBAAkB,WAAW;CAC5E,MAAM,QAAQ,IACZ,UAAU,KAAK,QACb,yBAAyB;EACvB,eAAe;EACf,OAAO,IAAI;CACb,CAAC,CACH,CACF;AACF"}
@@ -1,9 +0,0 @@
1
- //#region src/agent-host-capabilities.ts
2
- function supportsBackgroundSubagents(host, executionHost) {
3
- const capability = host.capabilities?.backgroundSubagents;
4
- return capability === "in-process" || capability === "durable" && executionHost !== void 0;
5
- }
6
- //#endregion
7
- export { supportsBackgroundSubagents };
8
-
9
- //# sourceMappingURL=agent-host-capabilities.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-host-capabilities.js","names":[],"sources":["../src/agent-host-capabilities.ts"],"sourcesContent":["import type { AgentHost, ExecutionHost } from \"./execution/types\";\n\nexport function supportsBackgroundSubagents(\n host: AgentHost,\n executionHost: ExecutionHost | undefined\n): boolean {\n const capability = host.capabilities?.backgroundSubagents;\n return (\n capability === \"in-process\" ||\n (capability === \"durable\" && executionHost !== undefined)\n );\n}\n"],"mappings":";AAEA,SAAgB,4BACd,MACA,eACS;CACT,MAAM,aAAa,KAAK,cAAc;CACtC,OACE,eAAe,gBACd,eAAe,aAAa,kBAAkB,KAAA;AAEnD"}