@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.
- package/dist/lib/browser/{chunk-DEIGOD4U.mjs → chunk-PND5VR6D.mjs} +84 -91
- package/dist/lib/browser/chunk-PND5VR6D.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +153 -275
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +25 -25
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-7VH7NMIM.cjs → chunk-IBOBRBDF.cjs} +98 -106
- package/dist/lib/node/chunk-IBOBRBDF.cjs.map +7 -0
- package/dist/lib/node/index.cjs +183 -302
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +33 -33
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node-esm/{chunk-7JI4MDGL.mjs → chunk-DCQJOLSR.mjs} +84 -91
- package/dist/lib/node-esm/chunk-DCQJOLSR.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +153 -275
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +25 -25
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/ai-service/edge-client.d.ts +5 -4
- package/dist/types/src/ai-service/edge-client.d.ts.map +1 -1
- package/dist/types/src/ai-service/message-collector.d.ts +6 -0
- package/dist/types/src/ai-service/message-collector.d.ts.map +1 -1
- package/dist/types/src/ai-service/ollama-client.d.ts +2 -6
- package/dist/types/src/ai-service/ollama-client.d.ts.map +1 -1
- package/dist/types/src/ai-service/parser.d.ts +3 -0
- package/dist/types/src/ai-service/parser.d.ts.map +1 -1
- package/dist/types/src/ai-service/service.d.ts +2 -18
- package/dist/types/src/ai-service/service.d.ts.map +1 -1
- package/dist/types/src/ai-service/testing/mock.d.ts +2 -6
- package/dist/types/src/ai-service/testing/mock.d.ts.map +1 -1
- package/dist/types/src/ai-service/types.d.ts +9 -52
- package/dist/types/src/ai-service/types.d.ts.map +1 -1
- package/dist/types/src/conversation/conversation.d.ts +3 -0
- package/dist/types/src/conversation/conversation.d.ts.map +1 -1
- package/dist/types/src/conversation/types.d.ts +3 -2
- package/dist/types/src/conversation/types.d.ts.map +1 -1
- package/dist/types/src/cypher/echo-data-source.d.ts.map +1 -1
- package/dist/types/src/session/index.d.ts +0 -1
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +10 -29
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +2 -2
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/ai-service/client.test.ts +68 -50
- package/src/ai-service/edge-client.ts +20 -13
- package/src/ai-service/ollama-client.ts +2 -9
- package/src/ai-service/parser.ts +2 -13
- package/src/ai-service/service.ts +3 -19
- package/src/ai-service/testing/mock.ts +1 -9
- package/src/ai-service/types.ts +6 -15
- package/src/bin/chat.ts +3 -3
- package/src/conversation/conversation.ts +11 -5
- package/src/conversation/types.ts +4 -1
- package/src/cypher/combinators.test.ts +4 -4
- package/src/cypher/echo-data-source.ts +2 -1
- package/src/cypher/execution-plan.test.ts +1 -1
- package/src/cypher/query-executor.test.ts +1 -1
- package/src/cypher/schema.test.ts +3 -3
- package/src/session/index.ts +0 -1
- package/src/session/session.test.ts +7 -8
- package/src/session/session.ts +148 -284
- package/src/testing/query.test.ts +19 -17
- package/src/testing/test-data.ts +22 -22
- package/src/testing/test-schema.ts +3 -3
- package/dist/lib/browser/chunk-DEIGOD4U.mjs.map +0 -7
- package/dist/lib/node/chunk-7VH7NMIM.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-7JI4MDGL.mjs.map +0 -7
- package/dist/types/src/session/version-pin.d.ts +0 -17
- package/dist/types/src/session/version-pin.d.ts.map +0 -1
- package/dist/types/src/session/version-pin.test.d.ts +0 -2
- package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
- package/src/session/version-pin.test.ts +0 -26
- 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,
|
|
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
|
|
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
|
|
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,
|
|
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-
|
|
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-
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/echo-
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/live-object": "0.8.2-
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/node-std": "0.8.2-
|
|
54
|
-
"@dxos/util": "0.8.2-
|
|
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,
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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.
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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.
|
|
176
|
-
prompt:
|
|
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.
|
|
211
|
-
prompt:
|
|
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.
|
|
232
|
-
prompt:
|
|
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
|
|
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
|
-
*
|
|
28
|
+
* @deprecated
|
|
26
29
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
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
|
|
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 {
|
package/src/ai-service/parser.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Message, type MessageContentBlock } from '@dxos/artifact';
|
|
6
6
|
import { Event } from '@dxos/async';
|
|
7
|
-
import {
|
|
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 =
|
|
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
|
|
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
|
|
19
|
+
async exec(request: GenerateRequest): Promise<GenerationStream> {
|
|
28
20
|
return createGenerationStream(new Response(createTestSSEStream(this._responses)));
|
|
29
21
|
}
|
|
30
22
|
}
|
package/src/ai-service/types.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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 = [
|
|
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 {
|
|
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.
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 {
|
|
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:
|
|
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 });
|