@dxos/assistant 0.8.2-staging.7ac8446 → 0.8.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 (277) hide show
  1. package/dist/lib/browser/index.mjs +1830 -228
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +1825 -229
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +1831 -228
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/{src/bin → bin}/chat.d.ts.map +1 -1
  11. package/dist/types/src/blueprint/blueprint.d.ts +79 -0
  12. package/dist/types/src/blueprint/blueprint.d.ts.map +1 -0
  13. package/dist/types/src/blueprint/blueprint.test.d.ts +2 -0
  14. package/dist/types/src/blueprint/blueprint.test.d.ts.map +1 -0
  15. package/dist/types/src/blueprint/index.d.ts +4 -0
  16. package/dist/types/src/blueprint/index.d.ts.map +1 -0
  17. package/dist/types/src/blueprint/logger.d.ts +3 -0
  18. package/dist/types/src/blueprint/logger.d.ts.map +1 -0
  19. package/dist/types/src/blueprint/machine.d.ts +113 -0
  20. package/dist/types/src/blueprint/machine.d.ts.map +1 -0
  21. package/dist/types/src/blueprint/test-data.d.ts +3 -0
  22. package/dist/types/src/blueprint/test-data.d.ts.map +1 -0
  23. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +4 -0
  24. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -0
  25. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +2 -0
  26. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +1 -0
  27. package/dist/types/src/extraction/extraction-llm-function/index.d.ts +2 -0
  28. package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +1 -0
  29. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +210 -0
  30. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -0
  31. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +2 -0
  32. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +1 -0
  33. package/dist/types/src/extraction/extraction-ner-function/index.d.ts +3 -0
  34. package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +1 -0
  35. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +14 -0
  36. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -0
  37. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.test.d.ts +2 -0
  38. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.test.d.ts.map +1 -0
  39. package/dist/types/src/extraction/extraction.d.ts +242 -0
  40. package/dist/types/src/extraction/extraction.d.ts.map +1 -0
  41. package/dist/types/src/extraction/index.d.ts +5 -0
  42. package/dist/types/src/extraction/index.d.ts.map +1 -0
  43. package/dist/types/src/extraction/quotes.d.ts +15 -0
  44. package/dist/types/src/extraction/quotes.d.ts.map +1 -0
  45. package/dist/types/src/extraction/quotes.test.d.ts +2 -0
  46. package/dist/types/src/extraction/quotes.test.d.ts.map +1 -0
  47. package/dist/types/src/index.d.ts +4 -3
  48. package/dist/types/src/index.d.ts.map +1 -1
  49. package/dist/types/src/research/exa.d.ts +7 -0
  50. package/dist/types/src/research/exa.d.ts.map +1 -0
  51. package/dist/types/src/research/graph.d.ts +39 -0
  52. package/dist/types/src/research/graph.d.ts.map +1 -0
  53. package/dist/types/src/research/graph.test.d.ts +2 -0
  54. package/dist/types/src/research/graph.test.d.ts.map +1 -0
  55. package/dist/types/src/research/index.d.ts +4 -0
  56. package/dist/types/src/research/index.d.ts.map +1 -0
  57. package/dist/types/src/research/research.d.ts +10 -0
  58. package/dist/types/src/research/research.d.ts.map +1 -0
  59. package/dist/types/src/research/research.test.d.ts +2 -0
  60. package/dist/types/src/research/research.test.d.ts.map +1 -0
  61. package/dist/types/src/session/index.d.ts +1 -0
  62. package/dist/types/src/session/index.d.ts.map +1 -1
  63. package/dist/types/src/session/session.d.ts +80 -35
  64. package/dist/types/src/session/session.d.ts.map +1 -1
  65. package/dist/types/src/session/version-pin.d.ts +21 -0
  66. package/dist/types/src/session/version-pin.d.ts.map +1 -0
  67. package/dist/types/src/session/version-pin.test.d.ts +2 -0
  68. package/dist/types/src/session/version-pin.test.d.ts.map +1 -0
  69. package/dist/types/src/summarization/summarization.test.d.ts +2 -0
  70. package/dist/types/src/summarization/summarization.test.d.ts.map +1 -0
  71. package/dist/types/src/testing/exa-search-1748337321991.d.ts +38 -0
  72. package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +1 -0
  73. package/dist/types/src/testing/exa-search-1748337331526.d.ts +37 -0
  74. package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +1 -0
  75. package/dist/types/src/testing/exa-search-1748337344119.d.ts +58 -0
  76. package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +1 -0
  77. package/dist/types/src/testing/index.d.ts +2 -6
  78. package/dist/types/src/testing/index.d.ts.map +1 -1
  79. package/dist/types/src/types.d.ts +3 -0
  80. package/dist/types/src/types.d.ts.map +1 -0
  81. package/dist/types/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +25 -35
  83. package/src/blueprint/blueprint.test.ts +142 -0
  84. package/src/blueprint/blueprint.ts +95 -0
  85. package/src/blueprint/index.ts +7 -0
  86. package/src/blueprint/logger.ts +66 -0
  87. package/src/blueprint/machine.ts +208 -0
  88. package/src/blueprint/test-data.ts +55 -0
  89. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +95 -0
  90. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +64 -0
  91. package/src/extraction/extraction-llm-function/index.ts +5 -0
  92. package/src/extraction/extraction-llm-function/instructions.tpl +28 -0
  93. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +115 -0
  94. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +54 -0
  95. package/src/extraction/extraction-ner-function/index.ts +6 -0
  96. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +94 -0
  97. package/src/extraction/extraction-ner-function/named-entity-recognition.ts +97 -0
  98. package/src/extraction/extraction.ts +75 -0
  99. package/src/extraction/index.ts +8 -0
  100. package/src/extraction/quotes.test.ts +27 -0
  101. package/src/extraction/quotes.ts +57 -0
  102. package/src/index.ts +4 -3
  103. package/src/research/exa.ts +100 -0
  104. package/src/research/graph.test.ts +15 -0
  105. package/src/research/graph.ts +291 -0
  106. package/src/research/index.ts +7 -0
  107. package/src/research/instructions-research.tpl +97 -0
  108. package/src/research/research.test.ts +189 -0
  109. package/src/research/research.ts +89 -0
  110. package/src/session/index.ts +1 -0
  111. package/src/session/session.test.ts +39 -67
  112. package/src/session/session.ts +328 -155
  113. package/src/session/version-pin.test.ts +26 -0
  114. package/src/session/version-pin.ts +48 -0
  115. package/src/summarization/summarization.test.ts +216 -0
  116. package/src/testing/exa-search-1748337321991.ts +131 -0
  117. package/src/testing/exa-search-1748337331526.ts +144 -0
  118. package/src/testing/exa-search-1748337344119.ts +133 -0
  119. package/src/testing/index.ts +8 -7
  120. package/src/typedefs.d.ts +8 -0
  121. package/src/types.ts +8 -0
  122. package/src/typings.d.ts +8 -0
  123. package/dist/lib/browser/chunk-PND5VR6D.mjs +0 -2315
  124. package/dist/lib/browser/chunk-PND5VR6D.mjs.map +0 -7
  125. package/dist/lib/browser/testing/index.mjs +0 -621
  126. package/dist/lib/browser/testing/index.mjs.map +0 -7
  127. package/dist/lib/node/chunk-IBOBRBDF.cjs +0 -2326
  128. package/dist/lib/node/chunk-IBOBRBDF.cjs.map +0 -7
  129. package/dist/lib/node/testing/index.cjs +0 -637
  130. package/dist/lib/node/testing/index.cjs.map +0 -7
  131. package/dist/lib/node-esm/chunk-DCQJOLSR.mjs +0 -2317
  132. package/dist/lib/node-esm/chunk-DCQJOLSR.mjs.map +0 -7
  133. package/dist/lib/node-esm/testing/index.mjs +0 -622
  134. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  135. package/dist/types/src/ai-service/client.test.d.ts +0 -2
  136. package/dist/types/src/ai-service/client.test.d.ts.map +0 -1
  137. package/dist/types/src/ai-service/defs.d.ts +0 -9
  138. package/dist/types/src/ai-service/defs.d.ts.map +0 -1
  139. package/dist/types/src/ai-service/edge-client.d.ts +0 -19
  140. package/dist/types/src/ai-service/edge-client.d.ts.map +0 -1
  141. package/dist/types/src/ai-service/index.d.ts +0 -10
  142. package/dist/types/src/ai-service/index.d.ts.map +0 -1
  143. package/dist/types/src/ai-service/message-collector.d.ts +0 -88
  144. package/dist/types/src/ai-service/message-collector.d.ts.map +0 -1
  145. package/dist/types/src/ai-service/ollama-client.d.ts +0 -39
  146. package/dist/types/src/ai-service/ollama-client.d.ts.map +0 -1
  147. package/dist/types/src/ai-service/parser.d.ts +0 -138
  148. package/dist/types/src/ai-service/parser.d.ts.map +0 -1
  149. package/dist/types/src/ai-service/service.d.ts +0 -9
  150. package/dist/types/src/ai-service/service.d.ts.map +0 -1
  151. package/dist/types/src/ai-service/stream.d.ts +0 -40
  152. package/dist/types/src/ai-service/stream.d.ts.map +0 -1
  153. package/dist/types/src/ai-service/stream.test.d.ts +0 -2
  154. package/dist/types/src/ai-service/stream.test.d.ts.map +0 -1
  155. package/dist/types/src/ai-service/testing/index.d.ts +0 -3
  156. package/dist/types/src/ai-service/testing/index.d.ts.map +0 -1
  157. package/dist/types/src/ai-service/testing/mock.d.ts +0 -7
  158. package/dist/types/src/ai-service/testing/mock.d.ts.map +0 -1
  159. package/dist/types/src/ai-service/testing/test-stream.d.ts +0 -7
  160. package/dist/types/src/ai-service/testing/test-stream.d.ts.map +0 -1
  161. package/dist/types/src/ai-service/transform.d.ts +0 -27
  162. package/dist/types/src/ai-service/transform.d.ts.map +0 -1
  163. package/dist/types/src/ai-service/types.d.ts +0 -167
  164. package/dist/types/src/ai-service/types.d.ts.map +0 -1
  165. package/dist/types/src/ai-service/util/index.d.ts +0 -2
  166. package/dist/types/src/ai-service/util/index.d.ts.map +0 -1
  167. package/dist/types/src/ai-service/util/sse.d.ts +0 -39
  168. package/dist/types/src/ai-service/util/sse.d.ts.map +0 -1
  169. package/dist/types/src/conversation/conversation.d.ts +0 -80
  170. package/dist/types/src/conversation/conversation.d.ts.map +0 -1
  171. package/dist/types/src/conversation/conversation.test.d.ts +0 -2
  172. package/dist/types/src/conversation/conversation.test.d.ts.map +0 -1
  173. package/dist/types/src/conversation/index.d.ts +0 -2
  174. package/dist/types/src/conversation/index.d.ts.map +0 -1
  175. package/dist/types/src/conversation/types.d.ts +0 -79
  176. package/dist/types/src/conversation/types.d.ts.map +0 -1
  177. package/dist/types/src/cypher/ast.d.ts +0 -56
  178. package/dist/types/src/cypher/ast.d.ts.map +0 -1
  179. package/dist/types/src/cypher/combinators.d.ts +0 -14
  180. package/dist/types/src/cypher/combinators.d.ts.map +0 -1
  181. package/dist/types/src/cypher/combinators.test.d.ts +0 -2
  182. package/dist/types/src/cypher/combinators.test.d.ts.map +0 -1
  183. package/dist/types/src/cypher/echo-data-source.d.ts +0 -16
  184. package/dist/types/src/cypher/echo-data-source.d.ts.map +0 -1
  185. package/dist/types/src/cypher/execution-plan.d.ts +0 -49
  186. package/dist/types/src/cypher/execution-plan.d.ts.map +0 -1
  187. package/dist/types/src/cypher/execution-plan.test.d.ts +0 -2
  188. package/dist/types/src/cypher/execution-plan.test.d.ts.map +0 -1
  189. package/dist/types/src/cypher/index.d.ts +0 -5
  190. package/dist/types/src/cypher/index.d.ts.map +0 -1
  191. package/dist/types/src/cypher/parjs.d.ts +0 -4
  192. package/dist/types/src/cypher/parjs.d.ts.map +0 -1
  193. package/dist/types/src/cypher/parser.d.ts +0 -6
  194. package/dist/types/src/cypher/parser.d.ts.map +0 -1
  195. package/dist/types/src/cypher/query-executor.d.ts +0 -26
  196. package/dist/types/src/cypher/query-executor.d.ts.map +0 -1
  197. package/dist/types/src/cypher/query-executor.test.d.ts +0 -2
  198. package/dist/types/src/cypher/query-executor.test.d.ts.map +0 -1
  199. package/dist/types/src/cypher/schema.d.ts +0 -12
  200. package/dist/types/src/cypher/schema.d.ts.map +0 -1
  201. package/dist/types/src/cypher/schema.test.d.ts +0 -2
  202. package/dist/types/src/cypher/schema.test.d.ts.map +0 -1
  203. package/dist/types/src/testing/artifacts.test.d.ts +0 -1
  204. package/dist/types/src/testing/artifacts.test.d.ts.map +0 -1
  205. package/dist/types/src/testing/data.d.ts +0 -2
  206. package/dist/types/src/testing/data.d.ts.map +0 -1
  207. package/dist/types/src/testing/defs.d.ts +0 -5
  208. package/dist/types/src/testing/defs.d.ts.map +0 -1
  209. package/dist/types/src/testing/logger.d.ts +0 -12
  210. package/dist/types/src/testing/logger.d.ts.map +0 -1
  211. package/dist/types/src/testing/object-extraction.test.d.ts +0 -1
  212. package/dist/types/src/testing/object-extraction.test.d.ts.map +0 -1
  213. package/dist/types/src/testing/ollama.d.ts +0 -6
  214. package/dist/types/src/testing/ollama.d.ts.map +0 -1
  215. package/dist/types/src/testing/query-promts.d.ts +0 -5
  216. package/dist/types/src/testing/query-promts.d.ts.map +0 -1
  217. package/dist/types/src/testing/query.test.d.ts +0 -2
  218. package/dist/types/src/testing/query.test.d.ts.map +0 -1
  219. package/dist/types/src/testing/test-data.d.ts +0 -29
  220. package/dist/types/src/testing/test-data.d.ts.map +0 -1
  221. package/dist/types/src/testing/test-schema.d.ts +0 -50
  222. package/dist/types/src/testing/test-schema.d.ts.map +0 -1
  223. package/dist/types/src/util/index.d.ts +0 -2
  224. package/dist/types/src/util/index.d.ts.map +0 -1
  225. package/dist/types/src/util/trim.d.ts +0 -5
  226. package/dist/types/src/util/trim.d.ts.map +0 -1
  227. package/src/ai-service/client.test.ts +0 -265
  228. package/src/ai-service/defs.ts +0 -39
  229. package/src/ai-service/edge-client.ts +0 -67
  230. package/src/ai-service/index.ts +0 -13
  231. package/src/ai-service/message-collector.ts +0 -84
  232. package/src/ai-service/ollama-client.ts +0 -499
  233. package/src/ai-service/parser.ts +0 -358
  234. package/src/ai-service/service.ts +0 -15
  235. package/src/ai-service/stream.test.ts +0 -125
  236. package/src/ai-service/stream.ts +0 -118
  237. package/src/ai-service/testing/index.ts +0 -6
  238. package/src/ai-service/testing/mock.ts +0 -22
  239. package/src/ai-service/testing/test-stream.ts +0 -93
  240. package/src/ai-service/transform.ts +0 -121
  241. package/src/ai-service/types.ts +0 -103
  242. package/src/ai-service/util/index.ts +0 -5
  243. package/src/ai-service/util/sse.ts +0 -341
  244. package/src/bin/chat.ts +0 -79
  245. package/src/conversation/conversation.test.ts +0 -73
  246. package/src/conversation/conversation.ts +0 -257
  247. package/src/conversation/index.ts +0 -5
  248. package/src/conversation/types.ts +0 -129
  249. package/src/cypher/ast.ts +0 -75
  250. package/src/cypher/combinators.test.ts +0 -137
  251. package/src/cypher/combinators.ts +0 -148
  252. package/src/cypher/echo-data-source.ts +0 -105
  253. package/src/cypher/execution-plan.test.ts +0 -44
  254. package/src/cypher/execution-plan.ts +0 -208
  255. package/src/cypher/index.ts +0 -8
  256. package/src/cypher/parjs-shims.d.ts +0 -10
  257. package/src/cypher/parjs.ts +0 -10
  258. package/src/cypher/parser.ts +0 -19
  259. package/src/cypher/query-executor.test.ts +0 -47
  260. package/src/cypher/query-executor.ts +0 -145
  261. package/src/cypher/schema.test.ts +0 -17
  262. package/src/cypher/schema.ts +0 -86
  263. package/src/testing/artifacts.test.ts +0 -182
  264. package/src/testing/data.ts +0 -13
  265. package/src/testing/defs.ts +0 -9
  266. package/src/testing/logger.ts +0 -129
  267. package/src/testing/object-extraction.test.ts +0 -71
  268. package/src/testing/ollama.ts +0 -15
  269. package/src/testing/query-promts.ts +0 -75
  270. package/src/testing/query.test.ts +0 -91
  271. package/src/testing/test-data.ts +0 -372
  272. package/src/testing/test-schema.ts +0 -80
  273. package/src/util/index.ts +0 -5
  274. package/src/util/trim.ts +0 -15
  275. package/vendor/parjs-browser.mjs +0 -4
  276. package/vendor/parjs-default.mjs +0 -8
  277. /package/dist/types/{src/bin → bin}/chat.d.ts +0 -0
