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

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 (161) hide show
  1. package/README.md +223 -191
  2. package/dist/agent-child-runs.js +16 -0
  3. package/dist/agent-child-runs.js.map +1 -0
  4. package/dist/agent-host-capabilities.js +9 -0
  5. package/dist/agent-host-capabilities.js.map +1 -0
  6. package/dist/agent-host-session-store.js +12 -0
  7. package/dist/agent-host-session-store.js.map +1 -0
  8. package/dist/agent-loop.js +59 -35
  9. package/dist/agent-loop.js.map +1 -1
  10. package/dist/agent-namespace.js +24 -0
  11. package/dist/agent-namespace.js.map +1 -0
  12. package/dist/agent-options.d.ts +35 -0
  13. package/dist/agent-options.js +16 -0
  14. package/dist/agent-options.js.map +1 -0
  15. package/dist/agent-resume.js +143 -0
  16. package/dist/agent-resume.js.map +1 -0
  17. package/dist/agent-session-entry.d.ts +13 -0
  18. package/dist/agent-validation.js +35 -0
  19. package/dist/agent-validation.js.map +1 -0
  20. package/dist/agent.d.ts +8 -33
  21. package/dist/agent.js +131 -55
  22. package/dist/agent.js.map +1 -1
  23. package/dist/child-session-cleanups.js +61 -0
  24. package/dist/child-session-cleanups.js.map +1 -0
  25. package/dist/execution/host.js +14 -0
  26. package/dist/execution/host.js.map +1 -0
  27. package/dist/execution/index.d.ts +4 -0
  28. package/dist/execution/index.js +3 -0
  29. package/dist/execution/memory-notifications.js +54 -0
  30. package/dist/execution/memory-notifications.js.map +1 -0
  31. package/dist/execution/memory-state.js +34 -0
  32. package/dist/execution/memory-state.js.map +1 -0
  33. package/dist/execution/memory-store.js +203 -0
  34. package/dist/execution/memory-store.js.map +1 -0
  35. package/dist/execution/memory.d.ts +7 -0
  36. package/dist/execution/memory.js +28 -0
  37. package/dist/execution/memory.js.map +1 -0
  38. package/dist/execution/run.js +55 -0
  39. package/dist/execution/run.js.map +1 -0
  40. package/dist/execution/types.d.ts +155 -0
  41. package/dist/index.d.ts +9 -10
  42. package/dist/index.js +1 -6
  43. package/dist/llm-tool-execution.d.ts +35 -0
  44. package/dist/llm-tool-execution.js +126 -0
  45. package/dist/llm-tool-execution.js.map +1 -0
  46. package/dist/llm.d.ts +11 -15
  47. package/dist/llm.js +5 -9
  48. package/dist/llm.js.map +1 -1
  49. package/dist/plugins.d.ts +20 -0
  50. package/dist/plugins.js +14 -0
  51. package/dist/plugins.js.map +1 -0
  52. package/dist/session/events.d.ts +26 -20
  53. package/dist/session/input-normalization.js +66 -0
  54. package/dist/session/input-normalization.js.map +1 -0
  55. package/dist/session/input.d.ts +0 -4
  56. package/dist/session/mapping.js +1 -2
  57. package/dist/session/mapping.js.map +1 -1
  58. package/dist/session/run.js +1 -0
  59. package/dist/session/run.js.map +1 -1
  60. package/dist/session/runtime-input.js +20 -58
  61. package/dist/session/runtime-input.js.map +1 -1
  62. package/dist/session/session-errors.js +18 -0
  63. package/dist/session/session-errors.js.map +1 -0
  64. package/dist/session/session-events.js +59 -0
  65. package/dist/session/session-events.js.map +1 -0
  66. package/dist/session/session-execution.js +88 -0
  67. package/dist/session/session-execution.js.map +1 -0
  68. package/dist/session/session-kill.js +23 -0
  69. package/dist/session/session-kill.js.map +1 -0
  70. package/dist/session/session-notification.js +58 -0
  71. package/dist/session/session-notification.js.map +1 -0
  72. package/dist/session/session-runtime-drain.js +22 -0
  73. package/dist/session/session-runtime-drain.js.map +1 -0
  74. package/dist/session/session-state.js +102 -0
  75. package/dist/session/session-state.js.map +1 -0
  76. package/dist/session/session-turn-error.js +35 -0
  77. package/dist/session/session-turn-error.js.map +1 -0
  78. package/dist/session/session-turn-processor.js +135 -0
  79. package/dist/session/session-turn-processor.js.map +1 -0
  80. package/dist/session/session.js +125 -335
  81. package/dist/session/session.js.map +1 -1
  82. package/dist/session/snapshot.js +5 -31
  83. package/dist/session/snapshot.js.map +1 -1
  84. package/dist/session/store/file.d.ts +1 -0
  85. package/dist/session/store/file.js +14 -0
  86. package/dist/session/store/file.js.map +1 -1
  87. package/dist/session/store/memory.d.ts +1 -0
  88. package/dist/session/store/memory.js +5 -0
  89. package/dist/session/store/memory.js.map +1 -1
  90. package/dist/session/store/types.d.ts +1 -0
  91. package/dist/subagent-background-child-run-state.js +51 -0
  92. package/dist/subagent-background-child-run-state.js.map +1 -0
  93. package/dist/subagent-background-child-run.js +103 -0
  94. package/dist/subagent-background-child-run.js.map +1 -0
  95. package/dist/subagent-background-in-process.js +98 -0
  96. package/dist/subagent-background-in-process.js.map +1 -0
  97. package/dist/subagent-background-notification-inbox.js +106 -0
  98. package/dist/subagent-background-notification-inbox.js.map +1 -0
  99. package/dist/subagent-background-notify.js +136 -0
  100. package/dist/subagent-background-notify.js.map +1 -0
  101. package/dist/subagent-background-resume-group.js +99 -0
  102. package/dist/subagent-background-resume-group.js.map +1 -0
  103. package/dist/subagent-background-runner.js +115 -0
  104. package/dist/subagent-background-runner.js.map +1 -0
  105. package/dist/subagent-background-schedule.js +43 -0
  106. package/dist/subagent-background-schedule.js.map +1 -0
  107. package/dist/subagent-child-run.js +68 -0
  108. package/dist/subagent-child-run.js.map +1 -0
  109. package/dist/subagent-job-cancel.js +84 -0
  110. package/dist/subagent-job-cancel.js.map +1 -0
  111. package/dist/subagent-job-observer.js +19 -0
  112. package/dist/subagent-job-observer.js.map +1 -0
  113. package/dist/subagent-job-output.js +87 -0
  114. package/dist/subagent-job-output.js.map +1 -0
  115. package/dist/subagent-job-state.js +66 -0
  116. package/dist/subagent-job-state.js.map +1 -0
  117. package/dist/subagent-jobs.js +96 -0
  118. package/dist/subagent-jobs.js.map +1 -0
  119. package/dist/subagent-prompt-schema.js +114 -0
  120. package/dist/subagent-prompt-schema.js.map +1 -0
  121. package/dist/subagent-run.js +111 -0
  122. package/dist/subagent-run.js.map +1 -0
  123. package/dist/subagents.js +125 -0
  124. package/dist/subagents.js.map +1 -0
  125. package/package.json +11 -6
  126. package/dist/plugins/compaction.d.ts +0 -15
  127. package/dist/plugins/compaction.js +0 -98
  128. package/dist/plugins/compaction.js.map +0 -1
  129. package/dist/plugins/index.d.ts +0 -5
  130. package/dist/plugins/index.js +0 -5
  131. package/dist/plugins/memory.d.ts +0 -11
  132. package/dist/plugins/memory.js +0 -146
  133. package/dist/plugins/memory.js.map +0 -1
  134. package/dist/plugins/runner.d.ts +0 -1
  135. package/dist/plugins/runner.js +0 -83
  136. package/dist/plugins/runner.js.map +0 -1
  137. package/dist/plugins/scope.js +0 -13
  138. package/dist/plugins/scope.js.map +0 -1
  139. package/dist/plugins/sessions.d.ts +0 -12
  140. package/dist/plugins/sessions.js +0 -34
  141. package/dist/plugins/sessions.js.map +0 -1
  142. package/dist/plugins/tool-hook-handlers.js +0 -77
  143. package/dist/plugins/tool-hook-handlers.js.map +0 -1
  144. package/dist/plugins/tool-hook-results.js +0 -64
  145. package/dist/plugins/tool-hook-results.js.map +0 -1
  146. package/dist/plugins/tool-hooks.js +0 -111
  147. package/dist/plugins/tool-hooks.js.map +0 -1
  148. package/dist/plugins/types.d.ts +0 -105
  149. package/dist/plugins/types.js +0 -20
  150. package/dist/plugins/types.js.map +0 -1
  151. package/dist/session/lifecycle.d.ts +0 -12
  152. package/dist/session/lifecycle.js +0 -126
  153. package/dist/session/lifecycle.js.map +0 -1
  154. package/dist/session/overlay-anchor.js +0 -151
  155. package/dist/session/overlay-anchor.js.map +0 -1
  156. package/dist/session/overlay.js +0 -141
  157. package/dist/session/overlay.js.map +0 -1
  158. package/dist/session/snapshot.d.ts +0 -1
  159. /package/dist/{agent-loop.d.ts → session/history.d.ts} +0 -0
  160. /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
  161. /package/dist/{plugins/scope.d.ts → session/session-state.d.ts} +0 -0
