@dxos/assistant 0.8.2-main.fbd8ed0 → 0.8.2-staging.4d6ad0f

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 (289) hide show
  1. package/dist/lib/browser/index.mjs +1983 -64
  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 +1976 -63
  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 +1984 -64
  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/{ai-service/parser.d.ts → blueprint/machine.d.ts} +46 -68
  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 -2
  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.map +1 -0
  60. package/dist/types/src/session/index.d.ts +0 -1
  61. package/dist/types/src/session/index.d.ts.map +1 -1
  62. package/dist/types/src/session/session.d.ts +47 -22
  63. package/dist/types/src/session/session.d.ts.map +1 -1
  64. package/dist/types/src/session/version-pin.d.ts +3 -4
  65. package/dist/types/src/session/version-pin.d.ts.map +1 -1
  66. package/dist/types/src/summarization/summarization.test.d.ts +2 -0
  67. package/dist/types/src/summarization/summarization.test.d.ts.map +1 -0
  68. package/dist/types/src/testing/exa-search-1748337321991.d.ts +38 -0
  69. package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +1 -0
  70. package/dist/types/src/testing/exa-search-1748337331526.d.ts +37 -0
  71. package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +1 -0
  72. package/dist/types/src/testing/exa-search-1748337344119.d.ts +58 -0
  73. package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +1 -0
  74. package/dist/types/src/testing/index.d.ts +2 -7
  75. package/dist/types/src/testing/index.d.ts.map +1 -1
  76. package/dist/types/src/types.d.ts +3 -0
  77. package/dist/types/src/types.d.ts.map +1 -0
  78. package/package.json +22 -38
  79. package/src/blueprint/blueprint.test.ts +142 -0
  80. package/src/blueprint/blueprint.ts +95 -0
  81. package/src/blueprint/index.ts +7 -0
  82. package/src/blueprint/logger.ts +66 -0
  83. package/src/blueprint/machine.ts +208 -0
  84. package/src/blueprint/test-data.ts +55 -0
  85. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +95 -0
  86. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +64 -0
  87. package/src/extraction/extraction-llm-function/index.ts +5 -0
  88. package/src/extraction/extraction-llm-function/instructions.tpl +28 -0
  89. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +115 -0
  90. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +54 -0
  91. package/src/extraction/extraction-ner-function/index.ts +6 -0
  92. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +94 -0
  93. package/src/extraction/extraction-ner-function/named-entity-recognition.ts +97 -0
  94. package/src/extraction/extraction.ts +75 -0
  95. package/src/extraction/index.ts +8 -0
  96. package/src/extraction/quotes.test.ts +27 -0
  97. package/src/extraction/quotes.ts +57 -0
  98. package/src/index.ts +4 -4
  99. package/src/research/exa.ts +100 -0
  100. package/src/research/graph.test.ts +15 -0
  101. package/src/research/graph.ts +291 -0
  102. package/src/research/index.ts +7 -0
  103. package/src/research/instructions-research.tpl +97 -0
  104. package/src/research/research.test.ts +189 -0
  105. package/src/research/research.ts +89 -0
  106. package/src/session/index.ts +0 -1
  107. package/src/session/session.test.ts +7 -7
  108. package/src/session/session.ts +46 -19
  109. package/src/session/version-pin.ts +2 -3
  110. package/src/summarization/summarization.test.ts +216 -0
  111. package/src/testing/exa-search-1748337321991.ts +131 -0
  112. package/src/testing/exa-search-1748337331526.ts +144 -0
  113. package/src/testing/exa-search-1748337344119.ts +133 -0
  114. package/src/testing/index.ts +8 -8
  115. package/src/types.ts +8 -0
  116. package/src/typings.d.ts +8 -0
  117. package/dist/lib/browser/chunk-B4HAWUFW.mjs +0 -2786
  118. package/dist/lib/browser/chunk-B4HAWUFW.mjs.map +0 -7
  119. package/dist/lib/browser/testing/index.mjs +0 -658
  120. package/dist/lib/browser/testing/index.mjs.map +0 -7
  121. package/dist/lib/node/chunk-NOB7CIIC.cjs +0 -2791
  122. package/dist/lib/node/chunk-NOB7CIIC.cjs.map +0 -7
  123. package/dist/lib/node/testing/index.cjs +0 -672
  124. package/dist/lib/node/testing/index.cjs.map +0 -7
  125. package/dist/lib/node-esm/chunk-SAWYU3V5.mjs +0 -2788
  126. package/dist/lib/node-esm/chunk-SAWYU3V5.mjs.map +0 -7
  127. package/dist/lib/node-esm/testing/index.mjs +0 -659
  128. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  129. package/dist/types/src/ai-service/client.test.d.ts +0 -2
  130. package/dist/types/src/ai-service/client.test.d.ts.map +0 -1
  131. package/dist/types/src/ai-service/defs.d.ts +0 -9
  132. package/dist/types/src/ai-service/defs.d.ts.map +0 -1
  133. package/dist/types/src/ai-service/edge-client.d.ts +0 -18
  134. package/dist/types/src/ai-service/edge-client.d.ts.map +0 -1
  135. package/dist/types/src/ai-service/index.d.ts +0 -10
  136. package/dist/types/src/ai-service/index.d.ts.map +0 -1
  137. package/dist/types/src/ai-service/message-collector.d.ts +0 -82
  138. package/dist/types/src/ai-service/message-collector.d.ts.map +0 -1
  139. package/dist/types/src/ai-service/ollama-client.d.ts +0 -43
  140. package/dist/types/src/ai-service/ollama-client.d.ts.map +0 -1
  141. package/dist/types/src/ai-service/parser.d.ts.map +0 -1
  142. package/dist/types/src/ai-service/service.d.ts +0 -25
  143. package/dist/types/src/ai-service/service.d.ts.map +0 -1
  144. package/dist/types/src/ai-service/stream.d.ts +0 -40
  145. package/dist/types/src/ai-service/stream.d.ts.map +0 -1
  146. package/dist/types/src/ai-service/stream.test.d.ts +0 -2
  147. package/dist/types/src/ai-service/stream.test.d.ts.map +0 -1
  148. package/dist/types/src/ai-service/testing/index.d.ts +0 -3
  149. package/dist/types/src/ai-service/testing/index.d.ts.map +0 -1
  150. package/dist/types/src/ai-service/testing/mock.d.ts +0 -11
  151. package/dist/types/src/ai-service/testing/mock.d.ts.map +0 -1
  152. package/dist/types/src/ai-service/testing/test-stream.d.ts +0 -7
  153. package/dist/types/src/ai-service/testing/test-stream.d.ts.map +0 -1
  154. package/dist/types/src/ai-service/transform.d.ts +0 -27
  155. package/dist/types/src/ai-service/transform.d.ts.map +0 -1
  156. package/dist/types/src/ai-service/types.d.ts +0 -210
  157. package/dist/types/src/ai-service/types.d.ts.map +0 -1
  158. package/dist/types/src/ai-service/util/index.d.ts +0 -2
  159. package/dist/types/src/ai-service/util/index.d.ts.map +0 -1
  160. package/dist/types/src/ai-service/util/sse.d.ts +0 -39
  161. package/dist/types/src/ai-service/util/sse.d.ts.map +0 -1
  162. package/dist/types/src/experimental/conversation/conversation.d.ts +0 -61
  163. package/dist/types/src/experimental/conversation/conversation.d.ts.map +0 -1
  164. package/dist/types/src/experimental/conversation/conversation.test.d.ts +0 -2
  165. package/dist/types/src/experimental/conversation/conversation.test.d.ts.map +0 -1
  166. package/dist/types/src/experimental/conversation/index.d.ts +0 -2
  167. package/dist/types/src/experimental/conversation/index.d.ts.map +0 -1
  168. package/dist/types/src/experimental/conversation/types.d.ts +0 -78
  169. package/dist/types/src/experimental/conversation/types.d.ts.map +0 -1
  170. package/dist/types/src/experimental/cypher/ast.d.ts +0 -56
  171. package/dist/types/src/experimental/cypher/ast.d.ts.map +0 -1
  172. package/dist/types/src/experimental/cypher/combinators.d.ts +0 -14
  173. package/dist/types/src/experimental/cypher/combinators.d.ts.map +0 -1
  174. package/dist/types/src/experimental/cypher/combinators.test.d.ts +0 -2
  175. package/dist/types/src/experimental/cypher/combinators.test.d.ts.map +0 -1
  176. package/dist/types/src/experimental/cypher/echo-data-source.d.ts +0 -16
  177. package/dist/types/src/experimental/cypher/echo-data-source.d.ts.map +0 -1
  178. package/dist/types/src/experimental/cypher/execution-plan.d.ts +0 -49
  179. package/dist/types/src/experimental/cypher/execution-plan.d.ts.map +0 -1
  180. package/dist/types/src/experimental/cypher/execution-plan.test.d.ts +0 -2
  181. package/dist/types/src/experimental/cypher/execution-plan.test.d.ts.map +0 -1
  182. package/dist/types/src/experimental/cypher/index.d.ts +0 -5
  183. package/dist/types/src/experimental/cypher/index.d.ts.map +0 -1
  184. package/dist/types/src/experimental/cypher/parjs.d.ts +0 -4
  185. package/dist/types/src/experimental/cypher/parjs.d.ts.map +0 -1
  186. package/dist/types/src/experimental/cypher/parser.d.ts +0 -6
  187. package/dist/types/src/experimental/cypher/parser.d.ts.map +0 -1
  188. package/dist/types/src/experimental/cypher/query-executor.d.ts +0 -26
  189. package/dist/types/src/experimental/cypher/query-executor.d.ts.map +0 -1
  190. package/dist/types/src/experimental/cypher/query-executor.test.d.ts +0 -2
  191. package/dist/types/src/experimental/cypher/query-executor.test.d.ts.map +0 -1
  192. package/dist/types/src/experimental/cypher/schema.d.ts +0 -12
  193. package/dist/types/src/experimental/cypher/schema.d.ts.map +0 -1
  194. package/dist/types/src/experimental/cypher/schema.test.d.ts +0 -2
  195. package/dist/types/src/experimental/cypher/schema.test.d.ts.map +0 -1
  196. package/dist/types/src/experimental/index.d.ts +0 -3
  197. package/dist/types/src/experimental/index.d.ts.map +0 -1
  198. package/dist/types/src/experimental/ner/ner.test.d.ts +0 -2
  199. package/dist/types/src/experimental/ner/ner.test.d.ts.map +0 -1
  200. package/dist/types/src/experimental/research/exa.d.ts +0 -6
  201. package/dist/types/src/experimental/research/exa.d.ts.map +0 -1
  202. package/dist/types/src/experimental/research/research.test.d.ts.map +0 -1
  203. package/dist/types/src/session/tools.d.ts +0 -18
  204. package/dist/types/src/session/tools.d.ts.map +0 -1
  205. package/dist/types/src/testing/artifacts.test.d.ts +0 -1
  206. package/dist/types/src/testing/artifacts.test.d.ts.map +0 -1
  207. package/dist/types/src/testing/data.d.ts +0 -2
  208. package/dist/types/src/testing/data.d.ts.map +0 -1
  209. package/dist/types/src/testing/defs.d.ts +0 -5
  210. package/dist/types/src/testing/defs.d.ts.map +0 -1
  211. package/dist/types/src/testing/logger.d.ts +0 -12
  212. package/dist/types/src/testing/logger.d.ts.map +0 -1
  213. package/dist/types/src/testing/object-extraction.test.d.ts +0 -1
  214. package/dist/types/src/testing/object-extraction.test.d.ts.map +0 -1
  215. package/dist/types/src/testing/ollama.d.ts +0 -6
  216. package/dist/types/src/testing/ollama.d.ts.map +0 -1
  217. package/dist/types/src/testing/printer.d.ts +0 -6
  218. package/dist/types/src/testing/printer.d.ts.map +0 -1
  219. package/dist/types/src/testing/query-promts.d.ts +0 -5
  220. package/dist/types/src/testing/query-promts.d.ts.map +0 -1
  221. package/dist/types/src/testing/query.test.d.ts +0 -2
  222. package/dist/types/src/testing/query.test.d.ts.map +0 -1
  223. package/dist/types/src/testing/test-data.d.ts +0 -29
  224. package/dist/types/src/testing/test-data.d.ts.map +0 -1
  225. package/dist/types/src/testing/test-schema.d.ts +0 -52
  226. package/dist/types/src/testing/test-schema.d.ts.map +0 -1
  227. package/dist/types/src/util/index.d.ts +0 -2
  228. package/dist/types/src/util/index.d.ts.map +0 -1
  229. package/dist/types/src/util/trim.d.ts +0 -5
  230. package/dist/types/src/util/trim.d.ts.map +0 -1
  231. package/src/ai-service/client.test.ts +0 -247
  232. package/src/ai-service/defs.ts +0 -39
  233. package/src/ai-service/edge-client.ts +0 -60
  234. package/src/ai-service/index.ts +0 -13
  235. package/src/ai-service/message-collector.ts +0 -84
  236. package/src/ai-service/ollama-client.ts +0 -506
  237. package/src/ai-service/parser.ts +0 -369
  238. package/src/ai-service/service.ts +0 -31
  239. package/src/ai-service/stream.test.ts +0 -125
  240. package/src/ai-service/stream.ts +0 -118
  241. package/src/ai-service/testing/index.ts +0 -6
  242. package/src/ai-service/testing/mock.ts +0 -30
  243. package/src/ai-service/testing/test-stream.ts +0 -93
  244. package/src/ai-service/transform.ts +0 -121
  245. package/src/ai-service/types.ts +0 -112
  246. package/src/ai-service/util/index.ts +0 -5
  247. package/src/ai-service/util/sse.ts +0 -341
  248. package/src/bin/chat.ts +0 -79
  249. package/src/experimental/conversation/conversation.test.ts +0 -73
  250. package/src/experimental/conversation/conversation.ts +0 -142
  251. package/src/experimental/conversation/index.ts +0 -5
  252. package/src/experimental/conversation/types.ts +0 -126
  253. package/src/experimental/cypher/ast.ts +0 -75
  254. package/src/experimental/cypher/combinators.test.ts +0 -137
  255. package/src/experimental/cypher/combinators.ts +0 -148
  256. package/src/experimental/cypher/echo-data-source.ts +0 -105
  257. package/src/experimental/cypher/execution-plan.test.ts +0 -44
  258. package/src/experimental/cypher/execution-plan.ts +0 -208
  259. package/src/experimental/cypher/index.ts +0 -8
  260. package/src/experimental/cypher/parjs-shims.d.ts +0 -10
  261. package/src/experimental/cypher/parjs.ts +0 -10
  262. package/src/experimental/cypher/parser.ts +0 -19
  263. package/src/experimental/cypher/query-executor.test.ts +0 -47
  264. package/src/experimental/cypher/query-executor.ts +0 -145
  265. package/src/experimental/cypher/schema.test.ts +0 -17
  266. package/src/experimental/cypher/schema.ts +0 -86
  267. package/src/experimental/index.ts +0 -6
  268. package/src/experimental/ner/ner.test.ts +0 -163
  269. package/src/experimental/research/exa.ts +0 -38
  270. package/src/experimental/research/instructions.tpl +0 -64
  271. package/src/experimental/research/research.test.ts +0 -263
  272. package/src/session/tools.ts +0 -117
  273. package/src/testing/artifacts.test.ts +0 -182
  274. package/src/testing/data.ts +0 -13
  275. package/src/testing/defs.ts +0 -9
  276. package/src/testing/logger.ts +0 -129
  277. package/src/testing/object-extraction.test.ts +0 -71
  278. package/src/testing/ollama.ts +0 -15
  279. package/src/testing/printer.ts +0 -41
  280. package/src/testing/query-promts.ts +0 -75
  281. package/src/testing/query.test.ts +0 -88
  282. package/src/testing/test-data.ts +0 -379
  283. package/src/testing/test-schema.ts +0 -79
  284. package/src/util/index.ts +0 -5
  285. package/src/util/trim.ts +0 -15
  286. package/vendor/parjs-browser.mjs +0 -4
  287. package/vendor/parjs-default.mjs +0 -8
  288. /package/dist/types/{src/bin → bin}/chat.d.ts +0 -0
  289. /package/dist/types/src/{experimental/research → research}/research.test.d.ts +0 -0
