@dxos/assistant 0.8.1 → 0.8.2-main.2f9c567
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-PND5VR6D.mjs → chunk-OLO6SVOL.mjs} +91 -84
- package/dist/lib/browser/chunk-OLO6SVOL.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +276 -154
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +98 -102
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/{chunk-IBOBRBDF.cjs → chunk-CI5Q7FBG.cjs} +106 -98
- package/dist/lib/node/chunk-CI5Q7FBG.cjs.map +7 -0
- package/dist/lib/node/index.cjs +302 -183
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +88 -93
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node-esm/{chunk-DCQJOLSR.mjs → chunk-Y3SYOFFJ.mjs} +91 -84
- package/dist/lib/node-esm/chunk-Y3SYOFFJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +276 -154
- 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 +98 -102
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/types/src/ai-service/edge-client.d.ts +4 -5
- package/dist/types/src/ai-service/edge-client.d.ts.map +1 -1
- package/dist/types/src/ai-service/message-collector.d.ts +0 -6
- package/dist/types/src/ai-service/message-collector.d.ts.map +1 -1
- package/dist/types/src/ai-service/ollama-client.d.ts +6 -2
- package/dist/types/src/ai-service/ollama-client.d.ts.map +1 -1
- package/dist/types/src/ai-service/parser.d.ts +0 -3
- package/dist/types/src/ai-service/parser.d.ts.map +1 -1
- package/dist/types/src/ai-service/service.d.ts +18 -2
- package/dist/types/src/ai-service/service.d.ts.map +1 -1
- package/dist/types/src/ai-service/testing/mock.d.ts +6 -2
- package/dist/types/src/ai-service/testing/mock.d.ts.map +1 -1
- package/dist/types/src/ai-service/types.d.ts +144 -101
- package/dist/types/src/ai-service/types.d.ts.map +1 -1
- package/dist/types/src/conversation/conversation.d.ts +0 -3
- package/dist/types/src/conversation/conversation.d.ts.map +1 -1
- package/dist/types/src/conversation/types.d.ts +11 -12
- 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 +1 -0
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +32 -13
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/version-pin.d.ts +17 -0
- package/dist/types/src/session/version-pin.d.ts.map +1 -0
- package/dist/types/src/session/version-pin.test.d.ts +2 -0
- package/dist/types/src/session/version-pin.test.d.ts.map +1 -0
- package/dist/types/src/testing/query-promts.d.ts +3 -3
- package/dist/types/src/testing/query-promts.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts +4 -4
- package/dist/types/src/testing/test-data.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +25 -23
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/package.json +15 -14
- package/src/ai-service/client.test.ts +55 -73
- package/src/ai-service/edge-client.ts +13 -20
- package/src/ai-service/ollama-client.ts +16 -9
- package/src/ai-service/parser.ts +13 -2
- package/src/ai-service/service.ts +19 -3
- package/src/ai-service/testing/mock.ts +9 -1
- package/src/ai-service/types.ts +24 -15
- package/src/bin/chat.ts +3 -3
- package/src/conversation/conversation.test.ts +3 -3
- package/src/conversation/conversation.ts +5 -11
- package/src/conversation/types.ts +11 -14
- package/src/cypher/combinators.test.ts +4 -4
- package/src/cypher/echo-data-source.ts +7 -6
- 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 +1 -0
- package/src/session/session.test.ts +29 -22
- package/src/session/session.ts +286 -150
- package/src/session/version-pin.test.ts +26 -0
- package/src/session/version-pin.ts +43 -0
- package/src/testing/artifacts.test.ts +22 -22
- package/src/testing/query-promts.ts +5 -5
- package/src/testing/query.test.ts +17 -19
- package/src/testing/test-data.ts +78 -71
- package/src/testing/test-schema.ts +28 -29
- package/dist/lib/browser/chunk-PND5VR6D.mjs.map +0 -7
- package/dist/lib/node/chunk-IBOBRBDF.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-DCQJOLSR.mjs.map +0 -7
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import type { MessageContentBlock } from '@dxos/artifact';
|
|
3
|
+
import type { ObjectVersion } from '@dxos/echo-db';
|
|
4
|
+
import { type BaseEchoObject } from '@dxos/echo-schema';
|
|
5
|
+
declare const VersionPinSchema: Schema.Struct<{
|
|
6
|
+
objectId: import("@dxos/echo-schema").ObjectIdClass;
|
|
7
|
+
version: Schema.Schema<ObjectVersion, ObjectVersion, never>;
|
|
8
|
+
}>;
|
|
9
|
+
export interface VersionPin extends Schema.Schema.Type<typeof VersionPinSchema> {
|
|
10
|
+
}
|
|
11
|
+
export declare const VersionPin: typeof VersionPinSchema & {
|
|
12
|
+
DISPOSITION: 'version-pin';
|
|
13
|
+
fromObject: (object: BaseEchoObject) => VersionPin;
|
|
14
|
+
createBlock: (pin: VersionPin) => MessageContentBlock;
|
|
15
|
+
};
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=version-pin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-pin.d.ts","sourceRoot":"","sources":["../../../../src/session/version-pin.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAKlE,QAAA,MAAM,gBAAgB;;;EAKpB,CAAC;AACH,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAAC;CAAG;AAElF,eAAO,MAAM,UAAU,EAAE,OAAO,gBAAgB,GAAG;IACjD,WAAW,EAAE,aAAa,CAAC;IAC3B,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,UAAU,CAAC;IACnD,WAAW,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,mBAAmB,CAAC;CAiBvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-pin.test.d.ts","sourceRoot":"","sources":["../../../../src/session/version-pin.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Schema
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
2
|
import { type DataSource } from '../cypher';
|
|
3
|
-
export declare const createCypherTool: (dataSource: DataSource, schemaTypes?:
|
|
4
|
-
export declare const createSystemPrompt: (schemaTypes:
|
|
3
|
+
export declare const createCypherTool: (dataSource: DataSource, schemaTypes?: Schema.Schema.Any[]) => import("@dxos/artifact").Tool;
|
|
4
|
+
export declare const createSystemPrompt: (schemaTypes: Schema.Schema.Any[]) => string;
|
|
5
5
|
//# sourceMappingURL=query-promts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-promts.d.ts","sourceRoot":"","sources":["../../../../src/testing/query-promts.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"query-promts.d.ts","sourceRoot":"","sources":["../../../../src/testing/query-promts.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,OAAO,EAAwC,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAGlF,eAAO,MAAM,gBAAgB,eAAgB,UAAU,gBAAe,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,kCA0CrF,CAAC;AAEL,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,WAiBlE,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Schema
|
|
1
|
+
import { type Schema } from 'effect';
|
|
2
2
|
import type { EchoDatabase } from '@dxos/echo-db';
|
|
3
3
|
import { type JsonSchemaType } from '@dxos/echo-schema';
|
|
4
4
|
import { type DataSource, type Node, type Relationship } from '../cypher';
|
|
@@ -6,14 +6,14 @@ export declare const seedTestData: (db: EchoDatabase) => void;
|
|
|
6
6
|
export declare const createTestData: () => MockDataSource;
|
|
7
7
|
export declare class MockDataSource implements DataSource {
|
|
8
8
|
objects: Record<string, {
|
|
9
|
-
schema:
|
|
9
|
+
schema: Schema.Schema.All;
|
|
10
10
|
typeDxn: string;
|
|
11
11
|
id: string;
|
|
12
12
|
data: unknown;
|
|
13
13
|
}>;
|
|
14
14
|
schema: Record<string, {
|
|
15
15
|
json: JsonSchemaType;
|
|
16
|
-
instance:
|
|
16
|
+
instance: Schema.Schema.All;
|
|
17
17
|
}>;
|
|
18
18
|
nodes: Node[];
|
|
19
19
|
relationships: Relationship[];
|
|
@@ -23,7 +23,7 @@ export declare class MockDataSource implements DataSource {
|
|
|
23
23
|
getRelationships({ label }: {
|
|
24
24
|
label?: string;
|
|
25
25
|
}): Promise<Relationship[]>;
|
|
26
|
-
add<S extends
|
|
26
|
+
add<S extends Schema.Schema.All>(schema: S, data: Schema.Schema.Type<S>): Schema.Schema.Type<S>;
|
|
27
27
|
computeGraph(): void;
|
|
28
28
|
}
|
|
29
29
|
//# sourceMappingURL=test-data.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-data.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-data.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"test-data.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-data.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAIL,KAAK,cAAc,EAGpB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EACL,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,YAAY,EAGlB,MAAM,WAAW,CAAC;AAGnB,eAAO,MAAM,YAAY,OAAQ,YAAY,SAoH5C,CAAC;AAGF,eAAO,MAAM,cAAc,QAAO,cAuGjC,CAAC;AAEF,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,EAAE,MAAM,CACb,MAAM,EACN;QACE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;KACf,CACF,CAAM;IAEP,MAAM,EAAE,MAAM,CACZ,MAAM,EACN;QACE,IAAI,EAAE,cAAc,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;KAC7B,CACF,CAAM;IAEP,KAAK,EAAE,IAAI,EAAE,CAAM;IACnB,aAAa,EAAE,YAAY,EAAE,CAAM;IAE7B,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAItC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAIpD,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAsBvE,YAAY;CA0Eb"}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
import { Schema
|
|
2
|
-
|
|
3
|
-
export declare const Contact:
|
|
4
|
-
id:
|
|
5
|
-
name:
|
|
6
|
-
email:
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
/** @deprecated */
|
|
3
|
+
export declare const Contact: Schema.mutable<Schema.Struct<{
|
|
4
|
+
id: import("@dxos/echo-schema").ObjectIdClass;
|
|
5
|
+
name: Schema.SchemaClass<string, string, never>;
|
|
6
|
+
email: Schema.optional<typeof Schema.String>;
|
|
7
7
|
}>>;
|
|
8
|
-
export interface Contact extends
|
|
8
|
+
export interface Contact extends Schema.Schema.Type<typeof Contact> {
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
/** @deprecated */
|
|
11
|
+
export declare const Project: Schema.mutable<Schema.Struct<{
|
|
12
|
+
id: import("@dxos/echo-schema").ObjectIdClass;
|
|
13
|
+
name: Schema.SchemaClass<string, string, never>;
|
|
14
|
+
description: Schema.optional<typeof Schema.String>;
|
|
14
15
|
}>>;
|
|
15
|
-
export interface Project extends
|
|
16
|
+
export interface Project extends Schema.Schema.Type<typeof Project> {
|
|
16
17
|
}
|
|
17
|
-
export declare const Task:
|
|
18
|
-
id:
|
|
19
|
-
name:
|
|
20
|
-
description:
|
|
18
|
+
export declare const Task: Schema.mutable<Schema.Struct<{
|
|
19
|
+
id: import("@dxos/echo-schema").ObjectIdClass;
|
|
20
|
+
name: Schema.SchemaClass<string, string, never>;
|
|
21
|
+
description: Schema.optional<typeof Schema.String>;
|
|
21
22
|
project: import("@dxos/echo-schema").Ref$<{
|
|
22
23
|
name: string;
|
|
23
24
|
description?: string | undefined;
|
|
@@ -29,22 +30,23 @@ export declare const Task: S.mutable<S.Struct<{
|
|
|
29
30
|
email?: string | undefined;
|
|
30
31
|
}>;
|
|
31
32
|
}>>;
|
|
32
|
-
export interface Task extends
|
|
33
|
+
export interface Task extends Schema.Schema.Type<typeof Task> {
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
/** @deprecated */
|
|
36
|
+
export declare const Organization: Schema.mutable<Schema.Struct<{
|
|
37
|
+
id: import("@dxos/echo-schema").ObjectIdClass;
|
|
38
|
+
name: Schema.SchemaClass<string, string, never>;
|
|
39
|
+
projects: Schema.Array$<import("@dxos/echo-schema").Ref$<{
|
|
38
40
|
name: string;
|
|
39
41
|
description?: string | undefined;
|
|
40
42
|
id: string;
|
|
41
43
|
}>>;
|
|
42
|
-
employees:
|
|
44
|
+
employees: Schema.Array$<import("@dxos/echo-schema").Ref$<{
|
|
43
45
|
name: string;
|
|
44
46
|
id: string;
|
|
45
47
|
email?: string | undefined;
|
|
46
48
|
}>>;
|
|
47
49
|
}>>;
|
|
48
|
-
export interface
|
|
50
|
+
export interface Organization extends Schema.Schema.Type<typeof Organization> {
|
|
49
51
|
}
|
|
50
52
|
//# 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,
|
|
1
|
+
{"version":3,"file":"test-schema.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,kBAAkB;AAClB,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEtE,kBAAkB;AAClB,eAAO,MAAM,OAAO;;;;GAahB,CAAC;AACL,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC;CAAG;AAEtE,eAAO,MAAM,IAAI;;;;;;;;;;;;;;GAeb,CAAC;AACL,MAAM,WAAW,IAAK,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC;CAAG;AAEhE,kBAAkB;AAClB,eAAO,MAAM,YAAY;;;;;;;;;;;;;GAcrB,CAAC;AACL,MAAM,WAAW,YAAa,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC;CAAG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/assistant",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2-main.2f9c567",
|
|
4
4
|
"description": "Natural language interface to DXOS",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -40,22 +40,23 @@
|
|
|
40
40
|
"parjs": "^1.3.9",
|
|
41
41
|
"parsimmon": "^1.18.1",
|
|
42
42
|
"ulidx": "^2.3.0",
|
|
43
|
-
"@dxos/artifact": "0.8.
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/
|
|
47
|
-
"@dxos/echo
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/
|
|
43
|
+
"@dxos/artifact": "0.8.2-main.2f9c567",
|
|
44
|
+
"@dxos/context": "0.8.2-main.2f9c567",
|
|
45
|
+
"@dxos/async": "0.8.2-main.2f9c567",
|
|
46
|
+
"@dxos/debug": "0.8.2-main.2f9c567",
|
|
47
|
+
"@dxos/echo": "0.8.2-main.2f9c567",
|
|
48
|
+
"@dxos/echo-db": "0.8.2-main.2f9c567",
|
|
49
|
+
"@dxos/echo-schema": "0.8.2-main.2f9c567",
|
|
50
|
+
"@dxos/invariant": "0.8.2-main.2f9c567",
|
|
51
|
+
"@dxos/keys": "0.8.2-main.2f9c567",
|
|
52
|
+
"@dxos/log": "0.8.2-main.2f9c567",
|
|
53
|
+
"@dxos/node-std": "0.8.2-main.2f9c567",
|
|
54
|
+
"@dxos/live-object": "0.8.2-main.2f9c567",
|
|
55
|
+
"@dxos/util": "0.8.2-main.2f9c567"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/parsimmon": "^1.10.9",
|
|
58
|
-
"effect": "3.
|
|
59
|
+
"effect": "3.14.21",
|
|
59
60
|
"inquirer": "^12.0.0"
|
|
60
61
|
},
|
|
61
62
|
"peerDependencies": {
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } 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, create } from '@dxos/echo-schema';
|
|
10
10
|
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { SpaceId } from '@dxos/keys';
|
|
12
11
|
import { log } from '@dxos/log';
|
|
13
12
|
|
|
14
13
|
import { DEFAULT_EDGE_MODEL } from './defs';
|
|
@@ -26,23 +25,18 @@ describe.skip('AI Service Client', () => {
|
|
|
26
25
|
endpoint: AI_SERVICE_ENDPOINT.LOCAL,
|
|
27
26
|
});
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
const stream = await client.exec({
|
|
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({
|
|
43
39
|
model: DEFAULT_EDGE_MODEL,
|
|
44
|
-
spaceId,
|
|
45
|
-
threadId,
|
|
46
40
|
systemPrompt: 'You are a poet',
|
|
47
41
|
tools: [],
|
|
48
42
|
});
|
|
@@ -64,30 +58,25 @@ describe.skip('AI Service Client', () => {
|
|
|
64
58
|
name: 'custodian',
|
|
65
59
|
description: 'Custodian can tell you the password if you say the magic word',
|
|
66
60
|
parameters: toJsonSchema(
|
|
67
|
-
|
|
68
|
-
magicWord:
|
|
61
|
+
Schema.Struct({
|
|
62
|
+
magicWord: Schema.String.annotations({ description: 'The magic word. Should be exactly "pretty please"' }),
|
|
69
63
|
}),
|
|
70
64
|
),
|
|
71
65
|
};
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
content: [{ type: 'text', text: 'What is the password? Ask the custodian' }],
|
|
83
|
-
},
|
|
84
|
-
]);
|
|
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
|
+
// ]);
|
|
85
76
|
|
|
86
77
|
{
|
|
87
|
-
const stream1 = await client.
|
|
78
|
+
const stream1 = await client.execStream({
|
|
88
79
|
model: DEFAULT_EDGE_MODEL,
|
|
89
|
-
spaceId,
|
|
90
|
-
threadId,
|
|
91
80
|
systemPrompt: 'You are a helpful assistant.',
|
|
92
81
|
tools: [custodian],
|
|
93
82
|
});
|
|
@@ -102,26 +91,24 @@ describe.skip('AI Service Client', () => {
|
|
|
102
91
|
|
|
103
92
|
const [message1] = messages;
|
|
104
93
|
log('full message', { message: message1 });
|
|
105
|
-
await client.appendMessages([message1]);
|
|
94
|
+
// await client.appendMessages([message1]);
|
|
106
95
|
|
|
107
96
|
const toolUse = message1.content.find(({ type }) => type === 'tool_use')!;
|
|
108
97
|
invariant(toolUse.type === 'tool_use');
|
|
109
|
-
await client.appendMessages([
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
]);
|
|
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
|
+
// ]);
|
|
118
107
|
}
|
|
119
108
|
|
|
120
109
|
{
|
|
121
|
-
const stream2 = await client.
|
|
110
|
+
const stream2 = await client.execStream({
|
|
122
111
|
model: DEFAULT_EDGE_MODEL,
|
|
123
|
-
spaceId,
|
|
124
|
-
threadId,
|
|
125
112
|
systemPrompt: 'You are a helpful assistant.',
|
|
126
113
|
tools: [custodian],
|
|
127
114
|
});
|
|
@@ -143,23 +130,18 @@ describe.skip('AI Service Client', () => {
|
|
|
143
130
|
endpoint: AI_SERVICE_ENDPOINT.LOCAL,
|
|
144
131
|
});
|
|
145
132
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
]);
|
|
158
|
-
|
|
159
|
-
const stream = await client.exec({
|
|
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({
|
|
160
144
|
model: DEFAULT_EDGE_MODEL,
|
|
161
|
-
spaceId,
|
|
162
|
-
threadId,
|
|
163
145
|
tools: [
|
|
164
146
|
{
|
|
165
147
|
name: 'text-to-image',
|
|
@@ -190,8 +172,8 @@ describe.skip('Ollama Client', () => {
|
|
|
190
172
|
const parser = new MixedStreamParser();
|
|
191
173
|
|
|
192
174
|
const messages = await parser.parse(
|
|
193
|
-
await client.
|
|
194
|
-
prompt:
|
|
175
|
+
await client.execStream({
|
|
176
|
+
prompt: create(Message, {
|
|
195
177
|
role: 'user',
|
|
196
178
|
content: [{ type: 'text', text: 'Hello, world!' }],
|
|
197
179
|
}),
|
|
@@ -212,8 +194,8 @@ describe.skip('Ollama Client', () => {
|
|
|
212
194
|
defineTool('test', {
|
|
213
195
|
name: 'encrypt',
|
|
214
196
|
description: 'Encrypt a message',
|
|
215
|
-
schema:
|
|
216
|
-
message:
|
|
197
|
+
schema: Schema.Struct({
|
|
198
|
+
message: Schema.String.annotations({ description: 'The message to encrypt' }),
|
|
217
199
|
}),
|
|
218
200
|
execute: async ({ message }) => ToolResult.Success(message.split('').reverse().join('')),
|
|
219
201
|
}),
|
|
@@ -225,8 +207,8 @@ describe.skip('Ollama Client', () => {
|
|
|
225
207
|
});
|
|
226
208
|
|
|
227
209
|
const messages = await parser.parse(
|
|
228
|
-
await client.
|
|
229
|
-
prompt:
|
|
210
|
+
await client.execStream({
|
|
211
|
+
prompt: create(Message, {
|
|
230
212
|
role: 'user',
|
|
231
213
|
content: [{ type: 'text', text: 'What is the encrypted message for "Hello, world!"' }],
|
|
232
214
|
}),
|
|
@@ -246,8 +228,8 @@ describe.skip('Ollama Client', () => {
|
|
|
246
228
|
const parser = new MixedStreamParser();
|
|
247
229
|
|
|
248
230
|
const messages = await parser.parse(
|
|
249
|
-
await client.
|
|
250
|
-
prompt:
|
|
231
|
+
await client.execStream({
|
|
232
|
+
prompt: create(Message, {
|
|
251
233
|
role: 'user',
|
|
252
234
|
content: [{ type: 'text', text: 'Generate an image of a cat' }],
|
|
253
235
|
}),
|
|
@@ -2,15 +2,12 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema as S } from 'effect';
|
|
6
|
-
|
|
7
|
-
import { Message } from '@dxos/artifact';
|
|
8
5
|
import { assertArgument, invariant } from '@dxos/invariant';
|
|
9
6
|
import { log } from '@dxos/log';
|
|
10
7
|
|
|
11
8
|
import type { AIServiceClient, GenerationStream } from './service';
|
|
12
9
|
import { createGenerationStream } from './stream';
|
|
13
|
-
import { type GenerateRequest } from './types';
|
|
10
|
+
import { type GenerateRequest, type GenerateResponse } from './types';
|
|
14
11
|
|
|
15
12
|
export type AIServiceEdgeClientOptions = {
|
|
16
13
|
endpoint: string;
|
|
@@ -25,28 +22,16 @@ export class AIServiceEdgeClient implements AIServiceClient {
|
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
/**
|
|
28
|
-
*
|
|
25
|
+
* Generate non-streaming response.
|
|
29
26
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
}
|
|
27
|
+
async exec(request: GenerateRequest): Promise<GenerateResponse> {
|
|
28
|
+
throw new Error('Not implemented');
|
|
44
29
|
}
|
|
45
30
|
|
|
46
31
|
/**
|
|
47
32
|
* Process request and open message stream.
|
|
48
33
|
*/
|
|
49
|
-
async
|
|
34
|
+
async execStream(request: GenerateRequest): Promise<GenerationStream> {
|
|
50
35
|
assertArgument(typeof request.model === 'string', 'model is required');
|
|
51
36
|
log('requesting', { endpoint: this._endpoint });
|
|
52
37
|
const controller = new AbortController();
|
|
@@ -61,7 +46,15 @@ export class AIServiceEdgeClient implements AIServiceClient {
|
|
|
61
46
|
}),
|
|
62
47
|
});
|
|
63
48
|
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw await parseErrorResponse(response);
|
|
51
|
+
}
|
|
52
|
+
|
|
64
53
|
invariant(response.body instanceof ReadableStream);
|
|
65
54
|
return createGenerationStream(response, controller);
|
|
66
55
|
}
|
|
67
56
|
}
|
|
57
|
+
|
|
58
|
+
const parseErrorResponse = async (response: Response): Promise<Error> => {
|
|
59
|
+
throw new Error(`AI Service error: ${response.status} ${response.statusText} ${await response.text()}`);
|
|
60
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Schema
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
7
|
import { type MessageContentBlock, defineTool, type Tool, ToolResult } from '@dxos/artifact';
|
|
8
8
|
import { ObjectId } from '@dxos/echo-schema';
|
|
@@ -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 GenerationStreamEvent } from './types';
|
|
16
|
+
import { ToolTypes, type GenerateRequest, type GenerateResponse, type GenerationStreamEvent } from './types';
|
|
17
17
|
import { isToolUse, runTools } from '../conversation';
|
|
18
18
|
|
|
19
19
|
export type OllamaClientParams = {
|
|
@@ -300,7 +300,14 @@ export class OllamaClient implements AIServiceClient {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
|
|
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> {
|
|
304
311
|
const controller = new AbortController();
|
|
305
312
|
|
|
306
313
|
try {
|
|
@@ -381,8 +388,8 @@ const WELL_KNOWN_TOOLS: Record<string, Tool> = {
|
|
|
381
388
|
[ToolTypes.TextToImage]: defineTool('system', {
|
|
382
389
|
name: 'text-to-image',
|
|
383
390
|
description: 'Generate an image from a text prompt',
|
|
384
|
-
schema:
|
|
385
|
-
prompt:
|
|
391
|
+
schema: Schema.Struct({
|
|
392
|
+
prompt: Schema.String.annotations({ description: 'The text prompt describing the image to generate' }),
|
|
386
393
|
}),
|
|
387
394
|
execute: async ({ prompt }) => {
|
|
388
395
|
const image = await fetch(SAMPLE_IMAGE_URL).then(async (res) => Buffer.from(await res.arrayBuffer()));
|
|
@@ -460,15 +467,15 @@ class OllamaDecoderStream extends TransformStream<string, OllamaResponseData> {
|
|
|
460
467
|
}
|
|
461
468
|
}
|
|
462
469
|
|
|
463
|
-
class ModelDoesNotSupportToolsError extends
|
|
470
|
+
class ModelDoesNotSupportToolsError extends Schema.TaggedError<ModelDoesNotSupportToolsError>()(
|
|
464
471
|
'ModelDoesNotSupportToolsError',
|
|
465
472
|
{
|
|
466
|
-
model:
|
|
473
|
+
model: Schema.String,
|
|
467
474
|
},
|
|
468
475
|
) {}
|
|
469
476
|
|
|
470
|
-
class ModelNotFoundError extends
|
|
471
|
-
model:
|
|
477
|
+
class ModelNotFoundError extends Schema.TaggedError<ModelNotFoundError>()('ModelNotFoundError', {
|
|
478
|
+
model: Schema.String,
|
|
472
479
|
}) {}
|
|
473
480
|
|
|
474
481
|
const parseOllamaError = (error: string): Error => {
|
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 { create } 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 = create(Message, { role: event.message.role, content: [...event.message.content] });
|
|
98
98
|
this.message.emit(this._message);
|
|
99
99
|
break;
|
|
100
100
|
}
|
|
@@ -316,6 +316,17 @@ 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
|
+
|
|
319
330
|
case 'select': {
|
|
320
331
|
return {
|
|
321
332
|
type: 'json',
|
|
@@ -2,13 +2,29 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type GenerateRequest, type GenerationStreamEvent } from './types';
|
|
5
|
+
import { type GenerateRequest, type GenerationStreamEvent, type GenerateResponse } from './types';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Interface for AI service.
|
|
9
|
+
* Generates chat completions, supports, history and tools.
|
|
10
|
+
*/
|
|
8
11
|
export interface AIServiceClient {
|
|
9
|
-
|
|
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>;
|
|
10
23
|
}
|
|
11
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Streaming chat completion stream.
|
|
27
|
+
*/
|
|
12
28
|
export interface GenerationStream extends AsyncIterable<GenerationStreamEvent> {
|
|
13
29
|
abort(): void;
|
|
14
30
|
complete(): Promise<void>;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type AIServiceClient,
|
|
8
8
|
type GenerateRequest,
|
|
9
9
|
createGenerationStream,
|
|
10
|
+
type GenerateResponse,
|
|
10
11
|
} from '@dxos/assistant';
|
|
11
12
|
|
|
12
13
|
import { createTestSSEStream } from './test-stream';
|
|
@@ -14,9 +15,16 @@ import { createTestSSEStream } from './test-stream';
|
|
|
14
15
|
export class MockAIService implements AIServiceClient {
|
|
15
16
|
constructor(private readonly _responses: string[]) {}
|
|
16
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Generate non-streaming response.
|
|
20
|
+
*/
|
|
21
|
+
async exec(request: GenerateRequest): Promise<GenerateResponse> {
|
|
22
|
+
throw new Error('Not implemented');
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
// TODO(burdon): Match response to request.
|
|
18
26
|
// TODO(burdon): See MockGpt (from conductor).
|
|
19
|
-
async
|
|
27
|
+
async execStream(request: GenerateRequest): Promise<GenerationStream> {
|
|
20
28
|
return createGenerationStream(new Response(createTestSSEStream(this._responses)));
|
|
21
29
|
}
|
|
22
30
|
}
|