@@ -1,14 +1,15 @@
1
+ import { normalizeAgentInput } from "./input-normalization.js";
1
2
  //#region src/session/runtime-input.ts
2
- function createRuntimeInputState() {
3
+ function createRuntimeInputState(queue) {
3
4
  return {
4
5
  pending: Promise.resolve(),
5
- queue: []
6
+ queue
6
7
  };
7
8
  }
8
- function addRuntimeInput(runtimeInput, input) {
9
+ function addSteeringInput(runtimeInput, input) {
9
10
  const next = runtimeInput.pending.then(() => {
10
11
  if (runtimeInput.closedReason) throw runtimeInputClosedError(runtimeInput.closedReason);
11
- runtimeInput.queue.push({
12
+ queueRuntimeInput(runtimeInput, {
12
13
  input: normalizeAgentInput(input),
13
14
  placement: runtimeInput.steerPlacement ?? runtimeInput.placement ?? "step-end"
14
15
  });
@@ -17,73 +18,34 @@ function addRuntimeInput(runtimeInput, input) {
17
18
  return next;
18
19
  }
19
20
  function closeRuntimeInput(runtimeInput, reason = "the run reached a terminal state") {
20
- if (!runtimeInput?.closedReason && runtimeInput) {
21
+ if (runtimeInput && !runtimeInput.closedReason) {
21
22
  runtimeInput.closedReason = reason;
22
23
  runtimeInput.placement = void 0;
23
24
  }
24
25
  }
26
+ async function withRuntimeInputWindow(runtimeInput, placement, callback) {
27
+ const previousSteerPlacement = runtimeInput.steerPlacement;
28
+ runtimeInput.placement = placement;
29
+ runtimeInput.steerPlacement = placement;
30
+ try {
31
+ return await callback();
32
+ } finally {
33
+ runtimeInput.placement = void 0;
34
+ runtimeInput.steerPlacement = previousSteerPlacement;
35
+ }
36
+ }
25
37
  function shiftRuntimeInput(runtimeInput, placement) {
26
38
  const index = runtimeInput.queue.findIndex((input) => input.placement === placement);
27
39
  if (index === -1) return;
28
40
  return runtimeInput.queue.splice(index, 1)[0];
29
41
  }
30
- function normalizeAgentInput(input) {
31
- if (typeof input === "string") return {
32
- type: "user-text",
33
- text: input
34
- };
35
- if (isStringArrayInput(input)) return {
36
- type: "user-text",
37
- text: structuredClone(input)
38
- };
39
- if (isArrayInput(input)) {
40
- assertUserMessageContent(input);
41
- return {
42
- type: "user-message",
43
- content: structuredClone(input)
44
- };
45
- }
46
- if (isUserMessage(input)) {
47
- assertUserMessageContent(input.content);
48
- assertUserMessageMetadata(input.metadata);
49
- }
50
- return structuredClone(input);
51
- }
52
- function isStringArrayInput(input) {
53
- return isArrayInput(input) && input.every((part) => typeof part === "string");
54
- }
55
- function isArrayInput(input) {
56
- return Array.isArray(input);
57
- }
58
- function isUserMessage(input) {
59
- return input.type === "user-message";
60
- }
61
- function assertUserMessageContent(input) {
62
- for (const part of input) if (!isUserMessageContentPart(part)) throw new TypeError("Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.");
63
- }
64
- function assertUserMessageMetadata(metadata) {
65
- if (metadata !== void 0 && (metadata === null || typeof metadata !== "object" || Array.isArray(metadata))) throw new TypeError("Agent input metadata must be an object when provided.");
66
- }
67
- function isUserMessageContentPart(part) {
68
- if (part === null || typeof part !== "object" || !("type" in part)) return false;
69
- if (part.type === "text") return "text" in part && typeof part.text === "string";
70
- if (part.type === "image") return "image" in part && typeof part.image === "string" && (!("mediaType" in part) || typeof part.mediaType === "string");
71
- if (part.type === "file") return "data" in part && isUserMessageFileData(part.data) && "mediaType" in part && typeof part.mediaType === "string" && (!("filename" in part) || typeof part.filename === "string");
72
- return false;
73
- }
74
- function isUserMessageFileData(data) {
75
- if (typeof data === "string") return true;
76
- if (data === null || typeof data !== "object" || !("type" in data)) return false;
77
- if (data.type === "data") return "data" in data && typeof data.data === "string";
78
- if (data.type === "reference") return "reference" in data && data.reference !== null && typeof data.reference === "object" && Object.values(data.reference).every((value) => typeof value === "string");
79
- if (data.type === "text") return "text" in data && typeof data.text === "string";
80
- if (data.type === "url") return "url" in data && typeof data.url === "string";
81
- return false;
42
+ function queueRuntimeInput(runtimeInput, input) {
43
+ runtimeInput.queue.push(input);
82
44
  }
83
45
  function runtimeInputClosedError(reason) {
84
46
  return /* @__PURE__ */ new Error(`session.steer() cannot be used after ${reason}`);
85
47
  }
86
48
  //#endregion
87
- export { addRuntimeInput, closeRuntimeInput, createRuntimeInputState, normalizeAgentInput, shiftRuntimeInput };
49
+ export { addSteeringInput, closeRuntimeInput, createRuntimeInputState, queueRuntimeInput, shiftRuntimeInput, withRuntimeInputWindow };
88
50
 
89
51
  //# sourceMappingURL=runtime-input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-input.js","names":[],"sources":["../../src/session/runtime-input.ts"],"sourcesContent":["import type {\n RuntimeInput,\n UserMessage,\n UserMessageContentPart,\n} from \"./events\";\nimport type { AgentInput, UserInput } from \"./input\";\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 function createRuntimeInputState(): RuntimeInputState {\n return {\n pending: Promise.resolve(),\n queue: [],\n };\n}\n\nexport function addRuntimeInput(\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 runtimeInput.queue.push({\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?.closedReason && runtimeInput) {\n runtimeInput.closedReason = reason;\n runtimeInput.placement = undefined;\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 normalizeAgentInput(input: AgentInput): UserInput {\n if (typeof input === \"string\") {\n return {\n type: \"user-text\",\n text: input,\n };\n }\n\n if (isStringArrayInput(input)) {\n return {\n type: \"user-text\",\n text: structuredClone(input) as readonly string[],\n };\n }\n\n if (isArrayInput(input)) {\n assertUserMessageContent(input);\n return {\n type: \"user-message\",\n content: structuredClone(input) as readonly UserMessageContentPart[],\n };\n }\n\n if (isUserMessage(input)) {\n assertUserMessageContent(input.content);\n assertUserMessageMetadata(input.metadata);\n }\n\n return structuredClone(input);\n}\n\nfunction isStringArrayInput(input: AgentInput): input is readonly string[] {\n return isArrayInput(input) && input.every((part) => typeof part === \"string\");\n}\n\nfunction isArrayInput(\n input: AgentInput\n): input is readonly string[] | readonly UserMessageContentPart[] {\n return Array.isArray(input);\n}\n\nfunction isUserMessage(input: UserInput): input is UserMessage {\n return input.type === \"user-message\";\n}\n\nfunction assertUserMessageContent(\n input: readonly unknown[]\n): asserts input is readonly UserMessageContentPart[] {\n for (const part of input) {\n if (!isUserMessageContentPart(part)) {\n throw new TypeError(\n 'Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.'\n );\n }\n }\n}\n\nfunction assertUserMessageMetadata(metadata: unknown): void {\n if (\n metadata !== undefined &&\n (metadata === null ||\n typeof metadata !== \"object\" ||\n Array.isArray(metadata))\n ) {\n throw new TypeError(\n \"Agent input metadata must be an object when provided.\"\n );\n }\n}\n\nfunction isUserMessageContentPart(\n part: unknown\n): part is UserMessageContentPart {\n if (part === null || typeof part !== \"object\" || !(\"type\" in part)) {\n return false;\n }\n\n if (part.type === \"text\") {\n return \"text\" in part && typeof part.text === \"string\";\n }\n\n if (part.type === \"image\") {\n return (\n \"image\" in part &&\n typeof part.image === \"string\" &&\n (!(\"mediaType\" in part) || typeof part.mediaType === \"string\")\n );\n }\n\n if (part.type === \"file\") {\n return (\n \"data\" in part &&\n isUserMessageFileData(part.data) &&\n \"mediaType\" in part &&\n typeof part.mediaType === \"string\" &&\n (!(\"filename\" in part) || typeof part.filename === \"string\")\n );\n }\n\n return false;\n}\n\nfunction isUserMessageFileData(data: unknown): boolean {\n if (typeof data === \"string\") {\n return true;\n }\n\n if (data === null || typeof data !== \"object\" || !(\"type\" in data)) {\n return false;\n }\n\n if (data.type === \"data\") {\n return \"data\" in data && typeof data.data === \"string\";\n }\n\n if (data.type === \"reference\") {\n return (\n \"reference\" in data &&\n data.reference !== null &&\n typeof data.reference === \"object\" &&\n Object.values(data.reference).every((value) => typeof value === \"string\")\n );\n }\n\n if (data.type === \"text\") {\n return \"text\" in data && typeof data.text === \"string\";\n }\n\n if (data.type === \"url\") {\n return \"url\" in data && typeof data.url === \"string\";\n }\n\n return false;\n}\n\nfunction runtimeInputClosedError(reason: string): Error {\n return new Error(`session.steer() cannot be used after ${reason}`);\n}\n"],"mappings":";AAsBA,SAAgB,0BAA6C;CAC3D,OAAO;EACL,SAAS,QAAQ,QAAQ;EACzB,OAAO,CAAC;CACV;AACF;AAEA,SAAgB,gBACd,cACA,OACe;CACf,MAAM,OAAO,aAAa,QAAQ,WAAW;EAC3C,IAAI,aAAa,cACf,MAAM,wBAAwB,aAAa,YAAY;EAGzD,aAAa,MAAM,KAAK;GACtB,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,CAAC,cAAc,gBAAgB,cAAc;EAC/C,aAAa,eAAe;EAC5B,aAAa,YAAY,KAAA;CAC3B;AACF;AAEA,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,oBAAoB,OAA8B;CAChE,IAAI,OAAO,UAAU,UACnB,OAAO;EACL,MAAM;EACN,MAAM;CACR;CAGF,IAAI,mBAAmB,KAAK,GAC1B,OAAO;EACL,MAAM;EACN,MAAM,gBAAgB,KAAK;CAC7B;CAGF,IAAI,aAAa,KAAK,GAAG;EACvB,yBAAyB,KAAK;EAC9B,OAAO;GACL,MAAM;GACN,SAAS,gBAAgB,KAAK;EAChC;CACF;CAEA,IAAI,cAAc,KAAK,GAAG;EACxB,yBAAyB,MAAM,OAAO;EACtC,0BAA0B,MAAM,QAAQ;CAC1C;CAEA,OAAO,gBAAgB,KAAK;AAC9B;AAEA,SAAS,mBAAmB,OAA+C;CACzE,OAAO,aAAa,KAAK,KAAK,MAAM,OAAO,SAAS,OAAO,SAAS,QAAQ;AAC9E;AAEA,SAAS,aACP,OACgE;CAChE,OAAO,MAAM,QAAQ,KAAK;AAC5B;AAEA,SAAS,cAAc,OAAwC;CAC7D,OAAO,MAAM,SAAS;AACxB;AAEA,SAAS,yBACP,OACoD;CACpD,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,yBAAyB,IAAI,GAChC,MAAM,IAAI,UACR,iIACF;AAGN;AAEA,SAAS,0BAA0B,UAAyB;CAC1D,IACE,aAAa,KAAA,MACZ,aAAa,QACZ,OAAO,aAAa,YACpB,MAAM,QAAQ,QAAQ,IAExB,MAAM,IAAI,UACR,uDACF;AAEJ;AAEA,SAAS,yBACP,MACgC;CAChC,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,EAAE,UAAU,OAC3D,OAAO;CAGT,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,SAChB,OACE,WAAW,QACX,OAAO,KAAK,UAAU,aACrB,EAAE,eAAe,SAAS,OAAO,KAAK,cAAc;CAIzD,IAAI,KAAK,SAAS,QAChB,OACE,UAAU,QACV,sBAAsB,KAAK,IAAI,KAC/B,eAAe,QACf,OAAO,KAAK,cAAc,aACzB,EAAE,cAAc,SAAS,OAAO,KAAK,aAAa;CAIvD,OAAO;AACT;AAEA,SAAS,sBAAsB,MAAwB;CACrD,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,EAAE,UAAU,OAC3D,OAAO;CAGT,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,aAChB,OACE,eAAe,QACf,KAAK,cAAc,QACnB,OAAO,KAAK,cAAc,YAC1B,OAAO,OAAO,KAAK,SAAS,EAAE,OAAO,UAAU,OAAO,UAAU,QAAQ;CAI5E,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,OAChB,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ;CAG9C,OAAO;AACT;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 { 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"}
@@ -0,0 +1,18 @@
1
+ //#region src/session/session-errors.ts
2
+ function errorMessage(error) {
3
+ if (error instanceof Error) return error.message;
4
+ return String(error);
5
+ }
6
+ function sessionKilledError() {
7
+ return /* @__PURE__ */ new Error("Session killed");
8
+ }
9
+ function sessionDeleteInProgressError() {
10
+ return /* @__PURE__ */ new Error("Session delete in progress");
11
+ }
12
+ function sessionTerminalError(killed) {
13
+ return killed ? sessionKilledError() : sessionDeleteInProgressError();
14
+ }
15
+ //#endregion
16
+ export { errorMessage, sessionKilledError, sessionTerminalError };
17
+
18
+ //# sourceMappingURL=session-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-errors.js","names":[],"sources":["../../src/session/session-errors.ts"],"sourcesContent":["export function errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n return String(error);\n}\n\nexport function sessionKilledError(): Error {\n return new Error(\"Session killed\");\n}\n\nexport function sessionDeleteInProgressError(): Error {\n return new Error(\"Session delete in progress\");\n}\n\nexport function sessionTerminalError(killed: boolean): Error {\n return killed ? sessionKilledError() : sessionDeleteInProgressError();\n}\n"],"mappings":";AAAA,SAAgB,aAAa,OAAwB;CACnD,IAAI,iBAAiB,OACnB,OAAO,MAAM;CAGf,OAAO,OAAO,KAAK;AACrB;AAEA,SAAgB,qBAA4B;CAC1C,uBAAO,IAAI,MAAM,gBAAgB;AACnC;AAEA,SAAgB,+BAAsC;CACpD,uBAAO,IAAI,MAAM,4BAA4B;AAC/C;AAEA,SAAgB,qBAAqB,QAAwB;CAC3D,OAAO,SAAS,mBAAmB,IAAI,6BAA6B;AACtE"}
@@ -0,0 +1,59 @@
1
+ import { runEventPlugins } from "../plugins.js";
2
+ //#region src/session/session-events.ts
3
+ var SessionEventDispatcher = class {
4
+ #history;
5
+ #observerEventBuffer;
6
+ #plugins;
7
+ #signal;
8
+ constructor(options) {
9
+ this.#history = options.history;
10
+ this.#plugins = options.plugins;
11
+ this.#signal = options.signal;
12
+ }
13
+ async captureObserverEvents(run, callback) {
14
+ const previousBuffer = this.#observerEventBuffer;
15
+ const buffer = [];
16
+ this.#observerEventBuffer = buffer;
17
+ try {
18
+ return {
19
+ events: buffer,
20
+ release: () => {
21
+ if (this.#observerEventBuffer === buffer) this.#observerEventBuffer = previousBuffer;
22
+ },
23
+ value: await callback()
24
+ };
25
+ } catch (error) {
26
+ for (const event of buffer.splice(0)) await this.emitRunEvent(run, event);
27
+ this.#observerEventBuffer = previousBuffer;
28
+ throw error;
29
+ }
30
+ }
31
+ emitObserverEvent(activeRun, event) {
32
+ const observerEventBuffer = this.#observerEventBuffer;
33
+ if (observerEventBuffer) {
34
+ observerEventBuffer.push(structuredClone(event));
35
+ return Promise.resolve();
36
+ }
37
+ if (!activeRun) return Promise.resolve();
38
+ return this.emitRunEvent(activeRun, event);
39
+ }
40
+ async emitRunBoundaryEvent(run, event) {
41
+ await this.#runPlugins(event);
42
+ await run.emitBoundary(event);
43
+ }
44
+ async emitRunEvent(run, event) {
45
+ await this.#runPlugins(event);
46
+ run.emit(event);
47
+ }
48
+ #runPlugins(event) {
49
+ return runEventPlugins(this.#plugins, {
50
+ event,
51
+ history: this.#history(),
52
+ signal: this.#signal()
53
+ });
54
+ }
55
+ };
56
+ //#endregion
57
+ export { SessionEventDispatcher };
58
+
59
+ //# sourceMappingURL=session-events.js.map
@@ -0,0 +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"}
@@ -0,0 +1,88 @@
1
+ import { persistedToolExecutionCheckpoint } from "../llm-tool-execution.js";
2
+ //#region src/session/session-execution.ts
3
+ const maxCheckpointWriteAttempts = 5;
4
+ var SessionExecutionCheckpointError = class extends Error {
5
+ constructor(runId, expectedVersion, currentVersion) {
6
+ super(`Session execution run ${runId} checkpoint conflict: expected ${expectedVersion}, got ${currentVersion}`);
7
+ this.name = "SessionExecutionCheckpointError";
8
+ }
9
+ };
10
+ async function startSessionExecutionRun({ executionHost, sessionKey, state, turnId }) {
11
+ if (!executionHost) return;
12
+ const runId = `turn:${sessionKey}:${turnId}`;
13
+ const run = {
14
+ checkpointVersion: 0,
15
+ dedupeKey: runId,
16
+ kind: "user-turn",
17
+ rootRunId: runId,
18
+ runId,
19
+ sessionKey,
20
+ status: "running"
21
+ };
22
+ await executionHost.store.runs.create(run);
23
+ return {
24
+ complete: (status) => completeSessionExecutionRun({
25
+ executionHost,
26
+ runId,
27
+ status
28
+ }),
29
+ runId,
30
+ toolExecution: {
31
+ attempt: 1,
32
+ afterTool: (checkpoint) => appendToolExecutionCheckpoint({
33
+ executionHost,
34
+ phase: "after-tool",
35
+ runId,
36
+ state,
37
+ toolCall: checkpoint
38
+ }),
39
+ beforeTool: async (checkpoint) => {
40
+ await appendToolExecutionCheckpoint({
41
+ executionHost,
42
+ phase: "before-tool",
43
+ runId,
44
+ state,
45
+ toolCall: checkpoint
46
+ });
47
+ },
48
+ runId
49
+ }
50
+ };
51
+ }
52
+ async function appendToolExecutionCheckpoint({ executionHost, phase, runId, state, toolCall }) {
53
+ let lastConflict;
54
+ for (let attempt = 0; attempt < maxCheckpointWriteAttempts; attempt += 1) {
55
+ const run = await executionHost.store.runs.get(runId);
56
+ if (!run) throw new Error(`Session execution run ${runId} is missing.`);
57
+ const result = await executionHost.store.checkpoints.append({
58
+ checkpointId: crypto.randomUUID(),
59
+ pendingToolCall: persistedToolExecutionCheckpoint(toolCall),
60
+ phase,
61
+ runId,
62
+ runtimeState: {
63
+ toolCallId: toolCall.toolCallId,
64
+ toolName: toolCall.toolName
65
+ },
66
+ sessionSnapshot: { history: state.modelSnapshot() },
67
+ version: run.checkpointVersion + 1
68
+ }, { expectedVersion: run.checkpointVersion });
69
+ if (result.ok) return;
70
+ lastConflict = {
71
+ current: result.currentVersion,
72
+ expected: run.checkpointVersion
73
+ };
74
+ }
75
+ throw new SessionExecutionCheckpointError(runId, lastConflict?.expected ?? 0, lastConflict?.current ?? 0);
76
+ }
77
+ async function completeSessionExecutionRun({ executionHost, runId, status }) {
78
+ const run = await executionHost.store.runs.get(runId);
79
+ if (!run) return;
80
+ await executionHost.store.runs.update({
81
+ ...run,
82
+ status
83
+ });
84
+ }
85
+ //#endregion
86
+ export { startSessionExecutionRun };
87
+
88
+ //# sourceMappingURL=session-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-execution.js","names":[],"sources":["../../src/session/session-execution.ts"],"sourcesContent":["import type {\n CheckpointPhase,\n ExecutionHost,\n RunRecord,\n RunStatus,\n} from \"../execution/types\";\nimport type {\n RuntimeToolExecutionCheckpoint,\n RuntimeToolExecutionContext,\n} from \"../llm\";\nimport { persistedToolExecutionCheckpoint } from \"../llm-tool-execution\";\nimport type { SessionState } from \"./session-state\";\n\nconst maxCheckpointWriteAttempts = 5;\n\nexport interface SessionExecutionOptions {\n readonly executionHost?: ExecutionHost;\n}\n\nexport interface SessionExecutionRun {\n complete(status: SessionExecutionTerminalStatus): Promise<void>;\n readonly runId: string;\n readonly toolExecution: RuntimeToolExecutionContext;\n}\n\nexport type SessionExecutionTerminalStatus = Extract<\n RunStatus,\n \"cancelled\" | \"completed\" | \"error\" | \"needs-recovery\"\n>;\n\nexport class SessionExecutionCheckpointError extends Error {\n constructor(runId: string, expectedVersion: number, currentVersion: number) {\n super(\n `Session execution run ${runId} checkpoint conflict: expected ${expectedVersion}, got ${currentVersion}`\n );\n this.name = \"SessionExecutionCheckpointError\";\n }\n}\n\nexport async function startSessionExecutionRun({\n executionHost,\n sessionKey,\n state,\n turnId,\n}: {\n readonly executionHost?: ExecutionHost;\n readonly sessionKey: string;\n readonly state: SessionState;\n readonly turnId: string;\n}): Promise<SessionExecutionRun | undefined> {\n if (!executionHost) {\n return;\n }\n\n const runId = `turn:${sessionKey}:${turnId}`;\n const run: RunRecord = {\n checkpointVersion: 0,\n dedupeKey: runId,\n kind: \"user-turn\",\n rootRunId: runId,\n runId,\n sessionKey,\n status: \"running\",\n };\n await executionHost.store.runs.create(run);\n\n return {\n complete: (status) =>\n completeSessionExecutionRun({ executionHost, runId, status }),\n runId,\n toolExecution: {\n attempt: 1,\n afterTool: (checkpoint) =>\n appendToolExecutionCheckpoint({\n executionHost,\n phase: \"after-tool\",\n runId,\n state,\n toolCall: checkpoint,\n }),\n beforeTool: async (checkpoint) => {\n await appendToolExecutionCheckpoint({\n executionHost,\n phase: \"before-tool\",\n runId,\n state,\n toolCall: checkpoint,\n });\n return;\n },\n runId,\n },\n };\n}\n\nasync function appendToolExecutionCheckpoint({\n executionHost,\n phase,\n runId,\n state,\n toolCall,\n}: {\n readonly executionHost: ExecutionHost;\n readonly phase: Extract<CheckpointPhase, \"after-tool\" | \"before-tool\">;\n readonly runId: string;\n readonly state: SessionState;\n readonly toolCall: RuntimeToolExecutionCheckpoint & {\n readonly output?: unknown;\n };\n}): Promise<void> {\n let lastConflict:\n | { readonly current: number; readonly expected: number }\n | undefined;\n for (let attempt = 0; attempt < maxCheckpointWriteAttempts; attempt += 1) {\n const run = await executionHost.store.runs.get(runId);\n if (!run) {\n throw new Error(`Session execution run ${runId} is missing.`);\n }\n\n const result = await executionHost.store.checkpoints.append(\n {\n checkpointId: crypto.randomUUID(),\n pendingToolCall: persistedToolExecutionCheckpoint(toolCall),\n phase,\n runId,\n runtimeState: {\n toolCallId: toolCall.toolCallId,\n toolName: toolCall.toolName,\n },\n sessionSnapshot: { history: state.modelSnapshot() },\n version: run.checkpointVersion + 1,\n },\n { expectedVersion: run.checkpointVersion }\n );\n\n if (result.ok) {\n return;\n }\n\n lastConflict = {\n current: result.currentVersion,\n expected: run.checkpointVersion,\n };\n }\n\n throw new SessionExecutionCheckpointError(\n runId,\n lastConflict?.expected ?? 0,\n lastConflict?.current ?? 0\n );\n}\n\nasync function completeSessionExecutionRun({\n executionHost,\n runId,\n status,\n}: {\n readonly executionHost: ExecutionHost;\n readonly runId: string;\n readonly status: SessionExecutionTerminalStatus;\n}): Promise<void> {\n const run = await executionHost.store.runs.get(runId);\n if (!run) {\n return;\n }\n\n await executionHost.store.runs.update({ ...run, status });\n}\n"],"mappings":";;AAaA,MAAM,6BAA6B;AAiBnC,IAAa,kCAAb,cAAqD,MAAM;CACzD,YAAY,OAAe,iBAAyB,gBAAwB;EAC1E,MACE,yBAAyB,MAAM,iCAAiC,gBAAgB,QAAQ,gBAC1F;EACA,KAAK,OAAO;CACd;AACF;AAEA,eAAsB,yBAAyB,EAC7C,eACA,YACA,OACA,UAM2C;CAC3C,IAAI,CAAC,eACH;CAGF,MAAM,QAAQ,QAAQ,WAAW,GAAG;CACpC,MAAM,MAAiB;EACrB,mBAAmB;EACnB,WAAW;EACX,MAAM;EACN,WAAW;EACX;EACA;EACA,QAAQ;CACV;CACA,MAAM,cAAc,MAAM,KAAK,OAAO,GAAG;CAEzC,OAAO;EACL,WAAW,WACT,4BAA4B;GAAE;GAAe;GAAO;EAAO,CAAC;EAC9D;EACA,eAAe;GACb,SAAS;GACT,YAAY,eACV,8BAA8B;IAC5B;IACA,OAAO;IACP;IACA;IACA,UAAU;GACZ,CAAC;GACH,YAAY,OAAO,eAAe;IAChC,MAAM,8BAA8B;KAClC;KACA,OAAO;KACP;KACA;KACA,UAAU;IACZ,CAAC;GAEH;GACA;EACF;CACF;AACF;AAEA,eAAe,8BAA8B,EAC3C,eACA,OACA,OACA,OACA,YASgB;CAChB,IAAI;CAGJ,KAAK,IAAI,UAAU,GAAG,UAAU,4BAA4B,WAAW,GAAG;EACxE,MAAM,MAAM,MAAM,cAAc,MAAM,KAAK,IAAI,KAAK;EACpD,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,yBAAyB,MAAM,aAAa;EAG9D,MAAM,SAAS,MAAM,cAAc,MAAM,YAAY,OACnD;GACE,cAAc,OAAO,WAAW;GAChC,iBAAiB,iCAAiC,QAAQ;GAC1D;GACA;GACA,cAAc;IACZ,YAAY,SAAS;IACrB,UAAU,SAAS;GACrB;GACA,iBAAiB,EAAE,SAAS,MAAM,cAAc,EAAE;GAClD,SAAS,IAAI,oBAAoB;EACnC,GACA,EAAE,iBAAiB,IAAI,kBAAkB,CAC3C;EAEA,IAAI,OAAO,IACT;EAGF,eAAe;GACb,SAAS,OAAO;GAChB,UAAU,IAAI;EAChB;CACF;CAEA,MAAM,IAAI,gCACR,OACA,cAAc,YAAY,GAC1B,cAAc,WAAW,CAC3B;AACF;AAEA,eAAe,4BAA4B,EACzC,eACA,OACA,UAKgB;CAChB,MAAM,MAAM,MAAM,cAAc,MAAM,KAAK,IAAI,KAAK;CACpD,IAAI,CAAC,KACH;CAGF,MAAM,cAAc,MAAM,KAAK,OAAO;EAAE,GAAG;EAAK;CAAO,CAAC;AAC1D"}
@@ -0,0 +1,23 @@
1
+ import { closeRuntimeInput } from "./runtime-input.js";
2
+ //#region src/session/session-kill.ts
3
+ function closeKilledRuntimeInputs({ activeRuntimeInput, inputQueue, message, runToClose }) {
4
+ closeRuntimeInput(activeRuntimeInput, message);
5
+ runToClose?.emit({
6
+ type: "turn-error",
7
+ message
8
+ });
9
+ runToClose?.close(void 0, message);
10
+ while (inputQueue.length > 0) {
11
+ const item = inputQueue.shift();
12
+ closeRuntimeInput(item?.runtimeInput, message);
13
+ item?.run.emit({
14
+ type: "turn-error",
15
+ message
16
+ });
17
+ item?.run.close(void 0, message);
18
+ }
19
+ }
20
+ //#endregion
21
+ export { closeKilledRuntimeInputs };
22
+
23
+ //# sourceMappingURL=session-kill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-kill.js","names":[],"sources":["../../src/session/session-kill.ts"],"sourcesContent":["import type { BufferedAgentRun } from \"./run\";\nimport {\n closeRuntimeInput,\n type QueuedInput,\n type RuntimeInputState,\n} from \"./runtime-input\";\n\ninterface CloseKilledRuntimeInputsOptions {\n readonly activeRuntimeInput: RuntimeInputState | undefined;\n readonly inputQueue: QueuedInput[];\n readonly message: string;\n readonly runToClose: BufferedAgentRun | undefined;\n}\n\nexport function closeKilledRuntimeInputs({\n activeRuntimeInput,\n inputQueue,\n message,\n runToClose,\n}: CloseKilledRuntimeInputsOptions): void {\n closeRuntimeInput(activeRuntimeInput, message);\n runToClose?.emit({ type: \"turn-error\", message });\n runToClose?.close(undefined, message);\n\n while (inputQueue.length > 0) {\n const item = inputQueue.shift();\n closeRuntimeInput(item?.runtimeInput, message);\n item?.run.emit({ type: \"turn-error\", message });\n item?.run.close(undefined, message);\n }\n}\n"],"mappings":";;AAcA,SAAgB,yBAAyB,EACvC,oBACA,YACA,SACA,cACwC;CACxC,kBAAkB,oBAAoB,OAAO;CAC7C,YAAY,KAAK;EAAE,MAAM;EAAc;CAAQ,CAAC;CAChD,YAAY,MAAM,KAAA,GAAW,OAAO;CAEpC,OAAO,WAAW,SAAS,GAAG;EAC5B,MAAM,OAAO,WAAW,MAAM;EAC9B,kBAAkB,MAAM,cAAc,OAAO;EAC7C,MAAM,IAAI,KAAK;GAAE,MAAM;GAAc;EAAQ,CAAC;EAC9C,MAAM,IAAI,MAAM,KAAA,GAAW,OAAO;CACpC;AACF"}
@@ -0,0 +1,58 @@
1
+ import { BufferedAgentRun } from "./run.js";
2
+ import { normalizeAgentInput } from "./input-normalization.js";
3
+ import { createRuntimeInputState, queueRuntimeInput } from "./runtime-input.js";
4
+ import { errorMessage } from "./session-errors.js";
5
+ //#region src/session/session-notification.ts
6
+ function queueSessionNotification(input, options, state) {
7
+ const queuedRuntimeInput = {
8
+ input: normalizeAgentInput(input),
9
+ placement: "turn-start"
10
+ };
11
+ const observerEvents = cloneObserverEvents(options.observerEvents ?? []);
12
+ const queuedTurn = state.inputQueue[0];
13
+ if (queuedTurn) {
14
+ queuedTurn.initialEvents.push(...observerEvents);
15
+ queuedTurn.preUserRuntimeInputs.push(queuedRuntimeInput);
16
+ return queuedTurn.run;
17
+ }
18
+ const activeRun = state.activeRun;
19
+ const runtimeInput = state.activeRuntimeInput;
20
+ if (runtimeInput && activeRun && !runtimeInput.closedReason) {
21
+ queueRuntimeInput(runtimeInput, {
22
+ input: structuredClone(queuedRuntimeInput.input),
23
+ placement: "step-end"
24
+ });
25
+ return activeRun;
26
+ }
27
+ if (options.deferWhenUnobserved === true) {
28
+ state.pendingRuntimeInputs.push(queuedRuntimeInput);
29
+ const deferredRun = new BufferedAgentRun();
30
+ deferredRun.close();
31
+ return deferredRun;
32
+ }
33
+ const run = new BufferedAgentRun();
34
+ state.inputQueue.push({
35
+ initialEvents: observerEvents,
36
+ preUserRuntimeInputs: [],
37
+ run,
38
+ runtimeInput: createRuntimeInputState([queuedRuntimeInput])
39
+ });
40
+ startSessionQueueDrain(run, state.drain);
41
+ return run;
42
+ }
43
+ function startSessionQueueDrain(run, drain) {
44
+ drain().catch((error) => {
45
+ run.emit({
46
+ type: "turn-error",
47
+ message: errorMessage(error)
48
+ });
49
+ run.close();
50
+ });
51
+ }
52
+ function cloneObserverEvents(events) {
53
+ return events.map((event) => structuredClone(event));
54
+ }
55
+ //#endregion
56
+ export { queueSessionNotification, startSessionQueueDrain };
57
+
58
+ //# sourceMappingURL=session-notification.js.map
@@ -0,0 +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"}
@@ -0,0 +1,22 @@
1
+ import { shiftRuntimeInput } from "./runtime-input.js";
2
+ //#region src/session/session-runtime-drain.ts
3
+ async function drainRuntimeInput({ emit, placement, runtimeInput, state }) {
4
+ let added = false;
5
+ let next = shiftRuntimeInput(runtimeInput, placement);
6
+ 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();
15
+ next = shiftRuntimeInput(runtimeInput, placement);
16
+ }
17
+ return added;
18
+ }
19
+ //#endregion
20
+ export { drainRuntimeInput };
21
+
22
+ //# sourceMappingURL=session-runtime-drain.js.map
@@ -0,0 +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"}
@@ -0,0 +1,102 @@
1
+ import { ModelMessageHistory } from "./history.js";
2
+ import { decodeStoredSessionSnapshot, encodeSessionSnapshot } from "./snapshot.js";
3
+ //#region src/session/session-state.ts
4
+ var SessionCommitConflictError = class extends Error {
5
+ constructor(key) {
6
+ super(`Session ${JSON.stringify(key)} commit conflict`);
7
+ }
8
+ };
9
+ var SessionState = class {
10
+ #persistence;
11
+ #deleteRequested = false;
12
+ #history = new ModelMessageHistory();
13
+ #deleted = false;
14
+ #loadPromise;
15
+ #loaded = false;
16
+ #storeVersion;
17
+ #writeQueue = Promise.resolve();
18
+ constructor(persistence) {
19
+ this.#persistence = persistence;
20
+ }
21
+ get history() {
22
+ return this.#history;
23
+ }
24
+ async ensureLoaded() {
25
+ if (this.#deleteRequested || this.#deleted) return;
26
+ if (this.#loaded) return;
27
+ this.#loadPromise ??= this.#loadSessionState();
28
+ try {
29
+ await this.#loadPromise;
30
+ } catch (error) {
31
+ this.#loadPromise = void 0;
32
+ throw error;
33
+ }
34
+ }
35
+ modelSnapshot() {
36
+ return this.#history.modelSnapshot();
37
+ }
38
+ appendUserInput(input) {
39
+ this.#history.appendUserInput(input);
40
+ }
41
+ rollback(snapshot) {
42
+ this.#history.rollback(snapshot);
43
+ }
44
+ async commit() {
45
+ if (this.#deleteRequested || this.#deleted) return;
46
+ const snapshot = this.#history.modelSnapshot();
47
+ await this.#enqueueWrite(async () => {
48
+ if (this.#deleteRequested || this.#deleted) return;
49
+ const result = await this.#persistence.store.commit(this.#persistence.key, { state: encodeSessionSnapshot(snapshot) }, { expectedVersion: this.#storeVersion ?? null });
50
+ if (!result.ok) {
51
+ await this.#replaceWithStoredSession();
52
+ throw new SessionCommitConflictError(this.#persistence.key);
53
+ }
54
+ this.#storeVersion = result.version;
55
+ });
56
+ }
57
+ async delete() {
58
+ if (this.#deleted) return;
59
+ const previous = {
60
+ history: this.#history.modelSnapshot(),
61
+ loaded: this.#loaded,
62
+ storeVersion: this.#storeVersion
63
+ };
64
+ this.#deleteRequested = true;
65
+ this.#loadPromise = void 0;
66
+ await this.#enqueueWrite(async () => {
67
+ try {
68
+ await this.#persistence.store.delete(this.#persistence.key);
69
+ } catch (error) {
70
+ this.#deleteRequested = false;
71
+ this.#loaded = previous.loaded;
72
+ this.#storeVersion = previous.storeVersion;
73
+ this.#history = new ModelMessageHistory(previous.history);
74
+ throw error;
75
+ }
76
+ this.#deleted = true;
77
+ this.#loadPromise = void 0;
78
+ this.#loaded = true;
79
+ this.#storeVersion = void 0;
80
+ this.#history = new ModelMessageHistory();
81
+ });
82
+ }
83
+ #enqueueWrite(operation) {
84
+ const next = this.#writeQueue.then(operation, operation);
85
+ this.#writeQueue = next.catch(() => void 0);
86
+ return next;
87
+ }
88
+ async #loadSessionState() {
89
+ if (this.#loaded) return;
90
+ await this.#replaceWithStoredSession();
91
+ this.#loaded = true;
92
+ }
93
+ async #replaceWithStoredSession() {
94
+ const stored = await this.#persistence.store.load(this.#persistence.key);
95
+ this.#storeVersion = stored?.version;
96
+ this.#history = new ModelMessageHistory(decodeStoredSessionSnapshot(stored));
97
+ }
98
+ };
99
+ //#endregion
100
+ export { SessionCommitConflictError, SessionState };
101
+
102
+ //# sourceMappingURL=session-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.js","names":["#persistence","#history","#deleteRequested","#deleted","#loaded","#loadPromise","#loadSessionState","#enqueueWrite","#storeVersion","#replaceWithStoredSession","#writeQueue"],"sources":["../../src/session/session-state.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport { ModelMessageHistory } from \"./history\";\nimport { decodeStoredSessionSnapshot, encodeSessionSnapshot } from \"./snapshot\";\nimport type { SessionStore } from \"./store/types\";\n\nexport interface SessionPersistenceOptions {\n readonly key: string;\n readonly store: SessionStore;\n}\n\nexport class SessionCommitConflictError extends Error {\n constructor(key: string) {\n super(`Session ${JSON.stringify(key)} commit conflict`);\n }\n}\n\nexport class SessionState {\n readonly #persistence: SessionPersistenceOptions;\n #deleteRequested = false;\n #history = new ModelMessageHistory();\n #deleted = false;\n #loadPromise?: Promise<void>;\n #loaded = false;\n #storeVersion: string | undefined;\n #writeQueue: Promise<void> = Promise.resolve();\n\n constructor(persistence: SessionPersistenceOptions) {\n this.#persistence = persistence;\n }\n\n get history(): ModelMessageHistory {\n return this.#history;\n }\n\n async ensureLoaded(): Promise<void> {\n if (this.#deleteRequested || this.#deleted) {\n return;\n }\n\n if (this.#loaded) {\n return;\n }\n\n this.#loadPromise ??= this.#loadSessionState();\n try {\n await this.#loadPromise;\n } catch (error) {\n this.#loadPromise = undefined;\n throw error;\n }\n }\n\n modelSnapshot(): ModelMessage[] {\n return this.#history.modelSnapshot();\n }\n\n appendUserInput(\n input: Parameters<ModelMessageHistory[\"appendUserInput\"]>[0]\n ) {\n this.#history.appendUserInput(input);\n }\n\n rollback(snapshot: ModelMessage[]): void {\n this.#history.rollback(snapshot);\n }\n\n async commit(): Promise<void> {\n if (this.#deleteRequested || this.#deleted) {\n return;\n }\n\n const snapshot = this.#history.modelSnapshot();\n await this.#enqueueWrite(async () => {\n if (this.#deleteRequested || this.#deleted) {\n return;\n }\n\n const result = await this.#persistence.store.commit(\n this.#persistence.key,\n { state: encodeSessionSnapshot(snapshot) },\n { expectedVersion: this.#storeVersion ?? null }\n );\n\n if (!result.ok) {\n await this.#replaceWithStoredSession();\n throw new SessionCommitConflictError(this.#persistence.key);\n }\n\n this.#storeVersion = result.version;\n });\n }\n\n async delete(): Promise<void> {\n if (this.#deleted) {\n return;\n }\n\n const previous = {\n history: this.#history.modelSnapshot(),\n loaded: this.#loaded,\n storeVersion: this.#storeVersion,\n };\n this.#deleteRequested = true;\n this.#loadPromise = undefined;\n\n await this.#enqueueWrite(async () => {\n try {\n await this.#persistence.store.delete(this.#persistence.key);\n } catch (error) {\n this.#deleteRequested = false;\n this.#loaded = previous.loaded;\n this.#storeVersion = previous.storeVersion;\n this.#history = new ModelMessageHistory(previous.history);\n throw error;\n }\n\n this.#deleted = true;\n this.#loadPromise = undefined;\n this.#loaded = true;\n this.#storeVersion = undefined;\n this.#history = new ModelMessageHistory();\n });\n }\n\n #enqueueWrite(operation: () => Promise<void>): Promise<void> {\n const next = this.#writeQueue.then(operation, operation);\n this.#writeQueue = next.catch(() => undefined);\n return next;\n }\n\n async #loadSessionState(): Promise<void> {\n if (this.#loaded) {\n return;\n }\n\n await this.#replaceWithStoredSession();\n this.#loaded = true;\n }\n\n async #replaceWithStoredSession(): Promise<void> {\n const stored = await this.#persistence.store.load(this.#persistence.key);\n this.#storeVersion = stored?.version;\n this.#history = new ModelMessageHistory(\n decodeStoredSessionSnapshot(stored)\n );\n }\n}\n"],"mappings":";;;AAUA,IAAa,6BAAb,cAAgD,MAAM;CACpD,YAAY,KAAa;EACvB,MAAM,WAAW,KAAK,UAAU,GAAG,EAAE,iBAAiB;CACxD;AACF;AAEA,IAAa,eAAb,MAA0B;CACxB;CACA,mBAAmB;CACnB,WAAW,IAAI,oBAAoB;CACnC,WAAW;CACX;CACA,UAAU;CACV;CACA,cAA6B,QAAQ,QAAQ;CAE7C,YAAY,aAAwC;EAClD,KAAKA,eAAe;CACtB;CAEA,IAAI,UAA+B;EACjC,OAAO,KAAKC;CACd;CAEA,MAAM,eAA8B;EAClC,IAAI,KAAKC,oBAAoB,KAAKC,UAChC;EAGF,IAAI,KAAKC,SACP;EAGF,KAAKC,iBAAiB,KAAKC,kBAAkB;EAC7C,IAAI;GACF,MAAM,KAAKD;EACb,SAAS,OAAO;GACd,KAAKA,eAAe,KAAA;GACpB,MAAM;EACR;CACF;CAEA,gBAAgC;EAC9B,OAAO,KAAKJ,SAAS,cAAc;CACrC;CAEA,gBACE,OACA;EACA,KAAKA,SAAS,gBAAgB,KAAK;CACrC;CAEA,SAAS,UAAgC;EACvC,KAAKA,SAAS,SAAS,QAAQ;CACjC;CAEA,MAAM,SAAwB;EAC5B,IAAI,KAAKC,oBAAoB,KAAKC,UAChC;EAGF,MAAM,WAAW,KAAKF,SAAS,cAAc;EAC7C,MAAM,KAAKM,cAAc,YAAY;GACnC,IAAI,KAAKL,oBAAoB,KAAKC,UAChC;GAGF,MAAM,SAAS,MAAM,KAAKH,aAAa,MAAM,OAC3C,KAAKA,aAAa,KAClB,EAAE,OAAO,sBAAsB,QAAQ,EAAE,GACzC,EAAE,iBAAiB,KAAKQ,iBAAiB,KAAK,CAChD;GAEA,IAAI,CAAC,OAAO,IAAI;IACd,MAAM,KAAKC,0BAA0B;IACrC,MAAM,IAAI,2BAA2B,KAAKT,aAAa,GAAG;GAC5D;GAEA,KAAKQ,gBAAgB,OAAO;EAC9B,CAAC;CACH;CAEA,MAAM,SAAwB;EAC5B,IAAI,KAAKL,UACP;EAGF,MAAM,WAAW;GACf,SAAS,KAAKF,SAAS,cAAc;GACrC,QAAQ,KAAKG;GACb,cAAc,KAAKI;EACrB;EACA,KAAKN,mBAAmB;EACxB,KAAKG,eAAe,KAAA;EAEpB,MAAM,KAAKE,cAAc,YAAY;GACnC,IAAI;IACF,MAAM,KAAKP,aAAa,MAAM,OAAO,KAAKA,aAAa,GAAG;GAC5D,SAAS,OAAO;IACd,KAAKE,mBAAmB;IACxB,KAAKE,UAAU,SAAS;IACxB,KAAKI,gBAAgB,SAAS;IAC9B,KAAKP,WAAW,IAAI,oBAAoB,SAAS,OAAO;IACxD,MAAM;GACR;GAEA,KAAKE,WAAW;GAChB,KAAKE,eAAe,KAAA;GACpB,KAAKD,UAAU;GACf,KAAKI,gBAAgB,KAAA;GACrB,KAAKP,WAAW,IAAI,oBAAoB;EAC1C,CAAC;CACH;CAEA,cAAc,WAA+C;EAC3D,MAAM,OAAO,KAAKS,YAAY,KAAK,WAAW,SAAS;EACvD,KAAKA,cAAc,KAAK,YAAY,KAAA,CAAS;EAC7C,OAAO;CACT;CAEA,MAAMJ,oBAAmC;EACvC,IAAI,KAAKF,SACP;EAGF,MAAM,KAAKK,0BAA0B;EACrC,KAAKL,UAAU;CACjB;CAEA,MAAMK,4BAA2C;EAC/C,MAAM,SAAS,MAAM,KAAKT,aAAa,MAAM,KAAK,KAAKA,aAAa,GAAG;EACvE,KAAKQ,gBAAgB,QAAQ;EAC7B,KAAKP,WAAW,IAAI,oBAClB,4BAA4B,MAAM,CACpC;CACF;AACF"}
@@ -0,0 +1,35 @@
1
+ import { closeRuntimeInput } from "./runtime-input.js";
2
+ import { errorMessage } from "./session-errors.js";
3
+ import { SessionCommitConflictError } from "./session-state.js";
4
+ //#region src/session/session-turn-error.ts
5
+ async function emitTurnErrorAfterRecovery({ error, historySnapshot, run, runtimeInput, state }) {
6
+ if (error instanceof SessionCommitConflictError) {
7
+ run.emit({
8
+ type: "turn-error",
9
+ message: error.message
10
+ });
11
+ closeRuntimeInput(runtimeInput, "a session commit conflict");
12
+ return;
13
+ }
14
+ state.rollback(historySnapshot);
15
+ try {
16
+ await state.commit();
17
+ } catch (rollbackError) {
18
+ const rollbackMessage = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
19
+ run.emit({
20
+ type: "turn-error",
21
+ message: `${errorMessage(error)}; history rollback persistence failed: ${rollbackMessage}`
22
+ });
23
+ closeRuntimeInput(runtimeInput, "turn-error");
24
+ return;
25
+ }
26
+ run.emit({
27
+ type: "turn-error",
28
+ message: errorMessage(error)
29
+ });
30
+ closeRuntimeInput(runtimeInput, "turn-error");
31
+ }
32
+ //#endregion
33
+ export { emitTurnErrorAfterRecovery };
34
+
35
+ //# sourceMappingURL=session-turn-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-turn-error.js","names":[],"sources":["../../src/session/session-turn-error.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport type { BufferedAgentRun } from \"./run\";\nimport { closeRuntimeInput, type RuntimeInputState } from \"./runtime-input\";\nimport { errorMessage } from \"./session-errors\";\nimport { SessionCommitConflictError, type SessionState } from \"./session-state\";\n\nexport async function emitTurnErrorAfterRecovery({\n error,\n historySnapshot,\n run,\n runtimeInput,\n state,\n}: {\n readonly error: unknown;\n readonly historySnapshot: ModelMessage[];\n readonly run: BufferedAgentRun;\n readonly runtimeInput: RuntimeInputState;\n readonly state: SessionState;\n}): Promise<void> {\n if (error instanceof SessionCommitConflictError) {\n run.emit({ type: \"turn-error\", message: error.message });\n closeRuntimeInput(runtimeInput, \"a session commit conflict\");\n return;\n }\n\n state.rollback(historySnapshot);\n try {\n await state.commit();\n } catch (rollbackError) {\n const rollbackMessage =\n rollbackError instanceof Error\n ? rollbackError.message\n : String(rollbackError);\n run.emit({\n type: \"turn-error\",\n message: `${errorMessage(error)}; history rollback persistence failed: ${rollbackMessage}`,\n });\n closeRuntimeInput(runtimeInput, \"turn-error\");\n return;\n }\n\n run.emit({ type: \"turn-error\", message: errorMessage(error) });\n closeRuntimeInput(runtimeInput, \"turn-error\");\n}\n"],"mappings":";;;;AAMA,eAAsB,2BAA2B,EAC/C,OACA,iBACA,KACA,cACA,SAOgB;CAChB,IAAI,iBAAiB,4BAA4B;EAC/C,IAAI,KAAK;GAAE,MAAM;GAAc,SAAS,MAAM;EAAQ,CAAC;EACvD,kBAAkB,cAAc,2BAA2B;EAC3D;CACF;CAEA,MAAM,SAAS,eAAe;CAC9B,IAAI;EACF,MAAM,MAAM,OAAO;CACrB,SAAS,eAAe;EACtB,MAAM,kBACJ,yBAAyB,QACrB,cAAc,UACd,OAAO,aAAa;EAC1B,IAAI,KAAK;GACP,MAAM;GACN,SAAS,GAAG,aAAa,KAAK,EAAE,yCAAyC;EAC3E,CAAC;EACD,kBAAkB,cAAc,YAAY;EAC5C;CACF;CAEA,IAAI,KAAK;EAAE,MAAM;EAAc,SAAS,aAAa,KAAK;CAAE,CAAC;CAC7D,kBAAkB,cAAc,YAAY;AAC9C"}