@dxos/assistant 0.7.4-df37807 → 0.7.5-feature-compute.4d9d99a

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 (96) hide show
  1. package/dist/lib/browser/{chunk-AKP45LQH.mjs → chunk-LVLSJQB3.mjs} +506 -357
  2. package/dist/lib/browser/chunk-LVLSJQB3.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +17 -17
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +10 -3
  6. package/dist/lib/browser/testing/index.mjs.map +4 -4
  7. package/dist/lib/node/{chunk-G6CGWEMO.cjs → chunk-SHOSAIOD.cjs} +507 -362
  8. package/dist/lib/node/chunk-SHOSAIOD.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +42 -42
  10. package/dist/lib/node/index.cjs.map +1 -1
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +18 -12
  13. package/dist/lib/node/testing/index.cjs.map +4 -4
  14. package/dist/lib/node-esm/{chunk-WUPUPEFB.mjs → chunk-ZLBTRSUY.mjs} +506 -357
  15. package/dist/lib/node-esm/chunk-ZLBTRSUY.mjs.map +7 -0
  16. package/dist/lib/node-esm/index.mjs +17 -17
  17. package/dist/lib/node-esm/meta.json +1 -1
  18. package/dist/lib/node-esm/testing/index.mjs +10 -3
  19. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  20. package/dist/types/src/ai-service/client.d.ts +15 -32
  21. package/dist/types/src/ai-service/client.d.ts.map +1 -1
  22. package/dist/types/src/ai-service/index.d.ts +2 -1
  23. package/dist/types/src/ai-service/index.d.ts.map +1 -1
  24. package/dist/types/src/ai-service/stream.d.ts +34 -0
  25. package/dist/types/src/ai-service/stream.d.ts.map +1 -0
  26. package/dist/types/src/ai-service/stream.test.d.ts +2 -0
  27. package/dist/types/src/ai-service/stream.test.d.ts.map +1 -0
  28. package/dist/types/src/ai-service/types/index.d.ts +3 -0
  29. package/dist/types/src/ai-service/types/index.d.ts.map +1 -0
  30. package/dist/types/src/ai-service/types/message.d.ts +191 -0
  31. package/dist/types/src/ai-service/types/message.d.ts.map +1 -0
  32. package/dist/types/src/ai-service/types/schema.d.ts +175 -0
  33. package/dist/types/src/ai-service/types/schema.d.ts.map +1 -0
  34. package/dist/types/src/ai-service/util/index.d.ts +2 -0
  35. package/dist/types/src/ai-service/util/index.d.ts.map +1 -0
  36. package/dist/types/src/ai-service/{sse.d.ts → util/sse.d.ts} +5 -0
  37. package/dist/types/src/ai-service/util/sse.d.ts.map +1 -0
  38. package/dist/types/src/conversation/conversation.d.ts +54 -4
  39. package/dist/types/src/conversation/conversation.d.ts.map +1 -1
  40. package/dist/types/src/conversation/types.d.ts +35 -4
  41. package/dist/types/src/conversation/types.d.ts.map +1 -1
  42. package/dist/types/src/cypher/combinators.d.ts.map +1 -1
  43. package/dist/types/src/cypher/parjs.d.ts +1 -1
  44. package/dist/types/src/cypher/parjs.d.ts.map +1 -1
  45. package/dist/types/src/cypher/schema.d.ts.map +1 -1
  46. package/dist/types/src/testing/artifacts.test.d.ts +1 -0
  47. package/dist/types/src/testing/artifacts.test.d.ts.map +1 -0
  48. package/dist/types/src/testing/data.d.ts +2 -0
  49. package/dist/types/src/testing/data.d.ts.map +1 -0
  50. package/dist/types/src/testing/defs.d.ts +5 -0
  51. package/dist/types/src/testing/defs.d.ts.map +1 -0
  52. package/dist/types/src/testing/index.d.ts +1 -0
  53. package/dist/types/src/testing/index.d.ts.map +1 -1
  54. package/dist/types/src/testing/test-data.d.ts +1 -1
  55. package/dist/types/src/testing/test-data.d.ts.map +1 -1
  56. package/package.json +20 -18
  57. package/src/ai-service/client.test.ts +25 -26
  58. package/src/ai-service/client.ts +29 -177
  59. package/src/ai-service/index.ts +2 -1
  60. package/src/ai-service/stream.test.ts +186 -0
  61. package/src/ai-service/stream.ts +181 -0
  62. package/src/ai-service/types/index.ts +6 -0
  63. package/src/ai-service/types/message.ts +147 -0
  64. package/src/ai-service/types/schema.ts +128 -0
  65. package/src/ai-service/util/index.ts +5 -0
  66. package/src/ai-service/{sse.ts → util/sse.ts} +5 -0
  67. package/src/bin/chat.ts +6 -9
  68. package/src/conversation/conversation.test.ts +10 -14
  69. package/src/conversation/conversation.ts +109 -14
  70. package/src/conversation/types.ts +47 -6
  71. package/src/cypher/combinators.test.ts +3 -3
  72. package/src/cypher/combinators.ts +0 -1
  73. package/src/cypher/execution-plan.test.ts +5 -3
  74. package/src/cypher/parjs-shims.d.ts +4 -0
  75. package/src/cypher/parjs.ts +2 -2
  76. package/src/cypher/query-executor.test.ts +1 -1
  77. package/src/cypher/schema.ts +0 -1
  78. package/src/index.ts +1 -1
  79. package/src/testing/artifacts.test.ts +182 -0
  80. package/src/testing/data.ts +13 -0
  81. package/src/testing/defs.ts +8 -0
  82. package/src/testing/index.ts +1 -0
  83. package/src/testing/query.test.ts +9 -9
  84. package/src/testing/test-data.ts +1 -1
  85. package/vendor/parjs-browser.mjs +4 -0
  86. package/vendor/parjs-default.mjs +8 -0
  87. package/dist/lib/browser/chunk-AKP45LQH.mjs.map +0 -7
  88. package/dist/lib/node/chunk-G6CGWEMO.cjs.map +0 -7
  89. package/dist/lib/node-esm/chunk-WUPUPEFB.mjs.map +0 -7
  90. package/dist/types/src/ai-service/schema.d.ts +0 -296
  91. package/dist/types/src/ai-service/schema.d.ts.map +0 -1
  92. package/dist/types/src/ai-service/sse.d.ts.map +0 -1
  93. package/dist/types/src/sanity.test.d.ts +0 -2
  94. package/dist/types/src/sanity.test.d.ts.map +0 -1
  95. package/src/ai-service/schema.ts +0 -260
  96. package/src/sanity.test.ts +0 -9