@@ -1,2786 +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 { assertArgument, invariant } from "@dxos/invariant";
363
- import { log as log2 } from "@dxos/log";
364
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/edge-client.ts";
365
- var AIServiceEdgeClient = class {
366
- constructor({ endpoint }) {
367
- invariant(endpoint, "endpoint is required", {
368
- F: __dxlog_file2,
369
- L: 20,
370
- S: this,
371
- A: [
372
- "endpoint",
373
- "'endpoint is required'"
374
- ]
375
- });
376
- this._endpoint = endpoint;
377
- }
378
- /**
379
- * Generate non-streaming response.
380
- */
381
- async exec(request) {
382
- throw new Error("Not implemented");
383
- }
384
- /**
385
- * Process request and open message stream.
386
- */
387
- async execStream(request) {
388
- assertArgument(typeof request.model === "string", "model is required");
389
- log2("requesting", {
390
- endpoint: this._endpoint
391
- }, {
392
- F: __dxlog_file2,
393
- L: 36,
394
- S: this,
395
- C: (f, a) => f(...a)
396
- });
397
- const controller = new AbortController();
398
- const response = await fetch(`${this._endpoint}/generate`, {
399
- signal: controller.signal,
400
- method: "POST",
401
- headers: {
402
- "Content-Type": "application/json"
403
- },
404
- body: JSON.stringify({
405
- // TODO(dmaretskyi): Errors if tools are not provided.
406
- tools: request.tools ?? [],
407
- ...request
408
- })
409
- });
410
- if (!response.ok) {
411
- throw await parseErrorResponse(response);
412
- }
413
- invariant(response.body instanceof ReadableStream, void 0, {
414
- F: __dxlog_file2,
415
- L: 53,
416
- S: this,
417
- A: [
418
- "response.body instanceof ReadableStream",
419
- ""
420
- ]
421
- });
422
- return createGenerationStream(response, controller);
423
- }
424
- };
425
- var parseErrorResponse = async (response) => {
426
- throw new Error(`AI Service error: ${response.status} ${response.statusText} ${await response.text()}`);
427
- };
428
-
429
- // packages/experimental/assistant/src/ai-service/message-collector.ts
430
- var MessageCollector = class {
431
- constructor() {
432
- this._messages = [];
433
- this._pendingMessage = void 0;
434
- }
435
- get messages() {
436
- return this._messages;
437
- }
438
- get pendingMessage() {
439
- return this._pendingMessage;
440
- }
441
- push(event) {
442
- switch (event.type) {
443
- case "message_start":
444
- this._pendingMessage = event.message;
445
- break;
446
- case "message_stop":
447
- if (this._pendingMessage) {
448
- this._messages.push(this._pendingMessage);
449
- this._pendingMessage = void 0;
450
- }
451
- break;
452
- case "content_block_start":
453
- if (this._pendingMessage) {
454
- this._pendingMessage.content = this._pendingMessage.content || [];
455
- this._pendingMessage.content[event.index] = event.content;
456
- }
457
- break;
458
- case "content_block_delta":
459
- if (this._pendingMessage && this._pendingMessage.content) {
460
- const block = this._pendingMessage.content[event.index];
461
- if (block && event.delta.type === "text_delta" && block.type === "text") {
462
- block.text = (block.text || "") + event.delta.text;
463
- }
464
- }
465
- break;
466
- case "content_block_stop":
467
- if (this._pendingMessage && this._pendingMessage.content) {
468
- const block = this._pendingMessage.content[event.index];
469
- if (block) {
470
- block.pending = false;
471
- }
472
- }
473
- break;
474
- case "message_delta":
475
- if (this._pendingMessage && event.delta) {
476
- Object.assign(this._pendingMessage, event.delta);
477
- }
478
- break;
479
- }
480
- }
481
- pushMessage(message) {
482
- this._messages.push(message);
483
- }
484
- };
485
- function* emitMessageAsEvents(message) {
486
- yield {
487
- type: "message_start",
488
- message
489
- };
490
- yield {
491
- type: "message_stop"
492
- };
493
- }
494
-
495
- // packages/experimental/assistant/src/ai-service/types.ts
496
- import { Schema } from "effect";
497
- import { Tool, Message } from "@dxos/artifact";
498
- var createArtifactElement = (id) => `<artifact id=${id} />`;
499
- var LLMModel = Schema.Literal(...DEFAULT_EDGE_MODELS, ...DEFAULT_OLLAMA_MODELS);
500
- var ToolTypes = Object.freeze({
501
- // TODO(dmaretskyi): Not implemented yet.
502
- // DatabaseQuery: 'database_query',
503
- TextToImage: "text_to_image"
504
- });
505
- var GenerateRequest = Schema.Struct({
506
- /**
507
- * Preferred model or system default.
508
- */
509
- model: Schema.optional(LLMModel),
510
- /**
511
- * Tools available for the LLM.
512
- */
513
- tools: Schema.optional(Schema.Array(Tool).pipe(Schema.mutable)),
514
- /**
515
- * System instructions to the LLM.
516
- */
517
- systemPrompt: Schema.optional(Schema.String),
518
- /**
519
- * History of messages to include in the context window.
520
- */
521
- // TODO(burdon): Rename messages.
522
- history: Schema.optional(Schema.Array(Message)),
523
- /**
524
- * Current request.
525
- */
526
- prompt: Schema.optional(Message)
527
- });
528
- var GenerateResponse = Schema.Struct({
529
- messages: Schema.Array(Message),
530
- /**
531
- * Number of tokens used in the response.
532
- */
533
- tokenCount: Schema.optional(Schema.Number)
534
- });
535
-
536
- // packages/experimental/assistant/src/session/tools.ts
537
- import { Message as Message2, ToolResult } from "@dxos/artifact";
538
- import { create } from "@dxos/echo-schema";
539
- import { invariant as invariant2 } from "@dxos/invariant";
540
- import { log as log3 } from "@dxos/log";
541
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/session/tools.ts";
542
- var isToolUse = (message, { onlyToolNames } = {}) => {
543
- const block = message.content.at(-1);
544
- invariant2(block, void 0, {
545
- F: __dxlog_file3,
546
- L: 12,
547
- S: void 0,
548
- A: [
549
- "block",
550
- ""
551
- ]
552
- });
553
- return block.type === "tool_use" && (!onlyToolNames || onlyToolNames.includes(block.name));
554
- };
555
- var runTools = async ({ message, tools, extensions }) => {
556
- const toolCalls = message.content.filter((block) => block.type === "tool_use");
557
- invariant2(toolCalls.length === 1, void 0, {
558
- F: __dxlog_file3,
559
- L: 34,
560
- S: void 0,
561
- A: [
562
- "toolCalls.length === 1",
563
- ""
564
- ]
565
- });
566
- const toolCall = toolCalls[0];
567
- const tool = tools.find((tool2) => tool2.name === toolCall.name);
568
- if (!tool) {
569
- const resultMessage = create(Message2, {
570
- role: "user",
571
- content: [
572
- {
573
- type: "tool_result",
574
- toolUseId: toolCall.id,
575
- content: `Tool not found: ${toolCall.name}`,
576
- isError: true
577
- }
578
- ]
579
- });
580
- return {
581
- type: "continue",
582
- message: resultMessage
583
- };
584
- }
585
- let toolResult;
586
- try {
587
- invariant2(tool.execute, void 0, {
588
- F: __dxlog_file3,
589
- L: 59,
590
- S: void 0,
591
- A: [
592
- "tool.execute",
593
- ""
594
- ]
595
- });
596
- toolResult = await tool.execute(toolCall.input, {
597
- extensions
598
- });
599
- } catch (error) {
600
- log3("tool error", {
601
- error
602
- }, {
603
- F: __dxlog_file3,
604
- L: 62,
605
- S: void 0,
606
- C: (f, a) => f(...a)
607
- });
608
- toolResult = ToolResult.Error(error.message);
609
- }
610
- switch (toolResult.kind) {
611
- case "error": {
612
- log3("tool error", {
613
- message: toolResult.message
614
- }, {
615
- F: __dxlog_file3,
616
- L: 68,
617
- S: void 0,
618
- C: (f, a) => f(...a)
619
- });
620
- const resultMessage = create(Message2, {
621
- role: "user",
622
- content: [
623
- {
624
- type: "tool_result",
625
- toolUseId: toolCall.id,
626
- content: toolResult.message,
627
- isError: true
628
- }
629
- ]
630
- });
631
- return {
632
- type: "continue",
633
- message: resultMessage
634
- };
635
- }
636
- case "success": {
637
- log3("tool success", {
638
- result: toolResult.result
639
- }, {
640
- F: __dxlog_file3,
641
- L: 89,
642
- S: void 0,
643
- C: (f, a) => f(...a)
644
- });
645
- const resultMessage = create(Message2, {
646
- role: "user",
647
- content: [
648
- {
649
- type: "tool_result",
650
- toolUseId: toolCall.id,
651
- content: typeof toolResult.result === "string" ? toolResult.result : JSON.stringify(toolResult.result) ?? ""
652
- },
653
- ...toolResult.extractContentBlocks ?? []
654
- ]
655
- });
656
- return {
657
- type: "continue",
658
- message: resultMessage
659
- };
660
- }
661
- case "break": {
662
- log3("tool break", {
663
- result: toolResult.result
664
- }, {
665
- F: __dxlog_file3,
666
- L: 110,
667
- S: void 0,
668
- C: (f, a) => f(...a)
669
- });
670
- return {
671
- type: "break",
672
- result: toolResult.result
673
- };
674
- }
675
- }
676
- };
677
-
678
- // packages/experimental/assistant/src/session/version-pin.ts
679
- import { Schema as Schema2 } from "effect";
680
- import { getVersion } from "@dxos/echo-db";
681
- import { ObjectId } from "@dxos/echo-schema";
682
- var ObjectVersionSchema = Schema2.Unknown;
683
- var VersionPinSchema = Schema2.Struct({
684
- // TODO(dmaretskyi): Use Ref when those support encoding.
685
- objectId: ObjectId,
686
- // TODO(dmaretskyi): Could be opaque
687
- version: ObjectVersionSchema
688
- });
689
- var VersionPin = class extends VersionPinSchema {
690
- static {
691
- this.DISPOSITION = "version-pin";
692
- }
693
- static fromObject(object) {
694
- return VersionPin.make({
695
- objectId: object.id,
696
- version: getVersion(object)
697
- });
698
- }
699
- static createBlock(pin) {
700
- return {
701
- type: "json",
702
- disposition: VersionPin.DISPOSITION,
703
- json: JSON.stringify(pin)
704
- };
705
- }
706
- };
707
-
708
- // packages/experimental/assistant/src/session/session.ts
709
- import { Option, Schema as Schema4 } from "effect";
710
- import { defineTool as defineTool2, Message as Message4, structuredOutputParser, ToolResult as ToolResult3 } from "@dxos/artifact";
711
- import { Event as Event2, synchronized } from "@dxos/async";
712
- import { ObjectVersion } from "@dxos/echo-db";
713
- import { create as create3 } from "@dxos/echo-schema";
714
- import { invariant as invariant5 } from "@dxos/invariant";
715
- import { log as log6 } from "@dxos/log";
716
-
717
- // packages/experimental/assistant/src/ai-service/ollama-client.ts
718
- import { Schema as Schema3 } from "effect";
719
- import { defineTool, ToolResult as ToolResult2 } from "@dxos/artifact";
720
- import { ObjectId as ObjectId2 } from "@dxos/echo-schema";
721
- import { invariant as invariant3 } from "@dxos/invariant";
722
- import { log as log4 } from "@dxos/log";
723
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/ollama-client.ts";
724
- var OllamaClient = class {
725
- /**
726
- * Check if Ollama server is running and accessible.
727
- * @returns Promise that resolves to true if Ollama is running, false otherwise.
728
- */
729
- static async isRunning() {
730
- try {
731
- const response = await fetch(`${DEFAULT_OLLAMA_ENDPOINT}/api/version`, {
732
- method: "GET",
733
- headers: {
734
- "Content-Type": "application/json"
735
- },
736
- signal: AbortSignal.timeout(100)
737
- });
738
- return response.ok;
739
- } catch (error) {
740
- return false;
741
- }
742
- }
743
- constructor({ endpoint, tools, overrides, maxToolInvocations } = {}) {
744
- this._endpoint = endpoint ?? DEFAULT_OLLAMA_ENDPOINT;
745
- this._tools = tools ?? [];
746
- this._modelOverride = overrides?.model;
747
- this._temperatureOverride = overrides?.temperature;
748
- this._maxToolInvocations = maxToolInvocations ?? 3;
749
- }
750
- _getEmbededTools(clientTools) {
751
- return [
752
- ...this._tools,
753
- ...clientTools.filter((tool) => tool.type !== void 0 && WELL_KNOWN_TOOLS[tool.type]).map((tool) => WELL_KNOWN_TOOLS[tool.type])
754
- ];
755
- }
756
- async *_generateStream(request, signal) {
757
- invariant3(request.prompt === void 0, "Prompt must be in history", {
758
- F: __dxlog_file4,
759
- L: 88,
760
- S: this,
761
- A: [
762
- "request.prompt === undefined",
763
- "'Prompt must be in history'"
764
- ]
765
- });
766
- const ollamaRequest = {
767
- model: this._modelOverride ?? request.model ?? "llama3",
768
- messages: [],
769
- stream: true,
770
- options: {
771
- temperature: this._temperatureOverride
772
- }
773
- };
774
- if (request.systemPrompt) {
775
- ollamaRequest.messages.push({
776
- role: "system",
777
- content: request.systemPrompt
778
- });
779
- }
780
- if (request.history?.length) {
781
- for (const message of request.history) {
782
- const role = message.role === "assistant" ? "assistant" : "user";
783
- if (message.content.length === 0) {
784
- continue;
785
- }
786
- for (const content of message.content) {
787
- switch (content.type) {
788
- case "text": {
789
- ollamaRequest.messages.push({
790
- role,
791
- content: content.text
792
- });
793
- break;
794
- }
795
- case "tool_use": {
796
- ollamaRequest.messages.push({
797
- role: "assistant",
798
- content: "",
799
- tool_calls: [
800
- {
801
- function: {
802
- name: content.name,
803
- arguments: content.input
804
- }
805
- }
806
- ]
807
- });
808
- break;
809
- }
810
- case "tool_result": {
811
- ollamaRequest.messages.push({
812
- role: "tool",
813
- content: JSON.stringify({
814
- type: "tool_result",
815
- toolUseId: content.toolUseId,
816
- content: content.content
817
- })
818
- });
819
- break;
820
- }
821
- }
822
- }
823
- }
824
- }
825
- if (request.tools?.length || this._tools.length) {
826
- const allTools = [
827
- ...request.tools ?? [],
828
- ...this._tools
829
- ];
830
- const withWellKnownTools = allTools.map((tool) => tool.type !== void 0 && WELL_KNOWN_TOOLS[tool.type] ? WELL_KNOWN_TOOLS[tool.type] : tool);
831
- if (withWellKnownTools.length > 0) {
832
- ollamaRequest.tools = withWellKnownTools.map((tool) => ({
833
- type: "function",
834
- function: {
835
- name: tool.name,
836
- description: tool.description,
837
- parameters: {
838
- type: "object",
839
- properties: tool.parameters?.properties,
840
- required: tool.parameters?.required
841
- }
842
- }
843
- }));
844
- }
845
- }
846
- log4("generate request", {
847
- history: request.history,
848
- prompt: request.prompt,
849
- ollamaRequest
850
- }, {
851
- F: __dxlog_file4,
852
- L: 182,
853
- S: this,
854
- C: (f, a) => f(...a)
855
- });
856
- const response = await fetch(`${this._endpoint}/api/chat`, {
857
- method: "POST",
858
- headers: {
859
- "Content-Type": "application/json"
860
- },
861
- body: JSON.stringify(ollamaRequest),
862
- signal
863
- });
864
- if (!response.ok) {
865
- throw await parseErrorResponse2(response);
866
- }
867
- if (!response.body) {
868
- throw new Error("Ollama API returned no response body");
869
- }
870
- const reader = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new OllamaDecoderStream()).getReader();
871
- try {
872
- const messageId = ObjectId2.random();
873
- yield {
874
- type: "message_start",
875
- message: {
876
- id: messageId,
877
- role: "assistant",
878
- content: []
879
- }
880
- };
881
- const textBlock = {
882
- type: "text",
883
- text: ""
884
- };
885
- let currentBlockIndex = 0;
886
- yield {
887
- type: "content_block_start",
888
- index: currentBlockIndex,
889
- content: textBlock
890
- };
891
- while (true) {
892
- const { done, value: data } = await reader.read();
893
- if (done) {
894
- break;
895
- }
896
- log4("ollama data", {
897
- data
898
- }, {
899
- F: __dxlog_file4,
900
- L: 244,
901
- S: this,
902
- C: (f, a) => f(...a)
903
- });
904
- if (data.message?.content) {
905
- yield {
906
- type: "content_block_delta",
907
- index: 0,
908
- delta: {
909
- type: "text_delta",
910
- text: data.message.content
911
- }
912
- };
913
- }
914
- if (data.message?.tool_calls && data.message?.tool_calls?.length > 0) {
915
- if (data.message.tool_calls.length > 1) {
916
- log4.warn("Ollama returned multiple tool calls. Only the first one will be used.", void 0, {
917
- F: __dxlog_file4,
918
- L: 261,
919
- S: this,
920
- C: (f, a) => f(...a)
921
- });
922
- }
923
- yield {
924
- type: "content_block_stop",
925
- index: currentBlockIndex++
926
- };
927
- yield {
928
- type: "content_block_start",
929
- index: currentBlockIndex,
930
- content: {
931
- type: "tool_use",
932
- id: ObjectId2.random(),
933
- name: data.message.tool_calls[0].function.name,
934
- input: sanitizeToolArguments(data.message.tool_calls[0].function.arguments)
935
- }
936
- };
937
- yield {
938
- type: "message_delta",
939
- delta: {
940
- stopReason: "tool_use"
941
- }
942
- };
943
- }
944
- }
945
- yield {
946
- type: "content_block_stop",
947
- index: currentBlockIndex
948
- };
949
- yield {
950
- type: "message_stop"
951
- };
952
- } finally {
953
- reader.releaseLock();
954
- }
955
- }
956
- /**
957
- * Generate non-streaming response.
958
- */
959
- async exec(request) {
960
- throw new Error("Not implemented");
961
- }
962
- async execStream(request) {
963
- const controller = new AbortController();
964
- try {
965
- return new GenerationStreamImpl(controller, async function* () {
966
- const collector = new MessageCollector();
967
- let toolInvocations = 0;
968
- while (true) {
969
- for await (const event of this._generateStream({
970
- ...request,
971
- history: [
972
- ...request.history ?? [],
973
- ...request.prompt ? [
974
- request.prompt
975
- ] : [],
976
- ...collector.messages
977
- ],
978
- prompt: void 0
979
- }, controller.signal)) {
980
- collector.push(event);
981
- yield event;
982
- }
983
- if (collector.messages.length > 0 && !isToolUse(collector.messages.at(-1), {
984
- onlyToolNames: this._getEmbededTools(request.tools ?? []).map((tool) => tool.name)
985
- })) {
986
- break;
987
- }
988
- if (++toolInvocations > this._maxToolInvocations) {
989
- throw new Error("Maximum number of tool invocations reached");
990
- }
991
- const result = await runTools({
992
- message: collector.messages.at(-1),
993
- tools: this._getEmbededTools(request.tools ?? [])
994
- });
995
- switch (result.type) {
996
- case "continue": {
997
- collector.pushMessage(result.message);
998
- yield* emitMessageAsEvents(result.message);
999
- break;
1000
- }
1001
- case "break": {
1002
- throw new Error("Tool use breaks not allowed");
1003
- }
1004
- }
1005
- }
1006
- }.bind(this));
1007
- } catch (error) {
1008
- controller.abort();
1009
- throw error;
1010
- }
1011
- }
1012
- };
1013
- var sanitizeToolArguments = (args) => {
1014
- if (args.type === "object" && typeof args.properties === "object" && Array.isArray(args.required)) {
1015
- return args.properties;
1016
- }
1017
- return args;
1018
- };
1019
- var SAMPLE_IMAGE_URL = "https://images.nightcafe.studio/jobs/BNmcRhHCM1JRKoUtqSei/BNmcRhHCM1JRKoUtqSei--1--5b9rv.jpg";
1020
- var WELL_KNOWN_TOOLS = {
1021
- [ToolTypes.TextToImage]: defineTool("system", {
1022
- name: "text-to-image",
1023
- description: "Generate an image from a text prompt",
1024
- schema: Schema3.Struct({
1025
- prompt: Schema3.String.annotations({
1026
- description: "The text prompt describing the image to generate"
1027
- })
1028
- }),
1029
- execute: async ({ prompt }) => {
1030
- const image = await fetch(SAMPLE_IMAGE_URL).then(async (res) => Buffer.from(await res.arrayBuffer()));
1031
- const imageBase64 = image.toString("base64");
1032
- const id = ObjectId2.random();
1033
- return ToolResult2.Success(`The generation was successful. Image ID: ${id} Prompt: ${prompt}`, [
1034
- {
1035
- type: "image",
1036
- id,
1037
- source: {
1038
- type: "base64",
1039
- mediaType: "image/jpeg",
1040
- data: imageBase64
1041
- }
1042
- }
1043
- ]);
1044
- }
1045
- })
1046
- };
1047
- var OllamaDecoderStream = class extends TransformStream {
1048
- constructor() {
1049
- super({
1050
- transform: (chunk, controller) => {
1051
- this._buffer += chunk;
1052
- const lines = this._buffer.split("\n");
1053
- this._buffer = lines.pop() || "";
1054
- for (const line of lines) {
1055
- controller.enqueue(JSON.parse(line.trim()));
1056
- }
1057
- },
1058
- flush: (controller) => {
1059
- this._buffer = this._buffer.trim();
1060
- if (this._buffer.length > 0) {
1061
- controller.enqueue(JSON.parse(this._buffer));
1062
- }
1063
- }
1064
- });
1065
- this._buffer = "";
1066
- }
1067
- };
1068
- var ModelDoesNotSupportToolsError = class extends Schema3.TaggedError()("ModelDoesNotSupportToolsError", {
1069
- model: Schema3.String
1070
- }) {
1071
- };
1072
- var ModelNotFoundError = class extends Schema3.TaggedError()("ModelNotFoundError", {
1073
- model: Schema3.String
1074
- }) {
1075
- };
1076
- var parseOllamaError = (error) => {
1077
- {
1078
- const match = error.match(/^([^']+) does not support tools$/);
1079
- if (match) {
1080
- return new ModelDoesNotSupportToolsError({
1081
- model: match[1]
1082
- });
1083
- }
1084
- }
1085
- {
1086
- const match = error.match(/^model "([^"]+)" not found, try pulling it first$/);
1087
- if (match) {
1088
- return new ModelNotFoundError({
1089
- model: match[1]
1090
- });
1091
- }
1092
- }
1093
- throw new Error(`Ollama API error: ${error}`);
1094
- };
1095
- var parseErrorResponse2 = async (response) => {
1096
- if (response.headers.get("content-type")?.includes("application/json")) {
1097
- const body = await response.json();
1098
- return parseOllamaError(body.error);
1099
- }
1100
- throw new Error(`Ollama API error: ${response.status} ${response.statusText} ${await response.text()}`);
1101
- };
1102
-
1103
- // packages/experimental/assistant/src/ai-service/parser.ts
1104
- import { Message as Message3 } from "@dxos/artifact";
1105
- import { Event } from "@dxos/async";
1106
- import { create as create2 } from "@dxos/echo-schema";
1107
- import { invariant as invariant4 } from "@dxos/invariant";
1108
- import { log as log5 } from "@dxos/log";
1109
- import { isNotFalsy, safeParseJson } from "@dxos/util";
1110
-
1111
- // packages/experimental/assistant/src/ai-service/transform.ts
1112
- import * as P from "parsimmon";
1113
- var textChunk = P.regexp(/[^<]+/).map((content) => ({
1114
- type: "text",
1115
- content
1116
- }));
1117
- 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]) => [
1118
- name,
1119
- value
1120
- ]);
1121
- var tagName = P.regexp(/[a-zA-Z_][a-zA-Z0-9_-]*/);
1122
- var selfClosingTag = P.seqMap(
1123
- //
1124
- P.string("<"),
1125
- tagName,
1126
- P.optWhitespace.then(attribute).many(),
1127
- P.optWhitespace.then(P.string("/>")),
1128
- P.optWhitespace,
1129
- (_, tag, attributes, __) => ({
1130
- type: "tag",
1131
- tag,
1132
- attributes: Object.fromEntries(attributes),
1133
- content: [],
1134
- selfClosing: true
1135
- })
1136
- );
1137
- var openTag = P.seqMap(
1138
- //
1139
- P.string("<"),
1140
- tagName,
1141
- P.optWhitespace.then(attribute).many(),
1142
- P.string(">"),
1143
- P.regexp(/[^<]*/),
1144
- (_, tag, attributes, __, content) => ({
1145
- type: "tag",
1146
- tag,
1147
- attributes: Object.fromEntries(attributes),
1148
- content: content.length ? [
1149
- {
1150
- type: "text",
1151
- content
1152
- }
1153
- ] : []
1154
- })
1155
- );
1156
- var closeTag = P.seqMap(
1157
- //
1158
- P.string("</"),
1159
- tagName,
1160
- P.string(">"),
1161
- P.optWhitespace,
1162
- (_, tag) => ({
1163
- type: "tag",
1164
- tag,
1165
- content: [],
1166
- closing: true
1167
- })
1168
- );
1169
- var mixedChunk = P.alt(selfClosingTag, openTag, closeTag, textChunk);
1170
- var StreamTransform = class {
1171
- constructor() {
1172
- this._buffer = "";
1173
- }
1174
- transform(chunk) {
1175
- this._buffer += chunk;
1176
- const results = [];
1177
- const parser = mixedChunk.many().skip(P.optWhitespace);
1178
- const result = parser.parse(this._buffer);
1179
- if (result.status) {
1180
- for (const chunk2 of result.value) {
1181
- results.push(chunk2);
1182
- }
1183
- this._buffer = "";
1184
- }
1185
- return results;
1186
- }
1187
- // TODO(burdon): Process remaining buffer?
1188
- flush() {
1189
- const remaining = this._buffer;
1190
- this._buffer = "";
1191
- return remaining.length > 0 ? [
1192
- {
1193
- type: "text",
1194
- content: remaining
1195
- }
1196
- ] : [];
1197
- }
1198
- };
1199
-
1200
- // packages/experimental/assistant/src/ai-service/parser.ts
1201
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/ai-service/parser.ts";
1202
- var MixedStreamParser = class {
1203
- constructor() {
1204
- /**
1205
- * New message.
1206
- */
1207
- this.message = new Event();
1208
- /**
1209
- * Complete block added to Message.
1210
- */
1211
- this.block = new Event();
1212
- /**
1213
- * Update partial block (while streaming).
1214
- */
1215
- this.update = new Event();
1216
- this.streamEvent = new Event();
1217
- }
1218
- _emitBlock(contentBlock, streamBlock) {
1219
- const messageBlock = streamBlock ? mergeMessageBlock(contentBlock, streamBlock) : contentBlock;
1220
- if (messageBlock) {
1221
- if (messageBlock.type === "text" && messageBlock.text.length === 0) {
1222
- return;
1223
- }
1224
- invariant4(this._message, void 0, {
1225
- F: __dxlog_file5,
1226
- L: 49,
1227
- S: this,
1228
- A: [
1229
- "this._message",
1230
- ""
1231
- ]
1232
- });
1233
- this._message.content.push(messageBlock);
1234
- this.block.emit(messageBlock);
1235
- }
1236
- }
1237
- _emitUpdate(contentBlock, streamBlock) {
1238
- const messageBlock = mergeMessageBlock(contentBlock, streamBlock);
1239
- if (messageBlock) {
1240
- messageBlock.pending = true;
1241
- this.update.emit(messageBlock);
1242
- }
1243
- }
1244
- /**
1245
- * Parse stream until end.
1246
- */
1247
- async parse(stream) {
1248
- const transformer = new StreamTransform();
1249
- let contentBlock;
1250
- let streamBlock;
1251
- const stack = [];
1252
- const messagesCollected = [];
1253
- for await (const event of stream) {
1254
- log5("streamEvent", {
1255
- event
1256
- }, {
1257
- F: __dxlog_file5,
1258
- L: 83,
1259
- S: this,
1260
- C: (f, a) => f(...a)
1261
- });
1262
- this.streamEvent.emit(event);
1263
- switch (event.type) {
1264
- //
1265
- // Messages.
1266
- //
1267
- case "message_start": {
1268
- if (this._message) {
1269
- log5.warn("unexpected message_start", void 0, {
1270
- F: __dxlog_file5,
1271
- L: 94,
1272
- S: this,
1273
- C: (f, a) => f(...a)
1274
- });
1275
- }
1276
- this._message = create2(Message3, {
1277
- role: event.message.role,
1278
- content: [
1279
- ...event.message.content
1280
- ]
1281
- });
1282
- this.message.emit(this._message);
1283
- break;
1284
- }
1285
- case "message_delta": {
1286
- if (!this._message) {
1287
- log5.warn("unexpected message_delta", void 0, {
1288
- F: __dxlog_file5,
1289
- L: 104,
1290
- S: this,
1291
- C: (f, a) => f(...a)
1292
- });
1293
- }
1294
- break;
1295
- }
1296
- case "message_stop": {
1297
- if (!this._message) {
1298
- log5.warn("unexpected message_stop", void 0, {
1299
- F: __dxlog_file5,
1300
- L: 112,
1301
- S: this,
1302
- C: (f, a) => f(...a)
1303
- });
1304
- } else {
1305
- messagesCollected.push(this._message);
1306
- this._message = void 0;
1307
- }
1308
- break;
1309
- }
1310
- //
1311
- // Content blocks.
1312
- //
1313
- case "content_block_start": {
1314
- if (contentBlock) {
1315
- log5.warn("unexpected content_block_start", {
1316
- content: contentBlock
1317
- }, {
1318
- F: __dxlog_file5,
1319
- L: 126,
1320
- S: this,
1321
- C: (f, a) => f(...a)
1322
- });
1323
- }
1324
- contentBlock = event.content;
1325
- break;
1326
- }
1327
- case "content_block_delta": {
1328
- if (!contentBlock) {
1329
- log5.warn("unexpected content_block_delta", void 0, {
1330
- F: __dxlog_file5,
1331
- L: 136,
1332
- S: this,
1333
- C: (f, a) => f(...a)
1334
- });
1335
- break;
1336
- }
1337
- switch (event.delta.type) {
1338
- //
1339
- // Text
1340
- //
1341
- case "text_delta": {
1342
- const chunks = transformer.transform(event.delta.text);
1343
- for (const chunk of chunks) {
1344
- log5("text_delta", {
1345
- chunk
1346
- }, {
1347
- F: __dxlog_file5,
1348
- L: 147,
1349
- S: this,
1350
- C: (f, a) => f(...a)
1351
- });
1352
- switch (streamBlock?.type) {
1353
- //
1354
- // XML Fragment.
1355
- //
1356
- case "tag": {
1357
- if (chunk.type === "tag") {
1358
- if (chunk.selfClosing) {
1359
- streamBlock.content.push(chunk);
1360
- } else if (chunk.closing) {
1361
- if (stack.length > 0) {
1362
- const top = stack.pop();
1363
- invariant4(top && top.type === "tag", void 0, {
1364
- F: __dxlog_file5,
1365
- L: 160,
1366
- S: this,
1367
- A: [
1368
- "top && top.type === 'tag'",
1369
- ""
1370
- ]
1371
- });
1372
- log5("pop", {
1373
- top
1374
- }, {
1375
- F: __dxlog_file5,
1376
- L: 161,
1377
- S: this,
1378
- C: (f, a) => f(...a)
1379
- });
1380
- top.content.push(streamBlock);
1381
- streamBlock = top;
1382
- } else {
1383
- this._emitBlock(contentBlock, streamBlock);
1384
- streamBlock = void 0;
1385
- }
1386
- } else {
1387
- stack.push(streamBlock);
1388
- streamBlock = chunk;
1389
- }
1390
- } else {
1391
- if (streamBlock.content.length === 0) {
1392
- streamBlock.content.push(chunk);
1393
- } else {
1394
- const last = streamBlock.content.at(-1);
1395
- invariant4(last, void 0, {
1396
- F: __dxlog_file5,
1397
- L: 178,
1398
- S: this,
1399
- A: [
1400
- "last",
1401
- ""
1402
- ]
1403
- });
1404
- if (last.type === "text") {
1405
- last.content += chunk.content;
1406
- } else {
1407
- streamBlock.content.push(chunk);
1408
- }
1409
- }
1410
- }
1411
- break;
1412
- }
1413
- //
1414
- // Text Fragment.
1415
- //
1416
- case "text": {
1417
- if (chunk.type === "tag") {
1418
- this._emitBlock(contentBlock, streamBlock);
1419
- if (chunk.selfClosing) {
1420
- this._emitBlock(contentBlock, chunk);
1421
- streamBlock = void 0;
1422
- } else {
1423
- streamBlock = chunk;
1424
- }
1425
- } else {
1426
- streamBlock.content += chunk.content;
1427
- }
1428
- break;
1429
- }
1430
- //
1431
- // No current chunk.
1432
- //
1433
- default: {
1434
- if (chunk.type === "tag" && chunk.selfClosing) {
1435
- this._emitBlock(contentBlock, chunk);
1436
- } else {
1437
- streamBlock = chunk;
1438
- }
1439
- }
1440
- }
1441
- }
1442
- break;
1443
- }
1444
- //
1445
- // JSON
1446
- //
1447
- case "input_json_delta": {
1448
- if (!contentBlock) {
1449
- log5.warn("unexpected input_json_delta", {
1450
- contentBlock
1451
- }, {
1452
- F: __dxlog_file5,
1453
- L: 228,
1454
- S: this,
1455
- C: (f, a) => f(...a)
1456
- });
1457
- break;
1458
- }
1459
- if (streamBlock?.type === "json") {
1460
- streamBlock.content += event.delta.partial_json;
1461
- } else {
1462
- streamBlock = {
1463
- type: "json",
1464
- content: event.delta.partial_json
1465
- };
1466
- }
1467
- break;
1468
- }
1469
- }
1470
- break;
1471
- }
1472
- case "content_block_stop": {
1473
- if (!contentBlock) {
1474
- log5.warn("unexpected content_block_stop", void 0, {
1475
- F: __dxlog_file5,
1476
- L: 245,
1477
- S: this,
1478
- C: (f, a) => f(...a)
1479
- });
1480
- break;
1481
- }
1482
- this._emitBlock(contentBlock, streamBlock);
1483
- contentBlock = void 0;
1484
- streamBlock = void 0;
1485
- break;
1486
- }
1487
- }
1488
- if (contentBlock && streamBlock) {
1489
- this._emitUpdate(contentBlock, streamBlock);
1490
- }
1491
- }
1492
- return messagesCollected;
1493
- }
1494
- };
1495
- var mergeMessageBlock = (contentBlock, streamBlock) => {
1496
- log5("mergeMessageBlock", {
1497
- contentBlock,
1498
- streamBlock
1499
- }, {
1500
- F: __dxlog_file5,
1501
- L: 272,
1502
- S: void 0,
1503
- C: (f, a) => f(...a)
1504
- });
1505
- switch (streamBlock.type) {
1506
- //
1507
- // Text
1508
- //
1509
- case "text": {
1510
- return {
1511
- ...contentBlock,
1512
- type: "text",
1513
- text: streamBlock.content
1514
- };
1515
- }
1516
- //
1517
- // XML
1518
- //
1519
- case "tag": {
1520
- switch (streamBlock.tag) {
1521
- case "cot": {
1522
- const content = streamBlock.content.map((block) => {
1523
- switch (block.type) {
1524
- case "text":
1525
- return block.content;
1526
- default:
1527
- return null;
1528
- }
1529
- }).filter(isNotFalsy).join("\n");
1530
- return {
1531
- ...contentBlock,
1532
- type: "text",
1533
- disposition: "cot",
1534
- text: content
1535
- };
1536
- }
1537
- case "artifact": {
1538
- const { attributes } = streamBlock;
1539
- return {
1540
- type: "json",
1541
- disposition: "artifact",
1542
- json: JSON.stringify(attributes)
1543
- };
1544
- }
1545
- case "suggest": {
1546
- if (streamBlock.content.length === 1 && streamBlock.content[0].type === "text") {
1547
- return {
1548
- type: "json",
1549
- disposition: "suggest",
1550
- json: JSON.stringify({
1551
- text: streamBlock.content[0].content
1552
- })
1553
- };
1554
- }
1555
- break;
1556
- }
1557
- case "proposal": {
1558
- if (streamBlock.content.length === 1 && streamBlock.content[0].type === "text") {
1559
- return {
1560
- type: "json",
1561
- disposition: "proposal",
1562
- json: JSON.stringify({
1563
- text: streamBlock.content[0].content
1564
- })
1565
- };
1566
- }
1567
- break;
1568
- }
1569
- case "select": {
1570
- return {
1571
- type: "json",
1572
- disposition: "select",
1573
- json: JSON.stringify({
1574
- options: streamBlock.content.flatMap((content) => content.type === "tag" && content.content.length === 1 && content.content[0].type === "text" ? [
1575
- content.content[0].content
1576
- ] : [])
1577
- })
1578
- };
1579
- }
1580
- case "tool-list": {
1581
- return {
1582
- type: "json",
1583
- disposition: "tool_list",
1584
- json: JSON.stringify({})
1585
- };
1586
- }
1587
- }
1588
- break;
1589
- }
1590
- //
1591
- // JSON
1592
- //
1593
- case "json": {
1594
- switch (contentBlock.type) {
1595
- case "tool_use": {
1596
- return {
1597
- ...contentBlock,
1598
- input: safeParseJson(streamBlock.content) ?? {}
1599
- };
1600
- }
1601
- }
1602
- return {
1603
- ...contentBlock,
1604
- type: "json",
1605
- disposition: "artifact",
1606
- json: streamBlock.content
1607
- };
1608
- }
1609
- }
1610
- };
1611
-
1612
- // packages/experimental/assistant/src/session/session.ts
1613
- function _ts_decorate(decorators, target, key, desc) {
1614
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1615
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1616
- 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;
1617
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1618
- }
1619
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/session/session.ts";
1620
- var AISession = class _AISession {
1621
- constructor(_options) {
1622
- this._options = _options;
1623
- this._parser = new MixedStreamParser();
1624
- this._pending = [];
1625
- this._history = [];
1626
- this.message = this._parser.message;
1627
- this.block = this._parser.block;
1628
- this.update = this._parser.update;
1629
- this.streamEvent = this._parser.streamEvent;
1630
- this.userMessage = new Event2();
1631
- this._parser.message.on((message) => {
1632
- this._pending.push(message);
1633
- });
1634
- }
1635
- async run(options) {
1636
- const systemTools = [];
1637
- switch (this._options.operationModel) {
1638
- case "planning":
1639
- systemTools.push(this._createQueryArtifactsTool(options.artifacts), this._createPlanningTool(options));
1640
- break;
1641
- case "importing":
1642
- systemTools.push(this._createQueryArtifactsTool(options.artifacts), this._createRequireTool(options.artifacts, (artifactDefinitionIds) => {
1643
- for (const artifactDefinitionId of artifactDefinitionIds) {
1644
- requiredArtifactIds.add(artifactDefinitionId);
1645
- }
1646
- }));
1647
- break;
1648
- case "configured":
1649
- break;
1650
- default:
1651
- throw new TypeError(`Invalid operation model: ${this._options.operationModel}`);
1652
- }
1653
- this._history = [
1654
- ...options.history
1655
- ];
1656
- this._pending = [
1657
- await this._formatUserPrompt(options.artifactDiffResolver, options.prompt, options.history)
1658
- ];
1659
- this.userMessage.emit(this._pending.at(-1));
1660
- this._stream = void 0;
1661
- let error;
1662
- const requiredArtifactIds = new Set(options.requiredArtifactIds ?? []);
1663
- try {
1664
- let more = false;
1665
- do {
1666
- const tools = [
1667
- ...systemTools,
1668
- ...options.tools,
1669
- ...options.artifacts.filter((artifact) => requiredArtifactIds.has(artifact.id)).flatMap((artifact) => artifact.tools)
1670
- ];
1671
- log6("request", {
1672
- pending: this._pending.length,
1673
- history: this._history.length,
1674
- tools: tools.map((tool) => tool.name)
1675
- }, {
1676
- F: __dxlog_file6,
1677
- L: 181,
1678
- S: this,
1679
- C: (f, a) => f(...a)
1680
- });
1681
- this._stream = await options.client.execStream({
1682
- ...options.generationOptions ?? {},
1683
- // TODO(burdon): Rename messages or separate history/message.
1684
- history: [
1685
- ...this._history,
1686
- ...this._pending
1687
- ],
1688
- tools,
1689
- systemPrompt: options.systemPrompt ?? createBaseInstructions({
1690
- availableArtifacts: Array.from(requiredArtifactIds),
1691
- operationModel: this._options.operationModel
1692
- })
1693
- });
1694
- await this._parser.parse(this._stream);
1695
- await this._stream.complete();
1696
- log6("response", {
1697
- pending: this._pending
1698
- }, {
1699
- F: __dxlog_file6,
1700
- L: 206,
1701
- S: this,
1702
- C: (f, a) => f(...a)
1703
- });
1704
- more = false;
1705
- const message = this._pending.at(-1);
1706
- invariant5(message, void 0, {
1707
- F: __dxlog_file6,
1708
- L: 211,
1709
- S: this,
1710
- A: [
1711
- "message",
1712
- ""
1713
- ]
1714
- });
1715
- if (isToolUse(message)) {
1716
- log6("tool request...", void 0, {
1717
- F: __dxlog_file6,
1718
- L: 213,
1719
- S: this,
1720
- C: (f, a) => f(...a)
1721
- });
1722
- const response = await runTools({
1723
- message: this._pending.at(-1),
1724
- tools,
1725
- extensions: options.extensions ?? {}
1726
- });
1727
- log6("tool response", {
1728
- response
1729
- }, {
1730
- F: __dxlog_file6,
1731
- L: 220,
1732
- S: this,
1733
- C: (f, a) => f(...a)
1734
- });
1735
- switch (response.type) {
1736
- case "continue": {
1737
- this._pending = [
1738
- ...this._pending,
1739
- response.message
1740
- ];
1741
- this.userMessage.emit(response.message);
1742
- more = true;
1743
- break;
1744
- }
1745
- }
1746
- }
1747
- } while (more);
1748
- } catch (err) {
1749
- log6.catch(err, void 0, {
1750
- F: __dxlog_file6,
1751
- L: 232,
1752
- S: this,
1753
- C: (f, a) => f(...a)
1754
- });
1755
- if (err instanceof Error && err.message.includes("Overloaded")) {
1756
- error = new AIServiecOverloadedError("AI service overloaded", {
1757
- cause: err
1758
- });
1759
- } else {
1760
- error = new Error("AI service error", {
1761
- cause: err
1762
- });
1763
- }
1764
- } finally {
1765
- this._stream = void 0;
1766
- }
1767
- if (error) {
1768
- throw error;
1769
- }
1770
- return this._pending;
1771
- }
1772
- async runStructured(schema, options) {
1773
- const parser = structuredOutputParser(schema);
1774
- const result = await this.run({
1775
- ...options,
1776
- tools: [
1777
- ...options.tools,
1778
- parser.tool
1779
- ]
1780
- });
1781
- return parser.getResult(result);
1782
- }
1783
- async _formatUserPrompt(artifactDiffResolver, prompt, history) {
1784
- const prelude = [];
1785
- if (artifactDiffResolver) {
1786
- const versions = gatherObjectVersions(history);
1787
- const artifactDiff = await artifactDiffResolver(Array.from(versions.entries()).map(([id, version]) => ({
1788
- id,
1789
- lastVersion: version
1790
- })));
1791
- log6.info("vision", {
1792
- artifactDiff,
1793
- versions
1794
- }, {
1795
- F: __dxlog_file6,
1796
- L: 272,
1797
- S: this,
1798
- C: (f, a) => f(...a)
1799
- });
1800
- for (const [id, { version }] of [
1801
- ...artifactDiff.entries()
1802
- ]) {
1803
- if (ObjectVersion.equals(version, versions.get(id))) {
1804
- artifactDiff.delete(id);
1805
- continue;
1806
- }
1807
- prelude.push(VersionPin.createBlock(VersionPin.make({
1808
- objectId: id,
1809
- version
1810
- })));
1811
- }
1812
- if (artifactDiff.size > 0) {
1813
- prelude.push(createArtifactUpdateBlock(artifactDiff));
1814
- }
1815
- }
1816
- return create3(Message4, {
1817
- role: "user",
1818
- content: [
1819
- ...prelude,
1820
- {
1821
- type: "text",
1822
- text: prompt
1823
- }
1824
- ]
1825
- });
1826
- }
1827
- _createQueryArtifactsTool(artifacts) {
1828
- return defineTool2("system", {
1829
- name: "query_artifact_definitions",
1830
- description: "Query the available artifact definitions",
1831
- schema: Schema4.Struct({}),
1832
- execute: async () => {
1833
- return ToolResult3.Success({
1834
- artifactDefinitions: artifacts.map((artifact) => ({
1835
- id: artifact.id,
1836
- name: artifact.name,
1837
- description: artifact.description
1838
- }))
1839
- });
1840
- }
1841
- });
1842
- }
1843
- _createRequireTool(artifacts, onRequire) {
1844
- return defineTool2("system", {
1845
- name: "require_artifact_definitions",
1846
- description: "Require the use of specific artifact definitions. This will allow the model to interact with artifact definitions and use their tools.",
1847
- schema: Schema4.Struct({
1848
- artifactDefinitionIds: Schema4.Array(Schema4.String).annotations({
1849
- description: "The ids of the artifact definitions to require",
1850
- examples: [
1851
- [
1852
- "artifact:dxos.org/example/Test"
1853
- ]
1854
- ]
1855
- })
1856
- }),
1857
- execute: async ({ artifactDefinitionIds }) => {
1858
- const missingArtifactDefinitionIds = artifactDefinitionIds.filter((artifactId) => !artifacts.some((artifact) => artifact.id === artifactId));
1859
- if (missingArtifactDefinitionIds.length > 0) {
1860
- return ToolResult3.Error(`One or more artifact definition ids are invalid: ${missingArtifactDefinitionIds.join(", ")}`);
1861
- }
1862
- onRequire(artifactDefinitionIds);
1863
- return ToolResult3.Success({});
1864
- }
1865
- });
1866
- }
1867
- _createPlanningTool(options) {
1868
- return defineTool2("system", {
1869
- name: "create_plan",
1870
- description: "Create a plan. Make sure that each step is independent and can be executed solely on the data returned by the previous step. The steps only share the data that is specified in the plan.",
1871
- schema: Schema4.Struct({
1872
- goal: Schema4.String.annotations({
1873
- description: "The goal that the plan will achieve."
1874
- }),
1875
- steps: Schema4.Array(Schema4.Struct({
1876
- action: Schema4.String.annotations({
1877
- description: "Complete, detailed action to perform."
1878
- }),
1879
- input: Schema4.String.annotations({
1880
- description: "The required input data for this step. First step must not require any data."
1881
- }),
1882
- output: Schema4.String.annotations({
1883
- description: "The output data from this step. This is passed to the next step as input."
1884
- }),
1885
- requiredArtifactIds: Schema4.Array(Schema4.String).annotations({
1886
- description: "The ids of the artifacts required to perform this step.",
1887
- examples: [
1888
- [
1889
- "artifact:dxos.org/example/Test"
1890
- ]
1891
- ]
1892
- })
1893
- })).annotations({
1894
- description: "Steps"
1895
- })
1896
- }),
1897
- execute: async ({ goal, steps }) => {
1898
- const missingArtifactIds = steps.flatMap((step) => step.requiredArtifactIds).filter((artifactId) => !options.artifacts.some((artifact) => artifact.id === artifactId));
1899
- if (missingArtifactIds.length > 0) {
1900
- return ToolResult3.Error(`One or more artifact ids are invalid: ${missingArtifactIds.join(", ")}`);
1901
- }
1902
- const stepResults = [];
1903
- for (const step of steps) {
1904
- log6("executing step", {
1905
- action: step.action
1906
- }, {
1907
- F: __dxlog_file6,
1908
- L: 379,
1909
- S: this,
1910
- C: (f, a) => f(...a)
1911
- });
1912
- const session = new _AISession({
1913
- operationModel: "importing"
1914
- });
1915
- session.message.on((ev) => this.message.emit(ev));
1916
- session.block.on((ev) => this.block.emit(ev));
1917
- session.update.on((ev) => this.update.emit(ev));
1918
- session.streamEvent.on((ev) => this.streamEvent.emit(ev));
1919
- session.userMessage.on((ev) => this.userMessage.emit(ev));
1920
- const messages = await session.run({
1921
- client: options.client,
1922
- artifacts: options.artifacts,
1923
- tools: options.tools,
1924
- history: options.history,
1925
- extensions: options.extensions,
1926
- generationOptions: options.generationOptions,
1927
- requiredArtifactIds: step.requiredArtifactIds.slice(),
1928
- artifactDiffResolver: options.artifactDiffResolver,
1929
- prompt: `
1930
- You are an agent that executes the subtask in a plan.
1931
-
1932
- While you know the plan's goal only focus on your subtask
1933
- Use the data from the previous step to complete your task.
1934
- Return all of the data from "output" in your last message.
1935
-
1936
- Current step (that you need to complete):
1937
- ${JSON.stringify({
1938
- goal,
1939
- input: step.input,
1940
- output: step.output,
1941
- yourTask: step.action
1942
- }, null, 2)}
1943
-
1944
- Previous step results:
1945
- ${JSON.stringify(stepResults.at(-1))}.
1946
- `
1947
- });
1948
- const result = messages.at(-1);
1949
- stepResults.push(result);
1950
- }
1951
- return ToolResult3.Success({
1952
- stepResults
1953
- });
1954
- }
1955
- });
1956
- }
1957
- abort() {
1958
- this._stream?.abort();
1959
- }
1960
- };
1961
- _ts_decorate([
1962
- synchronized
1963
- ], AISession.prototype, "run", null);
1964
- var createBaseInstructions = ({ availableArtifacts, operationModel }) => `
1965
- You are a friendly, advanced AI assistant capable of creating and managing artifacts from available data and tools.
1966
- Your task is to process user commands and questions and decide how best to respond.
1967
- In some cases, you will need to create or reference data objects called artifacts.
1968
-
1969
- Follow these guidelines carefully:
1970
-
1971
- Decision-making:
1972
-
1973
- - Analyze the structure and type of the content in the user's message.
1974
-
1975
-
1976
- ${operationModel === "planning" ? `
1977
- - Can you complete the task using the available artifacts?
1978
- - If you can't complete the task using the available artifacts, query the list of available artifacts using the appropriate tool.
1979
- - Identify which artifacts are relevant to the user's request.
1980
- - Break down the user's request into a step-by-step plan that you will use to execute the user's request, the plan items should include artifacts which will be used to perform the actions.
1981
- ` : ""}
1982
- ${operationModel === "importing" ? `
1983
- - Can you complete the task using the available artifacts?
1984
- - If you can't complete the task using the available artifacts, query the list of available artifacts using the appropriate tool.
1985
- - Identify which artifacts are relevant to the user's request.
1986
- - Are the required artifacts already available?
1987
- - If not, select which artifact(s) will be the most relevant and require them using the require_artifacts tool.
1988
- - The require'd artifact tools will be available for use after require.
1989
- ` : ""}
1990
- ${operationModel === "configured" ? `
1991
- - Select the most relevant artifact(s) to complete the task.
1992
- - Call the appropriate tool to use the artifact(s).
1993
- ` : ""}
1994
-
1995
- ${availableArtifacts.length > 0 ? `Artifacts already in context: ${availableArtifacts.join("\n")}` : ""}
1996
- `;
1997
- var AIServiecOverloadedError = class extends Schema4.TaggedError()("AIServiecOverloadedError", {}) {
1998
- };
1999
- var gatherObjectVersions = (messages) => {
2000
- const artifactIds = /* @__PURE__ */ new Map();
2001
- for (const message of messages) {
2002
- for (const block of message.content) {
2003
- if (block.type === "json" && block.disposition === VersionPin.DISPOSITION) {
2004
- const pin = VersionPin.pipe(Schema4.decodeOption)(JSON.parse(block.json)).pipe(Option.getOrUndefined);
2005
- if (!pin) {
2006
- continue;
2007
- }
2008
- artifactIds.set(pin.objectId, pin.version);
2009
- }
2010
- }
2011
- }
2012
- return artifactIds;
2013
- };
2014
- var createArtifactUpdateBlock = (artifactDiff) => {
2015
- return {
2016
- type: "text",
2017
- disposition: "artifact-update",
2018
- text: `
2019
- The following artifacts have been updated since the last message:
2020
- ${Array.from(artifactDiff.entries()).map(([id, { diff }]) => `<changed-artifact id="${id}">${diff ? `
2021
- ${diff}` : ""}</changed-artifact>`).join("\n")}
2022
- `
2023
- };
2024
- };
2025
-
2026
- // packages/experimental/assistant/src/experimental/conversation/conversation.ts
2027
- import { ObjectId as ObjectId3 } from "@dxos/echo-schema";
2028
- import { invariant as invariant6 } from "@dxos/invariant";
2029
- import { log as log7 } from "@dxos/log";
2030
- var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/experimental/conversation/conversation.ts";
2031
- var runLLM = async (params) => {
2032
- let conversationResult = null;
2033
- const history = params.history ?? [];
2034
- const generate = async () => {
2035
- log7("llm generate", {
2036
- tools: params.tools
2037
- }, {
2038
- F: __dxlog_file7,
2039
- L: 44,
2040
- S: void 0,
2041
- C: (f, a) => f(...a)
2042
- });
2043
- const beginTs = Date.now();
2044
- const stream = await params.client.execStream({
2045
- model: params.model,
2046
- history,
2047
- systemPrompt: params.system,
2048
- tools: params.tools
2049
- });
2050
- for await (const event of stream) {
2051
- params.logger?.(event);
2052
- }
2053
- await stream.complete();
2054
- const messages = [];
2055
- const message = messages.at(-1);
2056
- invariant6(message, void 0, {
2057
- F: __dxlog_file7,
2058
- L: 61,
2059
- S: void 0,
2060
- A: [
2061
- "message",
2062
- ""
2063
- ]
2064
- });
2065
- log7("llm result", {
2066
- time: Date.now() - beginTs,
2067
- message
2068
- }, {
2069
- F: __dxlog_file7,
2070
- L: 63,
2071
- S: void 0,
2072
- C: (f, a) => f(...a)
2073
- });
2074
- invariant6(message, void 0, {
2075
- F: __dxlog_file7,
2076
- L: 64,
2077
- S: void 0,
2078
- A: [
2079
- "message",
2080
- ""
2081
- ]
2082
- });
2083
- params.logger?.({
2084
- type: "message",
2085
- message
2086
- });
2087
- history.push(...messages.map((message2) => ({
2088
- ...message2,
2089
- content: message2.content.filter((block) => block.type !== "image")
2090
- })));
2091
- const isToolUse2 = message.content.at(-1)?.type === "tool_use";
2092
- if (isToolUse2) {
2093
- const toolCalls = message.content.filter((block) => block.type === "tool_use");
2094
- invariant6(toolCalls.length === 1, void 0, {
2095
- F: __dxlog_file7,
2096
- L: 75,
2097
- S: void 0,
2098
- A: [
2099
- "toolCalls.length === 1",
2100
- ""
2101
- ]
2102
- });
2103
- const toolCall = toolCalls[0];
2104
- const tool = params.tools.find((tool2) => tool2.name === toolCall.name);
2105
- if (!tool) {
2106
- throw new Error(`Tool not found: ${toolCall.name}`);
2107
- }
2108
- invariant6(tool.execute, void 0, {
2109
- F: __dxlog_file7,
2110
- L: 82,
2111
- S: void 0,
2112
- A: [
2113
- "tool.execute",
2114
- ""
2115
- ]
2116
- });
2117
- const toolResult = await tool.execute(toolCall.input);
2118
- switch (toolResult.kind) {
2119
- case "error": {
2120
- log7.warn("tool error", {
2121
- message: toolResult.message
2122
- }, {
2123
- F: __dxlog_file7,
2124
- L: 86,
2125
- S: void 0,
2126
- C: (f, a) => f(...a)
2127
- });
2128
- const resultMessage = {
2129
- id: ObjectId3.random(),
2130
- role: "user",
2131
- content: [
2132
- {
2133
- type: "tool_result",
2134
- toolUseId: toolCall.id,
2135
- content: toolResult.message,
2136
- isError: true
2137
- }
2138
- ]
2139
- };
2140
- params.logger?.({
2141
- type: "message",
2142
- message: resultMessage
2143
- });
2144
- history.push(resultMessage);
2145
- return true;
2146
- }
2147
- case "success": {
2148
- log7("tool success", {
2149
- result: toolResult.result
2150
- }, {
2151
- F: __dxlog_file7,
2152
- L: 106,
2153
- S: void 0,
2154
- C: (f, a) => f(...a)
2155
- });
2156
- const resultMessage = {
2157
- id: ObjectId3.random(),
2158
- role: "user",
2159
- content: [
2160
- {
2161
- type: "tool_result",
2162
- toolUseId: toolCall.id,
2163
- content: JSON.stringify(toolResult.result)
2164
- }
2165
- ]
2166
- };
2167
- params.logger?.({
2168
- type: "message",
2169
- message: resultMessage
2170
- });
2171
- history.push(resultMessage);
2172
- return true;
2173
- }
2174
- case "break": {
2175
- log7("tool break", {
2176
- result: toolResult.result
2177
- }, {
2178
- F: __dxlog_file7,
2179
- L: 125,
2180
- S: void 0,
2181
- C: (f, a) => f(...a)
2182
- });
2183
- conversationResult = toolResult.result;
2184
- return false;
2185
- }
2186
- }
2187
- }
2188
- return false;
2189
- };
2190
- while (await generate()) {
2191
- }
2192
- return {
2193
- result: conversationResult,
2194
- history
2195
- };
2196
- };
2197
-
2198
- // packages/experimental/assistant/src/experimental/cypher/parjs.ts
2199
- import { parjsCombinators, parjs } from "#parjs";
2200
-
2201
- // packages/experimental/assistant/src/experimental/cypher/combinators.ts
2202
- var ws = parjs.whitespace();
2203
- var nothing = parjs.string("").pipe(parjsCombinators.map(() => null));
2204
- var optional = (parser) => parser.pipe(parjsCombinators.recover(() => ({
2205
- kind: "Soft"
2206
- })), parjsCombinators.or(nothing));
2207
- var keyword = (word) => parjs.string(word).pipe(parjsCombinators.map(() => word));
2208
- var identifier = parjs.regexp(/[a-zA-Z_][a-zA-Z0-9_]*/).pipe(parjsCombinators.map((match) => ({
2209
- astKind: "Identifier",
2210
- name: match[0]
2211
- })));
2212
- var numberLiteral = parjs.regexp(/-?\d+(\.\d+)?/).pipe(parjsCombinators.map(Number));
2213
- var stringLiteral = parjs.regexp(/"([^"]*)"|'([^']*)'/).pipe(parjsCombinators.map((match) => ({
2214
- astKind: "StringLiteral",
2215
- value: match[1] || match[2]
2216
- })));
2217
- var variableTag = identifier.pipe(parjsCombinators.map((variable) => variable)).expects("variable tag");
2218
- var label = identifier.pipe(parjsCombinators.map((name) => name));
2219
- var property = identifier.pipe(parjsCombinators.then(parjs.string(":"), ws, stringLiteral), parjsCombinators.map(([key, , , value]) => ({
2220
- key,
2221
- value
2222
- })));
2223
- var properties = property.pipe(parjsCombinators.manySepBy(","), parjsCombinators.between("{", "}"), parjsCombinators.map((properties2) => ({
2224
- astKind: "Properties",
2225
- properties: properties2
2226
- })));
2227
- var nodePattern = optional(variableTag).pipe(parjsCombinators.then(":"), parjsCombinators.then(ws, label, ws), parjsCombinators.then(optional(properties)), parjsCombinators.between("(", ")"), parjsCombinators.map(([[[variable], _, label2], properties2]) => ({
2228
- astKind: "NodePattern",
2229
- variable,
2230
- label: label2,
2231
- properties: properties2
2232
- })));
2233
- var relationshipPattern = optional(variableTag).pipe(parjsCombinators.then(":"), parjsCombinators.then(ws, label, ws), parjsCombinators.then(optional(properties)), parjsCombinators.between("[", "]"), parjsCombinators.map(([[[variable], _, label2], properties2]) => ({
2234
- astKind: "RelationshipPattern",
2235
- variable,
2236
- label: label2,
2237
- properties: properties2
2238
- })));
2239
- var graphPatternConnector = parjs.string("->").pipe(parjsCombinators.or("<-", "-"), parjsCombinators.map((x) => ({
2240
- astKind: "GraphPatternConnector",
2241
- direction: x
2242
- })));
2243
- var graphPattern = nodePattern.pipe(parjsCombinators.or(relationshipPattern), parjsCombinators.manySepBy(graphPatternConnector), parjsCombinators.map((segments) => ({
2244
- astKind: "GraphPattern",
2245
- segments
2246
- })));
2247
- var matchClause = keyword("MATCH").pipe(parjsCombinators.then(ws), parjsCombinators.then(graphPattern), parjsCombinators.map(([, pattern]) => ({
2248
- astKind: "MatchClause",
2249
- pattern
2250
- })));
2251
- var memberExpression = identifier.pipe(parjsCombinators.manySepBy("."), parjsCombinators.map((path) => ({
2252
- astKind: "MemberExpression",
2253
- path
2254
- })));
2255
- var equalsPredicate = memberExpression.pipe(parjsCombinators.then(ws, parjs.string("="), ws, stringLiteral), parjsCombinators.map(([left, , , , right]) => ({
2256
- astKind: "EqualsPredicate",
2257
- left,
2258
- right
2259
- })));
2260
- var whereClause = keyword("WHERE").pipe(parjsCombinators.then(ws, equalsPredicate.pipe(parjsCombinators.between(ws, ws), parjsCombinators.manySepBy(parjs.string("AND"))), ws), parjsCombinators.map(([, , predicates]) => ({
2261
- astKind: "WhereClause",
2262
- predicates
2263
- })));
2264
- 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]) => ({
2265
- astKind: "ReturnClause",
2266
- fields: fields.map(([f]) => f)
2267
- })));
2268
- var cypherQuery = ws.pipe(parjsCombinators.then(matchClause, ws, optional(whereClause), ws, returnClause, ws), parjsCombinators.map(([, matchClause2, , whereClause2, , returnClause2]) => ({
2269
- astKind: "CypherQuery",
2270
- matchClause: matchClause2,
2271
- whereClause: whereClause2,
2272
- returnClause: returnClause2
2273
- })));
2274
-
2275
- // packages/experimental/assistant/src/experimental/cypher/parser.ts
2276
- var parseCypherQuery = (query) => {
2277
- const parseResult = cypherQuery.parse(query);
2278
- if (parseResult.isOk) {
2279
- return {
2280
- ast: parseResult.value
2281
- };
2282
- } else {
2283
- throw new Error(`Failed to parse query: ${parseResult}`);
2284
- }
2285
- };
2286
-
2287
- // packages/experimental/assistant/src/experimental/cypher/query-executor.ts
2288
- import { log as log9 } from "@dxos/log";
2289
- import { mapValues } from "@dxos/util";
2290
-
2291
- // packages/experimental/assistant/src/experimental/cypher/execution-plan.ts
2292
- import { invariant as invariant7 } from "@dxos/invariant";
2293
- import { log as log8 } from "@dxos/log";
2294
- var __dxlog_file8 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/experimental/cypher/execution-plan.ts";
2295
- var createExecutionPlan = (query) => {
2296
- return new ExecutionPlanBuilder().build(query);
2297
- };
2298
- var ExecutionPlanBuilder = class {
2299
- constructor() {
2300
- this.counter = 0;
2301
- }
2302
- newVariable() {
2303
- return `anon_${this.counter++}`;
2304
- }
2305
- build(query) {
2306
- log8("Creating execution plan for query", {
2307
- query
2308
- }, {
2309
- F: __dxlog_file8,
2310
- L: 76,
2311
- S: this,
2312
- C: (f, a) => f(...a)
2313
- });
2314
- return {
2315
- steps: [
2316
- ...this.createStepsForMatchClause(query.ast.matchClause),
2317
- ...query.ast.whereClause ? this.createStepsForWhereClause(query.ast.whereClause) : [],
2318
- ...this.createStepsForReturnClause(query.ast.returnClause)
2319
- ],
2320
- output: {
2321
- fields: this.getOutputFields(query.ast.returnClause)
2322
- }
2323
- };
2324
- }
2325
- createStepsForMatchClause(match) {
2326
- invariant7(match.pattern.segments.length > 0, void 0, {
2327
- F: __dxlog_file8,
2328
- L: 90,
2329
- S: this,
2330
- A: [
2331
- "match.pattern.segments.length > 0",
2332
- ""
2333
- ]
2334
- });
2335
- const firstSegment = match.pattern.segments[0];
2336
- invariant7(firstSegment.astKind === "NodePattern", void 0, {
2337
- F: __dxlog_file8,
2338
- L: 92,
2339
- S: this,
2340
- A: [
2341
- "firstSegment.astKind === 'NodePattern'",
2342
- ""
2343
- ]
2344
- });
2345
- let lastNodeVariable = firstSegment.variable?.name ?? this.newVariable();
2346
- const steps = [];
2347
- steps.push({
2348
- type: "NodeScan",
2349
- label: firstSegment.label.name,
2350
- into: lastNodeVariable
2351
- });
2352
- if (firstSegment.properties) {
2353
- for (const property2 of firstSegment.properties.properties) {
2354
- steps.push({
2355
- type: "FilterByProperty",
2356
- variable: lastNodeVariable,
2357
- property: property2.key.name,
2358
- value: property2.value.value
2359
- });
2360
- }
2361
- }
2362
- for (let i = 1; i < match.pattern.segments.length; i++) {
2363
- const relationshipSegment = match.pattern.segments[i++];
2364
- invariant7(relationshipSegment.astKind === "RelationshipPattern", void 0, {
2365
- F: __dxlog_file8,
2366
- L: 115,
2367
- S: this,
2368
- A: [
2369
- "relationshipSegment.astKind === 'RelationshipPattern'",
2370
- ""
2371
- ]
2372
- });
2373
- const nodeSegment = match.pattern.segments[i];
2374
- invariant7(nodeSegment.astKind === "NodePattern", void 0, {
2375
- F: __dxlog_file8,
2376
- L: 117,
2377
- S: this,
2378
- A: [
2379
- "nodeSegment.astKind === 'NodePattern'",
2380
- ""
2381
- ]
2382
- });
2383
- const leftSeparator = match.pattern.segments.separators[i - 2];
2384
- const rightSeparator = match.pattern.segments.separators[i - 1];
2385
- const direction = getDirection(leftSeparator.direction, rightSeparator.direction);
2386
- const relationshipVariable = relationshipSegment.variable?.name ?? this.newVariable();
2387
- const nodeVariable = nodeSegment.variable?.name ?? this.newVariable();
2388
- steps.push({
2389
- type: "RelationshipScan",
2390
- label: relationshipSegment.label.name,
2391
- direction,
2392
- anchor: lastNodeVariable,
2393
- relationshipInto: relationshipVariable,
2394
- nodeInto: nodeVariable
2395
- });
2396
- if (relationshipSegment.properties) {
2397
- for (const property2 of relationshipSegment.properties.properties) {
2398
- steps.push({
2399
- type: "FilterByProperty",
2400
- variable: relationshipVariable,
2401
- property: property2.key.name,
2402
- value: property2.value.value
2403
- });
2404
- }
2405
- }
2406
- if (nodeSegment.label) {
2407
- steps.push({
2408
- type: "FilterByLabel",
2409
- variable: nodeVariable,
2410
- label: nodeSegment.label.name
2411
- });
2412
- }
2413
- if (nodeSegment.properties) {
2414
- for (const property2 of nodeSegment.properties.properties) {
2415
- steps.push({
2416
- type: "FilterByProperty",
2417
- variable: nodeVariable,
2418
- property: property2.key.name,
2419
- value: property2.value.value
2420
- });
2421
- }
2422
- }
2423
- lastNodeVariable = nodeVariable;
2424
- }
2425
- return steps;
2426
- }
2427
- createStepsForWhereClause(where) {
2428
- return [];
2429
- }
2430
- createStepsForReturnClause(returnClause2) {
2431
- return [
2432
- {
2433
- type: "ProduceResults",
2434
- fields: returnClause2.fields.map((field) => ({
2435
- name: field.path.map((p) => p.name).join("_"),
2436
- variable: field.path[0].name,
2437
- path: field.path.length > 1 ? field.path.slice(1).map((p) => p.name).join(".") : "$"
2438
- }))
2439
- }
2440
- ];
2441
- }
2442
- getOutputFields(returnClause2) {
2443
- return returnClause2.fields.map((field) => field.path.map((p) => p.name).join("_"));
2444
- }
2445
- };
2446
- var getDirection = (left, right) => {
2447
- if (left === "-" && right === "->") {
2448
- return "out";
2449
- } else if (left === "<-" && right === "-") {
2450
- return "in";
2451
- } else if (left === "-" && right === "-") {
2452
- return "both";
2453
- }
2454
- throw new Error(`Invalid direction: ()${left}[]${right}()`);
2455
- };
2456
-
2457
- // packages/experimental/assistant/src/experimental/cypher/query-executor.ts
2458
- var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/experimental/cypher/query-executor.ts";
2459
- var executeQueryPlan = async (dataSource, plan) => {
2460
- let buffer = [];
2461
- const results = [];
2462
- for (const step of plan.steps) {
2463
- log9("begin step", {
2464
- step
2465
- }, {
2466
- F: __dxlog_file9,
2467
- L: 41,
2468
- S: void 0,
2469
- C: (f, a) => f(...a)
2470
- });
2471
- switch (step.type) {
2472
- case "NodeScan": {
2473
- const nodes = await dataSource.getNodes({
2474
- label: step.label
2475
- });
2476
- buffer.push(...nodes.map((node) => ({
2477
- [step.into]: node
2478
- })));
2479
- break;
2480
- }
2481
- case "FilterByLabel": {
2482
- buffer = buffer.filter((item) => {
2483
- const node = item[step.variable];
2484
- return node && node.kind === "node" && node.label === step.label;
2485
- });
2486
- break;
2487
- }
2488
- case "FilterByProperty": {
2489
- buffer = buffer.filter((item) => {
2490
- const node = item[step.variable];
2491
- return node && node.kind === "node" && node.properties[step.property] === step.value;
2492
- });
2493
- break;
2494
- }
2495
- case "RelationshipScan": {
2496
- const relationships = await dataSource.getRelationships({
2497
- label: step.label
2498
- });
2499
- for (const tuple of [
2500
- ...buffer
2501
- ]) {
2502
- if (tuple[step.anchor].kind !== "node") {
2503
- continue;
2504
- }
2505
- const filteredRelationships = relationships.filter((relationship) => {
2506
- switch (step.direction) {
2507
- case "in":
2508
- return relationship.target.id === tuple[step.anchor].id;
2509
- case "out":
2510
- return relationship.source.id === tuple[step.anchor].id;
2511
- case "both":
2512
- return relationship.source.id === tuple[step.anchor].id || relationship.target.id === tuple[step.anchor].id;
2513
- default:
2514
- throw new Error(`Unknown direction: ${step.direction}`);
2515
- }
2516
- });
2517
- for (let i = 0; i < filteredRelationships.length; i++) {
2518
- const relationship = filteredRelationships[i];
2519
- const newTuple = i === 0 ? tuple : {
2520
- ...tuple
2521
- };
2522
- if (newTuple !== tuple) {
2523
- buffer.push(newTuple);
2524
- }
2525
- newTuple[step.relationshipInto] = relationship;
2526
- switch (step.direction) {
2527
- case "in":
2528
- newTuple[step.nodeInto] = relationship.source;
2529
- break;
2530
- case "out":
2531
- newTuple[step.nodeInto] = relationship.target;
2532
- break;
2533
- case "both":
2534
- newTuple[step.nodeInto] = relationship.source.id === newTuple[step.anchor].id ? relationship.target : relationship.source;
2535
- break;
2536
- }
2537
- }
2538
- }
2539
- break;
2540
- }
2541
- case "ProduceResults": {
2542
- for (const tuple of buffer) {
2543
- const result = {};
2544
- for (const field of step.fields) {
2545
- result[field.name] = jsonPathGet(tuple[field.variable].properties, field.path);
2546
- }
2547
- results.push(result);
2548
- }
2549
- break;
2550
- }
2551
- }
2552
- log9("finish step", {
2553
- buffer: buffer.map((tuple) => mapValues(tuple, (x) => x.id)),
2554
- results
2555
- }, {
2556
- F: __dxlog_file9,
2557
- L: 118,
2558
- S: void 0,
2559
- C: (f, a) => f(...a)
2560
- });
2561
- }
2562
- return results;
2563
- };
2564
- var executeQuery = (dataSource, query) => {
2565
- const plan = createExecutionPlan(parseCypherQuery(query));
2566
- return executeQueryPlan(dataSource, plan);
2567
- };
2568
- var jsonPathGet = (obj, path) => {
2569
- if (path === "" || path === "$") {
2570
- return obj;
2571
- }
2572
- const parts = path.split(".");
2573
- if (parts[0] === "$") {
2574
- parts.shift();
2575
- }
2576
- let result = obj;
2577
- for (const part of parts) {
2578
- result = result?.[part];
2579
- }
2580
- return result;
2581
- };
2582
-
2583
- // packages/experimental/assistant/src/experimental/cypher/schema.ts
2584
- import { raise } from "@dxos/debug";
2585
- import { JSON_SCHEMA_ECHO_REF_ID } from "@dxos/echo-schema";
2586
-
2587
- // packages/experimental/assistant/src/util/trim.ts
2588
- var trim = (strings, ...values) => {
2589
- const combined = strings.reduce((acc, str, i) => {
2590
- return acc + str + (values[i] || "");
2591
- }, "");
2592
- return combined.replace("/^\n/", "").replace(/\n$/, "");
2593
- };
2594
-
2595
- // packages/experimental/assistant/src/experimental/cypher/schema.ts
2596
- var formatJsonSchemaForLLM = (schemaTypes) => {
2597
- return schemaTypes.flatMap((schema) => [
2598
- formatNodeSchema(schema),
2599
- ...formatInferredRelationships(schema, schemaTypes)
2600
- ]);
2601
- };
2602
- var formatNodeSchema = (schema) => {
2603
- const label2 = formatNodeLabel(schema.typename ?? raise(new Error("Schema must have $id")));
2604
- const properties2 = Object.entries(schema.properties).filter(([key, prop]) => key !== "id" && !isReference(prop));
2605
- return trim`
2606
- <node>
2607
- (:${label2})
2608
-
2609
- <description>${schema.description}</description>
2610
-
2611
- <properties>
2612
- ${properties2.map(([key, value]) => {
2613
- return trim`
2614
- <${key}>
2615
- <type>${value.type}</type>
2616
- <description>${value.description}</description>
2617
- </${key}>
2618
- `;
2619
- })}
2620
- </properties>
2621
- </node>
2622
- `;
2623
- };
2624
- var formatInferredRelationships = (schema, allSchema) => {
2625
- const nodeLabel = formatNodeLabel(schema.typename ?? raise(new Error("Schema must have $id")));
2626
- const relationships = Object.entries(schema.properties).filter(([key, prop]) => isReference(prop));
2627
- return relationships.map(([key, value]) => {
2628
- const relationshipLabel = formatInferredRelationshipLabel(schema.typename ?? raise(new Error("Schema must have $id")), key);
2629
- const targetSchema = allSchema.find((schema2) => `dxn:type/${schema2.typename}` === value.reference?.schema.$ref);
2630
- const targetLabel = targetSchema ? formatNodeLabel(targetSchema?.typename ?? "") : "";
2631
- return trim`
2632
- <relationship>
2633
- (:${nodeLabel})-[:${relationshipLabel}]->(:${targetLabel})
2634
-
2635
- <description>${value.description}</description>
2636
- </relationship>
2637
- `;
2638
- });
2639
- };
2640
- var formatNodeLabel = (typename) => {
2641
- return typename.replace(/^example\.com\/type\//g, "");
2642
- };
2643
- var formatInferredRelationshipLabel = (typename, property2) => {
2644
- const nodeLabel = formatNodeLabel(typename);
2645
- return `${nodeLabel}_${property2}`.toUpperCase();
2646
- };
2647
- 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;
2648
-
2649
- // packages/experimental/assistant/src/experimental/cypher/echo-data-source.ts
2650
- import { raise as raise2 } from "@dxos/debug";
2651
- import { Filter } from "@dxos/echo-db";
2652
- import { getSchema, getSchemaTypename, StoredSchema, toJsonSchema } from "@dxos/echo-schema";
2653
- import { log as log10 } from "@dxos/log";
2654
- function _ts_decorate2(decorators, target, key, desc) {
2655
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2656
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2657
- 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;
2658
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2659
- }
2660
- var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/experimental/assistant/src/experimental/cypher/echo-data-source.ts";
2661
- var EchoDataSource = class {
2662
- constructor(_db) {
2663
- this._db = _db;
2664
- }
2665
- async getNodes({ label: label2 }) {
2666
- if (!label2) {
2667
- const { objects: objects2 } = await this._db.query().run();
2668
- return objects2.map(this._objectToNode);
2669
- }
2670
- const schema = (await this._getAllSchema()).find((schema2) => getSchemaTypename(schema2)?.endsWith(label2));
2671
- if (!schema) {
2672
- return [];
2673
- }
2674
- const { objects } = await this._db.query(Filter.type(schema)).run();
2675
- return objects.map(this._objectToNode);
2676
- }
2677
- async getRelationships({ label: label2 }) {
2678
- const syntheticRefRelationships = (await this._getAllSchema()).filter((schema) => getSchemaTypename(schema) !== StoredSchema.typename).flatMap((schema) => {
2679
- const jsonSchema = toJsonSchema(schema);
2680
- const relationships = Object.entries(jsonSchema.properties).filter(([key, prop]) => isReference(prop));
2681
- return relationships.map(([key, value]) => {
2682
- const relationshipLabel = formatInferredRelationshipLabel(jsonSchema.typename ?? raise2(new Error("Schema must have typename")), key);
2683
- return {
2684
- label: relationshipLabel,
2685
- schema,
2686
- property: key
2687
- };
2688
- });
2689
- });
2690
- const relationship = syntheticRefRelationships.find((r) => r.label === label2);
2691
- if (!relationship) {
2692
- return [];
2693
- }
2694
- const { objects } = await this._db.query(Filter.type(relationship.schema)).run();
2695
- return (await Promise.all(objects.map((object) => this._projectRefRelationship(object, relationship.property)))).flat();
2696
- }
2697
- async _getAllSchema() {
2698
- return [
2699
- ...await this._db.schemaRegistry.query().run(),
2700
- // TODO(dmaretskyi): Remove once we can serialize recursive schema.
2701
- ...this._db.graph.schemaRegistry.schemas.filter((schema) => getSchemaTypename(schema)?.startsWith("example.org"))
2702
- ].filter((schema) => getSchemaTypename(schema) !== StoredSchema.typename);
2703
- }
2704
- _objectToNode(object) {
2705
- const { id, ...properties2 } = object;
2706
- return {
2707
- id,
2708
- kind: "node",
2709
- label: formatNodeLabel(getSchemaTypename(getSchema(object))),
2710
- properties: properties2
2711
- };
2712
- }
2713
- async _projectRefRelationship(object, prop) {
2714
- if (!object[prop]) {
2715
- return [];
2716
- }
2717
- const value = Array.isArray(object[prop]) ? object[prop] : [
2718
- object[prop]
2719
- ];
2720
- return Promise.all(value.map(async (ref) => {
2721
- const target = await ref.load();
2722
- return {
2723
- id: `${object.id}-${prop}-${target.id}`,
2724
- kind: "relationship",
2725
- label: formatInferredRelationshipLabel(getSchemaTypename(getSchema(object)), prop),
2726
- properties: {},
2727
- source: this._objectToNode(object),
2728
- target: this._objectToNode(target)
2729
- };
2730
- }));
2731
- }
2732
- };
2733
- _ts_decorate2([
2734
- log10.method(void 0, void 0, {
2735
- F: __dxlog_file10,
2736
- L: 18,
2737
- S: void 0,
2738
- C: (f, a) => f(...a)
2739
- })
2740
- ], EchoDataSource.prototype, "getNodes", null);
2741
- _ts_decorate2([
2742
- log10.method(void 0, void 0, {
2743
- F: __dxlog_file10,
2744
- L: 34,
2745
- S: void 0,
2746
- C: (f, a) => f(...a)
2747
- })
2748
- ], EchoDataSource.prototype, "getRelationships", null);
2749
-
2750
- export {
2751
- DEFAULT_EDGE_MODEL,
2752
- DEFAULT_EDGE_MODELS,
2753
- DEFAULT_OLLAMA_ENDPOINT,
2754
- DEFAULT_OLLAMA_MODEL,
2755
- DEFAULT_OLLAMA_MODELS,
2756
- createGenerationStream,
2757
- GenerationStreamImpl,
2758
- AIServiceEdgeClient,
2759
- MessageCollector,
2760
- emitMessageAsEvents,
2761
- createArtifactElement,
2762
- LLMModel,
2763
- ToolTypes,
2764
- GenerateRequest,
2765
- GenerateResponse,
2766
- isToolUse,
2767
- runTools,
2768
- VersionPin,
2769
- AISession,
2770
- AIServiecOverloadedError,
2771
- OllamaClient,
2772
- StreamTransform,
2773
- MixedStreamParser,
2774
- mergeMessageBlock,
2775
- runLLM,
2776
- parseCypherQuery,
2777
- executeQueryPlan,
2778
- executeQuery,
2779
- trim,
2780
- formatJsonSchemaForLLM,
2781
- formatNodeLabel,
2782
- formatInferredRelationshipLabel,
2783
- isReference,
2784
- EchoDataSource
2785
- };
2786
- //# sourceMappingURL=chunk-B4HAWUFW.mjs.map