@@ -1,2315 +0,0 @@
1
- // packages/experimental/assistant/src/ai-service/defs.ts
2
- var DEFAULT_EDGE_MODEL = "@anthropic/claude-3-5-sonnet-20241022";
3
- var DEFAULT_EDGE_MODELS = [
4
- // AI Gateway.
5
- // https://developers.cloudflare.com/ai-gateway
6
- "@anthropic/claude-3-5-haiku-20241022",
7
- "@anthropic/claude-3-5-sonnet-20241022",
8
- "@anthropic/claude-3-7-sonnet-20250219",
9
- // Workers AI.
10
- // https://developers.cloudflare.com/workers-ai/models
11
- "@cf/deepseek-ai/deepseek-r1-distill-qwen-32b",
12
- "@hf/nousresearch/hermes-2-pro-mistral-7b",
13
- "@ollama/llama-3-1-nemotron-70b-instruct",
14
- "@ollama/llama-3-1-nemotron-mini-4b-instruct",
15
- "@ollama/llama-3-2-3b"
16
- ];
17
- var DEFAULT_OLLAMA_ENDPOINT = "http://localhost:11434";
18
- var DEFAULT_OLLAMA_MODEL = "llama3.2:1b";
19
- var DEFAULT_OLLAMA_MODELS = [
20
- //
21
- "llama3.2:1b",
22
- "llama3:70b",
23
- "deepseek-r1:latest"
24
- ];
25
-
26
- // packages/experimental/assistant/src/ai-service/stream.ts
27
- import { Trigger } from "@dxos/async";
28
- import { log } from "@dxos/log";
29
-
30
- // packages/experimental/assistant/src/ai-service/util/sse.ts
31
- async function* iterSSEMessages(response, controller) {
32
- if (!response.body) {
33
- controller.abort();
34
- throw new Error("Attempted to iterate over a response with no body");
35
- }
36
- const sseDecoder = new SSEDecoder();
37
- const lineDecoder = new LineDecoder();
38
- const iter = readableStreamAsyncIterable(response.body);
39
- for await (const sseChunk of iterSSEChunks(iter)) {
40
- for (const line of lineDecoder.decode(sseChunk)) {
41
- const sse = sseDecoder.decode(line);
42
- if (sse) {
43
- yield sse;
44
- }
45
- }
46
- }
47
- for (const line of lineDecoder.flush()) {
48
- const sse = sseDecoder.decode(line);
49
- if (sse) {
50
- yield sse;
51
- }
52
- }
53
- }
54
- async function* iterSSEChunks(iterator) {
55
- let data = new Uint8Array();
56
- for await (const chunk of iterator) {
57
- if (chunk == null) {
58
- continue;
59
- }
60
- const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk;
61
- const newData = new Uint8Array(data.length + binaryChunk.length);
62
- newData.set(data);
63
- newData.set(binaryChunk, data.length);
64
- data = newData;
65
- let patternIndex;
66
- while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
67
- yield data.slice(0, patternIndex);
68
- data = data.slice(patternIndex);
69
- }
70
- }
71
- if (data.length > 0) {
72
- yield data;
73
- }
74
- }
75
- var findDoubleNewlineIndex = (buffer) => {
76
- const newline = 10;
77
- const carriage = 13;
78
- for (let i = 0; i < buffer.length - 2; i++) {
79
- if (buffer[i] === newline && buffer[i + 1] === newline) {
80
- return i + 2;
81
- }
82
- if (buffer[i] === carriage && buffer[i + 1] === carriage) {
83
- return i + 2;
84
- }
85
- if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) {
86
- return i + 4;
87
- }
88
- }
89
- return -1;
90
- };
91
- var SSEDecoder = class {
92
- constructor() {
93
- this.event = null;
94
- this.data = [];
95
- this.chunks = [];
96
- }
97
- decode(line) {
98
- if (line.endsWith("\r")) {
99
- line = line.substring(0, line.length - 1);
100
- }
101
- if (!line) {
102
- if (!this.event && !this.data.length) {
103
- return null;
104
- }
105
- const sse = {
106
- event: this.event,
107
- data: this.data.join("\n"),
108
- raw: this.chunks
109
- };
110
- this.event = null;
111
- this.data = [];
112
- this.chunks = [];
113
- return sse;
114
- }
115
- this.chunks.push(line);
116
- if (line.startsWith(":")) {
117
- return null;
118
- }
119
- let [fieldname, _, value] = partition(line, ":");
120
- if (value.startsWith(" ")) {
121
- value = value.substring(1);
122
- }
123
- if (fieldname === "event") {
124
- this.event = value;
125
- } else if (fieldname === "data") {
126
- this.data.push(value);
127
- }
128
- return null;
129
- }
130
- };
131
- var partition = (str, delimiter) => {
132
- const index = str.indexOf(delimiter);
133
- if (index !== -1) {
134
- return [
135
- str.substring(0, index),
136
- delimiter,
137
- str.substring(index + delimiter.length)
138
- ];
139
- }
140
- return [
141
- str,
142
- "",
143
- ""
144
- ];
145
- };
146
- function readableStreamAsyncIterable(stream) {
147
- if (stream[Symbol.asyncIterator]) {
148
- return stream;
149
- }
150
- const reader = stream.getReader();
151
- return {
152
- next: async () => {
153
- try {
154
- const result = await reader.read();
155
- if (result?.done) {
156
- reader.releaseLock();
157
- }
158
- return result;
159
- } catch (e) {
160
- reader.releaseLock();
161
- throw e;
162
- }
163
- },
164
- return: async () => {
165
- const cancelPromise = reader.cancel();
166
- reader.releaseLock();
167
- await cancelPromise;
168
- return {
169
- done: true,
170
- value: void 0
171
- };
172
- },
173
- [Symbol.asyncIterator]() {
174
- return this;
175
- }
176
- };
177
- }
178
- var LineDecoder = class _LineDecoder {
179
- static {
180
- // prettier-ignore
181
- this.NEWLINE_CHARS = /* @__PURE__ */ new Set([
182
- "\n",
183
- "\r"
184
- ]);
185
- }
186
- static {
187
- this.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
188
- }
189
- constructor() {
190
- this.buffer = [];
191
- this.trailingCR = false;
192
- }
193
- decode(chunk) {
194
- let text = this.decodeText(chunk);
195
- if (this.trailingCR) {
196
- text = "\r" + text;
197
- this.trailingCR = false;
198
- }
199
- if (text.endsWith("\r")) {
200
- this.trailingCR = true;
201
- text = text.slice(0, -1);
202
- }
203
- if (!text) {
204
- return [];
205
- }
206
- const trailingNewline = _LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || "");
207
- let lines = text.split(_LineDecoder.NEWLINE_REGEXP);
208
- if (trailingNewline) {
209
- lines.pop();
210
- }
211
- if (lines.length === 1 && !trailingNewline) {
212
- this.buffer.push(lines[0]);
213
- return [];
214
- }
215
- if (this.buffer.length > 0) {
216
- lines = [
217
- this.buffer.join("") + lines[0],
218
- ...lines.slice(1)
219
- ];
220
- this.buffer = [];
221
- }
222
- if (!trailingNewline) {
223
- this.buffer = [
224
- lines.pop() || ""
225
- ];
226
- }
227
- return lines;
228
- }
229
- decodeText(bytes) {
230
- if (bytes == null) {
231
- return "";
232
- }
233
- if (typeof bytes === "string") {
234
- return bytes;
235
- }
236
- if (typeof Buffer !== "undefined") {
237
- if (bytes instanceof Buffer) {
238
- return bytes.toString();
239
- }
240
- if (bytes instanceof Uint8Array) {
241
- return Buffer.from(bytes).toString();
242
- }
243
- throw new Error(`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`);
244
- }
245
- if (typeof TextDecoder !== "undefined") {
246
- if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
247
- this.textDecoder ??= new TextDecoder("utf8");
248
- return this.textDecoder.decode(bytes);
249
- }
250
- throw new Error(`Unexpected: received non-Uint8Array/ArrayBuffer (${bytes.constructor.name}) in a web platform. Please report this error.`);
251
- }
252
- throw new Error("Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.");
253
- }
254
- flush() {
255
- if (!this.buffer.length && !this.trailingCR) {
256
- return [];
257
- }
258
- const lines = [
259
- this.buffer.join("")
260
- ];
261
- this.buffer = [];
262
- this.trailingCR = false;
263
- return lines;
264
- }
265
- };
266
-
267
- // packages/experimental/assistant/src/ai-service/stream.ts
268
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/stream.ts";
269
- var createGenerationStream = (response, controller = new AbortController()) => {
270
- const iterator = async function* () {
271
- for await (const sse of iterSSEMessages(response, controller)) {
272
- if (sse.event === "completion") {
273
- try {
274
- yield JSON.parse(sse.data);
275
- } catch (err) {
276
- log.error("could not parse message into JSON:", {
277
- data: sse.data,
278
- raw: sse.raw
279
- }, {
280
- F: __dxlog_file,
281
- L: 22,
282
- S: this,
283
- C: (f, a) => f(...a)
284
- });
285
- throw err;
286
- }
287
- }
288
- if (sse.event === "message_start" || sse.event === "message_delta" || sse.event === "message_stop" || sse.event === "content_block_start" || sse.event === "content_block_delta" || sse.event === "content_block_stop") {
289
- try {
290
- yield JSON.parse(sse.data);
291
- } catch (err) {
292
- log.error("could not parse message into JSON:", {
293
- data: sse.data,
294
- raw: sse.raw
295
- }, {
296
- F: __dxlog_file,
297
- L: 38,
298
- S: this,
299
- C: (f, a) => f(...a)
300
- });
301
- throw err;
302
- }
303
- }
304
- if (sse.event === "ping") {
305
- continue;
306
- }
307
- if (sse.event === "error") {
308
- throw new Error(`Message generation error: ${sse.data}`);
309
- }
310
- }
311
- };
312
- return new GenerationStreamImpl(controller, iterator);
313
- };
314
- var GenerationStreamImpl = class {
315
- constructor(_controller, _getIterator) {
316
- this._controller = _controller;
317
- this._getIterator = _getIterator;
318
- this._done = new Trigger();
319
- this._iterator = void 0;
320
- }
321
- /**
322
- * Returns an iterator over the stream.
323
- */
324
- [Symbol.asyncIterator]() {
325
- return this._createIterator();
326
- }
327
- /**
328
- * Aborts the stream.
329
- */
330
- abort() {
331
- this._controller.abort();
332
- }
333
- /**
334
- * Returns the complete message list generated by the AI service.
335
- */
336
- async complete() {
337
- await this._done.wait();
338
- }
339
- /**
340
- * Creates an iterator over the stream.
341
- */
342
- _createIterator() {
343
- const self = this;
344
- return this._iterator ??= (() => {
345
- const generator = async function* () {
346
- try {
347
- for await (const event of self._getIterator()) {
348
- yield event;
349
- }
350
- this._done.wake();
351
- } catch (err) {
352
- this._done.throw(err);
353
- throw err;
354
- }
355
- };
356
- return generator.call(this);
357
- })();
358
- }
359
- };
360
-
361
- // packages/experimental/assistant/src/ai-service/edge-client.ts
362
- import { Schema as S } from "effect";
363
- import { Message } from "@dxos/artifact";
364
- import { assertArgument, invariant } from "@dxos/invariant";
365
- import { log as log2 } from "@dxos/log";
366
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/edge-client.ts";
367
- var AIServiceEdgeClient = class {
368
- constructor({ endpoint }) {
369
- invariant(endpoint, "endpoint is required", {
370
- F: __dxlog_file2,
371
- L: 23,
372
- S: this,
373
- A: [
374
- "endpoint",
375
- "'endpoint is required'"
376
- ]
377
- });
378
- this._endpoint = endpoint;
379
- }
380
- /**
381
- * @deprecated
382
- */
383
- // TODO(burdon): Remove.
384
- async appendMessages(messages) {
385
- const url = `${this._endpoint}/message`;
386
- const res = await fetch(url, {
387
- method: "POST",
388
- headers: {
389
- "Content-Type": "application/json"
390
- },
391
- body: JSON.stringify({
392
- messages: await S.encodePromise(S.Array(Message))(messages)
393
- })
394
- });
395
- if (!res.ok) {
396
- throw new Error(`${await res.text()} [${url}]`);
397
- }
398
- }
399
- /**
400
- * Process request and open message stream.
401
- */
402
- async exec(request) {
403
- assertArgument(typeof request.model === "string", "model is required");
404
- log2("requesting", {
405
- endpoint: this._endpoint
406
- }, {
407
- F: __dxlog_file2,
408
- L: 51,
409
- S: this,
410
- C: (f, a) => f(...a)
411
- });
412
- const controller = new AbortController();
413
- const response = await fetch(`${this._endpoint}/generate`, {
414
- signal: controller.signal,
415
- method: "POST",
416
- headers: {
417
- "Content-Type": "application/json"
418
- },
419
- body: JSON.stringify({
420
- // TODO(dmaretskyi): Errors if tools are not provided.
421
- tools: request.tools ?? [],
422
- ...request
423
- })
424
- });
425
- invariant(response.body instanceof ReadableStream, void 0, {
426
- F: __dxlog_file2,
427
- L: 64,
428
- S: this,
429
- A: [
430
- "response.body instanceof ReadableStream",
431
- ""
432
- ]
433
- });
434
- return createGenerationStream(response, controller);
435
- }
436
- };
437
-
438
- // packages/experimental/assistant/src/ai-service/message-collector.ts
439
- var MessageCollector = class {
440
- constructor() {
441
- this._messages = [];
442
- this._pendingMessage = void 0;
443
- }
444
- get messages() {
445
- return this._messages;
446
- }
447
- get pendingMessage() {
448
- return this._pendingMessage;
449
- }
450
- push(event) {
451
- switch (event.type) {
452
- case "message_start":
453
- this._pendingMessage = event.message;
454
- break;
455
- case "message_stop":
456
- if (this._pendingMessage) {
457
- this._messages.push(this._pendingMessage);
458
- this._pendingMessage = void 0;
459
- }
460
- break;
461
- case "content_block_start":
462
- if (this._pendingMessage) {
463
- this._pendingMessage.content = this._pendingMessage.content || [];
464
- this._pendingMessage.content[event.index] = event.content;
465
- }
466
- break;
467
- case "content_block_delta":
468
- if (this._pendingMessage && this._pendingMessage.content) {
469
- const block = this._pendingMessage.content[event.index];
470
- if (block && event.delta.type === "text_delta" && block.type === "text") {
471
- block.text = (block.text || "") + event.delta.text;
472
- }
473
- }
474
- break;
475
- case "content_block_stop":
476
- if (this._pendingMessage && this._pendingMessage.content) {
477
- const block = this._pendingMessage.content[event.index];
478
- if (block) {
479
- block.pending = false;
480
- }
481
- }
482
- break;
483
- case "message_delta":
484
- if (this._pendingMessage && event.delta) {
485
- Object.assign(this._pendingMessage, event.delta);
486
- }
487
- break;
488
- }
489
- }
490
- pushMessage(message) {
491
- this._messages.push(message);
492
- }
493
- };
494
- function* emitMessageAsEvents(message) {
495
- yield {
496
- type: "message_start",
497
- message
498
- };
499
- yield {
500
- type: "message_stop"
501
- };
502
- }
503
-
504
- // packages/experimental/assistant/src/ai-service/types.ts
505
- import { Schema as S2 } from "effect";
506
- import { Tool, Message as Message2, SpaceIdSchema } from "@dxos/artifact";
507
- import { ObjectId } from "@dxos/echo-schema";
508
- var createArtifactElement = (id) => `<artifact id=${id} />`;
509
- var LLMModel = S2.Literal(...DEFAULT_EDGE_MODELS, ...DEFAULT_OLLAMA_MODELS);
510
- var ToolTypes = Object.freeze({
511
- // TODO(dmaretskyi): Not implemented yet.
512
- // DatabaseQuery: 'database_query',
513
- TextToImage: "text_to_image"
514
- });
515
- var GenerateRequest = S2.Struct({
516
- spaceId: S2.optional(SpaceIdSchema),
517
- threadId: S2.optional(ObjectId),
518
- /**
519
- * Preferred model or system default.
520
- */
521
- model: S2.optional(LLMModel),
522
- /**
523
- * Tools available for the LLM.
524
- */
525
- tools: S2.optional(S2.Array(Tool).pipe(S2.mutable)),
526
- /**
527
- * System instructions to the LLM.
528
- */
529
- systemPrompt: S2.optional(S2.String),
530
- /**
531
- * History of messages to include in the context window.
532
- */
533
- // TODO(burdon): Rename messages.
534
- history: S2.optional(S2.Array(Message2)),
535
- /**
536
- * Current request.
537
- */
538
- prompt: S2.optional(Message2)
539
- });
540
-
541
- // packages/experimental/assistant/src/conversation/conversation.ts
542
- import { ToolResult, Message as Message3 } from "@dxos/artifact";
543
- import { createStatic, ObjectId as ObjectId2 } from "@dxos/echo-schema";
544
- import { invariant as invariant2 } from "@dxos/invariant";
545
- import { log as log3 } from "@dxos/log";
546
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/conversation/conversation.ts";
547
- var runLLM = async (params) => {
548
- let conversationResult = null;
549
- const history = params.history ?? [];
550
- const generate = async () => {
551
- log3("llm generate", {
552
- tools: params.tools
553
- }, {
554
- F: __dxlog_file3,
555
- L: 44,
556
- S: void 0,
557
- C: (f, a) => f(...a)
558
- });
559
- const beginTs = Date.now();
560
- const stream = await params.client.exec({
561
- model: params.model,
562
- spaceId: params.spaceId,
563
- threadId: params.threadId,
564
- history,
565
- systemPrompt: params.system,
566
- tools: params.tools
567
- });
568
- for await (const event of stream) {
569
- params.logger?.(event);
570
- }
571
- await stream.complete();
572
- const messages = [];
573
- const message = messages.at(-1);
574
- invariant2(message, void 0, {
575
- F: __dxlog_file3,
576
- L: 63,
577
- S: void 0,
578
- A: [
579
- "message",
580
- ""
581
- ]
582
- });
583
- log3("llm result", {
584
- time: Date.now() - beginTs,
585
- message
586
- }, {
587
- F: __dxlog_file3,
588
- L: 65,
589
- S: void 0,
590
- C: (f, a) => f(...a)
591
- });
592
- invariant2(message, void 0, {
593
- F: __dxlog_file3,
594
- L: 66,
595
- S: void 0,
596
- A: [
597
- "message",
598
- ""
599
- ]
600
- });
601
- params.logger?.({
602
- type: "message",
603
- message
604
- });
605
- history.push(...messages.map((message2) => ({
606
- ...message2,
607
- content: message2.content.filter((block) => block.type !== "image")
608
- })));
609
- const isToolUse2 = message.content.at(-1)?.type === "tool_use";
610
- if (isToolUse2) {
611
- const toolCalls = message.content.filter((block) => block.type === "tool_use");
612
- invariant2(toolCalls.length === 1, void 0, {
613
- F: __dxlog_file3,
614
- L: 77,
615
- S: void 0,
616
- A: [
617
- "toolCalls.length === 1",
618
- ""
619
- ]
620
- });
621
- const toolCall = toolCalls[0];
622
- const tool = params.tools.find((tool2) => tool2.name === toolCall.name);
623
- if (!tool) {
624
- throw new Error(`Tool not found: ${toolCall.name}`);
625
- }
626
- invariant2(tool.execute, void 0, {
627
- F: __dxlog_file3,
628
- L: 84,
629
- S: void 0,
630
- A: [
631
- "tool.execute",
632
- ""
633
- ]
634
- });
635
- const toolResult = await tool.execute(toolCall.input);
636
- switch (toolResult.kind) {
637
- case "error": {
638
- log3.warn("tool error", {
639
- message: toolResult.message
640
- }, {
641
- F: __dxlog_file3,
642
- L: 88,
643
- S: void 0,
644
- C: (f, a) => f(...a)
645
- });
646
- const resultMessage = {
647
- id: ObjectId2.random(),
648
- spaceId: params.spaceId,
649
- threadId: params.threadId,
650
- role: "user",
651
- content: [
652
- {
653
- type: "tool_result",
654
- toolUseId: toolCall.id,
655
- content: toolResult.message,
656
- isError: true
657
- }
658
- ]
659
- };
660
- params.logger?.({
661
- type: "message",
662
- message: resultMessage
663
- });
664
- history.push(resultMessage);
665
- return true;
666
- }
667
- case "success": {
668
- log3("tool success", {
669
- result: toolResult.result
670
- }, {
671
- F: __dxlog_file3,
672
- L: 110,
673
- S: void 0,
674
- C: (f, a) => f(...a)
675
- });
676
- const resultMessage = {
677
- id: ObjectId2.random(),
678
- spaceId: params.spaceId,
679
- threadId: params.threadId,
680
- role: "user",
681
- content: [
682
- {
683
- type: "tool_result",
684
- toolUseId: toolCall.id,
685
- content: JSON.stringify(toolResult.result)
686
- }
687
- ]
688
- };
689
- params.logger?.({
690
- type: "message",
691
- message: resultMessage
692
- });
693
- history.push(resultMessage);
694
- return true;
695
- }
696
- case "break": {
697
- log3("tool break", {
698
- result: toolResult.result
699
- }, {
700
- F: __dxlog_file3,
701
- L: 131,
702
- S: void 0,
703
- C: (f, a) => f(...a)
704
- });
705
- conversationResult = toolResult.result;
706
- return false;
707
- }
708
- }
709
- }
710
- return false;
711
- };
712
- while (await generate()) {
713
- }
714
- return {
715
- result: conversationResult,
716
- history
717
- };
718
- };
719
- var isToolUse = (message, { onlyToolNames } = {}) => {
720
- const block = message.content.at(-1);
721
- invariant2(block, void 0, {
722
- F: __dxlog_file3,
723
- L: 152,
724
- S: void 0,
725
- A: [
726
- "block",
727
- ""
728
- ]
729
- });
730
- return block.type === "tool_use" && (!onlyToolNames || onlyToolNames.includes(block.name));
731
- };
732
- var runTools = async ({ message, tools, extensions }) => {
733
- const toolCalls = message.content.filter((block) => block.type === "tool_use");
734
- invariant2(toolCalls.length === 1, void 0, {
735
- F: __dxlog_file3,
736
- L: 174,
737
- S: void 0,
738
- A: [
739
- "toolCalls.length === 1",
740
- ""
741
- ]
742
- });
743
- const toolCall = toolCalls[0];
744
- const tool = tools.find((tool2) => tool2.name === toolCall.name);
745
- if (!tool) {
746
- const resultMessage = createStatic(Message3, {
747
- role: "user",
748
- content: [
749
- {
750
- type: "tool_result",
751
- toolUseId: toolCall.id,
752
- content: `Tool not found: ${toolCall.name}`,
753
- isError: true
754
- }
755
- ]
756
- });
757
- return {
758
- type: "continue",
759
- message: resultMessage
760
- };
761
- }
762
- let toolResult;
763
- try {
764
- invariant2(tool.execute, void 0, {
765
- F: __dxlog_file3,
766
- L: 199,
767
- S: void 0,
768
- A: [
769
- "tool.execute",
770
- ""
771
- ]
772
- });
773
- toolResult = await tool.execute(toolCall.input, {
774
- extensions
775
- });
776
- } catch (error) {
777
- log3("tool error", {
778
- error
779
- }, {
780
- F: __dxlog_file3,
781
- L: 202,
782
- S: void 0,
783
- C: (f, a) => f(...a)
784
- });
785
- toolResult = ToolResult.Error(error.message);
786
- }
787
- switch (toolResult.kind) {
788
- case "error": {
789
- log3("tool error", {
790
- message: toolResult.message
791
- }, {
792
- F: __dxlog_file3,
793
- L: 208,
794
- S: void 0,
795
- C: (f, a) => f(...a)
796
- });
797
- const resultMessage = createStatic(Message3, {
798
- role: "user",
799
- content: [
800
- {
801
- type: "tool_result",
802
- toolUseId: toolCall.id,
803
- content: toolResult.message,
804
- isError: true
805
- }
806
- ]
807
- });
808
- return {
809
- type: "continue",
810
- message: resultMessage
811
- };
812
- }
813
- case "success": {
814
- log3("tool success", {
815
- result: toolResult.result
816
- }, {
817
- F: __dxlog_file3,
818
- L: 229,
819
- S: void 0,
820
- C: (f, a) => f(...a)
821
- });
822
- const resultMessage = createStatic(Message3, {
823
- role: "user",
824
- content: [
825
- {
826
- type: "tool_result",
827
- toolUseId: toolCall.id,
828
- content: typeof toolResult.result === "string" ? toolResult.result : JSON.stringify(toolResult.result) ?? ""
829
- },
830
- ...toolResult.extractContentBlocks ?? []
831
- ]
832
- });
833
- return {
834
- type: "continue",
835
- message: resultMessage
836
- };
837
- }
838
- case "break": {
839
- log3("tool break", {
840
- result: toolResult.result
841
- }, {
842
- F: __dxlog_file3,
843
- L: 250,
844
- S: void 0,
845
- C: (f, a) => f(...a)
846
- });
847
- return {
848
- type: "break",
849
- result: toolResult.result
850
- };
851
- }
852
- }
853
- };
854
-
855
- // packages/experimental/assistant/src/ai-service/ollama-client.ts
856
- import { Schema as S3 } from "effect";
857
- import { defineTool, ToolResult as ToolResult2 } from "@dxos/artifact";
858
- import { ObjectId as ObjectId3 } from "@dxos/echo-schema";
859
- import { invariant as invariant3 } from "@dxos/invariant";
860
- import { log as log4 } from "@dxos/log";
861
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/ollama-client.ts";
862
- var OllamaClient = class {
863
- /**
864
- * Check if Ollama server is running and accessible.
865
- * @returns Promise that resolves to true if Ollama is running, false otherwise.
866
- */
867
- static async isRunning() {
868
- try {
869
- const response = await fetch(`${DEFAULT_OLLAMA_ENDPOINT}/api/version`, {
870
- method: "GET",
871
- headers: {
872
- "Content-Type": "application/json"
873
- },
874
- signal: AbortSignal.timeout(100)
875
- });
876
- return response.ok;
877
- } catch (error) {
878
- return false;
879
- }
880
- }
881
- constructor({ endpoint, tools, overrides, maxToolInvocations } = {}) {
882
- this._endpoint = endpoint ?? DEFAULT_OLLAMA_ENDPOINT;
883
- this._tools = tools ?? [];
884
- this._modelOverride = overrides?.model;
885
- this._temperatureOverride = overrides?.temperature;
886
- this._maxToolInvocations = maxToolInvocations ?? 3;
887
- }
888
- _getEmbededTools(clientTools) {
889
- return [
890
- ...this._tools,
891
- ...clientTools.filter((tool) => tool.type !== void 0 && WELL_KNOWN_TOOLS[tool.type]).map((tool) => WELL_KNOWN_TOOLS[tool.type])
892
- ];
893
- }
894
- async *_generateStream(request, signal) {
895
- invariant3(request.prompt === void 0, "Prompt must be in history", {
896
- F: __dxlog_file4,
897
- L: 88,
898
- S: this,
899
- A: [
900
- "request.prompt === undefined",
901
- "'Prompt must be in history'"
902
- ]
903
- });
904
- const ollamaRequest = {
905
- model: this._modelOverride ?? request.model ?? "llama3",
906
- messages: [],
907
- stream: true,
908
- options: {
909
- temperature: this._temperatureOverride
910
- }
911
- };
912
- if (request.systemPrompt) {
913
- ollamaRequest.messages.push({
914
- role: "system",
915
- content: request.systemPrompt
916
- });
917
- }
918
- if (request.history?.length) {
919
- for (const message of request.history) {
920
- const role = message.role === "assistant" ? "assistant" : "user";
921
- if (message.content.length === 0) {
922
- continue;
923
- }
924
- for (const content of message.content) {
925
- switch (content.type) {
926
- case "text": {
927
- ollamaRequest.messages.push({
928
- role,
929
- content: content.text
930
- });
931
- break;
932
- }
933
- case "tool_use": {
934
- ollamaRequest.messages.push({
935
- role: "assistant",
936
- content: "",
937
- tool_calls: [
938
- {
939
- function: {
940
- name: content.name,
941
- arguments: content.input
942
- }
943
- }
944
- ]
945
- });
946
- break;
947
- }
948
- case "tool_result": {
949
- ollamaRequest.messages.push({
950
- role: "tool",
951
- content: JSON.stringify({
952
- type: "tool_result",
953
- toolUseId: content.toolUseId,
954
- content: content.content
955
- })
956
- });
957
- break;
958
- }
959
- }
960
- }
961
- }
962
- }
963
- if (request.tools?.length || this._tools.length) {
964
- const allTools = [
965
- ...request.tools ?? [],
966
- ...this._tools
967
- ];
968
- const withWellKnownTools = allTools.map((tool) => tool.type !== void 0 && WELL_KNOWN_TOOLS[tool.type] ? WELL_KNOWN_TOOLS[tool.type] : tool);
969
- if (withWellKnownTools.length > 0) {
970
- ollamaRequest.tools = withWellKnownTools.map((tool) => ({
971
- type: "function",
972
- function: {
973
- name: tool.name,
974
- description: tool.description,
975
- parameters: {
976
- type: "object",
977
- properties: tool.parameters?.properties,
978
- required: tool.parameters?.required
979
- }
980
- }
981
- }));
982
- }
983
- }
984
- log4("generate request", {
985
- history: request.history,
986
- prompt: request.prompt,
987
- ollamaRequest
988
- }, {
989
- F: __dxlog_file4,
990
- L: 182,
991
- S: this,
992
- C: (f, a) => f(...a)
993
- });
994
- const response = await fetch(`${this._endpoint}/api/chat`, {
995
- method: "POST",
996
- headers: {
997
- "Content-Type": "application/json"
998
- },
999
- body: JSON.stringify(ollamaRequest),
1000
- signal
1001
- });
1002
- if (!response.ok) {
1003
- throw await parseErrorResponse(response);
1004
- }
1005
- if (!response.body) {
1006
- throw new Error("Ollama API returned no response body");
1007
- }
1008
- const reader = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new OllamaDecoderStream()).getReader();
1009
- try {
1010
- const messageId = ObjectId3.random();
1011
- yield {
1012
- type: "message_start",
1013
- message: {
1014
- id: messageId,
1015
- role: "assistant",
1016
- content: []
1017
- }
1018
- };
1019
- const textBlock = {
1020
- type: "text",
1021
- text: ""
1022
- };
1023
- let currentBlockIndex = 0;
1024
- yield {
1025
- type: "content_block_start",
1026
- index: currentBlockIndex,
1027
- content: textBlock
1028
- };
1029
- while (true) {
1030
- const { done, value: data } = await reader.read();
1031
- if (done) {
1032
- break;
1033
- }
1034
- log4("ollama data", {
1035
- data
1036
- }, {
1037
- F: __dxlog_file4,
1038
- L: 244,
1039
- S: this,
1040
- C: (f, a) => f(...a)
1041
- });
1042
- if (data.message?.content) {
1043
- yield {
1044
- type: "content_block_delta",
1045
- index: 0,
1046
- delta: {
1047
- type: "text_delta",
1048
- text: data.message.content
1049
- }
1050
- };
1051
- }
1052
- if (data.message?.tool_calls && data.message?.tool_calls?.length > 0) {
1053
- if (data.message.tool_calls.length > 1) {
1054
- log4.warn("Ollama returned multiple tool calls. Only the first one will be used.", void 0, {
1055
- F: __dxlog_file4,
1056
- L: 261,
1057
- S: this,
1058
- C: (f, a) => f(...a)
1059
- });
1060
- }
1061
- yield {
1062
- type: "content_block_stop",
1063
- index: currentBlockIndex++
1064
- };
1065
- yield {
1066
- type: "content_block_start",
1067
- index: currentBlockIndex,
1068
- content: {
1069
- type: "tool_use",
1070
- id: ObjectId3.random(),
1071
- name: data.message.tool_calls[0].function.name,
1072
- input: sanitizeToolArguments(data.message.tool_calls[0].function.arguments)
1073
- }
1074
- };
1075
- yield {
1076
- type: "message_delta",
1077
- delta: {
1078
- stopReason: "tool_use"
1079
- }
1080
- };
1081
- }
1082
- }
1083
- yield {
1084
- type: "content_block_stop",
1085
- index: currentBlockIndex
1086
- };
1087
- yield {
1088
- type: "message_stop"
1089
- };
1090
- } finally {
1091
- reader.releaseLock();
1092
- }
1093
- }
1094
- async exec(request) {
1095
- const controller = new AbortController();
1096
- try {
1097
- return new GenerationStreamImpl(controller, async function* () {
1098
- const collector = new MessageCollector();
1099
- let toolInvocations = 0;
1100
- while (true) {
1101
- for await (const event of this._generateStream({
1102
- ...request,
1103
- history: [
1104
- ...request.history ?? [],
1105
- ...request.prompt ? [
1106
- request.prompt
1107
- ] : [],
1108
- ...collector.messages
1109
- ],
1110
- prompt: void 0
1111
- }, controller.signal)) {
1112
- collector.push(event);
1113
- yield event;
1114
- }
1115
- if (collector.messages.length > 0 && !isToolUse(collector.messages.at(-1), {
1116
- onlyToolNames: this._getEmbededTools(request.tools ?? []).map((tool) => tool.name)
1117
- })) {
1118
- break;
1119
- }
1120
- if (++toolInvocations > this._maxToolInvocations) {
1121
- throw new Error("Maximum number of tool invocations reached");
1122
- }
1123
- const result = await runTools({
1124
- message: collector.messages.at(-1),
1125
- tools: this._getEmbededTools(request.tools ?? [])
1126
- });
1127
- switch (result.type) {
1128
- case "continue": {
1129
- collector.pushMessage(result.message);
1130
- yield* emitMessageAsEvents(result.message);
1131
- break;
1132
- }
1133
- case "break": {
1134
- throw new Error("Tool use breaks not allowed");
1135
- }
1136
- }
1137
- }
1138
- }.bind(this));
1139
- } catch (error) {
1140
- controller.abort();
1141
- throw error;
1142
- }
1143
- }
1144
- };
1145
- var sanitizeToolArguments = (args) => {
1146
- if (args.type === "object" && typeof args.properties === "object" && Array.isArray(args.required)) {
1147
- return args.properties;
1148
- }
1149
- return args;
1150
- };
1151
- var SAMPLE_IMAGE_URL = "https://images.nightcafe.studio/jobs/BNmcRhHCM1JRKoUtqSei/BNmcRhHCM1JRKoUtqSei--1--5b9rv.jpg";
1152
- var WELL_KNOWN_TOOLS = {
1153
- [ToolTypes.TextToImage]: defineTool("system", {
1154
- name: "text-to-image",
1155
- description: "Generate an image from a text prompt",
1156
- schema: S3.Struct({
1157
- prompt: S3.String.annotations({
1158
- description: "The text prompt describing the image to generate"
1159
- })
1160
- }),
1161
- execute: async ({ prompt }) => {
1162
- const image = await fetch(SAMPLE_IMAGE_URL).then(async (res) => Buffer.from(await res.arrayBuffer()));
1163
- const imageBase64 = image.toString("base64");
1164
- const id = ObjectId3.random();
1165
- return ToolResult2.Success(`The generation was successful. Image ID: ${id} Prompt: ${prompt}`, [
1166
- {
1167
- type: "image",
1168
- id,
1169
- source: {
1170
- type: "base64",
1171
- mediaType: "image/jpeg",
1172
- data: imageBase64
1173
- }
1174
- }
1175
- ]);
1176
- }
1177
- })
1178
- };
1179
- var OllamaDecoderStream = class extends TransformStream {
1180
- constructor() {
1181
- super({
1182
- transform: (chunk, controller) => {
1183
- this._buffer += chunk;
1184
- const lines = this._buffer.split("\n");
1185
- this._buffer = lines.pop() || "";
1186
- for (const line of lines) {
1187
- controller.enqueue(JSON.parse(line.trim()));
1188
- }
1189
- },
1190
- flush: (controller) => {
1191
- this._buffer = this._buffer.trim();
1192
- if (this._buffer.length > 0) {
1193
- controller.enqueue(JSON.parse(this._buffer));
1194
- }
1195
- }
1196
- });
1197
- this._buffer = "";
1198
- }
1199
- };
1200
- var ModelDoesNotSupportToolsError = class extends S3.TaggedError()("ModelDoesNotSupportToolsError", {
1201
- model: S3.String
1202
- }) {
1203
- };
1204
- var ModelNotFoundError = class extends S3.TaggedError()("ModelNotFoundError", {
1205
- model: S3.String
1206
- }) {
1207
- };
1208
- var parseOllamaError = (error) => {
1209
- {
1210
- const match = error.match(/^([^']+) does not support tools$/);
1211
- if (match) {
1212
- return new ModelDoesNotSupportToolsError({
1213
- model: match[1]
1214
- });
1215
- }
1216
- }
1217
- {
1218
- const match = error.match(/^model "([^"]+)" not found, try pulling it first$/);
1219
- if (match) {
1220
- return new ModelNotFoundError({
1221
- model: match[1]
1222
- });
1223
- }
1224
- }
1225
- throw new Error(`Ollama API error: ${error}`);
1226
- };
1227
- var parseErrorResponse = async (response) => {
1228
- if (response.headers.get("content-type")?.includes("application/json")) {
1229
- const body = await response.json();
1230
- return parseOllamaError(body.error);
1231
- }
1232
- throw new Error(`Ollama API error: ${response.status} ${response.statusText} ${await response.text()}`);
1233
- };
1234
-
1235
- // packages/experimental/assistant/src/ai-service/transform.ts
1236
- import * as P from "parsimmon";
1237
- var textChunk = P.regexp(/[^<]+/).map((content) => ({
1238
- type: "text",
1239
- content
1240
- }));
1241
- var attribute = P.seq(P.regexp(/[a-zA-Z_][a-zA-Z0-9_-]*/), P.string("=").trim(P.optWhitespace), P.alt(P.regexp(/"[^"]*"/).map((s) => s.slice(1, -1)), P.regexp(/'[^']*'/).map((s) => s.slice(1, -1)))).map(([name, _, value]) => [
1242
- name,
1243
- value
1244
- ]);
1245
- var tagName = P.regexp(/[a-zA-Z_][a-zA-Z0-9_-]*/);
1246
- var selfClosingTag = P.seqMap(
1247
- //
1248
- P.string("<"),
1249
- tagName,
1250
- P.optWhitespace.then(attribute).many(),
1251
- P.optWhitespace.then(P.string("/>")),
1252
- P.optWhitespace,
1253
- (_, tag, attributes, __) => ({
1254
- type: "tag",
1255
- tag,
1256
- attributes: Object.fromEntries(attributes),
1257
- content: [],
1258
- selfClosing: true
1259
- })
1260
- );
1261
- var openTag = P.seqMap(
1262
- //
1263
- P.string("<"),
1264
- tagName,
1265
- P.optWhitespace.then(attribute).many(),
1266
- P.string(">"),
1267
- P.regexp(/[^<]*/),
1268
- (_, tag, attributes, __, content) => ({
1269
- type: "tag",
1270
- tag,
1271
- attributes: Object.fromEntries(attributes),
1272
- content: content.length ? [
1273
- {
1274
- type: "text",
1275
- content
1276
- }
1277
- ] : []
1278
- })
1279
- );
1280
- var closeTag = P.seqMap(
1281
- //
1282
- P.string("</"),
1283
- tagName,
1284
- P.string(">"),
1285
- P.optWhitespace,
1286
- (_, tag) => ({
1287
- type: "tag",
1288
- tag,
1289
- content: [],
1290
- closing: true
1291
- })
1292
- );
1293
- var mixedChunk = P.alt(selfClosingTag, openTag, closeTag, textChunk);
1294
- var StreamTransform = class {
1295
- constructor() {
1296
- this._buffer = "";
1297
- }
1298
- transform(chunk) {
1299
- this._buffer += chunk;
1300
- const results = [];
1301
- const parser = mixedChunk.many().skip(P.optWhitespace);
1302
- const result = parser.parse(this._buffer);
1303
- if (result.status) {
1304
- for (const chunk2 of result.value) {
1305
- results.push(chunk2);
1306
- }
1307
- this._buffer = "";
1308
- }
1309
- return results;
1310
- }
1311
- // TODO(burdon): Process remaining buffer?
1312
- flush() {
1313
- const remaining = this._buffer;
1314
- this._buffer = "";
1315
- return remaining.length > 0 ? [
1316
- {
1317
- type: "text",
1318
- content: remaining
1319
- }
1320
- ] : [];
1321
- }
1322
- };
1323
-
1324
- // packages/experimental/assistant/src/ai-service/parser.ts
1325
- import { Message as Message4 } from "@dxos/artifact";
1326
- import { Event } from "@dxos/async";
1327
- import { createStatic as createStatic2 } from "@dxos/echo-schema";
1328
- import { invariant as invariant4 } from "@dxos/invariant";
1329
- import { log as log5 } from "@dxos/log";
1330
- import { isNotFalsy, safeParseJson } from "@dxos/util";
1331
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/parser.ts";
1332
- var MixedStreamParser = class {
1333
- constructor() {
1334
- /**
1335
- * New message.
1336
- */
1337
- this.message = new Event();
1338
- /**
1339
- * Complete block added to Message.
1340
- */
1341
- this.block = new Event();
1342
- /**
1343
- * Update partial block (while streaming).
1344
- */
1345
- this.update = new Event();
1346
- this.streamEvent = new Event();
1347
- }
1348
- _emitBlock(contentBlock, streamBlock) {
1349
- const messageBlock = streamBlock ? mergeMessageBlock(contentBlock, streamBlock) : contentBlock;
1350
- if (messageBlock) {
1351
- if (messageBlock.type === "text" && messageBlock.text.length === 0) {
1352
- return;
1353
- }
1354
- invariant4(this._message, void 0, {
1355
- F: __dxlog_file5,
1356
- L: 49,
1357
- S: this,
1358
- A: [
1359
- "this._message",
1360
- ""
1361
- ]
1362
- });
1363
- this._message.content.push(messageBlock);
1364
- this.block.emit(messageBlock);
1365
- }
1366
- }
1367
- _emitUpdate(contentBlock, streamBlock) {
1368
- const messageBlock = mergeMessageBlock(contentBlock, streamBlock);
1369
- if (messageBlock) {
1370
- messageBlock.pending = true;
1371
- this.update.emit(messageBlock);
1372
- }
1373
- }
1374
- /**
1375
- * Parse stream until end.
1376
- */
1377
- async parse(stream) {
1378
- const transformer = new StreamTransform();
1379
- let contentBlock;
1380
- let streamBlock;
1381
- const stack = [];
1382
- const messagesCollected = [];
1383
- for await (const event of stream) {
1384
- log5("streamEvent", {
1385
- event
1386
- }, {
1387
- F: __dxlog_file5,
1388
- L: 83,
1389
- S: this,
1390
- C: (f, a) => f(...a)
1391
- });
1392
- this.streamEvent.emit(event);
1393
- switch (event.type) {
1394
- //
1395
- // Messages.
1396
- //
1397
- case "message_start": {
1398
- if (this._message) {
1399
- log5.warn("unexpected message_start", void 0, {
1400
- F: __dxlog_file5,
1401
- L: 94,
1402
- S: this,
1403
- C: (f, a) => f(...a)
1404
- });
1405
- }
1406
- this._message = createStatic2(Message4, {
1407
- role: event.message.role,
1408
- content: [
1409
- ...event.message.content
1410
- ]
1411
- });
1412
- this.message.emit(this._message);
1413
- break;
1414
- }
1415
- case "message_delta": {
1416
- if (!this._message) {
1417
- log5.warn("unexpected message_delta", void 0, {
1418
- F: __dxlog_file5,
1419
- L: 104,
1420
- S: this,
1421
- C: (f, a) => f(...a)
1422
- });
1423
- }
1424
- break;
1425
- }
1426
- case "message_stop": {
1427
- if (!this._message) {
1428
- log5.warn("unexpected message_stop", void 0, {
1429
- F: __dxlog_file5,
1430
- L: 112,
1431
- S: this,
1432
- C: (f, a) => f(...a)
1433
- });
1434
- } else {
1435
- messagesCollected.push(this._message);
1436
- this._message = void 0;
1437
- }
1438
- break;
1439
- }
1440
- //
1441
- // Content blocks.
1442
- //
1443
- case "content_block_start": {
1444
- if (contentBlock) {
1445
- log5.warn("unexpected content_block_start", {
1446
- content: contentBlock
1447
- }, {
1448
- F: __dxlog_file5,
1449
- L: 126,
1450
- S: this,
1451
- C: (f, a) => f(...a)
1452
- });
1453
- }
1454
- contentBlock = event.content;
1455
- break;
1456
- }
1457
- case "content_block_delta": {
1458
- if (!contentBlock) {
1459
- log5.warn("unexpected content_block_delta", void 0, {
1460
- F: __dxlog_file5,
1461
- L: 136,
1462
- S: this,
1463
- C: (f, a) => f(...a)
1464
- });
1465
- break;
1466
- }
1467
- switch (event.delta.type) {
1468
- //
1469
- // Text
1470
- //
1471
- case "text_delta": {
1472
- const chunks = transformer.transform(event.delta.text);
1473
- for (const chunk of chunks) {
1474
- log5("text_delta", {
1475
- chunk
1476
- }, {
1477
- F: __dxlog_file5,
1478
- L: 147,
1479
- S: this,
1480
- C: (f, a) => f(...a)
1481
- });
1482
- switch (streamBlock?.type) {
1483
- //
1484
- // XML Fragment.
1485
- //
1486
- case "tag": {
1487
- if (chunk.type === "tag") {
1488
- if (chunk.selfClosing) {
1489
- streamBlock.content.push(chunk);
1490
- } else if (chunk.closing) {
1491
- if (stack.length > 0) {
1492
- const top = stack.pop();
1493
- invariant4(top && top.type === "tag", void 0, {
1494
- F: __dxlog_file5,
1495
- L: 160,
1496
- S: this,
1497
- A: [
1498
- "top && top.type === 'tag'",
1499
- ""
1500
- ]
1501
- });
1502
- log5("pop", {
1503
- top
1504
- }, {
1505
- F: __dxlog_file5,
1506
- L: 161,
1507
- S: this,
1508
- C: (f, a) => f(...a)
1509
- });
1510
- top.content.push(streamBlock);
1511
- streamBlock = top;
1512
- } else {
1513
- this._emitBlock(contentBlock, streamBlock);
1514
- streamBlock = void 0;
1515
- }
1516
- } else {
1517
- stack.push(streamBlock);
1518
- streamBlock = chunk;
1519
- }
1520
- } else {
1521
- if (streamBlock.content.length === 0) {
1522
- streamBlock.content.push(chunk);
1523
- } else {
1524
- const last = streamBlock.content.at(-1);
1525
- invariant4(last, void 0, {
1526
- F: __dxlog_file5,
1527
- L: 178,
1528
- S: this,
1529
- A: [
1530
- "last",
1531
- ""
1532
- ]
1533
- });
1534
- if (last.type === "text") {
1535
- last.content += chunk.content;
1536
- } else {
1537
- streamBlock.content.push(chunk);
1538
- }
1539
- }
1540
- }
1541
- break;
1542
- }
1543
- //
1544
- // Text Fragment.
1545
- //
1546
- case "text": {
1547
- if (chunk.type === "tag") {
1548
- this._emitBlock(contentBlock, streamBlock);
1549
- if (chunk.selfClosing) {
1550
- this._emitBlock(contentBlock, chunk);
1551
- streamBlock = void 0;
1552
- } else {
1553
- streamBlock = chunk;
1554
- }
1555
- } else {
1556
- streamBlock.content += chunk.content;
1557
- }
1558
- break;
1559
- }
1560
- //
1561
- // No current chunk.
1562
- //
1563
- default: {
1564
- if (chunk.type === "tag" && chunk.selfClosing) {
1565
- this._emitBlock(contentBlock, chunk);
1566
- } else {
1567
- streamBlock = chunk;
1568
- }
1569
- }
1570
- }
1571
- }
1572
- break;
1573
- }
1574
- //
1575
- // JSON
1576
- //
1577
- case "input_json_delta": {
1578
- if (!contentBlock) {
1579
- log5.warn("unexpected input_json_delta", {
1580
- contentBlock
1581
- }, {
1582
- F: __dxlog_file5,
1583
- L: 228,
1584
- S: this,
1585
- C: (f, a) => f(...a)
1586
- });
1587
- break;
1588
- }
1589
- if (streamBlock?.type === "json") {
1590
- streamBlock.content += event.delta.partial_json;
1591
- } else {
1592
- streamBlock = {
1593
- type: "json",
1594
- content: event.delta.partial_json
1595
- };
1596
- }
1597
- break;
1598
- }
1599
- }
1600
- break;
1601
- }
1602
- case "content_block_stop": {
1603
- if (!contentBlock) {
1604
- log5.warn("unexpected content_block_stop", void 0, {
1605
- F: __dxlog_file5,
1606
- L: 245,
1607
- S: this,
1608
- C: (f, a) => f(...a)
1609
- });
1610
- break;
1611
- }
1612
- this._emitBlock(contentBlock, streamBlock);
1613
- contentBlock = void 0;
1614
- streamBlock = void 0;
1615
- break;
1616
- }
1617
- }
1618
- if (contentBlock && streamBlock) {
1619
- this._emitUpdate(contentBlock, streamBlock);
1620
- }
1621
- }
1622
- return messagesCollected;
1623
- }
1624
- };
1625
- var mergeMessageBlock = (contentBlock, streamBlock) => {
1626
- log5("mergeMessageBlock", {
1627
- contentBlock,
1628
- streamBlock
1629
- }, {
1630
- F: __dxlog_file5,
1631
- L: 272,
1632
- S: void 0,
1633
- C: (f, a) => f(...a)
1634
- });
1635
- switch (streamBlock.type) {
1636
- //
1637
- // Text
1638
- //
1639
- case "text": {
1640
- return {
1641
- ...contentBlock,
1642
- type: "text",
1643
- text: streamBlock.content
1644
- };
1645
- }
1646
- //
1647
- // XML
1648
- //
1649
- case "tag": {
1650
- switch (streamBlock.tag) {
1651
- case "cot": {
1652
- const content = streamBlock.content.map((block) => {
1653
- switch (block.type) {
1654
- case "text":
1655
- return block.content;
1656
- default:
1657
- return null;
1658
- }
1659
- }).filter(isNotFalsy).join("\n");
1660
- return {
1661
- ...contentBlock,
1662
- type: "text",
1663
- disposition: "cot",
1664
- text: content
1665
- };
1666
- }
1667
- case "artifact": {
1668
- const { attributes } = streamBlock;
1669
- return {
1670
- type: "json",
1671
- disposition: "artifact",
1672
- json: JSON.stringify(attributes)
1673
- };
1674
- }
1675
- case "suggest": {
1676
- if (streamBlock.content.length === 1 && streamBlock.content[0].type === "text") {
1677
- return {
1678
- type: "json",
1679
- disposition: "suggest",
1680
- json: JSON.stringify({
1681
- text: streamBlock.content[0].content
1682
- })
1683
- };
1684
- }
1685
- break;
1686
- }
1687
- case "select": {
1688
- return {
1689
- type: "json",
1690
- disposition: "select",
1691
- json: JSON.stringify({
1692
- options: streamBlock.content.flatMap((content) => content.type === "tag" && content.content.length === 1 && content.content[0].type === "text" ? [
1693
- content.content[0].content
1694
- ] : [])
1695
- })
1696
- };
1697
- }
1698
- case "tool-list": {
1699
- return {
1700
- type: "json",
1701
- disposition: "tool_list",
1702
- json: JSON.stringify({})
1703
- };
1704
- }
1705
- }
1706
- break;
1707
- }
1708
- //
1709
- // JSON
1710
- //
1711
- case "json": {
1712
- switch (contentBlock.type) {
1713
- case "tool_use": {
1714
- return {
1715
- ...contentBlock,
1716
- input: safeParseJson(streamBlock.content) ?? {}
1717
- };
1718
- }
1719
- }
1720
- return {
1721
- ...contentBlock,
1722
- type: "json",
1723
- disposition: "artifact",
1724
- json: streamBlock.content
1725
- };
1726
- }
1727
- }
1728
- };
1729
-
1730
- // packages/experimental/assistant/src/cypher/parjs.ts
1731
- import { parjsCombinators, parjs } from "#parjs";
1732
-
1733
- // packages/experimental/assistant/src/cypher/combinators.ts
1734
- var ws = parjs.whitespace();
1735
- var nothing = parjs.string("").pipe(parjsCombinators.map(() => null));
1736
- var optional = (parser) => parser.pipe(parjsCombinators.recover(() => ({
1737
- kind: "Soft"
1738
- })), parjsCombinators.or(nothing));
1739
- var keyword = (word) => parjs.string(word).pipe(parjsCombinators.map(() => word));
1740
- var identifier = parjs.regexp(/[a-zA-Z_][a-zA-Z0-9_]*/).pipe(parjsCombinators.map((match) => ({
1741
- astKind: "Identifier",
1742
- name: match[0]
1743
- })));
1744
- var numberLiteral = parjs.regexp(/-?\d+(\.\d+)?/).pipe(parjsCombinators.map(Number));
1745
- var stringLiteral = parjs.regexp(/"([^"]*)"|'([^']*)'/).pipe(parjsCombinators.map((match) => ({
1746
- astKind: "StringLiteral",
1747
- value: match[1] || match[2]
1748
- })));
1749
- var variableTag = identifier.pipe(parjsCombinators.map((variable) => variable)).expects("variable tag");
1750
- var label = identifier.pipe(parjsCombinators.map((name) => name));
1751
- var property = identifier.pipe(parjsCombinators.then(parjs.string(":"), ws, stringLiteral), parjsCombinators.map(([key, , , value]) => ({
1752
- key,
1753
- value
1754
- })));
1755
- var properties = property.pipe(parjsCombinators.manySepBy(","), parjsCombinators.between("{", "}"), parjsCombinators.map((properties2) => ({
1756
- astKind: "Properties",
1757
- properties: properties2
1758
- })));
1759
- var nodePattern = optional(variableTag).pipe(parjsCombinators.then(":"), parjsCombinators.then(ws, label, ws), parjsCombinators.then(optional(properties)), parjsCombinators.between("(", ")"), parjsCombinators.map(([[[variable], _, label2], properties2]) => ({
1760
- astKind: "NodePattern",
1761
- variable,
1762
- label: label2,
1763
- properties: properties2
1764
- })));
1765
- var relationshipPattern = optional(variableTag).pipe(parjsCombinators.then(":"), parjsCombinators.then(ws, label, ws), parjsCombinators.then(optional(properties)), parjsCombinators.between("[", "]"), parjsCombinators.map(([[[variable], _, label2], properties2]) => ({
1766
- astKind: "RelationshipPattern",
1767
- variable,
1768
- label: label2,
1769
- properties: properties2
1770
- })));
1771
- var graphPatternConnector = parjs.string("->").pipe(parjsCombinators.or("<-", "-"), parjsCombinators.map((x) => ({
1772
- astKind: "GraphPatternConnector",
1773
- direction: x
1774
- })));
1775
- var graphPattern = nodePattern.pipe(parjsCombinators.or(relationshipPattern), parjsCombinators.manySepBy(graphPatternConnector), parjsCombinators.map((segments) => ({
1776
- astKind: "GraphPattern",
1777
- segments
1778
- })));
1779
- var matchClause = keyword("MATCH").pipe(parjsCombinators.then(ws), parjsCombinators.then(graphPattern), parjsCombinators.map(([, pattern]) => ({
1780
- astKind: "MatchClause",
1781
- pattern
1782
- })));
1783
- var memberExpression = identifier.pipe(parjsCombinators.manySepBy("."), parjsCombinators.map((path) => ({
1784
- astKind: "MemberExpression",
1785
- path
1786
- })));
1787
- var equalsPredicate = memberExpression.pipe(parjsCombinators.then(ws, parjs.string("="), ws, stringLiteral), parjsCombinators.map(([left, , , , right]) => ({
1788
- astKind: "EqualsPredicate",
1789
- left,
1790
- right
1791
- })));
1792
- var whereClause = keyword("WHERE").pipe(parjsCombinators.then(ws, equalsPredicate.pipe(parjsCombinators.between(ws, ws), parjsCombinators.manySepBy(parjs.string("AND"))), ws), parjsCombinators.map(([, , predicates]) => ({
1793
- astKind: "WhereClause",
1794
- predicates
1795
- })));
1796
- var returnClause = keyword("RETURN").pipe(parjsCombinators.then(ws, memberExpression.pipe(parjsCombinators.then(optional(parjs.string("AS").pipe(parjsCombinators.between(ws), parjsCombinators.then(identifier))), ws), parjsCombinators.manySepBy(parjs.string(",").pipe(parjsCombinators.then(ws)))), ws), parjsCombinators.map(([, , fields]) => ({
1797
- astKind: "ReturnClause",
1798
- fields: fields.map(([f]) => f)
1799
- })));
1800
- var cypherQuery = ws.pipe(parjsCombinators.then(matchClause, ws, optional(whereClause), ws, returnClause, ws), parjsCombinators.map(([, matchClause2, , whereClause2, , returnClause2]) => ({
1801
- astKind: "CypherQuery",
1802
- matchClause: matchClause2,
1803
- whereClause: whereClause2,
1804
- returnClause: returnClause2
1805
- })));
1806
-
1807
- // packages/experimental/assistant/src/cypher/parser.ts
1808
- var parseCypherQuery = (query) => {
1809
- const parseResult = cypherQuery.parse(query);
1810
- if (parseResult.isOk) {
1811
- return {
1812
- ast: parseResult.value
1813
- };
1814
- } else {
1815
- throw new Error(`Failed to parse query: ${parseResult}`);
1816
- }
1817
- };
1818
-
1819
- // packages/experimental/assistant/src/cypher/query-executor.ts
1820
- import { log as log7 } from "@dxos/log";
1821
- import { mapValues } from "@dxos/util";
1822
-
1823
- // packages/experimental/assistant/src/cypher/execution-plan.ts
1824
- import { invariant as invariant5 } from "@dxos/invariant";
1825
- import { log as log6 } from "@dxos/log";
1826
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/cypher/execution-plan.ts";
1827
- var createExecutionPlan = (query) => {
1828
- return new ExecutionPlanBuilder().build(query);
1829
- };
1830
- var ExecutionPlanBuilder = class {
1831
- constructor() {
1832
- this.counter = 0;
1833
- }
1834
- newVariable() {
1835
- return `anon_${this.counter++}`;
1836
- }
1837
- build(query) {
1838
- log6("Creating execution plan for query", {
1839
- query
1840
- }, {
1841
- F: __dxlog_file6,
1842
- L: 76,
1843
- S: this,
1844
- C: (f, a) => f(...a)
1845
- });
1846
- return {
1847
- steps: [
1848
- ...this.createStepsForMatchClause(query.ast.matchClause),
1849
- ...query.ast.whereClause ? this.createStepsForWhereClause(query.ast.whereClause) : [],
1850
- ...this.createStepsForReturnClause(query.ast.returnClause)
1851
- ],
1852
- output: {
1853
- fields: this.getOutputFields(query.ast.returnClause)
1854
- }
1855
- };
1856
- }
1857
- createStepsForMatchClause(match) {
1858
- invariant5(match.pattern.segments.length > 0, void 0, {
1859
- F: __dxlog_file6,
1860
- L: 90,
1861
- S: this,
1862
- A: [
1863
- "match.pattern.segments.length > 0",
1864
- ""
1865
- ]
1866
- });
1867
- const firstSegment = match.pattern.segments[0];
1868
- invariant5(firstSegment.astKind === "NodePattern", void 0, {
1869
- F: __dxlog_file6,
1870
- L: 92,
1871
- S: this,
1872
- A: [
1873
- "firstSegment.astKind === 'NodePattern'",
1874
- ""
1875
- ]
1876
- });
1877
- let lastNodeVariable = firstSegment.variable?.name ?? this.newVariable();
1878
- const steps = [];
1879
- steps.push({
1880
- type: "NodeScan",
1881
- label: firstSegment.label.name,
1882
- into: lastNodeVariable
1883
- });
1884
- if (firstSegment.properties) {
1885
- for (const property2 of firstSegment.properties.properties) {
1886
- steps.push({
1887
- type: "FilterByProperty",
1888
- variable: lastNodeVariable,
1889
- property: property2.key.name,
1890
- value: property2.value.value
1891
- });
1892
- }
1893
- }
1894
- for (let i = 1; i < match.pattern.segments.length; i++) {
1895
- const relationshipSegment = match.pattern.segments[i++];
1896
- invariant5(relationshipSegment.astKind === "RelationshipPattern", void 0, {
1897
- F: __dxlog_file6,
1898
- L: 115,
1899
- S: this,
1900
- A: [
1901
- "relationshipSegment.astKind === 'RelationshipPattern'",
1902
- ""
1903
- ]
1904
- });
1905
- const nodeSegment = match.pattern.segments[i];
1906
- invariant5(nodeSegment.astKind === "NodePattern", void 0, {
1907
- F: __dxlog_file6,
1908
- L: 117,
1909
- S: this,
1910
- A: [
1911
- "nodeSegment.astKind === 'NodePattern'",
1912
- ""
1913
- ]
1914
- });
1915
- const leftSeparator = match.pattern.segments.separators[i - 2];
1916
- const rightSeparator = match.pattern.segments.separators[i - 1];
1917
- const direction = getDirection(leftSeparator.direction, rightSeparator.direction);
1918
- const relationshipVariable = relationshipSegment.variable?.name ?? this.newVariable();
1919
- const nodeVariable = nodeSegment.variable?.name ?? this.newVariable();
1920
- steps.push({
1921
- type: "RelationshipScan",
1922
- label: relationshipSegment.label.name,
1923
- direction,
1924
- anchor: lastNodeVariable,
1925
- relationshipInto: relationshipVariable,
1926
- nodeInto: nodeVariable
1927
- });
1928
- if (relationshipSegment.properties) {
1929
- for (const property2 of relationshipSegment.properties.properties) {
1930
- steps.push({
1931
- type: "FilterByProperty",
1932
- variable: relationshipVariable,
1933
- property: property2.key.name,
1934
- value: property2.value.value
1935
- });
1936
- }
1937
- }
1938
- if (nodeSegment.label) {
1939
- steps.push({
1940
- type: "FilterByLabel",
1941
- variable: nodeVariable,
1942
- label: nodeSegment.label.name
1943
- });
1944
- }
1945
- if (nodeSegment.properties) {
1946
- for (const property2 of nodeSegment.properties.properties) {
1947
- steps.push({
1948
- type: "FilterByProperty",
1949
- variable: nodeVariable,
1950
- property: property2.key.name,
1951
- value: property2.value.value
1952
- });
1953
- }
1954
- }
1955
- lastNodeVariable = nodeVariable;
1956
- }
1957
- return steps;
1958
- }
1959
- createStepsForWhereClause(where) {
1960
- return [];
1961
- }
1962
- createStepsForReturnClause(returnClause2) {
1963
- return [
1964
- {
1965
- type: "ProduceResults",
1966
- fields: returnClause2.fields.map((field) => ({
1967
- name: field.path.map((p) => p.name).join("_"),
1968
- variable: field.path[0].name,
1969
- path: field.path.length > 1 ? field.path.slice(1).map((p) => p.name).join(".") : "$"
1970
- }))
1971
- }
1972
- ];
1973
- }
1974
- getOutputFields(returnClause2) {
1975
- return returnClause2.fields.map((field) => field.path.map((p) => p.name).join("_"));
1976
- }
1977
- };
1978
- var getDirection = (left, right) => {
1979
- if (left === "-" && right === "->") {
1980
- return "out";
1981
- } else if (left === "<-" && right === "-") {
1982
- return "in";
1983
- } else if (left === "-" && right === "-") {
1984
- return "both";
1985
- }
1986
- throw new Error(`Invalid direction: ()${left}[]${right}()`);
1987
- };
1988
-
1989
- // packages/experimental/assistant/src/cypher/query-executor.ts
1990
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/cypher/query-executor.ts";
1991
- var executeQueryPlan = async (dataSource, plan) => {
1992
- let buffer = [];
1993
- const results = [];
1994
- for (const step of plan.steps) {
1995
- log7("begin step", {
1996
- step
1997
- }, {
1998
- F: __dxlog_file7,
1999
- L: 41,
2000
- S: void 0,
2001
- C: (f, a) => f(...a)
2002
- });
2003
- switch (step.type) {
2004
- case "NodeScan": {
2005
- const nodes = await dataSource.getNodes({
2006
- label: step.label
2007
- });
2008
- buffer.push(...nodes.map((node) => ({
2009
- [step.into]: node
2010
- })));
2011
- break;
2012
- }
2013
- case "FilterByLabel": {
2014
- buffer = buffer.filter((item) => {
2015
- const node = item[step.variable];
2016
- return node && node.kind === "node" && node.label === step.label;
2017
- });
2018
- break;
2019
- }
2020
- case "FilterByProperty": {
2021
- buffer = buffer.filter((item) => {
2022
- const node = item[step.variable];
2023
- return node && node.kind === "node" && node.properties[step.property] === step.value;
2024
- });
2025
- break;
2026
- }
2027
- case "RelationshipScan": {
2028
- const relationships = await dataSource.getRelationships({
2029
- label: step.label
2030
- });
2031
- for (const tuple of [
2032
- ...buffer
2033
- ]) {
2034
- if (tuple[step.anchor].kind !== "node") {
2035
- continue;
2036
- }
2037
- const filteredRelationships = relationships.filter((relationship) => {
2038
- switch (step.direction) {
2039
- case "in":
2040
- return relationship.target.id === tuple[step.anchor].id;
2041
- case "out":
2042
- return relationship.source.id === tuple[step.anchor].id;
2043
- case "both":
2044
- return relationship.source.id === tuple[step.anchor].id || relationship.target.id === tuple[step.anchor].id;
2045
- default:
2046
- throw new Error(`Unknown direction: ${step.direction}`);
2047
- }
2048
- });
2049
- for (let i = 0; i < filteredRelationships.length; i++) {
2050
- const relationship = filteredRelationships[i];
2051
- const newTuple = i === 0 ? tuple : {
2052
- ...tuple
2053
- };
2054
- if (newTuple !== tuple) {
2055
- buffer.push(newTuple);
2056
- }
2057
- newTuple[step.relationshipInto] = relationship;
2058
- switch (step.direction) {
2059
- case "in":
2060
- newTuple[step.nodeInto] = relationship.source;
2061
- break;
2062
- case "out":
2063
- newTuple[step.nodeInto] = relationship.target;
2064
- break;
2065
- case "both":
2066
- newTuple[step.nodeInto] = relationship.source.id === newTuple[step.anchor].id ? relationship.target : relationship.source;
2067
- break;
2068
- }
2069
- }
2070
- }
2071
- break;
2072
- }
2073
- case "ProduceResults": {
2074
- for (const tuple of buffer) {
2075
- const result = {};
2076
- for (const field of step.fields) {
2077
- result[field.name] = jsonPathGet(tuple[field.variable].properties, field.path);
2078
- }
2079
- results.push(result);
2080
- }
2081
- break;
2082
- }
2083
- }
2084
- log7("finish step", {
2085
- buffer: buffer.map((tuple) => mapValues(tuple, (x) => x.id)),
2086
- results
2087
- }, {
2088
- F: __dxlog_file7,
2089
- L: 118,
2090
- S: void 0,
2091
- C: (f, a) => f(...a)
2092
- });
2093
- }
2094
- return results;
2095
- };
2096
- var executeQuery = (dataSource, query) => {
2097
- const plan = createExecutionPlan(parseCypherQuery(query));
2098
- return executeQueryPlan(dataSource, plan);
2099
- };
2100
- var jsonPathGet = (obj, path) => {
2101
- if (path === "" || path === "$") {
2102
- return obj;
2103
- }
2104
- const parts = path.split(".");
2105
- if (parts[0] === "$") {
2106
- parts.shift();
2107
- }
2108
- let result = obj;
2109
- for (const part of parts) {
2110
- result = result?.[part];
2111
- }
2112
- return result;
2113
- };
2114
-
2115
- // packages/experimental/assistant/src/cypher/schema.ts
2116
- import { raise } from "@dxos/debug";
2117
- import { JSON_SCHEMA_ECHO_REF_ID } from "@dxos/echo-schema";
2118
-
2119
- // packages/experimental/assistant/src/util/trim.ts
2120
- var trim = (strings, ...values) => {
2121
- const combined = strings.reduce((acc, str, i) => {
2122
- return acc + str + (values[i] || "");
2123
- }, "");
2124
- return combined.replace("/^\n/", "").replace(/\n$/, "");
2125
- };
2126
-
2127
- // packages/experimental/assistant/src/cypher/schema.ts
2128
- var formatJsonSchemaForLLM = (schemaTypes) => {
2129
- return schemaTypes.flatMap((schema) => [
2130
- formatNodeSchema(schema),
2131
- ...formatInferredRelationships(schema, schemaTypes)
2132
- ]);
2133
- };
2134
- var formatNodeSchema = (schema) => {
2135
- const label2 = formatNodeLabel(schema.typename ?? raise(new Error("Schema must have $id")));
2136
- const properties2 = Object.entries(schema.properties).filter(([key, prop]) => key !== "id" && !isReference(prop));
2137
- return trim`
2138
- <node>
2139
- (:${label2})
2140
-
2141
- <description>${schema.description}</description>
2142
-
2143
- <properties>
2144
- ${properties2.map(([key, value]) => {
2145
- return trim`
2146
- <${key}>
2147
- <type>${value.type}</type>
2148
- <description>${value.description}</description>
2149
- </${key}>
2150
- `;
2151
- })}
2152
- </properties>
2153
- </node>
2154
- `;
2155
- };
2156
- var formatInferredRelationships = (schema, allSchema) => {
2157
- const nodeLabel = formatNodeLabel(schema.typename ?? raise(new Error("Schema must have $id")));
2158
- const relationships = Object.entries(schema.properties).filter(([key, prop]) => isReference(prop));
2159
- return relationships.map(([key, value]) => {
2160
- const relationshipLabel = formatInferredRelationshipLabel(schema.typename ?? raise(new Error("Schema must have $id")), key);
2161
- const targetSchema = allSchema.find((schema2) => `dxn:type/${schema2.typename}` === value.reference?.schema.$ref);
2162
- const targetLabel = targetSchema ? formatNodeLabel(targetSchema?.typename ?? "") : "";
2163
- return trim`
2164
- <relationship>
2165
- (:${nodeLabel})-[:${relationshipLabel}]->(:${targetLabel})
2166
-
2167
- <description>${value.description}</description>
2168
- </relationship>
2169
- `;
2170
- });
2171
- };
2172
- var formatNodeLabel = (typename) => {
2173
- return typename.replace(/^example\.com\/type\//g, "");
2174
- };
2175
- var formatInferredRelationshipLabel = (typename, property2) => {
2176
- const nodeLabel = formatNodeLabel(typename);
2177
- return `${nodeLabel}_${property2}`.toUpperCase();
2178
- };
2179
- var isReference = (schema) => schema.$id === JSON_SCHEMA_ECHO_REF_ID || schema.type === "array" && !Array.isArray(schema.items) && typeof schema.items === "object" && "$id" in schema.items && schema.items.$id === JSON_SCHEMA_ECHO_REF_ID;
2180
-
2181
- // packages/experimental/assistant/src/cypher/echo-data-source.ts
2182
- import { raise as raise2 } from "@dxos/debug";
2183
- import { Filter } from "@dxos/echo-db";
2184
- import { getSchemaTypename, StoredSchema, toJsonSchema } from "@dxos/echo-schema";
2185
- import { getSchema } from "@dxos/live-object";
2186
- import { log as log8 } from "@dxos/log";
2187
- function _ts_decorate(decorators, target, key, desc) {
2188
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2189
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2190
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2191
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2192
- }
2193
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/cypher/echo-data-source.ts";
2194
- var EchoDataSource = class {
2195
- constructor(_db) {
2196
- this._db = _db;
2197
- }
2198
- async getNodes({ label: label2 }) {
2199
- if (!label2) {
2200
- const { objects: objects2 } = await this._db.query().run();
2201
- return objects2.map(this._objectToNode);
2202
- }
2203
- const schema = (await this._getAllSchema()).find((s) => getSchemaTypename(s)?.endsWith(label2));
2204
- if (!schema) {
2205
- return [];
2206
- }
2207
- const { objects } = await this._db.query(Filter.schema(schema)).run();
2208
- return objects.map(this._objectToNode);
2209
- }
2210
- async getRelationships({ label: label2 }) {
2211
- const syntheticRefRelationships = (await this._getAllSchema()).filter((schema) => getSchemaTypename(schema) !== StoredSchema.typename).flatMap((schema) => {
2212
- const jsonSchema = toJsonSchema(schema);
2213
- const relationships = Object.entries(jsonSchema.properties).filter(([key, prop]) => isReference(prop));
2214
- return relationships.map(([key, value]) => {
2215
- const relationshipLabel = formatInferredRelationshipLabel(jsonSchema.typename ?? raise2(new Error("Schema must have typename")), key);
2216
- return {
2217
- label: relationshipLabel,
2218
- schema,
2219
- property: key
2220
- };
2221
- });
2222
- });
2223
- const relationship = syntheticRefRelationships.find((r) => r.label === label2);
2224
- if (!relationship) {
2225
- return [];
2226
- }
2227
- const { objects } = await this._db.query(Filter.schema(relationship.schema)).run();
2228
- return (await Promise.all(objects.map((object) => this._projectRefRelationship(object, relationship.property)))).flat();
2229
- }
2230
- async _getAllSchema() {
2231
- return [
2232
- ...await this._db.schemaRegistry.query().run(),
2233
- // TODO(dmaretskyi): Remove once we can serialize recursive schema.
2234
- ...this._db.graph.schemaRegistry.schemas.filter((s) => getSchemaTypename(s)?.startsWith("example.org"))
2235
- ].filter((schema) => getSchemaTypename(schema) !== StoredSchema.typename);
2236
- }
2237
- _objectToNode(object) {
2238
- const { id, ...properties2 } = object;
2239
- return {
2240
- id,
2241
- kind: "node",
2242
- label: formatNodeLabel(getSchemaTypename(getSchema(object))),
2243
- properties: properties2
2244
- };
2245
- }
2246
- async _projectRefRelationship(object, prop) {
2247
- if (!object[prop]) {
2248
- return [];
2249
- }
2250
- const value = Array.isArray(object[prop]) ? object[prop] : [
2251
- object[prop]
2252
- ];
2253
- return Promise.all(value.map(async (ref) => {
2254
- const target = await ref.load();
2255
- return {
2256
- id: `${object.id}-${prop}-${target.id}`,
2257
- kind: "relationship",
2258
- label: formatInferredRelationshipLabel(getSchemaTypename(getSchema(object)), prop),
2259
- properties: {},
2260
- source: this._objectToNode(object),
2261
- target: this._objectToNode(target)
2262
- };
2263
- }));
2264
- }
2265
- };
2266
- _ts_decorate([
2267
- log8.method(void 0, void 0, {
2268
- F: __dxlog_file8,
2269
- L: 17,
2270
- S: void 0,
2271
- C: (f, a) => f(...a)
2272
- })
2273
- ], EchoDataSource.prototype, "getNodes", null);
2274
- _ts_decorate([
2275
- log8.method(void 0, void 0, {
2276
- F: __dxlog_file8,
2277
- L: 34,
2278
- S: void 0,
2279
- C: (f, a) => f(...a)
2280
- })
2281
- ], EchoDataSource.prototype, "getRelationships", null);
2282
-
2283
- export {
2284
- DEFAULT_EDGE_MODEL,
2285
- DEFAULT_EDGE_MODELS,
2286
- DEFAULT_OLLAMA_ENDPOINT,
2287
- DEFAULT_OLLAMA_MODEL,
2288
- DEFAULT_OLLAMA_MODELS,
2289
- createGenerationStream,
2290
- GenerationStreamImpl,
2291
- AIServiceEdgeClient,
2292
- MessageCollector,
2293
- emitMessageAsEvents,
2294
- createArtifactElement,
2295
- LLMModel,
2296
- ToolTypes,
2297
- GenerateRequest,
2298
- runLLM,
2299
- isToolUse,
2300
- runTools,
2301
- OllamaClient,
2302
- StreamTransform,
2303
- MixedStreamParser,
2304
- mergeMessageBlock,
2305
- parseCypherQuery,
2306
- executeQueryPlan,
2307
- executeQuery,
2308
- trim,
2309
- formatJsonSchemaForLLM,
2310
- formatNodeLabel,
2311
- formatInferredRelationshipLabel,
2312
- isReference,
2313
- EchoDataSource
2314
- };
2315
- //# sourceMappingURL=chunk-PND5VR6D.mjs.map