@dxos/assistant 0.8.2-main.f11618f → 0.8.2-staging.7ac8446

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 (77) hide show
  1. package/dist/lib/browser/{chunk-DEIGOD4U.mjs → chunk-PND5VR6D.mjs} +84 -91
  2. package/dist/lib/browser/chunk-PND5VR6D.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +153 -275
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing/index.mjs +25 -25
  7. package/dist/lib/browser/testing/index.mjs.map +3 -3
  8. package/dist/lib/node/{chunk-7VH7NMIM.cjs → chunk-IBOBRBDF.cjs} +98 -106
  9. package/dist/lib/node/chunk-IBOBRBDF.cjs.map +7 -0
  10. package/dist/lib/node/index.cjs +183 -302
  11. package/dist/lib/node/index.cjs.map +4 -4
  12. package/dist/lib/node/meta.json +1 -1
  13. package/dist/lib/node/testing/index.cjs +33 -33
  14. package/dist/lib/node/testing/index.cjs.map +3 -3
  15. package/dist/lib/node-esm/{chunk-7JI4MDGL.mjs → chunk-DCQJOLSR.mjs} +84 -91
  16. package/dist/lib/node-esm/chunk-DCQJOLSR.mjs.map +7 -0
  17. package/dist/lib/node-esm/index.mjs +153 -275
  18. package/dist/lib/node-esm/index.mjs.map +4 -4
  19. package/dist/lib/node-esm/meta.json +1 -1
  20. package/dist/lib/node-esm/testing/index.mjs +25 -25
  21. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  22. package/dist/types/src/ai-service/edge-client.d.ts +5 -4
  23. package/dist/types/src/ai-service/edge-client.d.ts.map +1 -1
  24. package/dist/types/src/ai-service/message-collector.d.ts +6 -0
  25. package/dist/types/src/ai-service/message-collector.d.ts.map +1 -1
  26. package/dist/types/src/ai-service/ollama-client.d.ts +2 -6
  27. package/dist/types/src/ai-service/ollama-client.d.ts.map +1 -1
  28. package/dist/types/src/ai-service/parser.d.ts +3 -0
  29. package/dist/types/src/ai-service/parser.d.ts.map +1 -1
  30. package/dist/types/src/ai-service/service.d.ts +2 -18
  31. package/dist/types/src/ai-service/service.d.ts.map +1 -1
  32. package/dist/types/src/ai-service/testing/mock.d.ts +2 -6
  33. package/dist/types/src/ai-service/testing/mock.d.ts.map +1 -1
  34. package/dist/types/src/ai-service/types.d.ts +9 -52
  35. package/dist/types/src/ai-service/types.d.ts.map +1 -1
  36. package/dist/types/src/conversation/conversation.d.ts +3 -0
  37. package/dist/types/src/conversation/conversation.d.ts.map +1 -1
  38. package/dist/types/src/conversation/types.d.ts +3 -2
  39. package/dist/types/src/conversation/types.d.ts.map +1 -1
  40. package/dist/types/src/cypher/echo-data-source.d.ts.map +1 -1
  41. package/dist/types/src/session/index.d.ts +0 -1
  42. package/dist/types/src/session/index.d.ts.map +1 -1
  43. package/dist/types/src/session/session.d.ts +10 -29
  44. package/dist/types/src/session/session.d.ts.map +1 -1
  45. package/dist/types/src/testing/test-schema.d.ts +2 -2
  46. package/dist/types/src/testing/test-schema.d.ts.map +1 -1
  47. package/package.json +13 -13
  48. package/src/ai-service/client.test.ts +68 -50
  49. package/src/ai-service/edge-client.ts +20 -13
  50. package/src/ai-service/ollama-client.ts +2 -9
  51. package/src/ai-service/parser.ts +2 -13
  52. package/src/ai-service/service.ts +3 -19
  53. package/src/ai-service/testing/mock.ts +1 -9
  54. package/src/ai-service/types.ts +6 -15
  55. package/src/bin/chat.ts +3 -3
  56. package/src/conversation/conversation.ts +11 -5
  57. package/src/conversation/types.ts +4 -1
  58. package/src/cypher/combinators.test.ts +4 -4
  59. package/src/cypher/echo-data-source.ts +2 -1
  60. package/src/cypher/execution-plan.test.ts +1 -1
  61. package/src/cypher/query-executor.test.ts +1 -1
  62. package/src/cypher/schema.test.ts +3 -3
  63. package/src/session/index.ts +0 -1
  64. package/src/session/session.test.ts +7 -8
  65. package/src/session/session.ts +148 -284
  66. package/src/testing/query.test.ts +19 -17
  67. package/src/testing/test-data.ts +22 -22
  68. package/src/testing/test-schema.ts +3 -3
  69. package/dist/lib/browser/chunk-DEIGOD4U.mjs.map +0 -7
  70. package/dist/lib/node/chunk-7VH7NMIM.cjs.map +0 -7
  71. package/dist/lib/node-esm/chunk-7JI4MDGL.mjs.map +0 -7
  72. package/dist/types/src/session/version-pin.d.ts +0 -17
  73. package/dist/types/src/session/version-pin.d.ts.map +0 -1
  74. package/dist/types/src/session/version-pin.test.d.ts +0 -2
  75. package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
  76. package/src/session/version-pin.test.ts +0 -26
  77. package/src/session/version-pin.ts +0 -43
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/session/session.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAEL,OAAO,EAEP,KAAK,kBAAkB,EAEvB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAgB,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAK1D,OAAO,EAAqB,KAAK,eAAe,EAAE,KAAK,eAAe,EAAyB,MAAM,eAAe,CAAC;AAGrH;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE;IAAE,EAAE,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,aAAa,CAAA;CAAE,EAAE,KAAK,OAAO,CACvG,GAAG,CACD,QAAQ,EACR;IACE,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CACF,CACF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,eAAe,CAAC;IAExB,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAEhC;;OAEG;IACH,KAAK,EAAE,IAAI,EAAE,CAAC;IAEd,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IAEf,iBAAiB,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAEnD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;OAEG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C,CAAC;AAEF,KAAK,cAAc,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAE9D,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;;;OAMG;IACH,cAAc,EAAE,cAAc,CAAC;CAChC,CAAC;AAEF,qBAAa,SAAS;IAmCR,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAlCrC,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAiB;IAEjC,kCAAkC;IAClC,OAAO,CAAC,OAAO,CAA+B;IAE9C,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAiB;IAEjC;;OAEG;IACH,SAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAwB;IAE/C;;OAEG;IACH,SAAgB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAsB;IAE3C;;OAEG;IACH,SAAgB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAuB;IAE7C,SAAgB,WAAW,4CAA4B;IAEvD;;OAEG;IACH,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAwB;gBAEtB,QAAQ,EAAE,gBAAgB;IAQjD,GAAG,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YA6G3C,iBAAiB;IAsC/B,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,kBAAkB;IA+B1B,OAAO,CAAC,mBAAmB;IAoF3B,KAAK;CAGN;;;;AAuDD,qBAAa,wBAAyB,SAAQ,6BAG7C;CAAG"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/session/session.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAc,OAAO,EAAc,KAAK,kBAAkB,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,KAAK,EAAgB,MAAM,aAAa,CAAC;AAKlD,OAAO,EAAqB,KAAK,eAAe,EAAE,KAAK,eAAe,EAAyB,MAAM,eAAe,CAAC;AAErH;;;;;;;;;GASG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,eAAe,CAAC;IAExB,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAEhC;;OAEG;IACH,KAAK,EAAE,IAAI,EAAE,CAAC;IAEd,OAAO,EAAE,OAAO,EAAE,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IAEf,iBAAiB,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAEnD,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAEnC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC;AAEF,KAAK,cAAc,GAAG,UAAU,GAAG,WAAW,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;CAChC,CAAC;AAEF,qBAAa,SAAS;IAmCR,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAlCrC,yBAAyB;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD,yDAAyD;IACzD,OAAO,CAAC,QAAQ,CAAiB;IAEjC,kCAAkC;IAClC,OAAO,CAAC,OAAO,CAA+B;IAE9C,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAiB;IAEjC;;OAEG;IACH,SAAgB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAwB;IAE/C;;OAEG;IACH,SAAgB,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAsB;IAE3C;;OAEG;IACH,SAAgB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAuB;IAE7C,SAAgB,WAAW,4CAA4B;IAEvD;;OAEG;IACH,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAAwB;gBAEtB,QAAQ,EAAE,gBAAgB;IAQjD,GAAG,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAkOzD,KAAK;CAGN;;;;AAqCD,qBAAa,wBAAyB,SAAQ,6BAG7C;CAAG"}
@@ -31,7 +31,7 @@ export declare const Task: S.mutable<S.Struct<{
31
31
  }>>;
