assistant-stream 0.3.25 → 0.3.27

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 (216) hide show
  1. package/README.md +4 -1
  2. package/dist/core/AssistantStream.d.ts +0 -1
  3. package/dist/core/AssistantStream.d.ts.map +1 -1
  4. package/dist/core/AssistantStreamChunk.d.ts +26 -14
  5. package/dist/core/AssistantStreamChunk.d.ts.map +1 -1
  6. package/dist/core/accumulators/AssistantMessageStream.d.ts +0 -1
  7. package/dist/core/accumulators/AssistantMessageStream.d.ts.map +1 -1
  8. package/dist/core/accumulators/TimingTracker.d.ts +0 -1
  9. package/dist/core/accumulators/TimingTracker.d.ts.map +1 -1
  10. package/dist/core/accumulators/assistant-message-accumulator.d.ts +3 -9
  11. package/dist/core/accumulators/assistant-message-accumulator.d.ts.map +1 -1
  12. package/dist/core/accumulators/assistant-message-accumulator.js +70 -28
  13. package/dist/core/accumulators/assistant-message-accumulator.js.map +1 -1
  14. package/dist/core/converters/toGenericMessages.d.ts.map +1 -1
  15. package/dist/core/converters/toGenericMessages.js +2 -1
  16. package/dist/core/converters/toGenericMessages.js.map +1 -1
  17. package/dist/core/gorp/GorpStreamAccumulator.d.ts +15 -0
  18. package/dist/core/gorp/GorpStreamAccumulator.d.ts.map +1 -0
  19. package/dist/core/{object/ObjectStreamAccumulator.js → gorp/GorpStreamAccumulator.js} +11 -9
  20. package/dist/core/gorp/GorpStreamAccumulator.js.map +1 -0
  21. package/dist/core/gorp/GorpStreamDeltaTracker.d.ts +17 -0
  22. package/dist/core/gorp/GorpStreamDeltaTracker.d.ts.map +1 -0
  23. package/dist/core/gorp/GorpStreamDeltaTracker.js +38 -0
  24. package/dist/core/gorp/GorpStreamDeltaTracker.js.map +1 -0
  25. package/dist/core/gorp/GorpStreamResponse.d.ts +16 -0
  26. package/dist/core/gorp/GorpStreamResponse.d.ts.map +1 -0
  27. package/dist/core/gorp/GorpStreamResponse.js +51 -0
  28. package/dist/core/gorp/GorpStreamResponse.js.map +1 -0
  29. package/dist/core/gorp/changeTree.d.ts +16 -0
  30. package/dist/core/gorp/changeTree.d.ts.map +1 -0
  31. package/dist/core/gorp/changeTree.js +77 -0
  32. package/dist/core/gorp/changeTree.js.map +1 -0
  33. package/dist/core/gorp/createGorpStream.d.ts +16 -0
  34. package/dist/core/gorp/createGorpStream.d.ts.map +1 -0
  35. package/dist/core/{object/createObjectStream.js → gorp/createGorpStream.js} +13 -8
  36. package/dist/core/gorp/createGorpStream.js.map +1 -0
  37. package/dist/core/gorp/types.d.ts +20 -0
  38. package/dist/core/gorp/types.d.ts.map +1 -0
  39. package/dist/core/modules/assistant-stream.d.ts +18 -11
  40. package/dist/core/modules/assistant-stream.d.ts.map +1 -1
  41. package/dist/core/modules/assistant-stream.js +10 -6
  42. package/dist/core/modules/assistant-stream.js.map +1 -1
  43. package/dist/core/modules/text.d.ts +0 -1
  44. package/dist/core/modules/text.d.ts.map +1 -1
  45. package/dist/core/modules/tool-call.d.ts +0 -1
  46. package/dist/core/modules/tool-call.d.ts.map +1 -1
  47. package/dist/core/modules/tool-call.js +2 -2
  48. package/dist/core/modules/tool-call.js.map +1 -1
  49. package/dist/core/serialization/PlainText.d.ts +0 -1
  50. package/dist/core/serialization/PlainText.d.ts.map +1 -1
  51. package/dist/core/serialization/assistant-transport/AssistantTransport.d.ts +0 -1
  52. package/dist/core/serialization/assistant-transport/AssistantTransport.d.ts.map +1 -1
  53. package/dist/core/serialization/assistant-transport/AssistantTransport.js +93 -53
  54. package/dist/core/serialization/assistant-transport/AssistantTransport.js.map +1 -1
  55. package/dist/core/serialization/data-stream/DataStream.d.ts +0 -1
  56. package/dist/core/serialization/data-stream/DataStream.d.ts.map +1 -1
  57. package/dist/core/serialization/data-stream/chunk-types.d.ts +3 -4
  58. package/dist/core/serialization/data-stream/chunk-types.d.ts.map +1 -1
  59. package/dist/core/serialization/data-stream/chunk-types.js.map +1 -1
  60. package/dist/core/serialization/data-stream/serialization.d.ts +0 -1
  61. package/dist/core/serialization/data-stream/serialization.d.ts.map +1 -1
  62. package/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts +0 -1
  63. package/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts.map +1 -1
  64. package/dist/core/serialization/ui-message-stream/UIMessageStream.js +76 -53
  65. package/dist/core/serialization/ui-message-stream/UIMessageStream.js.map +1 -1
  66. package/dist/core/serialization/ui-message-stream/chunk-types.d.ts +0 -1
  67. package/dist/core/serialization/ui-message-stream/chunk-types.d.ts.map +1 -1
  68. package/dist/core/tool/ToolCallReader.d.ts +1 -0
  69. package/dist/core/tool/ToolCallReader.d.ts.map +1 -1
  70. package/dist/core/tool/ToolCallReader.js.map +1 -1
  71. package/dist/core/tool/ToolExecutionStream.d.ts +0 -1
  72. package/dist/core/tool/ToolExecutionStream.d.ts.map +1 -1
  73. package/dist/core/tool/ToolExecutionStream.js +9 -1
  74. package/dist/core/tool/ToolExecutionStream.js.map +1 -1
  75. package/dist/core/tool/ToolResponse.d.ts +6 -4
  76. package/dist/core/tool/ToolResponse.d.ts.map +1 -1
  77. package/dist/core/tool/schema-utils.d.ts +0 -1
  78. package/dist/core/tool/schema-utils.d.ts.map +1 -1
  79. package/dist/core/tool/tool-types.d.ts +71 -33
  80. package/dist/core/tool/tool-types.d.ts.map +1 -1
  81. package/dist/core/tool/toolResultStream.d.ts +3 -2
  82. package/dist/core/tool/toolResultStream.d.ts.map +1 -1
  83. package/dist/core/tool/toolResultStream.js +7 -2
  84. package/dist/core/tool/toolResultStream.js.map +1 -1
  85. package/dist/core/tool/type-path-utils.d.ts +2 -2
  86. package/dist/core/tool/type-path-utils.d.ts.map +1 -1
  87. package/dist/core/utils/Counter.d.ts.map +1 -1
  88. package/dist/core/utils/generateId.d.ts.map +1 -1
  89. package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +0 -1
  90. package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts.map +1 -1
  91. package/dist/core/utils/stream/AssistantTransformStream.d.ts +0 -1
  92. package/dist/core/utils/stream/AssistantTransformStream.d.ts.map +1 -1
  93. package/dist/core/utils/stream/LineDecoderStream.d.ts +1 -0
  94. package/dist/core/utils/stream/LineDecoderStream.d.ts.map +1 -1
  95. package/dist/core/utils/stream/LineDecoderStream.js +19 -6
  96. package/dist/core/utils/stream/LineDecoderStream.js.map +1 -1
  97. package/dist/core/utils/stream/PipeableTransformStream.d.ts.map +1 -1
  98. package/dist/core/utils/stream/SSE.d.ts +0 -1
  99. package/dist/core/utils/stream/SSE.d.ts.map +1 -1
  100. package/dist/core/utils/stream/SSE.js +2 -52
  101. package/dist/core/utils/stream/SSE.js.map +1 -1
  102. package/dist/core/utils/stream/SSEEventDecoder.d.ts +27 -0
  103. package/dist/core/utils/stream/SSEEventDecoder.d.ts.map +1 -0
  104. package/dist/core/utils/stream/SSEEventDecoder.js +84 -0
  105. package/dist/core/utils/stream/SSEEventDecoder.js.map +1 -0
  106. package/dist/core/utils/stream/SSEEventDecoderStream.d.ts +13 -0
  107. package/dist/core/utils/stream/SSEEventDecoderStream.d.ts.map +1 -0
  108. package/dist/core/utils/stream/SSEEventDecoderStream.js +24 -0
  109. package/dist/core/utils/stream/SSEEventDecoderStream.js.map +1 -0
  110. package/dist/core/utils/stream/UnderlyingReadable.d.ts.map +1 -1
  111. package/dist/core/utils/stream/merge.d.ts +2 -1
  112. package/dist/core/utils/stream/merge.d.ts.map +1 -1
  113. package/dist/core/utils/stream/merge.js +27 -8
  114. package/dist/core/utils/stream/merge.js.map +1 -1
  115. package/dist/core/utils/stream/path-utils.d.ts +0 -1
  116. package/dist/core/utils/stream/path-utils.d.ts.map +1 -1
  117. package/dist/core/utils/types.d.ts +16 -8
  118. package/dist/core/utils/types.d.ts.map +1 -1
  119. package/dist/core/utils/withPromiseOrValue.d.ts.map +1 -1
  120. package/dist/index.d.ts +25 -4
  121. package/dist/index.d.ts.map +1 -0
  122. package/dist/index.js +14 -3
  123. package/dist/index.js.map +1 -0
  124. package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +3 -3
  125. package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -1
  126. package/dist/resumable/ResumableStreamContext.d.ts +0 -1
  127. package/dist/resumable/ResumableStreamContext.d.ts.map +1 -1
  128. package/dist/resumable/ResumableStreamContext.js +12 -5
  129. package/dist/resumable/ResumableStreamContext.js.map +1 -1
  130. package/dist/resumable/constants.d.ts.map +1 -1
  131. package/dist/resumable/createResumableAssistantStreamResponse.d.ts +6 -4
  132. package/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +1 -1
  133. package/dist/resumable/errors.d.ts.map +1 -1
  134. package/dist/resumable/stores/InMemoryResumableStreamStore.d.ts +0 -1
  135. package/dist/resumable/stores/InMemoryResumableStreamStore.d.ts.map +1 -1
  136. package/dist/resumable/stores/InMemoryResumableStreamStore.js +2 -1
  137. package/dist/resumable/stores/InMemoryResumableStreamStore.js.map +1 -1
  138. package/dist/resumable/stores/ioredis.d.ts +0 -1
  139. package/dist/resumable/stores/ioredis.d.ts.map +1 -1
  140. package/dist/resumable/stores/redis-impl.d.ts +2 -2
  141. package/dist/resumable/stores/redis-impl.d.ts.map +1 -1
  142. package/dist/resumable/stores/redis.d.ts +0 -1
  143. package/dist/resumable/stores/redis.d.ts.map +1 -1
  144. package/dist/resumable/types.d.ts.map +1 -1
  145. package/dist/utils/AsyncIterableStream.d.ts.map +1 -1
  146. package/dist/utils/AsyncIterableStream.js +18 -3
  147. package/dist/utils/AsyncIterableStream.js.map +1 -1
  148. package/dist/utils/json/fix-json.d.ts.map +1 -1
  149. package/dist/utils/json/json-value.d.ts.map +1 -1
  150. package/dist/utils/json/parse-partial-json-object.d.ts +0 -1
  151. package/dist/utils/json/parse-partial-json-object.d.ts.map +1 -1
  152. package/dist/utils/promiseWithResolvers.d.ts.map +1 -1
  153. package/dist/utils.d.ts +2 -1
  154. package/dist/utils.js +2 -1
  155. package/package.json +5 -5
  156. package/src/core/AssistantStreamChunk.ts +5 -3
  157. package/src/core/accumulators/assistant-message-accumulator.test.ts +437 -1
  158. package/src/core/accumulators/assistant-message-accumulator.ts +89 -26
  159. package/src/core/{object/ObjectStream.test.ts → gorp/GorpStream.test.ts} +104 -23
  160. package/src/core/gorp/GorpStreamAccumulator.test.ts +28 -0
  161. package/src/core/{object/ObjectStreamAccumulator.ts → gorp/GorpStreamAccumulator.ts} +13 -15
  162. package/src/core/gorp/GorpStreamDeltaTracker.test.ts +182 -0
  163. package/src/core/gorp/GorpStreamDeltaTracker.ts +55 -0
  164. package/src/core/gorp/GorpStreamResponse.test.ts +32 -0
  165. package/src/core/gorp/GorpStreamResponse.ts +88 -0
  166. package/src/core/gorp/changeTree.test.ts +168 -0
  167. package/src/core/gorp/changeTree.ts +96 -0
  168. package/src/core/{object/createObjectStream.ts → gorp/createGorpStream.ts} +23 -17
  169. package/src/core/{object → gorp}/types.ts +5 -3
  170. package/src/core/modules/assistant-stream.test.ts +154 -2
  171. package/src/core/modules/assistant-stream.ts +16 -6
  172. package/src/core/modules/tool-call.test.ts +67 -0
  173. package/src/core/modules/tool-call.ts +3 -3
  174. package/src/core/serialization/assistant-transport/AssistantTransport.test.ts +215 -1
  175. package/src/core/serialization/assistant-transport/AssistantTransport.ts +83 -71
  176. package/src/core/serialization/data-stream/chunk-types.ts +2 -2
  177. package/src/core/serialization/ui-message-stream/UIMessageStream.test.ts +323 -4
  178. package/src/core/serialization/ui-message-stream/UIMessageStream.ts +81 -71
  179. package/src/core/tool/ToolExecutionStream.ts +10 -0
  180. package/src/core/tool/toolResultStream.test.ts +50 -0
  181. package/src/core/tool/toolResultStream.ts +7 -2
  182. package/src/core/utils/stream/LineDecoderStream.test.ts +26 -2
  183. package/src/core/utils/stream/LineDecoderStream.ts +21 -11
  184. package/src/core/utils/stream/SSE.ts +6 -70
  185. package/src/core/utils/stream/SSEEventDecoder.test.ts +146 -0
  186. package/src/core/utils/stream/SSEEventDecoder.ts +109 -0
  187. package/src/core/utils/stream/SSEEventDecoderStream.test.ts +42 -0
  188. package/src/core/utils/stream/SSEEventDecoderStream.ts +34 -0
  189. package/src/core/utils/stream/merge.ts +31 -9
  190. package/src/gorp.test.ts +42 -0
  191. package/src/index.ts +21 -6
  192. package/src/resumable/ResumableStreamContext.test.ts +116 -1
  193. package/src/resumable/ResumableStreamContext.ts +32 -5
  194. package/src/resumable/createResumableAssistantStreamResponse.test.ts +1 -25
  195. package/src/utils/AsyncIterableStream.test.ts +61 -0
  196. package/src/utils/AsyncIterableStream.ts +18 -3
  197. package/src/utils.ts +4 -0
  198. package/dist/core/object/ObjectStreamAccumulator.d.ts +0 -15
  199. package/dist/core/object/ObjectStreamAccumulator.d.ts.map +0 -1
  200. package/dist/core/object/ObjectStreamAccumulator.js.map +0 -1
  201. package/dist/core/object/ObjectStreamResponse.d.ts +0 -17
  202. package/dist/core/object/ObjectStreamResponse.d.ts.map +0 -1
  203. package/dist/core/object/ObjectStreamResponse.js +0 -57
  204. package/dist/core/object/ObjectStreamResponse.js.map +0 -1
  205. package/dist/core/object/createObjectStream.d.ts +0 -19
  206. package/dist/core/object/createObjectStream.d.ts.map +0 -1
  207. package/dist/core/object/createObjectStream.js.map +0 -1
  208. package/dist/core/object/types.d.ts +0 -18
  209. package/dist/core/object/types.d.ts.map +0 -1
  210. package/dist/utils/json/is-json.d.ts +0 -9
  211. package/dist/utils/json/is-json.d.ts.map +0 -1
  212. package/dist/utils/json/is-json.js +0 -17
  213. package/dist/utils/json/is-json.js.map +0 -1
  214. package/src/core/object/ObjectStreamResponse.ts +0 -109
  215. package/src/utils/json/is-json.ts +0 -43
  216. /package/dist/core/{object → gorp}/types.js +0 -0