@@ -4,12 +4,11 @@
4
4
 
5
5
  import { Schema as S } from '@effect/schema';
6
6
 
7
- import { toJsonSchema } from '@dxos/echo-schema';
8
- import { JsonSchemaType } from '@dxos/echo-schema';
7
+ import { toJsonSchema, JsonSchemaType, ObjectId } from '@dxos/echo-schema';
9
8
  import type { SpaceId } from '@dxos/keys';
10
9
  import { log } from '@dxos/log';
11
10
 
12
- import { ObjectId, type Message } from '../ai-service';
11
+ import { type Message, type MessageContentBlock } from '../ai-service';
13
12
 
14
13
  export const createUserMessage = (spaceId: SpaceId, threadId: ObjectId, text: string): Message => ({
15
14
  id: ObjectId.random(),
@@ -19,6 +18,9 @@ export const createUserMessage = (spaceId: SpaceId, threadId: ObjectId, text: st
19
18
  content: [{ type: 'text', text }],
20
19
  });
21
20
 
21
+ /**
22
+ * @deprecated Use {@link LLMTool} instead.
23
+ */
22
24
  export const LLMToolDefinition = S.Struct({
23
25
  name: S.String,
24
26
  description: S.String,
@@ -26,6 +28,9 @@ export const LLMToolDefinition = S.Struct({
26
28
  execute: S.Any,
27
29
  });
28
30
 
31
+ /**
32
+ * @deprecated Use {@link LLMTool} instead.
33
+ */
29
34
  export type LLMToolDefinition = {
30
35
  name: string;
31
36
  description: string;
@@ -33,10 +38,34 @@ export type LLMToolDefinition = {
33
38
  execute: (params: unknown, context: ToolExecutionContext) => Promise<LLMToolResult>;
34
39
  };
35
40
 
36
- export type ToolExecutionContext = {};
41
+ declare global {
42
+ /**
43
+ * Extensions to the tool execution context.
44
+ *
45
+ * Different modules can extend this definition to add their own properties.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * declare global {
50
+ * interface LLMToolContextExtensions {
51
+ * chess: {
52
+ * board: string;
53
+ * };
54
+ * }
55
+ * }
56
+ * ```
57
+ *
58
+ * @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
59
+ */
60
+ interface LLMToolContextExtensions {}
61
+ }
62
+
63
+ export type ToolExecutionContext = {
64
+ extensions: LLMToolContextExtensions;
65
+ };
37
66
 
38
67
  export type LLMToolResult =
39
- | { kind: 'success'; result: unknown }
68
+ | { kind: 'success'; result: unknown; extractContentBlocks?: MessageContentBlock[] }
40
69
  | { kind: 'error'; message: string }
41
70
  | { kind: 'break'; result: unknown };
42
71
 
@@ -45,9 +74,14 @@ export const LLMToolResult = Object.freeze({
45
74
  * The tool execution was successful.
46
75
  * Gives the result back to the LLM.
47
76
  */
48
- Success: (result: unknown): LLMToolResult => ({ kind: 'success', result }),
77
+ Success: (result: unknown, extractContentBlocks?: MessageContentBlock[]): LLMToolResult => ({
78
+ kind: 'success',
79
+ result,
80
+ extractContentBlocks,
81
+ }),
49
82
 
50
83
  Error: (message: string): LLMToolResult => ({ kind: 'error', message }),
84
+
51
85
  /**
52
86
  * Stop the conversation and return the result.
53
87
  */
@@ -78,9 +112,16 @@ export const defineTool = <Params extends S.Schema.AnyNoContext>({
78
112
  };
79
113
  };
80
114
 
115
+ /**
116
+ * Adapts schems to be able to pass to AI providers.
117
+ */
81
118
  const toFunctionParameterSchema = (schema: S.Schema.All) => {
82
119
  const jsonSchema = toJsonSchema(schema);
83
120
  log('tool schema', { jsonSchema });
121
+ delete jsonSchema.anyOf;
122
+ delete jsonSchema.$id;
123
+ jsonSchema.type = 'object';
124
+ jsonSchema.properties ??= {};
84
125
  for (const key in jsonSchema.properties) {
85
126
  if (typeof jsonSchema.properties![key].description !== 'string') {
86
127
  throw new Error(`Property missing description: ${key}`);
@@ -58,13 +58,13 @@ describe('Cypher Combinators', () => {
58
58
  const parser = or(node)(relation);
59
59
  const input = '[a:b]';
60
60
  const result = parser.parse(input);
61
- log.info('', { result });
61
+ log('result', { result });
62
62
  });
63
63
 
64
64
  test('properties', ({ expect }) => {
65
65
  const input = "{name: 'John'}";
66
66
  const result = properties.parse(input);
67
- log.info('', { result });
67
+ log('result', { result });
68
68
  expect(result).toMatchObject({ isOk: true });
69
69
  });
70
70
 
@@ -92,7 +92,7 @@ describe('Cypher Combinators', () => {
92
92
  const cases = ['RETURN n, m'];
93
93
  for (const input of cases) {
94
94
  const result = returnClause.parse(input);
95
- log.info('', { result });
95
+ log('result', { result });
96
96
  expect(result).toMatchObject({ isOk: true });
97
97
  }
98
98
  });
@@ -21,7 +21,6 @@ import type {
21
21
  StringLiteral,
22
22
  WhereClause,
23
23
  } from './ast';
24
-
25
24
  import { Parjser, parjs, parjsCombinators } from './parjs';
26
25
 
27
26
  // Helper parsers
@@ -9,10 +9,12 @@ import { log } from '@dxos/log';
9
9
  import { createExecutionPlan } from './execution-plan';
10
10
  import { parseCypherQuery } from './parser';
11
11
 
12
+ // log.config({ filter: 'debug' });
13
+
12
14
  describe('Execution Plan', () => {
13
15
  test('trivial', ({ expect }) => {
14
16
  const plan = createExecutionPlan(parseCypherQuery('MATCH (n:Person) RETURN n'));
15
- log.info('', { plan });
17
+ log('', { plan });
16
18
  expect(plan.steps.map((step) => step.type)).toEqual(['NodeScan', 'ProduceResults']);
17
19
  });
18
20
 
@@ -22,9 +24,9 @@ describe('Execution Plan', () => {
22
24
  "MATCH (org:Org {name: 'DXOS'})-[:ORG_EMPLOYEES]->(c:Contact)<-[:TASK_ASSIGNEE]-(:Task)-[:TASK_PROJECT]->(p:Project {name: 'Composer'}) RETURN c.name",
23
25
  ),
24
26
  );
25
- log.info('', { plan });
27
+ log('', { plan });
26
28
  for (const step of plan.steps) {
27
- log.info('', { step });
29
+ log('step', { step });
28
30
  }
29
31
  expect(plan.steps.map((step) => step.type)).toEqual([
30
32
  'NodeScan',
@@ -1,3 +1,7 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
1
5
  declare module '#parjs' {
2
6
  import * as parjs from 'parjs';
3
7
  import * as parjsCombinators from 'parjs/combinators';
@@ -3,8 +3,8 @@
3
3
  //
4
4
 
5
5
  // Workaround for https://github.com/vitest-dev/vitest/issues/7174.
6
- import { parjsCombinators, parjs } from '#parjs';
7
-
8
6
  import type { Parjser } from 'parjs';
9
7
 
8
+ import { parjsCombinators, parjs } from '#parjs';
9
+
10
10
  export { type Parjser, parjsCombinators, parjs };
@@ -9,7 +9,7 @@ import { log } from '@dxos/log';
9
9
  import { executeQuery } from './query-executor';
10
10
  import { createTestData } from '../testing';
11
11
 
12
- test('run', async ({ expect }) => {
12
+ test.skip('run', async ({ expect }) => {
13
13
  const dataSource = createTestData();
14
14
  // for (const node of dataSource.nodes) {
15
15
  // log.info('node', { id: node.id, label: node.label, name: node.properties.name });
@@ -4,7 +4,6 @@
4
4
 
5
5
  import { raise } from '@dxos/debug';
6
6
  import { JSON_SCHEMA_ECHO_REF_ID, type JsonSchemaType } from '@dxos/echo-schema';
7
- import { DXN } from '@dxos/keys';
8
7
 
9
8
  import { trim } from '../util';
10
9
 
package/src/index.ts CHANGED
@@ -4,4 +4,4 @@
4
4
 
5
5
  export * from './ai-service';
6
6
  export * from './cypher';
7
- export * from './conversation';
7
+ export * from './conversation';
@@ -0,0 +1,182 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ /*
6
+ import { Schema as S } from '@effect/schema';
7
+ import { describe, test } from 'vitest';
8
+
9
+ import { ObjectId, toJsonSchema } from '@dxos/echo-schema';
10
+ import { invariant } from '@dxos/invariant';
11
+ import { SpaceId } from '@dxos/keys';
12
+ import { log } from '@dxos/log';
13
+
14
+ import { AIServiceClientImpl, LLMTool } from '../ai-service';
15
+ import { defineTool, LLMToolResult } from '../conversation';
16
+
17
+ // TODO(dmaretskyi): Effect schema.
18
+ const ArtifactDef = S.Struct({
19
+ typename: S.String,
20
+ description: S.String,
21
+ schema: S.Any,
22
+ actions: S.Array(LLMTool),
23
+ }).pipe(S.mutable);
24
+
25
+ type ArtifactDef = S.Schema.Type<typeof ArtifactDef>;
26
+
27
+ const ListItem = S.Struct({
28
+ name: S.String,
29
+ });
30
+
31
+ const ListSchema = S.Struct({
32
+ id: ObjectId,
33
+ title: S.String,
34
+ items: S.Array(ListItem).pipe(S.mutable),
35
+ }).pipe(S.mutable);
36
+
37
+ type ListSchema = S.Schema.Type<typeof ListSchema>;
38
+
39
+ const list: ArtifactDef = {
40
+ typename: 'example.com/type/List',
41
+ description: 'Ordered set of text items.',
42
+ schema: ListSchema,
43
+ actions: [
44
+ defineTool({
45
+ name: 'list.query',
46
+ description: 'Query all lists',
47
+ schema: S.Struct({}),
48
+ execute: async ({}, context) => {
49
+ return LLMToolResult.Success(LISTS[id]);
50
+ },
51
+ }),
52
+ defineTool({
53
+ name: 'list.inspect',
54
+ description: 'Get contents of the list',
55
+ schema: S.Struct({
56
+ id: ObjectId.annotations({ description: 'The list to inspect' }),
57
+ }),
58
+ execute: async ({ id }, context) => {
59
+ return LLMToolResult.Success(LISTS[id]);
60
+ },
61
+ }),
62
+ defineTool({
63
+ name: 'list.add',
64
+ description: 'Add one or more items to an existing list',
65
+ schema: S.Struct({
66
+ id: ObjectId.annotations({ description: 'The list to add items to' }),
67
+ items: S.Array(ListItem).annotations({ description: 'The items to add to the list' }),
68
+ }),
69
+ execute: async ({ id, items }, context) => {
70
+ LISTS[id].items.push(...items);
71
+ return LLMToolResult.Success(LISTS[id]);
72
+ },
73
+ }),
74
+ ],
75
+ };
76
+
77
+ const LISTS: Record<ObjectId, ListSchema> = {};
78
+
79
+ const artifacts = [list];
80
+
81
+ const getArtifactDefinitions = defineTool({
82
+ name: 'getArtifactDefinitions',
83
+ description: 'Queries the definitions and metadata of artifacts defined in the system',
84
+ schema: S.Any,
85
+ execute: async (_, context) => {
86
+ return LLMToolResult.Success(
87
+ artifacts.map((artifact) => ({
88
+ typename: artifact.typename,
89
+ description: artifact.description,
90
+ schema: toJsonSchema(artifact.schema),
91
+ actions: artifact.actions.map((action) => ({
92
+ name: action.name,
93
+ description: action.description,
94
+ })),
95
+ })),
96
+ );
97
+ },
98
+ });
99
+
100
+ const ARTIFACT_INSTRUCTIONS = `
101
+ You have ability to interact with artifacts.
102
+ Artifacts are persistent structured objects that have actions associated with them.
103
+
104
+ Before replying to the user you should first query the artifact definitions and metadata.
105
+ If there's
106
+
107
+ `;
108
+
109
+ describe('Artifacts', () => {
110
+ test('shopping list', async () => {
111
+ const client = new AIServiceClientImpl({
112
+ endpoint: ENDPOINT,
113
+ });
114
+
115
+ const custodian: LLMTool = {
116
+ name: 'custodian',
117
+ description: 'Custodian can tell you the password if you say the magic word',
118
+ parameters: toJsonSchema(
119
+ S.Struct({
120
+ magicWord: S.String.annotations({ description: 'The magic word. Should be exactly "pretty please"' }),
121
+ }),
122
+ ),
123
+ };
124
+
125
+ const spaceId = SpaceId.random();
126
+ const threadId = ObjectId.random();
127
+
128
+ await client.appendMessages([
129
+ {
130
+ id: ObjectId.random(),
131
+ spaceId,
132
+ threadId,
133
+ role: 'user',
134
+ content: [{ type: 'text', text: 'What is the password? Ask the custodian' }],
135
+ },
136
+ ]);
137
+
138
+ const stream = await client.generate({
139
+ model: '@anthropic/claude-3-5-haiku-20241022',
140
+ spaceId,
141
+ threadId,
142
+ systemPrompt: 'You are a helpful assistant.',
143
+ tools: [custodian],
144
+ });
145
+ for await (const event of stream) {
146
+ log.info('event', event);
147
+ }
148
+ const [message] = await stream.complete();
149
+ log.info('full message', {
150
+ message,
151
+ });
152
+ await client.appendMessages([message]);
153
+
154
+ const toolUse = message.content.find(({ type }) => type === 'tool_use')!;
155
+ invariant(toolUse.type === 'tool_use');
156
+ await client.appendMessages([
157
+ {
158
+ id: ObjectId.random(),
159
+ spaceId,
160
+ threadId,
161
+ role: 'user',
162
+ content: [{ type: 'tool_result', toolUseId: toolUse.id, content: 'password="The sky is gray"' }],
163
+ },
164
+ ]);
165
+
166
+ const stream2 = await client.generate({
167
+ model: '@anthropic/claude-3-5-haiku-20241022',
168
+ spaceId,
169
+ threadId,
170
+ systemPrompt: 'You are a helpful assistant.',
171
+ tools: [custodian],
172
+ });
173
+ for await (const event of stream2) {
174
+ log.info('event', event);
175
+ }
176
+ const [message2] = await stream2.complete();
177
+ log.info('full message', {
178
+ message: message2,
179
+ });
180
+ });
181
+ });
182
+ */
@@ -0,0 +1,13 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export const DATA_MESSAGES = [
6
+ `
7
+ <cot>
8
+ ${Array.from({ length: 5 })
9
+ .map((_, i) => `${i + 1}. Step`)
10
+ .join('\n')}
11
+ </cot>
12
+ `,
13
+ ];
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export const AI_SERVICE_ENDPOINT = {
6
+ LOCAL: 'http://localhost:8788',
7
+ REMOTE: 'https://ai-service.dxos.workers.dev',
8
+ };
@@ -2,6 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ export * from './defs';
5
6
  export * from './logger';
6
7
  export * from './query-promts';
7
8
  export * from './test-data';
@@ -4,22 +4,22 @@
4
4
 
5
5
  import { test } from 'vitest';
6
6
 
7
+ import { EchoTestBuilder } from '@dxos/echo-db/testing';
8
+ import { ObjectId } from '@dxos/echo-schema';
7
9
  import { SpaceId } from '@dxos/keys';
8
10
  import { log } from '@dxos/log';
9
- import { EchoTestBuilder } from '@dxos/echo-db/testing';
10
11
 
12
+ import { AI_SERVICE_ENDPOINT } from './defs';
11
13
  import { createLogger } from './logger';
12
14
  import { createCypherTool, createSystemPrompt } from './query-promts';
13
15
  import { createTestData, seedTestData } from './test-data';
14
16
  import { Contact, Org, Project, Task } from './test-schema';
15
- import { AIServiceClientImpl, ObjectId } from '../ai-service';
17
+ import { AIServiceClientImpl } from '../ai-service';
16
18
  import { runLLM, createUserMessage } from '../conversation';
17
- import { EchoDataSource } from '../cypher/echo-data-source';
18
-
19
- const ENDPOINT = 'http://localhost:8787';
19
+ import { EchoDataSource } from '../cypher';
20
20
 
21
21
  const client = new AIServiceClientImpl({
22
- endpoint: ENDPOINT,
22
+ endpoint: AI_SERVICE_ENDPOINT.LOCAL,
23
23
  });
24
24
 
25
25
  test.skip('cypher query', async () => {
@@ -31,7 +31,7 @@ test.skip('cypher query', async () => {
31
31
  const spaceId = SpaceId.random();
32
32
  const threadId = ObjectId.random();
33
33
 
34
- await client.insertMessages([
34
+ await client.appendMessages([
35
35
  createUserMessage(
36
36
  spaceId,
37
37
  threadId,
@@ -52,7 +52,7 @@ test.skip('cypher query', async () => {
52
52
  log.info('DONE', { result: result.result });
53
53
  });
54
54
 
55
- test.only('query ECHO', async () => {
55
+ test.skip('query ECHO', async () => {
56
56
  await using builder = await new EchoTestBuilder().open();
57
57
  const { db, graph } = await builder.createDatabase();
58
58
 
@@ -68,7 +68,7 @@ test.only('query ECHO', async () => {
68
68
  const spaceId = SpaceId.random();
69
69
  const threadId = ObjectId.random();
70
70
 
71
- await client.insertMessages([
71
+ await client.appendMessages([
72
72
  createUserMessage(
73
73
  spaceId,
74
74
  threadId,
@@ -5,6 +5,7 @@
5
5
  import { type Schema as S } from '@effect/schema';
6
6
 
7
7
  import { raise } from '@dxos/debug';
8
+ import type { EchoDatabase } from '@dxos/echo-db';
8
9
  import { JSON_SCHEMA_ECHO_REF_ID, ObjectId, toJsonSchema, type JsonSchemaType, type Ref } from '@dxos/echo-schema';
9
10
  import { invariant } from '@dxos/invariant';
10
11
  import { create, makeRef } from '@dxos/live-object';
@@ -17,7 +18,6 @@ import {
17
18
  formatNodeLabel,
18
19
  } from '../cypher';
19
20
  import { Contact, Org, Project, Task } from '../testing';
20
- import type { EchoDatabase } from '@dxos/echo-db';
21
21
 
22
22
  export const seedTestData = (db: EchoDatabase) => {
23
23
  const contactRich = db.add(
@@ -0,0 +1,4 @@
1
+ import * as parjs from 'parjs';
2
+ import * as parjsCombinators from 'parjs/combinators';
3
+
4
+ export { parjsCombinators, parjs };
@@ -0,0 +1,8 @@
1
+ import { createRequire } from 'node:module';
2
+
3
+ // TODO(dmaretskyi): Must be like this or it breaks vitest.
4
+ const require = createRequire(import.meta.url);
5
+ const parjs = require('parjs');
6
+ const parjsCombinators = require('parjs/combinators');
7
+
8
+ export { parjsCombinators, parjs };