32
32
  export interface Task extends S.Schema.Type<typeof Task> {
33
33
  }
34
- export declare const Organization: S.mutable<S.Struct<{
34
+ export declare const Org: S.mutable<S.Struct<{
35
35
  id: S.SchemaClass<string, string, never>;
36
36
  name: S.SchemaClass<string, string, never>;
37
37
  projects: S.Array$<import("@dxos/echo-schema").Ref$<{
@@ -45,6 +45,6 @@ export declare const Organization: S.mutable<S.Struct<{
45
45
  email?: string | undefined;
46
46
  }>>;
47
47
  }>>;
48
- export interface Organization extends S.Schema.Type<typeof Organization> {
48
+ export interface Org extends S.Schema.Type<typeof Org> {
49
49
  }
50
50
  //# sourceMappingURL=test-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-schema.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC;AAQrC,eAAO,MAAM,QAAQ,sCAAyE,CAAC;AAE/F,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEjE,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEjE,eAAO,MAAM,IAAI;;;;;;;;;;;;;;GAeb,CAAC;AACL,MAAM,WAAW,IAAK,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC;CAAG;AAE3D,eAAO,MAAM,YAAY;;;;;;;;;;;;;GAcrB,CAAC;AACL,MAAM,WAAW,YAAa,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC;CAAG"}
1
+ {"version":3,"file":"test-schema.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAC;AAQrC,eAAO,MAAM,QAAQ,sCAAyE,CAAC;AAE/F,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEjE,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEjE,eAAO,MAAM,IAAI;;;;;;;;;;;;;;GAeb,CAAC;AACL,MAAM,WAAW,IAAK,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC;CAAG;AAE3D,eAAO,MAAM,GAAG;;;;;;;;;;;;;GAcZ,CAAC;AACL,MAAM,WAAW,GAAI,SAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC;CAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/assistant",
3
- "version": "0.8.2-main.f11618f",
3
+ "version": "0.8.2-staging.7ac8446",
4
4
  "description": "Natural language interface to DXOS",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -40,18 +40,18 @@
40
40
  "parjs": "^1.3.9",
41
41
  "parsimmon": "^1.18.1",
42
42
  "ulidx": "^2.3.0",
43
- "@dxos/artifact": "0.8.2-main.f11618f",
44
- "@dxos/context": "0.8.2-main.f11618f",
45
- "@dxos/async": "0.8.2-main.f11618f",
46
- "@dxos/echo-db": "0.8.2-main.f11618f",
47
- "@dxos/echo-schema": "0.8.2-main.f11618f",
48
- "@dxos/debug": "0.8.2-main.f11618f",
49
- "@dxos/invariant": "0.8.2-main.f11618f",
50
- "@dxos/log": "0.8.2-main.f11618f",
51
- "@dxos/live-object": "0.8.2-main.f11618f",
52
- "@dxos/keys": "0.8.2-main.f11618f",
53
- "@dxos/node-std": "0.8.2-main.f11618f",
54
- "@dxos/util": "0.8.2-main.f11618f"
43
+ "@dxos/artifact": "0.8.2-staging.7ac8446",
44
+ "@dxos/async": "0.8.2-staging.7ac8446",
45
+ "@dxos/context": "0.8.2-staging.7ac8446",
46
+ "@dxos/debug": "0.8.2-staging.7ac8446",
47
+ "@dxos/echo-db": "0.8.2-staging.7ac8446",
48
+ "@dxos/echo-schema": "0.8.2-staging.7ac8446",
49
+ "@dxos/keys": "0.8.2-staging.7ac8446",
50
+ "@dxos/invariant": "0.8.2-staging.7ac8446",
51
+ "@dxos/live-object": "0.8.2-staging.7ac8446",
52
+ "@dxos/log": "0.8.2-staging.7ac8446",
53
+ "@dxos/node-std": "0.8.2-staging.7ac8446",
54
+ "@dxos/util": "0.8.2-staging.7ac8446"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/parsimmon": "^1.10.9",
@@ -6,8 +6,9 @@ import { Schema as S } from 'effect';
6
6
  import { test, describe } from 'vitest';
7
7
 
8
8
  import { defineTool, Message, ToolResult, type Tool } from '@dxos/artifact';
9
- import { toJsonSchema, create } from '@dxos/echo-schema';
9
+ import { toJsonSchema, ObjectId, createStatic } from '@dxos/echo-schema';
10
10
  import { invariant } from '@dxos/invariant';
11
+ import { SpaceId } from '@dxos/keys';
11
12
  import { log } from '@dxos/log';
12
13
 
13
14
  import { DEFAULT_EDGE_MODEL } from './defs';
@@ -25,18 +26,23 @@ describe.skip('AI Service Client', () => {
25
26
  endpoint: AI_SERVICE_ENDPOINT.LOCAL,
26
27
  });
27
28
 
28
- // await client.appendMessages([
29
- // {
30
- // id: ObjectId.random(),
31
- // spaceId,
32
- // threadId,
33
- // role: 'user',
34
- // content: [{ type: 'text', text: 'Hello' }],
35
- // },
36
- // ]);
37
-
38
- const stream = await client.execStream({
29
+ const spaceId = SpaceId.random();
30
+ const threadId = ObjectId.random();
31
+
32
+ await client.appendMessages([
33
+ {
34
+ id: ObjectId.random(),
35
+ spaceId,
36
+ threadId,
37
+ role: 'user',
38
+ content: [{ type: 'text', text: 'Hello' }],
39
+ },
40
+ ]);
41
+
42
+ const stream = await client.exec({
39
43
  model: DEFAULT_EDGE_MODEL,
44
+ spaceId,
45
+ threadId,
40
46
  systemPrompt: 'You are a poet',
41
47
  tools: [],
42
48
  });
@@ -64,19 +70,24 @@ describe.skip('AI Service Client', () => {
64
70
  ),
65
71
  };
66
72
 
67
- // await client.appendMessages([
68
- // {
69
- // id: ObjectId.random(),
70
- // spaceId,
71
- // threadId,
72
- // role: 'user',
73
- // content: [{ type: 'text', text: 'What is the password? Ask the custodian' }],
74
- // },
75
- // ]);
73
+ const spaceId = SpaceId.random();
74
+ const threadId = ObjectId.random();
75
+
76
+ await client.appendMessages([
77
+ {
78
+ id: ObjectId.random(),
79
+ spaceId,
80
+ threadId,
81
+ role: 'user',
82
+ content: [{ type: 'text', text: 'What is the password? Ask the custodian' }],
83
+ },
84
+ ]);
76
85
 
77
86
  {
78
- const stream1 = await client.execStream({
87
+ const stream1 = await client.exec({
79
88
  model: DEFAULT_EDGE_MODEL,
89
+ spaceId,
90
+ threadId,
80
91
  systemPrompt: 'You are a helpful assistant.',
81
92
  tools: [custodian],
82
93
  });
@@ -91,24 +102,26 @@ describe.skip('AI Service Client', () => {
91
102
 
92
103
  const [message1] = messages;
93
104
  log('full message', { message: message1 });
94
- // await client.appendMessages([message1]);
105
+ await client.appendMessages([message1]);
95
106
 
96
107
  const toolUse = message1.content.find(({ type }) => type === 'tool_use')!;
97
108
  invariant(toolUse.type === 'tool_use');
98
- // await client.appendMessages([
99
- // {
100
- // id: ObjectId.random(),
101
- // spaceId,
102
- // threadId,
103
- // role: 'user',
104
- // content: [{ type: 'tool_result', toolUseId: toolUse.id, content: 'password="The sky is blue"' }],
105
- // },
106
- // ]);
109
+ await client.appendMessages([
110
+ {
111
+ id: ObjectId.random(),
112
+ spaceId,
113
+ threadId,
114
+ role: 'user',
115
+ content: [{ type: 'tool_result', toolUseId: toolUse.id, content: 'password="The sky is blue"' }],
116
+ },
117
+ ]);
107
118
  }
108
119
 
109
120
  {
110
- const stream2 = await client.execStream({
121
+ const stream2 = await client.exec({
111
122
  model: DEFAULT_EDGE_MODEL,
123
+ spaceId,
124
+ threadId,
112
125
  systemPrompt: 'You are a helpful assistant.',
113
126
  tools: [custodian],
114
127
  });
@@ -130,18 +143,23 @@ describe.skip('AI Service Client', () => {
130
143
  endpoint: AI_SERVICE_ENDPOINT.LOCAL,
131
144
  });
132
145
 
133
- // await client.appendMessages([
134
- // {
135
- // id: ObjectId.random(),
136
- // spaceId,
137
- // threadId,
138
- // role: 'user',
139
- // content: [{ type: 'text', text: 'Generate an image of a cat' }],
140
- // },
141
- // ]);
142
-
143
- const stream = await client.execStream({
146
+ const spaceId = SpaceId.random();
147
+ const threadId = ObjectId.random();
148
+
149
+ await client.appendMessages([
150
+ {
151
+ id: ObjectId.random(),
152
+ spaceId,
153
+ threadId,
154
+ role: 'user',
155
+ content: [{ type: 'text', text: 'Generate an image of a cat' }],
156
+ },
157
+ ]);
158
+
159
+ const stream = await client.exec({
144
160
  model: DEFAULT_EDGE_MODEL,
161
+ spaceId,
162
+ threadId,
145
163
  tools: [
146
164
  {
147
165
  name: 'text-to-image',
@@ -172,8 +190,8 @@ describe.skip('Ollama Client', () => {
172
190
  const parser = new MixedStreamParser();
173
191
 
174
192
  const messages = await parser.parse(
175
- await client.execStream({
176
- prompt: create(Message, {
193
+ await client.exec({
194
+ prompt: createStatic(Message, {
177
195
  role: 'user',
178
196
  content: [{ type: 'text', text: 'Hello, world!' }],
179
197
  }),
@@ -207,8 +225,8 @@ describe.skip('Ollama Client', () => {
207
225
  });
208
226
 
209
227
  const messages = await parser.parse(
210
- await client.execStream({
211
- prompt: create(Message, {
228
+ await client.exec({
229
+ prompt: createStatic(Message, {
212
230
  role: 'user',
213
231
  content: [{ type: 'text', text: 'What is the encrypted message for "Hello, world!"' }],
214
232
  }),
@@ -228,8 +246,8 @@ describe.skip('Ollama Client', () => {
228
246
  const parser = new MixedStreamParser();
229
247
 
230
248
  const messages = await parser.parse(
231
- await client.execStream({
232
- prompt: create(Message, {
249
+ await client.exec({
250
+ prompt: createStatic(Message, {
233
251
  role: 'user',
234
252
  content: [{ type: 'text', text: 'Generate an image of a cat' }],
235
253
  }),
@@ -2,12 +2,15 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { Schema as S } from 'effect';
6
+
7
+ import { Message } from '@dxos/artifact';
5
8
  import { assertArgument, invariant } from '@dxos/invariant';
6
9
  import { log } from '@dxos/log';
7
10
 
8
11
  import type { AIServiceClient, GenerationStream } from './service';
9
12
  import { createGenerationStream } from './stream';
10
- import { type GenerateRequest, type GenerateResponse } from './types';
13
+ import { type GenerateRequest } from './types';
11
14
 
12
15
  export type AIServiceEdgeClientOptions = {
13
16
  endpoint: string;
@@ -22,16 +25,28 @@ export class AIServiceEdgeClient implements AIServiceClient {
22
25
  }
23
26
 
24
27
  /**
25
- * Generate non-streaming response.
28
+ * @deprecated
26
29
  */
27
- async exec(request: GenerateRequest): Promise<GenerateResponse> {
28
- throw new Error('Not implemented');
30
+ // TODO(burdon): Remove.
31
+ async appendMessages(messages: Message[]): Promise<void> {
32
+ const url = `${this._endpoint}/message`;
33
+ const res = await fetch(url, {
34
+ method: 'POST',
35
+ headers: { 'Content-Type': 'application/json' },
36
+ body: JSON.stringify({
37
+ messages: await S.encodePromise(S.Array(Message))(messages),
38
+ }),
39
+ });
40
+
41
+ if (!res.ok) {
42
+ throw new Error(`${await res.text()} [${url}]`);
43
+ }
29
44
  }
30
45
 
31
46
  /**
32
47
  * Process request and open message stream.
33
48
  */
34
- async execStream(request: GenerateRequest): Promise<GenerationStream> {
49
+ async exec(request: GenerateRequest): Promise<GenerationStream> {
35
50
  assertArgument(typeof request.model === 'string', 'model is required');
36
51
  log('requesting', { endpoint: this._endpoint });
37
52
  const controller = new AbortController();
@@ -46,15 +61,7 @@ export class AIServiceEdgeClient implements AIServiceClient {
46
61
  }),
47
62
  });
48
63
 
49
- if (!response.ok) {
50
- throw await parseErrorResponse(response);
51
- }
52
-
53
64
  invariant(response.body instanceof ReadableStream);
54
65
  return createGenerationStream(response, controller);
55
66
  }
56
67
  }
57
-
58
- const parseErrorResponse = async (response: Response): Promise<Error> => {
59
- throw new Error(`AI Service error: ${response.status} ${response.statusText} ${await response.text()}`);
60
- };
@@ -13,7 +13,7 @@ import { DEFAULT_OLLAMA_ENDPOINT } from './defs';
13
13
  import { MessageCollector, emitMessageAsEvents } from './message-collector';
14
14
  import { type AIServiceClient, type GenerationStream } from './service';
15
15
  import { GenerationStreamImpl } from './stream';
16
- import { ToolTypes, type GenerateRequest, type GenerateResponse, type GenerationStreamEvent } from './types';
16
+ import { ToolTypes, type GenerateRequest, type GenerationStreamEvent } from './types';
17
17
  import { isToolUse, runTools } from '../conversation';
18
18
 
19
19
  export type OllamaClientParams = {
@@ -300,14 +300,7 @@ export class OllamaClient implements AIServiceClient {
300
300
  }
301
301
  }
302
302
 
303
- /**
304
- * Generate non-streaming response.
305
- */
306
- async exec(request: GenerateRequest): Promise<GenerateResponse> {
307
- throw new Error('Not implemented');
308
- }
309
-
310
- async execStream(request: GenerateRequest): Promise<GenerationStream> {
303
+ async exec(request: GenerateRequest): Promise<GenerationStream> {
311
304
  const controller = new AbortController();
312
305
 
313
306
  try {
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { Message, type MessageContentBlock } from '@dxos/artifact';
6
6
  import { Event } from '@dxos/async';
7
- import { create } from '@dxos/echo-schema';
7
+ import { createStatic } from '@dxos/echo-schema';
8
8
  import { invariant } from '@dxos/invariant';
9
9
  import { log } from '@dxos/log';
10
10
  import { isNotFalsy, safeParseJson } from '@dxos/util';
@@ -94,7 +94,7 @@ export class MixedStreamParser {
94
94
  log.warn('unexpected message_start');
95
95
  }
96
96
 
97
- this._message = create(Message, { role: event.message.role, content: [...event.message.content] });
97
+ this._message = createStatic(Message, { role: event.message.role, content: [...event.message.content] });
98
98
  this.message.emit(this._message);
99
99
  break;
100
100
  }
@@ -316,17 +316,6 @@ export const mergeMessageBlock = (
316
316
  break;
317
317
  }
318
318
 
319
- case 'proposal': {
320
- if (streamBlock.content.length === 1 && streamBlock.content[0].type === 'text') {
321
- return {
322
- type: 'json',
323
- disposition: 'proposal',
324
- json: JSON.stringify({ text: streamBlock.content[0].content }),
325
- };
326
- }
327
- break;
328
- }
329
-
330
319
  case 'select': {
331
320
  return {
332
321
  type: 'json',
@@ -2,29 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type GenerateRequest, type GenerationStreamEvent, type GenerateResponse } from './types';
5
+ import { type GenerateRequest, type GenerationStreamEvent } from './types';
6
6
 
7
- /**
8
- * Interface for AI service.
9
- * Generates chat completions, supports, history and tools.
10
- */
7
+ // TODO(burdon): Create wrapper for edge/ollama. Create session?
11
8
  export interface AIServiceClient {
12
- /**
13
- * Generate chat completions, supports, history and tools.
14
- * Generate non-streaming response.
15
- */
16
- exec(request: GenerateRequest): Promise<GenerateResponse>;
17
-
18
- /**
19
- * Generate chat completions, supports, history and tools.
20
- * Process request and open message stream.
21
- */
22
- execStream(request: GenerateRequest): Promise<GenerationStream>;
9
+ exec(request: GenerateRequest): Promise<GenerationStream>;
23
10
  }
24
11
 
25
- /**
26
- * Streaming chat completion stream.
27
- */
28
12
  export interface GenerationStream extends AsyncIterable<GenerationStreamEvent> {
29
13
  abort(): void;
30
14
  complete(): Promise<void>;
@@ -7,7 +7,6 @@ import {
7
7
  type AIServiceClient,
8
8
  type GenerateRequest,
9
9
  createGenerationStream,
10
- type GenerateResponse,
11
10
  } from '@dxos/assistant';
12
11
 
13
12
  import { createTestSSEStream } from './test-stream';
@@ -15,16 +14,9 @@ import { createTestSSEStream } from './test-stream';
15
14
  export class MockAIService implements AIServiceClient {
16
15
  constructor(private readonly _responses: string[]) {}
17
16
 
18
- /**
19
- * Generate non-streaming response.
20
- */
21
- async exec(request: GenerateRequest): Promise<GenerateResponse> {
22
- throw new Error('Not implemented');
23
- }
24
-
25
17
  // TODO(burdon): Match response to request.
26
18
  // TODO(burdon): See MockGpt (from conductor).
27
- async execStream(request: GenerateRequest): Promise<GenerationStream> {
19
+ async exec(request: GenerateRequest): Promise<GenerationStream> {
28
20
  return createGenerationStream(new Response(createTestSSEStream(this._responses)));
29
21
  }
30
22
  }
@@ -4,8 +4,8 @@
4
4
 
5
5
  import { Schema as S } from 'effect';
6
6
 
7
- import { Tool, Message, type MessageContentBlock } from '@dxos/artifact';
8
- import { type ObjectId } from '@dxos/echo-schema';
7
+ import { Tool, Message, type MessageContentBlock, SpaceIdSchema } from '@dxos/artifact';
8
+ import { ObjectId } from '@dxos/echo-schema';
9
9
 
10
10
  import { DEFAULT_EDGE_MODELS, DEFAULT_OLLAMA_MODELS } from './defs';
11
11
 
@@ -25,6 +25,9 @@ export const ToolTypes = Object.freeze({
25
25
  * Client GPT request.
26
26
  */
27
27
  export const GenerateRequest = S.Struct({
28
+ spaceId: S.optional(SpaceIdSchema),
29
+ threadId: S.optional(ObjectId),
30
+
28
31
  /**
29
32
  * Preferred model or system default.
30
33
  */
@@ -51,20 +54,8 @@ export const GenerateRequest = S.Struct({
51
54
  */
52
55
  prompt: S.optional(Message),
53
56
  });
54
- export type GenerateRequest = S.Schema.Type<typeof GenerateRequest>;
55
-
56
- /**
57
- * Non-streaming response.
58
- */
59
- export const GenerateResponse = S.Struct({
60
- messages: S.Array(Message),
61
57
 
62
- /**
63
- * Number of tokens used in the response.
64
- */
65
- tokenCount: S.optional(S.Number),
66
- });
67
- export type GenerateResponse = S.Schema.Type<typeof GenerateResponse>;
58
+ export type GenerateRequest = S.Schema.Type<typeof GenerateRequest>;
68
59
 
69
60
  /**
70
61
  * Server-Sent Events (SSE) stream from the AI service.
package/src/bin/chat.ts CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  createSystemPrompt,
20
20
  createTestData,
21
21
  Contact,
22
- Organization,
22
+ Org,
23
23
  Project,
24
24
  Task,
25
25
  } from '../testing';
@@ -33,7 +33,7 @@ const dataSource = createTestData();
33
33
 
34
34
  const cypherTool = createCypherTool(dataSource);
35
35
 
36
- const schemaTypes = [Organization, Project, Task, Contact];
36
+ const schemaTypes = [Org, Project, Task, Contact];
37
37
 
38
38
  const spaceId = SpaceId.random();
39
39
  const threadId = ObjectId.random();
@@ -46,6 +46,7 @@ while (true) {
46
46
  message: 'Enter a message:',
47
47
  },
48
48
  ]);
49
+ await client.appendMessages([createUserMessage(spaceId, threadId, prompt.message)]);
49
50
 
50
51
  await runLLM({
51
52
  model: DEFAULT_EDGE_MODEL,
@@ -60,7 +61,6 @@ while (true) {
60
61
  },
61
62
  ],
62
63
  client,
63
- history: [createUserMessage(spaceId, threadId, prompt.message)],
64
64
  logger: createLogger({
65
65
  stream: true,
66
66
  filter: (e) => {
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { type Tool, ToolResult, Message } from '@dxos/artifact';
6
- import { create, ObjectId } from '@dxos/echo-schema';
6
+ import { createStatic, ObjectId } from '@dxos/echo-schema';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { type SpaceId } from '@dxos/keys';
9
9
  import { log } from '@dxos/log';
@@ -43,8 +43,10 @@ export const runLLM = async (params: CreateLLMConversationParams) => {
43
43
  const generate = async () => {
44
44
  log('llm generate', { tools: params.tools });
45
45
  const beginTs = Date.now();
46
- const stream = await params.client.execStream({
46
+ const stream = await params.client.exec({
47
47
  model: params.model,
48
+ spaceId: params.spaceId,
49
+ threadId: params.threadId,
48
50
  history,
49
51
  systemPrompt: params.system,
50
52
  tools: params.tools as any,
@@ -86,6 +88,8 @@ export const runLLM = async (params: CreateLLMConversationParams) => {
86
88
  log.warn('tool error', { message: toolResult.message });
87
89
  const resultMessage: Message = {
88
90
  id: ObjectId.random(),
91
+ spaceId: params.spaceId,
92
+ threadId: params.threadId,
89
93
  role: 'user',
90
94
  content: [
91
95
  {
@@ -106,6 +110,8 @@ export const runLLM = async (params: CreateLLMConversationParams) => {
106
110
  log('tool success', { result: toolResult.result });
107
111
  const resultMessage: Message = {
108
112
  id: ObjectId.random(),
113
+ spaceId: params.spaceId,
114
+ threadId: params.threadId,
109
115
  role: 'user',
110
116
  content: [
111
117
  {
@@ -169,7 +175,7 @@ export const runTools = async ({ message, tools, extensions }: RunToolsOptions):
169
175
  const toolCall = toolCalls[0];
170
176
  const tool = tools.find((tool) => tool.name === toolCall.name);
171
177
  if (!tool) {
172
- const resultMessage = create(Message, {
178
+ const resultMessage = createStatic(Message, {
173
179
  role: 'user',
174
180
  content: [
175
181
  {
@@ -200,7 +206,7 @@ export const runTools = async ({ message, tools, extensions }: RunToolsOptions):
200
206
  switch (toolResult.kind) {
201
207
  case 'error': {
202
208
  log('tool error', { message: toolResult.message });
203
- const resultMessage = create(Message, {
209
+ const resultMessage = createStatic(Message, {
204
210
  role: 'user',
205
211
  content: [
206
212
  {
@@ -221,7 +227,7 @@ export const runTools = async ({ message, tools, extensions }: RunToolsOptions):
221
227
 
222
228
  case 'success': {
223
229
  log('tool success', { result: toolResult.result });
224
- const resultMessage = create(Message, {
230
+ const resultMessage = createStatic(Message, {
225
231
  role: 'user',
226
232
  content: [
227
233
  {
@@ -6,10 +6,13 @@ import { Schema as S } from 'effect';
6
6
 
7
7
  import { type Message, type MessageContentBlock } from '@dxos/artifact';
8
8
  import { toJsonSchema, JsonSchemaType, ObjectId } from '@dxos/echo-schema';
9
+ import type { SpaceId } from '@dxos/keys';
9
10
  import { log } from '@dxos/log';
10
11
 
11
- export const createUserMessage = (text: string): Message => ({
12
+ export const createUserMessage = (spaceId: SpaceId, threadId: ObjectId, text: string): Message => ({
12
13
  id: ObjectId.random(),
14
+ spaceId,
15
+ threadId,
13
16
  role: 'user',
14
17
  content: [{ type: 'text', text }],
15
18
  });
@@ -77,7 +77,7 @@ describe('Cypher Combinators', () => {
77
77
  test('match clause', ({ expect }) => {
78
78
  testParser(matchClause, 'MATCH (n:Person)');
79
79
  testParser(matchClause, 'MATCH (n:Person)-[r:KNOWS]->(m:Person)');
80
- testParser(matchClause, 'MATCH (o:Organization)-[:HAS_EMPLOYEE]->(e:Employee)');
80
+ testParser(matchClause, 'MATCH (o:Org)-[:HAS_EMPLOYEE]->(e:Employee)');
81
81
  });
82
82
 
83
83
  test('where clause', ({ expect }) => {
@@ -116,15 +116,15 @@ describe('Cypher Combinators', () => {
116
116
  );
117
117
  testParser(
118
118
  cypherQuery,
119
- 'MATCH (o:Organization)-[:HAS_EMPLOYEE]->(e:Employee)-[:WORKS_ON]->(p:Project) WHERE o.name = "DXOS" AND p.name = "Composer" RETURN e.name, e.id, p.name, p.id',
119
+ 'MATCH (o:Org)-[:HAS_EMPLOYEE]->(e:Employee)-[:WORKS_ON]->(p:Project) WHERE o.name = "DXOS" AND p.name = "Composer" RETURN e.name, e.id, p.name, p.id',
120
120
  );
121
121
  testParser(
122
122
  cypherQuery,
123
- 'MATCH (n:Organization {name: "DXOS"})-[:HAS_EMPLOYEE]->(m:Employee)<-[:WORKS_ON]-(p:Project {name: "Composer"}) RETURN m.name AS employee',
123
+ 'MATCH (n:Org {name: "DXOS"})-[:HAS_EMPLOYEE]->(m:Employee)<-[:WORKS_ON]-(p:Project {name: "Composer"}) RETURN m.name AS employee',
124
124
  );
125
125
  testParser(
126
126
  cypherQuery,
127
- "MATCH (org:Organization {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(t:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'}) RETURN c.name",
127
+ "MATCH (org:Org {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(t:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'}) RETURN c.name",
128
128
  );
129
129
  });
130
130
  });
@@ -4,7 +4,8 @@
4
4
 
5
5
  import { raise } from '@dxos/debug';
6
6
  import { type EchoDatabase, Filter, type ReactiveEchoObject } from '@dxos/echo-db';
7
- import { getSchema, getSchemaTypename, type S, StoredSchema, toJsonSchema } from '@dxos/echo-schema';
7
+ import { type S, getSchemaTypename, StoredSchema, toJsonSchema } from '@dxos/echo-schema';
8
+ import { getSchema } from '@dxos/live-object';
8
9
  import { log } from '@dxos/log';
9
10
 
10
11
  import type { DataSource, Node, Relationship } from './query-executor';
@@ -21,7 +21,7 @@ describe('Execution Plan', () => {
21
21
  test('complex query', ({ expect }) => {
22
22
  const plan = createExecutionPlan(
23
23
  parseCypherQuery(
24
- "MATCH (org:Organization {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'}) RETURN c.name",
24
+ "MATCH (org:Org {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'}) RETURN c.name",
25
25
  ),
26
26
  );
27
27
  log('', { plan });