@@ -1,5 +1,6 @@
1
- //#region src/core/object/ObjectStreamAccumulator.ts
2
- var ObjectStreamAccumulator = class ObjectStreamAccumulator {
1
+ import { assertSafePathSegment } from "./changeTree.js";
2
+ //#region src/core/gorp/GorpStreamAccumulator.ts
3
+ var GorpStreamAccumulator = class GorpStreamAccumulator {
3
4
  _state;
4
5
  constructor(initialValue = null) {
5
6
  this._state = initialValue;
@@ -8,13 +9,13 @@ var ObjectStreamAccumulator = class ObjectStreamAccumulator {
8
9
  return this._state;
9
10
  }
10
11
  append(ops) {
11
- this._state = ops.reduce((state, op) => ObjectStreamAccumulator.apply(state, op), this._state);
12
+ this._state = ops.reduce((state, op) => GorpStreamAccumulator.apply(state, op), this._state);
12
13
  }
13
14
  static apply(state, op) {
14
15
  const type = op.type;
15
16
  switch (type) {
16
- case "set": return ObjectStreamAccumulator.updatePath(state, op.path, () => op.value);
17
- case "append-text": return ObjectStreamAccumulator.updatePath(state, op.path, (current) => {
17
+ case "set": return GorpStreamAccumulator.updatePath(state, op.path, () => op.value);
18
+ case "append-text": return GorpStreamAccumulator.updatePath(state, op.path, (current) => {
18
19
  if (typeof current !== "string") throw new Error(`Expected string at path [${op.path.join(", ")}]`);
19
20
  return current + op.value;
20
21
  });
@@ -26,20 +27,21 @@ var ObjectStreamAccumulator = class ObjectStreamAccumulator {
26
27
  state ??= {};
27
28
  if (typeof state !== "object") throw new Error(`Invalid path: [${path.join(", ")}]`);
28
29
  const [key, ...rest] = path;
30
+ assertSafePathSegment(key);
29
31
  if (Array.isArray(state)) {
30
32
  const idx = Number(key);
31
33
  if (Number.isNaN(idx)) throw new Error(`Expected array index at [${path.join(", ")}]`);
32
34
  if (idx > state.length || idx < 0) throw new Error(`Insert array index out of bounds`);
33
35
  const nextState = [...state];
34
- nextState[idx] = ObjectStreamAccumulator.updatePath(nextState[idx], rest, updater);
36
+ nextState[idx] = GorpStreamAccumulator.updatePath(Object.hasOwn(nextState, idx) ? nextState[idx] : void 0, rest, updater);
35
37
  return nextState;
36
38
  }
37
39
  const nextState = { ...state };
38
- nextState[key] = ObjectStreamAccumulator.updatePath(nextState[key], rest, updater);
40
+ nextState[key] = GorpStreamAccumulator.updatePath(Object.hasOwn(nextState, key) ? nextState[key] : void 0, rest, updater);
39
41
  return nextState;
40
42
  }
41
43
  };
42
44
  //#endregion
43
- export { ObjectStreamAccumulator };
45
+ export { GorpStreamAccumulator };
44
46
 
45
- //# sourceMappingURL=ObjectStreamAccumulator.js.map
47
+ //# sourceMappingURL=GorpStreamAccumulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GorpStreamAccumulator.js","names":["_exhaustiveCheck"],"sources":["../../../src/core/gorp/GorpStreamAccumulator.ts"],"sourcesContent":["import type { ReadonlyJSONValue, ReadonlyJSONObject } from \"../../utils\";\nimport { assertSafePathSegment } from \"./changeTree\";\nimport type { GorpStreamOperation } from \"./types\";\n\nexport class GorpStreamAccumulator {\n private _state: ReadonlyJSONValue;\n\n constructor(initialValue: ReadonlyJSONValue = null) {\n this._state = initialValue;\n }\n\n get state() {\n return this._state;\n }\n\n append(ops: readonly GorpStreamOperation[]) {\n this._state = ops.reduce(\n (state, op) => GorpStreamAccumulator.apply(state, op),\n this._state,\n );\n }\n\n private static apply(state: ReadonlyJSONValue, op: GorpStreamOperation) {\n const type = op.type;\n switch (type) {\n case \"set\":\n return GorpStreamAccumulator.updatePath(state, op.path, () => op.value);\n case \"append-text\":\n return GorpStreamAccumulator.updatePath(state, op.path, (current) => {\n if (typeof current !== \"string\")\n throw new Error(`Expected string at path [${op.path.join(\", \")}]`);\n return current + op.value;\n });\n\n default: {\n const _exhaustiveCheck: never = type;\n throw new Error(`Invalid operation type: ${_exhaustiveCheck}`);\n }\n }\n }\n\n private static updatePath(\n state: ReadonlyJSONValue | undefined,\n path: readonly string[],\n updater: (current: ReadonlyJSONValue | undefined) => ReadonlyJSONValue,\n ): ReadonlyJSONValue {\n if (path.length === 0) return updater(state);\n\n // Initialize state as empty object if it's null and we're trying to set a property\n state ??= {};\n\n if (typeof state !== \"object\") {\n throw new Error(`Invalid path: [${path.join(\", \")}]`);\n }\n\n const [key, ...rest] = path as [string, ...(readonly string[])];\n assertSafePathSegment(key);\n if (Array.isArray(state)) {\n const idx = Number(key);\n if (Number.isNaN(idx))\n throw new Error(`Expected array index at [${path.join(\", \")}]`);\n if (idx > state.length || idx < 0)\n throw new Error(`Insert array index out of bounds`);\n\n const nextState = [...state];\n nextState[idx] = GorpStreamAccumulator.updatePath(\n Object.hasOwn(nextState, idx) ? nextState[idx] : undefined,\n rest,\n updater,\n );\n\n return nextState;\n }\n\n const nextState = { ...(state as ReadonlyJSONObject) };\n nextState[key] = GorpStreamAccumulator.updatePath(\n Object.hasOwn(nextState, key) ? nextState[key] : undefined,\n rest,\n updater,\n );\n\n return nextState;\n }\n}\n"],"mappings":";;AAIA,IAAa,wBAAb,MAAa,sBAAsB;CACjC;CAEA,YAAY,eAAkC,MAAM;EAClD,KAAK,SAAS;CAChB;CAEA,IAAI,QAAQ;EACV,OAAO,KAAK;CACd;CAEA,OAAO,KAAqC;EAC1C,KAAK,SAAS,IAAI,QACf,OAAO,OAAO,sBAAsB,MAAM,OAAO,EAAE,GACpD,KAAK,MACP;CACF;CAEA,OAAe,MAAM,OAA0B,IAAyB;EACtE,MAAM,OAAO,GAAG;EAChB,QAAQ,MAAR;GACE,KAAK,OACH,OAAO,sBAAsB,WAAW,OAAO,GAAG,YAAY,GAAG,KAAK;GACxE,KAAK,eACH,OAAO,sBAAsB,WAAW,OAAO,GAAG,OAAO,YAAY;IACnE,IAAI,OAAO,YAAY,UACrB,MAAM,IAAI,MAAM,4BAA4B,GAAG,KAAK,KAAK,IAAI,EAAE,EAAE;IACnE,OAAO,UAAU,GAAG;GACtB,CAAC;GAEH,SAEE,MAAM,IAAI,MAAM,2BAA2BA,MAAkB;EAEjE;CACF;CAEA,OAAe,WACb,OACA,MACA,SACmB;EACnB,IAAI,KAAK,WAAW,GAAG,OAAO,QAAQ,KAAK;EAG3C,UAAU,CAAC;EAEX,IAAI,OAAO,UAAU,UACnB,MAAM,IAAI,MAAM,kBAAkB,KAAK,KAAK,IAAI,EAAE,EAAE;EAGtD,MAAM,CAAC,KAAK,GAAG,QAAQ;EACvB,sBAAsB,GAAG;EACzB,IAAI,MAAM,QAAQ,KAAK,GAAG;GACxB,MAAM,MAAM,OAAO,GAAG;GACtB,IAAI,OAAO,MAAM,GAAG,GAClB,MAAM,IAAI,MAAM,4BAA4B,KAAK,KAAK,IAAI,EAAE,EAAE;GAChE,IAAI,MAAM,MAAM,UAAU,MAAM,GAC9B,MAAM,IAAI,MAAM,kCAAkC;GAEpD,MAAM,YAAY,CAAC,GAAG,KAAK;GAC3B,UAAU,OAAO,sBAAsB,WACrC,OAAO,OAAO,WAAW,GAAG,IAAI,UAAU,OAAO,KAAA,GACjD,MACA,OACF;GAEA,OAAO;EACT;EAEA,MAAM,YAAY,EAAE,GAAI,MAA6B;EACrD,UAAU,OAAO,sBAAsB,WACrC,OAAO,OAAO,WAAW,GAAG,IAAI,UAAU,OAAO,KAAA,GACjD,MACA,OACF;EAEA,OAAO;CACT;AACF"}
@@ -0,0 +1,17 @@
1
+ import { ReadonlyJSONValue } from "../../utils/json/json-value.js";
2
+ import "../../utils.js";
3
+ import { GorpStreamOperation } from "./types.js";
4
+ //#region src/core/gorp/GorpStreamDeltaTracker.d.ts
5
+ declare class GorpStreamDeltaTracker {
6
+ private readonly accumulator;
7
+ private previousState;
8
+ private changes;
9
+ constructor(initialValue?: ReadonlyJSONValue);
10
+ get state(): ReadonlyJSONValue;
11
+ append(operations: readonly GorpStreamOperation[]): void;
12
+ isChangedAt(path: readonly string[]): boolean;
13
+ getChangedKeys(path: readonly string[]): string[];
14
+ }
15
+ //#endregion
16
+ export { GorpStreamDeltaTracker };
17
+ //# sourceMappingURL=GorpStreamDeltaTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GorpStreamDeltaTracker.d.ts","names":[],"sources":["../../../src/core/gorp/GorpStreamDeltaTracker.ts"],"mappings":";;;;cAYa;mBACM;UACT;UACA;EAEI,YAAA,eAAc;MAKtB,SAAS;EAIb,OAAO,qBAAqB;EAW5B,YAAY;EAMZ,eAAe"}
@@ -0,0 +1,38 @@
1
+ import { createChangeNode, diffKeys, lookupChange, lookupValue, markChanged } from "./changeTree.js";
2
+ import { GorpStreamAccumulator } from "./GorpStreamAccumulator.js";
3
+ //#region src/core/gorp/GorpStreamDeltaTracker.ts
4
+ var GorpStreamDeltaTracker = class {
5
+ accumulator;
6
+ previousState;
7
+ changes = createChangeNode();
8
+ constructor(initialValue = null) {
9
+ this.accumulator = new GorpStreamAccumulator(initialValue);
10
+ this.previousState = this.accumulator.state;
11
+ }
12
+ get state() {
13
+ return this.accumulator.state;
14
+ }
15
+ append(operations) {
16
+ const previousState = this.accumulator.state;
17
+ let changes = createChangeNode();
18
+ for (const op of operations) changes = markChanged(changes, op.path);
19
+ this.accumulator.append(operations);
20
+ this.previousState = previousState;
21
+ this.changes = changes;
22
+ }
23
+ isChangedAt(path) {
24
+ const node = lookupChange(this.changes, path);
25
+ if (node === true) return true;
26
+ return node !== false && Object.keys(node).length > 0;
27
+ }
28
+ getChangedKeys(path) {
29
+ const node = lookupChange(this.changes, path);
30
+ if (node === false) return [];
31
+ if (node === true) return diffKeys(lookupValue(this.accumulator.state, path), lookupValue(this.previousState, path));
32
+ return Object.keys(node);
33
+ }
34
+ };
35
+ //#endregion
36
+ export { GorpStreamDeltaTracker };
37
+
38
+ //# sourceMappingURL=GorpStreamDeltaTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GorpStreamDeltaTracker.js","names":[],"sources":["../../../src/core/gorp/GorpStreamDeltaTracker.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"../../utils\";\nimport { GorpStreamAccumulator } from \"./GorpStreamAccumulator\";\nimport type { GorpStreamOperation } from \"./types\";\nimport {\n type ChangeNode,\n createChangeNode,\n diffKeys,\n lookupChange,\n lookupValue,\n markChanged,\n} from \"./changeTree\";\n\nexport class GorpStreamDeltaTracker {\n private readonly accumulator: GorpStreamAccumulator;\n private previousState: ReadonlyJSONValue;\n private changes: ChangeNode = createChangeNode();\n\n constructor(initialValue: ReadonlyJSONValue = null) {\n this.accumulator = new GorpStreamAccumulator(initialValue);\n this.previousState = this.accumulator.state;\n }\n\n get state(): ReadonlyJSONValue {\n return this.accumulator.state;\n }\n\n append(operations: readonly GorpStreamOperation[]): void {\n const previousState = this.accumulator.state;\n let changes: ChangeNode = createChangeNode();\n for (const op of operations) {\n changes = markChanged(changes, op.path);\n }\n this.accumulator.append(operations);\n this.previousState = previousState;\n this.changes = changes;\n }\n\n isChangedAt(path: readonly string[]): boolean {\n const node = lookupChange(this.changes, path);\n if (node === true) return true;\n return node !== false && Object.keys(node).length > 0;\n }\n\n getChangedKeys(path: readonly string[]): string[] {\n const node = lookupChange(this.changes, path);\n if (node === false) return [];\n if (node === true) {\n return diffKeys(\n lookupValue(this.accumulator.state, path),\n lookupValue(this.previousState, path),\n );\n }\n return Object.keys(node);\n }\n}\n"],"mappings":";;;AAYA,IAAa,yBAAb,MAAoC;CAClC;CACA;CACA,UAA8B,iBAAiB;CAE/C,YAAY,eAAkC,MAAM;EAClD,KAAK,cAAc,IAAI,sBAAsB,YAAY;EACzD,KAAK,gBAAgB,KAAK,YAAY;CACxC;CAEA,IAAI,QAA2B;EAC7B,OAAO,KAAK,YAAY;CAC1B;CAEA,OAAO,YAAkD;EACvD,MAAM,gBAAgB,KAAK,YAAY;EACvC,IAAI,UAAsB,iBAAiB;EAC3C,KAAK,MAAM,MAAM,YACf,UAAU,YAAY,SAAS,GAAG,IAAI;EAExC,KAAK,YAAY,OAAO,UAAU;EAClC,KAAK,gBAAgB;EACrB,KAAK,UAAU;CACjB;CAEA,YAAY,MAAkC;EAC5C,MAAM,OAAO,aAAa,KAAK,SAAS,IAAI;EAC5C,IAAI,SAAS,MAAM,OAAO;EAC1B,OAAO,SAAS,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS;CACtD;CAEA,eAAe,MAAmC;EAChD,MAAM,OAAO,aAAa,KAAK,SAAS,IAAI;EAC5C,IAAI,SAAS,OAAO,OAAO,CAAC;EAC5B,IAAI,SAAS,MACX,OAAO,SACL,YAAY,KAAK,YAAY,OAAO,IAAI,GACxC,YAAY,KAAK,eAAe,IAAI,CACtC;EAEF,OAAO,OAAO,KAAK,IAAI;CACzB;AACF"}
@@ -0,0 +1,16 @@
1
+ import { GorpStreamChunk } from "./types.js";
2
+ import { PipeableTransformStream } from "../utils/stream/PipeableTransformStream.js";
3
+ //#region src/core/gorp/GorpStreamResponse.d.ts
4
+ declare class GorpStreamEncoder extends PipeableTransformStream<GorpStreamChunk, Uint8Array> {
5
+ constructor();
6
+ }
7
+ declare class GorpStreamDecoder extends PipeableTransformStream<Uint8Array<ArrayBuffer>, GorpStreamChunk> {
8
+ constructor();
9
+ }
10
+ declare class GorpStreamResponse extends Response {
11
+ constructor(body: ReadableStream<GorpStreamChunk>);
12
+ }
13
+ declare const fromGorpStreamResponse: (response: Response) => ReadableStream<GorpStreamChunk>;
14
+ //#endregion
15
+ export { GorpStreamDecoder, GorpStreamEncoder, GorpStreamResponse, fromGorpStreamResponse };
16
+ //# sourceMappingURL=GorpStreamResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GorpStreamResponse.d.ts","names":[],"sources":["../../../src/core/gorp/GorpStreamResponse.ts"],"mappings":";;;cAKa,0BAA0B,wBACrC,iBACA;;;cAyBW,0BAA0B,wBACrC,WAAW,cACX;;;cAsBW,2BAA2B;EAC1B,YAAA,MAAM,eAAe;;cAYtB,yBACX,UAAU,aACT,eAAe"}
@@ -0,0 +1,51 @@
1
+ import { PipeableTransformStream } from "../utils/stream/PipeableTransformStream.js";
2
+ import { GorpStreamAccumulator } from "./GorpStreamAccumulator.js";
3
+ import { SSEDecoder, SSEEncoder } from "../utils/stream/SSE.js";
4
+ //#region src/core/gorp/GorpStreamResponse.ts
5
+ var GorpStreamEncoder = class extends PipeableTransformStream {
6
+ constructor() {
7
+ let isFirstChunk = true;
8
+ super((readable) => readable.pipeThrough(new TransformStream({ transform(chunk, controller) {
9
+ if (isFirstChunk) controller.enqueue([{
10
+ type: "set",
11
+ path: [],
12
+ value: chunk.snapshot
13
+ }]);
14
+ else controller.enqueue(chunk.operations);
15
+ isFirstChunk = false;
16
+ } })).pipeThrough(new SSEEncoder()));
17
+ }
18
+ };
19
+ var GorpStreamDecoder = class extends PipeableTransformStream {
20
+ constructor() {
21
+ const accumulator = new GorpStreamAccumulator();
22
+ super((readable) => readable.pipeThrough(new SSEDecoder()).pipeThrough(new TransformStream({ transform(operations, controller) {
23
+ accumulator.append(operations);
24
+ controller.enqueue({
25
+ snapshot: accumulator.state,
26
+ operations
27
+ });
28
+ } })));
29
+ }
30
+ };
31
+ var GorpStreamResponse = class extends Response {
32
+ constructor(body) {
33
+ super(body.pipeThrough(new GorpStreamEncoder()), { headers: new Headers({
34
+ "Content-Type": "text/event-stream",
35
+ "Cache-Control": "no-cache",
36
+ Connection: "keep-alive",
37
+ "Assistant-Stream-Format": "object-stream/v0"
38
+ }) });
39
+ }
40
+ };
41
+ const fromGorpStreamResponse = (response) => {
42
+ if (!response.ok) throw new Error(`Response failed, status ${response.status}`);
43
+ if (!response.body) throw new Error("Response body is null");
44
+ if (response.headers.get("Content-Type")?.split(";", 1)[0]?.trim().toLowerCase() !== "text/event-stream") throw new Error("Response is not an event stream");
45
+ if (response.headers.get("Assistant-Stream-Format") !== "object-stream/v0") throw new Error("Unsupported Assistant-Stream-Format header");
46
+ return response.body.pipeThrough(new GorpStreamDecoder());
47
+ };
48
+ //#endregion
49
+ export { GorpStreamDecoder, GorpStreamEncoder, GorpStreamResponse, fromGorpStreamResponse };
50
+
51
+ //# sourceMappingURL=GorpStreamResponse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GorpStreamResponse.js","names":[],"sources":["../../../src/core/gorp/GorpStreamResponse.ts"],"sourcesContent":["import { PipeableTransformStream } from \"../utils/stream/PipeableTransformStream\";\nimport { GorpStreamAccumulator } from \"./GorpStreamAccumulator\";\nimport { SSEDecoder, SSEEncoder } from \"../utils/stream/SSE\";\nimport type { GorpStreamChunk, GorpStreamOperation } from \"./types\";\n\nexport class GorpStreamEncoder extends PipeableTransformStream<\n GorpStreamChunk,\n Uint8Array\n> {\n constructor() {\n let isFirstChunk = true;\n super((readable) =>\n readable\n .pipeThrough(\n new TransformStream<GorpStreamChunk, readonly GorpStreamOperation[]>({\n transform(chunk, controller) {\n if (isFirstChunk) {\n controller.enqueue([\n { type: \"set\", path: [], value: chunk.snapshot },\n ]);\n } else {\n controller.enqueue(chunk.operations);\n }\n isFirstChunk = false;\n },\n }),\n )\n .pipeThrough(new SSEEncoder()),\n );\n }\n}\n\nexport class GorpStreamDecoder extends PipeableTransformStream<\n Uint8Array<ArrayBuffer>,\n GorpStreamChunk\n> {\n constructor() {\n const accumulator = new GorpStreamAccumulator();\n super((readable) =>\n readable\n .pipeThrough(new SSEDecoder<readonly GorpStreamOperation[]>())\n .pipeThrough(\n new TransformStream<readonly GorpStreamOperation[], GorpStreamChunk>({\n transform(operations, controller) {\n accumulator.append(operations);\n controller.enqueue({\n snapshot: accumulator.state,\n operations,\n });\n },\n }),\n ),\n );\n }\n}\n\nexport class GorpStreamResponse extends Response {\n constructor(body: ReadableStream<GorpStreamChunk>) {\n super(body.pipeThrough(new GorpStreamEncoder()), {\n headers: new Headers({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Assistant-Stream-Format\": \"object-stream/v0\",\n }),\n });\n }\n}\n\nexport const fromGorpStreamResponse = (\n response: Response,\n): ReadableStream<GorpStreamChunk> => {\n if (!response.ok)\n throw new Error(`Response failed, status ${response.status}`);\n if (!response.body) throw new Error(\"Response body is null\");\n const mediaType = response.headers\n .get(\"Content-Type\")\n ?.split(\";\", 1)[0]\n ?.trim()\n .toLowerCase();\n if (mediaType !== \"text/event-stream\") {\n throw new Error(\"Response is not an event stream\");\n }\n if (response.headers.get(\"Assistant-Stream-Format\") !== \"object-stream/v0\") {\n throw new Error(\"Unsupported Assistant-Stream-Format header\");\n }\n return response.body.pipeThrough(new GorpStreamDecoder());\n};\n"],"mappings":";;;;AAKA,IAAa,oBAAb,cAAuC,wBAGrC;CACA,cAAc;EACZ,IAAI,eAAe;EACnB,OAAO,aACL,SACG,YACC,IAAI,gBAAiE,EACnE,UAAU,OAAO,YAAY;GAC3B,IAAI,cACF,WAAW,QAAQ,CACjB;IAAE,MAAM;IAAO,MAAM,CAAC;IAAG,OAAO,MAAM;GAAS,CACjD,CAAC;QAED,WAAW,QAAQ,MAAM,UAAU;GAErC,eAAe;EACjB,EACF,CAAC,CACH,CAAC,CACA,YAAY,IAAI,WAAW,CAAC,CACjC;CACF;AACF;AAEA,IAAa,oBAAb,cAAuC,wBAGrC;CACA,cAAc;EACZ,MAAM,cAAc,IAAI,sBAAsB;EAC9C,OAAO,aACL,SACG,YAAY,IAAI,WAA2C,CAAC,CAAC,CAC7D,YACC,IAAI,gBAAiE,EACnE,UAAU,YAAY,YAAY;GAChC,YAAY,OAAO,UAAU;GAC7B,WAAW,QAAQ;IACjB,UAAU,YAAY;IACtB;GACF,CAAC;EACH,EACF,CAAC,CACH,CACJ;CACF;AACF;AAEA,IAAa,qBAAb,cAAwC,SAAS;CAC/C,YAAY,MAAuC;EACjD,MAAM,KAAK,YAAY,IAAI,kBAAkB,CAAC,GAAG,EAC/C,SAAS,IAAI,QAAQ;GACnB,gBAAgB;GAChB,iBAAiB;GACjB,YAAY;GACZ,2BAA2B;EAC7B,CAAC,EACH,CAAC;CACH;AACF;AAEA,MAAa,0BACX,aACoC;CACpC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,2BAA2B,SAAS,QAAQ;CAC9D,IAAI,CAAC,SAAS,MAAM,MAAM,IAAI,MAAM,uBAAuB;CAM3D,IALkB,SAAS,QACxB,IAAI,cAAc,CAAC,EAClB,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAChB,KAAK,CAAC,CACP,YAAY,MACG,qBAChB,MAAM,IAAI,MAAM,iCAAiC;CAEnD,IAAI,SAAS,QAAQ,IAAI,yBAAyB,MAAM,oBACtD,MAAM,IAAI,MAAM,4CAA4C;CAE9D,OAAO,SAAS,KAAK,YAAY,IAAI,kBAAkB,CAAC;AAC1D"}
@@ -0,0 +1,16 @@
1
+ //#region src/core/gorp/changeTree.d.ts
2
+ type ChangeNode = true | {
3
+ [key: string]: ChangeNode;
4
+ };
5
+ declare function createChangeNode(): {
6
+ [key: string]: ChangeNode;
7
+ };
8
+ declare function assertSafePathSegment(segment: string): void;
9
+ declare function markChanged(node: ChangeNode, path: readonly string[]): ChangeNode;
10
+ declare function mergeChanged(target: ChangeNode, source: ChangeNode): ChangeNode;
11
+ declare function lookupChange(node: ChangeNode, path: readonly string[]): ChangeNode | false;
12
+ declare function lookupValue(state: unknown, path: readonly string[]): unknown;
13
+ declare function diffKeys(newNode: unknown, oldNode: unknown): string[];
14
+ //#endregion
15
+ export { ChangeNode, assertSafePathSegment, createChangeNode, diffKeys, lookupChange, lookupValue, markChanged, mergeChanged };
16
+ //# sourceMappingURL=changeTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeTree.d.ts","names":[],"sources":["../../../src/core/gorp/changeTree.ts"],"mappings":";KAAY;GAAuB,cAAc;;iBAEjC;GAAuB,cAAc;;iBAMrC,sBAAsB;iBAMtB,YACd,MAAM,YACN,0BACC;iBAiBa,aACd,QAAQ,YACR,QAAQ,aACP;iBAwBa,aACd,MAAM,YACN,0BACC;iBAUa,YAAY,gBAAgB;iBAY5B,SAAS,kBAAkB"}
@@ -0,0 +1,77 @@
1
+ //#region src/core/gorp/changeTree.ts
2
+ function createChangeNode() {
3
+ return Object.create(null);
4
+ }
5
+ const UNSAFE_PATH_SEGMENTS = /* @__PURE__ */ new Set([
6
+ "__proto__",
7
+ "constructor",
8
+ "prototype"
9
+ ]);
10
+ function assertSafePathSegment(segment) {
11
+ if (UNSAFE_PATH_SEGMENTS.has(segment)) throw new Error(`Unsafe gorp path segment: ${segment}`);
12
+ }
13
+ function markChanged(node, path) {
14
+ if (node === true || path.length === 0) return true;
15
+ let cursor = node;
16
+ for (let i = 0; i < path.length - 1; i++) {
17
+ const key = path[i];
18
+ assertSafePathSegment(key);
19
+ const next = Object.hasOwn(cursor, key) ? cursor[key] : void 0;
20
+ if (next === true) return node;
21
+ if (next === void 0) cursor[key] = createChangeNode();
22
+ cursor = cursor[key];
23
+ }
24
+ const leaf = path[path.length - 1];
25
+ assertSafePathSegment(leaf);
26
+ cursor[leaf] = true;
27
+ return node;
28
+ }
29
+ function mergeChanged(target, source) {
30
+ if (target === true || source === true) return true;
31
+ for (const key of Object.keys(source)) {
32
+ assertSafePathSegment(key);
33
+ const sChild = source[key];
34
+ const tChild = Object.hasOwn(target, key) ? target[key] : void 0;
35
+ target[key] = tChild === void 0 ? cloneChangeNode(sChild) : mergeChanged(tChild, sChild);
36
+ }
37
+ return target;
38
+ }
39
+ function cloneChangeNode(source) {
40
+ if (source === true) return true;
41
+ const clone = createChangeNode();
42
+ for (const key of Object.keys(source)) {
43
+ assertSafePathSegment(key);
44
+ clone[key] = cloneChangeNode(source[key]);
45
+ }
46
+ return clone;
47
+ }
48
+ function lookupChange(node, path) {
49
+ for (const key of path) {
50
+ if (node === true) return true;
51
+ const next = Object.hasOwn(node, key) ? node[key] : void 0;
52
+ if (next === void 0) return false;
53
+ node = next;
54
+ }
55
+ return node;
56
+ }
57
+ function lookupValue(state, path) {
58
+ let node = state;
59
+ for (const key of path) {
60
+ assertSafePathSegment(key);
61
+ if (typeof node !== "object" || node === null) return void 0;
62
+ node = Object.hasOwn(node, key) ? node[key] : void 0;
63
+ }
64
+ return node;
65
+ }
66
+ function diffKeys(newNode, oldNode) {
67
+ const newKeys = typeof newNode === "object" && newNode !== null ? Object.keys(newNode) : [];
68
+ const oldKeys = typeof oldNode === "object" && oldNode !== null ? Object.keys(oldNode) : [];
69
+ if (oldKeys.length === 0) return newKeys;
70
+ const newSet = new Set(newKeys);
71
+ const deletedKeys = oldKeys.filter((k) => !newSet.has(k)).reverse();
72
+ return [...newKeys, ...deletedKeys];
73
+ }
74
+ //#endregion
75
+ export { assertSafePathSegment, createChangeNode, diffKeys, lookupChange, lookupValue, markChanged, mergeChanged };
76
+
77
+ //# sourceMappingURL=changeTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeTree.js","names":[],"sources":["../../../src/core/gorp/changeTree.ts"],"sourcesContent":["export type ChangeNode = true | { [key: string]: ChangeNode };\n\nexport function createChangeNode(): { [key: string]: ChangeNode } {\n return Object.create(null);\n}\n\nconst UNSAFE_PATH_SEGMENTS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nexport function assertSafePathSegment(segment: string): void {\n if (UNSAFE_PATH_SEGMENTS.has(segment)) {\n throw new Error(`Unsafe gorp path segment: ${segment}`);\n }\n}\n\nexport function markChanged(\n node: ChangeNode,\n path: readonly string[],\n): ChangeNode {\n if (node === true || path.length === 0) return true;\n let cursor = node;\n for (let i = 0; i < path.length - 1; i++) {\n const key = path[i]!;\n assertSafePathSegment(key);\n const next = Object.hasOwn(cursor, key) ? cursor[key] : undefined;\n if (next === true) return node;\n if (next === undefined) cursor[key] = createChangeNode();\n cursor = cursor[key] as { [k: string]: ChangeNode };\n }\n const leaf = path[path.length - 1]!;\n assertSafePathSegment(leaf);\n cursor[leaf] = true;\n return node;\n}\n\nexport function mergeChanged(\n target: ChangeNode,\n source: ChangeNode,\n): ChangeNode {\n if (target === true || source === true) return true;\n for (const key of Object.keys(source)) {\n assertSafePathSegment(key);\n const sChild = source[key]!;\n const tChild = Object.hasOwn(target, key) ? target[key] : undefined;\n target[key] =\n tChild === undefined\n ? cloneChangeNode(sChild)\n : mergeChanged(tChild, sChild);\n }\n return target;\n}\n\nfunction cloneChangeNode(source: ChangeNode): ChangeNode {\n if (source === true) return true;\n const clone = createChangeNode();\n for (const key of Object.keys(source)) {\n assertSafePathSegment(key);\n clone[key] = cloneChangeNode(source[key]!);\n }\n return clone;\n}\n\nexport function lookupChange(\n node: ChangeNode,\n path: readonly string[],\n): ChangeNode | false {\n for (const key of path) {\n if (node === true) return true;\n const next = Object.hasOwn(node, key) ? node[key] : undefined;\n if (next === undefined) return false;\n node = next;\n }\n return node;\n}\n\nexport function lookupValue(state: unknown, path: readonly string[]): unknown {\n let node = state;\n for (const key of path) {\n assertSafePathSegment(key);\n if (typeof node !== \"object\" || node === null) return undefined;\n node = Object.hasOwn(node, key)\n ? (node as Record<string, unknown>)[key]\n : undefined;\n }\n return node;\n}\n\nexport function diffKeys(newNode: unknown, oldNode: unknown): string[] {\n const newKeys =\n typeof newNode === \"object\" && newNode !== null ? Object.keys(newNode) : [];\n const oldKeys =\n typeof oldNode === \"object\" && oldNode !== null ? Object.keys(oldNode) : [];\n if (oldKeys.length === 0) return newKeys;\n const newSet = new Set(newKeys);\n const deletedKeys = oldKeys.filter((k) => !newSet.has(k)).reverse();\n return [...newKeys, ...deletedKeys];\n}\n"],"mappings":";AAEA,SAAgB,mBAAkD;CAChE,OAAO,OAAO,OAAO,IAAI;AAC3B;AAEA,MAAM,uCAAuB,IAAI,IAAI;CAAC;CAAa;CAAe;AAAW,CAAC;AAE9E,SAAgB,sBAAsB,SAAuB;CAC3D,IAAI,qBAAqB,IAAI,OAAO,GAClC,MAAM,IAAI,MAAM,6BAA6B,SAAS;AAE1D;AAEA,SAAgB,YACd,MACA,MACY;CACZ,IAAI,SAAS,QAAQ,KAAK,WAAW,GAAG,OAAO;CAC/C,IAAI,SAAS;CACb,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;EACxC,MAAM,MAAM,KAAK;EACjB,sBAAsB,GAAG;EACzB,MAAM,OAAO,OAAO,OAAO,QAAQ,GAAG,IAAI,OAAO,OAAO,KAAA;EACxD,IAAI,SAAS,MAAM,OAAO;EAC1B,IAAI,SAAS,KAAA,GAAW,OAAO,OAAO,iBAAiB;EACvD,SAAS,OAAO;CAClB;CACA,MAAM,OAAO,KAAK,KAAK,SAAS;CAChC,sBAAsB,IAAI;CAC1B,OAAO,QAAQ;CACf,OAAO;AACT;AAEA,SAAgB,aACd,QACA,QACY;CACZ,IAAI,WAAW,QAAQ,WAAW,MAAM,OAAO;CAC/C,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EACrC,sBAAsB,GAAG;EACzB,MAAM,SAAS,OAAO;EACtB,MAAM,SAAS,OAAO,OAAO,QAAQ,GAAG,IAAI,OAAO,OAAO,KAAA;EAC1D,OAAO,OACL,WAAW,KAAA,IACP,gBAAgB,MAAM,IACtB,aAAa,QAAQ,MAAM;CACnC;CACA,OAAO;AACT;AAEA,SAAS,gBAAgB,QAAgC;CACvD,IAAI,WAAW,MAAM,OAAO;CAC5B,MAAM,QAAQ,iBAAiB;CAC/B,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAAG;EACrC,sBAAsB,GAAG;EACzB,MAAM,OAAO,gBAAgB,OAAO,IAAK;CAC3C;CACA,OAAO;AACT;AAEA,SAAgB,aACd,MACA,MACoB;CACpB,KAAK,MAAM,OAAO,MAAM;EACtB,IAAI,SAAS,MAAM,OAAO;EAC1B,MAAM,OAAO,OAAO,OAAO,MAAM,GAAG,IAAI,KAAK,OAAO,KAAA;EACpD,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,YAAY,OAAgB,MAAkC;CAC5E,IAAI,OAAO;CACX,KAAK,MAAM,OAAO,MAAM;EACtB,sBAAsB,GAAG;EACzB,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO,KAAA;EACtD,OAAO,OAAO,OAAO,MAAM,GAAG,IACzB,KAAiC,OAClC,KAAA;CACN;CACA,OAAO;AACT;AAEA,SAAgB,SAAS,SAAkB,SAA4B;CACrE,MAAM,UACJ,OAAO,YAAY,YAAY,YAAY,OAAO,OAAO,KAAK,OAAO,IAAI,CAAC;CAC5E,MAAM,UACJ,OAAO,YAAY,YAAY,YAAY,OAAO,OAAO,KAAK,OAAO,IAAI,CAAC;CAC5E,IAAI,QAAQ,WAAW,GAAG,OAAO;CACjC,MAAM,SAAS,IAAI,IAAI,OAAO;CAC9B,MAAM,cAAc,QAAQ,QAAQ,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ;CAClE,OAAO,CAAC,GAAG,SAAS,GAAG,WAAW;AACpC"}
@@ -0,0 +1,16 @@
1
+ import { ReadonlyJSONValue } from "../../utils/json/json-value.js";
2
+ import "../../utils.js";
3
+ import { GorpStreamChunk, GorpStreamOperation } from "./types.js";
4
+ //#region src/core/gorp/createGorpStream.d.ts
5
+ type GorpStreamController = {
6
+ readonly abortSignal: AbortSignal;
7
+ enqueue(operations: readonly GorpStreamOperation[]): void;
8
+ };
9
+ type CreateGorpStreamOptions = {
10
+ execute: (controller: GorpStreamController) => void | PromiseLike<void>;
11
+ defaultValue?: ReadonlyJSONValue;
12
+ };
13
+ declare const createGorpStream: ({ execute, defaultValue }: CreateGorpStreamOptions) => ReadableStream<GorpStreamChunk>;
14
+ //#endregion
15
+ export { createGorpStream };
16
+ //# sourceMappingURL=createGorpStream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createGorpStream.d.ts","names":[],"sources":["../../../src/core/gorp/createGorpStream.ts"],"mappings":";;;;KAKK;WACM,aAAa;EAEtB,QAAQ,qBAAqB;;KA8D1B;EACH,UAAU,YAAY,gCAAgC;EACtD,eAAe;;cAGJ,qBAAoB,SAAA,gBAG9B,4BAAuB,eAAA"}
@@ -1,18 +1,20 @@
1
- import { ObjectStreamAccumulator } from "./ObjectStreamAccumulator.js";
1
+ import { GorpStreamAccumulator } from "./GorpStreamAccumulator.js";
2
2
  import { withPromiseOrValue } from "../utils/withPromiseOrValue.js";
3
- //#region src/core/object/createObjectStream.ts
4
- var ObjectStreamControllerImpl = class {
3
+ //#region src/core/gorp/createGorpStream.ts
4
+ var GorpStreamControllerImpl = class {
5
5
  _controller;
6
6
  _abortController = new AbortController();
7
7
  _accumulator;
8
+ _cancelled = false;
8
9
  get abortSignal() {
9
10
  return this._abortController.signal;
10
11
  }
11
12
  constructor(controller, defaultValue) {
12
13
  this._controller = controller;
13
- this._accumulator = new ObjectStreamAccumulator(defaultValue);
14
+ this._accumulator = new GorpStreamAccumulator(defaultValue);
14
15
  }
15
16
  enqueue(operations) {
17
+ if (this._cancelled) return;
16
18
  this._accumulator.append(operations);
17
19
  this._controller.enqueue({
18
20
  snapshot: this._accumulator.state,
@@ -20,12 +22,15 @@ var ObjectStreamControllerImpl = class {
20
22
  });
21
23
  }
22
24
  __internalError(error) {
25
+ if (this._cancelled) return;
23
26
  this._controller.error(error);
24
27
  }
25
28
  __internalClose() {
29
+ if (this._cancelled) return;
26
30
  this._controller.close();
27
31
  }
28
32
  __internalCancel(reason) {
33
+ this._cancelled = true;
29
34
  this._abortController.abort(reason);
30
35
  }
31
36
  };
@@ -33,14 +38,14 @@ const getStreamControllerPair = (defaultValue) => {
33
38
  let controller;
34
39
  return [new ReadableStream({
35
40
  start(c) {
36
- controller = new ObjectStreamControllerImpl(c, defaultValue);
41
+ controller = new GorpStreamControllerImpl(c, defaultValue);
37
42
  },
38
43
  cancel(reason) {
39
44
  controller.__internalCancel(reason);
40
45
  }
41
46
  }), controller];
42
47
  };
43
- const createObjectStream = ({ execute, defaultValue = {} }) => {
48
+ const createGorpStream = ({ execute, defaultValue = {} }) => {
44
49
  const [stream, controller] = getStreamControllerPair(defaultValue);
45
50
  withPromiseOrValue(() => execute(controller), () => {
46
51
  controller.__internalClose();
@@ -50,6 +55,6 @@ const createObjectStream = ({ execute, defaultValue = {} }) => {
50
55
  return stream;
51
56
  };
52
57
  //#endregion
53
- export { createObjectStream };
58
+ export { createGorpStream };
54
59
 
55
- //# sourceMappingURL=createObjectStream.js.map
60
+ //# sourceMappingURL=createGorpStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createGorpStream.js","names":[],"sources":["../../../src/core/gorp/createGorpStream.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"../../utils\";\nimport { withPromiseOrValue } from \"../utils/withPromiseOrValue\";\nimport { GorpStreamAccumulator } from \"./GorpStreamAccumulator\";\nimport type { GorpStreamOperation, GorpStreamChunk } from \"./types\";\n\ntype GorpStreamController = {\n readonly abortSignal: AbortSignal;\n\n enqueue(operations: readonly GorpStreamOperation[]): void;\n};\n\nclass GorpStreamControllerImpl implements GorpStreamController {\n private _controller: ReadableStreamDefaultController<GorpStreamChunk>;\n private _abortController = new AbortController();\n private _accumulator: GorpStreamAccumulator;\n private _cancelled = false;\n\n get abortSignal() {\n return this._abortController.signal;\n }\n\n constructor(\n controller: ReadableStreamDefaultController<GorpStreamChunk>,\n defaultValue: ReadonlyJSONValue,\n ) {\n this._controller = controller;\n this._accumulator = new GorpStreamAccumulator(defaultValue);\n }\n\n enqueue(operations: readonly GorpStreamOperation[]) {\n if (this._cancelled) return;\n\n this._accumulator.append(operations);\n\n this._controller.enqueue({\n snapshot: this._accumulator.state,\n operations,\n });\n }\n\n __internalError(error: unknown) {\n if (this._cancelled) return;\n this._controller.error(error);\n }\n\n __internalClose() {\n if (this._cancelled) return;\n this._controller.close();\n }\n\n __internalCancel(reason?: unknown) {\n this._cancelled = true;\n this._abortController.abort(reason);\n }\n}\n\nconst getStreamControllerPair = (defaultValue: ReadonlyJSONValue) => {\n let controller!: GorpStreamControllerImpl;\n const stream = new ReadableStream<GorpStreamChunk>({\n start(c) {\n controller = new GorpStreamControllerImpl(c, defaultValue);\n },\n cancel(reason: unknown) {\n controller.__internalCancel(reason);\n },\n });\n\n return [stream, controller] as const;\n};\n\ntype CreateGorpStreamOptions = {\n execute: (controller: GorpStreamController) => void | PromiseLike<void>;\n defaultValue?: ReadonlyJSONValue;\n};\n\nexport const createGorpStream = ({\n execute,\n defaultValue = {},\n}: CreateGorpStreamOptions) => {\n const [stream, controller] = getStreamControllerPair(defaultValue);\n\n withPromiseOrValue(\n () => execute(controller),\n () => {\n controller.__internalClose();\n },\n (e: unknown) => {\n controller.__internalError(e);\n },\n );\n\n return stream;\n};\n"],"mappings":";;;AAWA,IAAM,2BAAN,MAA+D;CAC7D;CACA,mBAA2B,IAAI,gBAAgB;CAC/C;CACA,aAAqB;CAErB,IAAI,cAAc;EAChB,OAAO,KAAK,iBAAiB;CAC/B;CAEA,YACE,YACA,cACA;EACA,KAAK,cAAc;EACnB,KAAK,eAAe,IAAI,sBAAsB,YAAY;CAC5D;CAEA,QAAQ,YAA4C;EAClD,IAAI,KAAK,YAAY;EAErB,KAAK,aAAa,OAAO,UAAU;EAEnC,KAAK,YAAY,QAAQ;GACvB,UAAU,KAAK,aAAa;GAC5B;EACF,CAAC;CACH;CAEA,gBAAgB,OAAgB;EAC9B,IAAI,KAAK,YAAY;EACrB,KAAK,YAAY,MAAM,KAAK;CAC9B;CAEA,kBAAkB;EAChB,IAAI,KAAK,YAAY;EACrB,KAAK,YAAY,MAAM;CACzB;CAEA,iBAAiB,QAAkB;EACjC,KAAK,aAAa;EAClB,KAAK,iBAAiB,MAAM,MAAM;CACpC;AACF;AAEA,MAAM,2BAA2B,iBAAoC;CACnE,IAAI;CAUJ,OAAO,CAAC,IATW,eAAgC;EACjD,MAAM,GAAG;GACP,aAAa,IAAI,yBAAyB,GAAG,YAAY;EAC3D;EACA,OAAO,QAAiB;GACtB,WAAW,iBAAiB,MAAM;EACpC;CACF,CAEa,GAAG,UAAU;AAC5B;AAOA,MAAa,oBAAoB,EAC/B,SACA,eAAe,CAAC,QACa;CAC7B,MAAM,CAAC,QAAQ,cAAc,wBAAwB,YAAY;CAEjE,yBACQ,QAAQ,UAAU,SAClB;EACJ,WAAW,gBAAgB;CAC7B,IACC,MAAe;EACd,WAAW,gBAAgB,CAAC;CAC9B,CACF;CAEA,OAAO;AACT"}
@@ -0,0 +1,20 @@
1
+ import { ReadonlyJSONValue } from "../../utils/json/json-value.js";
2
+ import "../../utils.js";
3
+ //#region src/core/gorp/types.d.ts
4
+ type AssistantTransportStateOperation = {
5
+ readonly type: "set";
6
+ readonly path: readonly string[];
7
+ readonly value: ReadonlyJSONValue;
8
+ } | {
9
+ readonly type: "append-text";
10
+ readonly path: readonly string[];
11
+ readonly value: string;
12
+ };
13
+ type GorpStreamOperation = AssistantTransportStateOperation;
14
+ type GorpStreamChunk = {
15
+ readonly snapshot: ReadonlyJSONValue;
16
+ readonly operations: readonly GorpStreamOperation[];
17
+ };
18
+ //#endregion
19
+ export { AssistantTransportStateOperation, GorpStreamChunk, GorpStreamOperation };
20
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/core/gorp/types.ts"],"mappings":";;;KAEY;WAEG;WACA;WACA,OAAO;;WAGP;WACA;WACA;;KAGH,sBAAsB;KAEtB;WACD,UAAU;WACV,qBAAqB"}
@@ -5,7 +5,6 @@ import { ToolCallStreamController } from "./tool-call.js";
5
5
  import { DataPart, FilePart, SourcePart } from "../utils/types.js";
6
6
  import { AssistantStreamChunk } from "../AssistantStreamChunk.js";
7
7
  import { AssistantStream } from "../AssistantStream.js";
8
-
9
8
  //#region src/core/modules/assistant-stream.d.ts
10
9
  type ToolCallPartInit = {
11
10
  toolCallId?: string;
@@ -22,10 +21,15 @@ type ToolCallPartInit = {
22
21
  * parts with `addTextPart` and `addToolCallPart` when you need direct control.
23
22
  */
24
23
  type AssistantStreamController = {
25
- /** Appends text to the current text part, opening one if needed. */appendText(textDelta: string): void; /** Appends reasoning text to the current reasoning part, opening one if needed. */
26
- appendReasoning(reasoningDelta: string): void; /** Appends a source citation part to the stream. */
27
- appendSource(options: SourcePart): void; /** Appends a file part to the stream. */
28
- appendFile(options: FilePart): void; /** Appends a named data part to the stream. */
24
+ /** Appends text to the current text part, opening one if needed. */
25
+ appendText(textDelta: string): void;
26
+ /** Appends reasoning text to the current reasoning part, opening one if needed. */
27
+ appendReasoning(reasoningDelta: string): void;
28
+ /** Appends a source citation part to the stream. */
29
+ appendSource(options: SourcePart): void;
30
+ /** Appends a file part to the stream. */
31
+ appendFile(options: FilePart): void;
32
+ /** Appends a named data part to the stream. */
29
33
  appendData(options: DataPart): void;
30
34
  /**
31
35
  * Opens a text part and returns its writer.
@@ -48,7 +52,8 @@ type AssistantStreamController = {
48
52
  * Use this overload to provide a stable `toolCallId`, initial arguments,
49
53
  * streamed argument text, or an immediate {@link ToolResponseLike}.
50
54
  */
51
- addToolCallPart(options: ToolCallPartInit): ToolCallStreamController; /** Enqueues a raw protocol chunk. Prefer higher-level helpers when possible. */
55
+ addToolCallPart(options: ToolCallPartInit): ToolCallStreamController;
56
+ /** Enqueues a raw protocol chunk. Prefer higher-level helpers when possible. */
52
57
  enqueue(chunk: AssistantStreamChunk): void;
53
58
  /**
54
59
  * Merges another assistant stream into this stream.
@@ -56,7 +61,8 @@ type AssistantStreamController = {
56
61
  * Paths from the merged stream are remapped so its parts appear at the next
57
62
  * available position in this controller's output.
58
63
  */
59
- merge(stream: AssistantStream): void; /** Closes any active part and finishes the stream. */
64
+ merge(stream: AssistantStream): void;
65
+ /** Closes any active part and finishes the stream. */
60
66
  close(): void;
61
67
  /**
62
68
  * Returns a controller that writes child parts with `parentId` attached.
@@ -70,10 +76,11 @@ type AssistantStreamController = {
70
76
  * Creates an {@link AssistantStream} and writes to it with an
71
77
  * {@link AssistantStreamController}.
72
78
  *
73
- * The callback may write synchronously or asynchronously. If it throws, an
74
- * `error` chunk is emitted before the error is rethrown; when the callback
75
- * settles, the stream is closed automatically unless the controller was
76
- * already closed.
79
+ * The callback may write synchronously or asynchronously. If it throws while
80
+ * the stream is open, an `error` chunk is emitted. Failures after an explicit
81
+ * close are logged, while failures after consumer cancellation are discarded.
82
+ * When the callback settles, the stream is closed automatically unless the
83
+ * controller was already closed.
77
84
  */
78
85
  declare function createAssistantStream(callback: (controller: AssistantStreamController) => PromiseLike<void> | void): AssistantStream;
79
86
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-stream.d.ts","names":[],"sources":["../../../src/core/modules/assistant-stream.ts"],"mappings":";;;;;;;;;KAuBK,gBAAA;EACH,UAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA,GAAO,kBAAA;EACP,QAAA,GAAW,gBAAA,CAAiB,iBAAA;AAAA;;;;;;;;KAUlB,yBAAA;EAVV,oEAYA,UAAA,CAAW,SAAA,iBAZiB;EAc5B,eAAA,CAAgB,cAAA,iBAd6B;EAgB7C,YAAA,CAAa,OAAA,EAAS,UAAA,SANa;EAQnC,UAAA,CAAW,OAAA,EAAS,QAAA,SAFE;EAItB,UAAA,CAAW,OAAA,EAAS,QAAA;EAAA;;;;;;;EAQpB,WAAA,IAAe,oBAAA;EAgC0C;;;;;;EAzBzD,eAAA,CAAgB,OAAA,WAAkB,wBAAA;EAnBZ;;;;;;EA0BtB,eAAA,CAAgB,OAAA,EAAS,gBAAA,GAAmB,wBAAA,EAtBjC;EAwBX,OAAA,CAAQ,KAAA,EAAO,oBAAA;EAhBA;;;;;;EAuBf,KAAA,CAAM,MAAA,EAAQ,eAAA,SAT8B;EAW5C,KAAA;EATe;;;;;;EAgBf,YAAA,CAAa,QAAA,WAAmB,yBAAA;AAAA;;;AAAyB;AA2M3D;;;;;;iBAAgB,qBAAA,CACd,QAAA,GAAW,UAAA,EAAY,yBAAA,KAA8B,WAAA,gBACpD,eAAA;;;;;;;;iBAiCa,+BAAA,cAA+B,eAAA,EAAA,yBAAA;AAA/C;;;;AAA+C;AAsB/C;;AAtBA,iBAsBgB,6BAAA,CACd,QAAA,GAAW,UAAA,EAAY,yBAAA,KAA8B,WAAA,gBAAwB,QAAA"}
1
+ {"version":3,"file":"assistant-stream.d.ts","names":[],"sources":["../../../src/core/modules/assistant-stream.ts"],"mappings":";;;;;;;;KAuBK;EACH;EACA;EACA;EACA,OAAO;EACP,WAAW,iBAAiB;;;;;;;;;KAUlB;;EAEV,WAAW;;EAEX,gBAAgB;;EAEhB,aAAa,SAAS;;EAEtB,WAAW,SAAS;;EAEpB,WAAW,SAAS;;;;;;;;EAQpB,eAAe;;;;;;;EAOf,gBAAgB,kBAAkB;;;;;;;EAOlC,gBAAgB,SAAS,mBAAmB;;EAE5C,QAAQ,OAAO;;;;;;;EAOf,MAAM,QAAQ;;EAEd;;;;;;;EAOA,aAAa,mBAAmB;;;;;;;;;;;;iBAoNlB,sBACd,WAAW,YAAY,8BAA8B,2BACpD;;;;;;;;iBAkCa,6CAA+B,iBAAA;;;;;;;;iBAsB/B,8BACd,WAAW,YAAY,8BAA8B,2BAAwB"}
@@ -18,7 +18,10 @@ var AssistantStreamControllerImpl = class AssistantStreamControllerImpl {
18
18
  };
19
19
  }
20
20
  get __internal_isClosed() {
21
- return this._state.merger.isSealed();
21
+ return this._state.merger.isSealed() || this._state.merger.isCancelled() || this._state.merger.isErrored();
22
+ }
23
+ get __internal_isCancelled() {
24
+ return this._state.merger.isCancelled();
22
25
  }
23
26
  __internal_getReadable() {
24
27
  return this._state.merger.readable;
@@ -133,10 +136,11 @@ var AssistantStreamControllerImpl = class AssistantStreamControllerImpl {
133
136
  * Creates an {@link AssistantStream} and writes to it with an
134
137
  * {@link AssistantStreamController}.
135
138
  *
136
- * The callback may write synchronously or asynchronously. If it throws, an
137
- * `error` chunk is emitted before the error is rethrown; when the callback
138
- * settles, the stream is closed automatically unless the controller was
139
- * already closed.
139
+ * The callback may write synchronously or asynchronously. If it throws while
140
+ * the stream is open, an `error` chunk is emitted. Failures after an explicit
141
+ * close are logged, while failures after consumer cancellation are discarded.
142
+ * When the callback settles, the stream is closed automatically unless the
143
+ * controller was already closed.
140
144
  */
141
145
  function createAssistantStream(callback) {
142
146
  const controller = new AssistantStreamControllerImpl();
@@ -149,7 +153,7 @@ function createAssistantStream(callback) {
149
153
  path: [],
150
154
  error: String(e)
151
155
  });
152
- throw e;
156
+ else if (!controller.__internal_isCancelled) console.error(e);
153
157
  } finally {
154
158
  if (!controller.__internal_isClosed) controller.close();
155
159
  }