@dxos/assistant 0.8.4-main.f9ba587 → 0.8.4-main.fd6878d
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-6WRGDEMH.mjs +89 -0
- package/dist/lib/browser/chunk-6WRGDEMH.mjs.map +7 -0
- package/dist/lib/browser/chunk-NZGGCEF3.mjs +341 -0
- package/dist/lib/browser/chunk-NZGGCEF3.mjs.map +7 -0
- package/dist/lib/browser/extraction/index.mjs +269 -0
- package/dist/lib/browser/extraction/index.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +240 -1905
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/named-entity-recognition-O46UTCLR.mjs +13 -0
- package/dist/lib/browser/named-entity-recognition-O46UTCLR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-3UU5V4FS.mjs +91 -0
- package/dist/lib/node-esm/chunk-3UU5V4FS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XOOPGSGW.mjs +343 -0
- package/dist/lib/node-esm/chunk-XOOPGSGW.mjs.map +7 -0
- package/dist/lib/node-esm/extraction/index.mjs +270 -0
- package/dist/lib/node-esm/extraction/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +240 -1906
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs +14 -0
- package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs.map +7 -0
- package/dist/types/src/conversation/context.d.ts +90 -0
- package/dist/types/src/conversation/context.d.ts.map +1 -0
- package/dist/types/src/conversation/conversation.d.ts +31 -25
- package/dist/types/src/conversation/conversation.d.ts.map +1 -1
- package/dist/types/src/conversation/index.d.ts +1 -0
- package/dist/types/src/conversation/index.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts +39 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +143 -45
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction.d.ts +106 -44
- package/dist/types/src/extraction/extraction.d.ts.map +1 -1
- package/dist/types/src/functions/index.d.ts +2 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/services.d.ts +7 -0
- package/dist/types/src/functions/services.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/session/artifact-diff.d.ts +27 -0
- package/dist/types/src/session/artifact-diff.d.ts.map +1 -0
- package/dist/types/src/session/format.d.ts +168 -0
- package/dist/types/src/session/format.d.ts.map +1 -0
- package/dist/types/src/session/format.test.d.ts +2 -0
- package/dist/types/src/session/format.test.d.ts.map +1 -0
- 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 +123 -239
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/version-pin.d.ts +4 -4
- package/dist/types/src/session/version-pin.d.ts.map +1 -1
- package/dist/types/src/templates/index.d.ts +2 -0
- package/dist/types/src/templates/index.d.ts.map +1 -0
- package/dist/types/src/templates/system.d.ts +22 -0
- package/dist/types/src/templates/system.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +13 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +46 -22
- package/src/{context/binder.ts → conversation/context.ts} +51 -19
- package/src/conversation/conversation.ts +90 -68
- package/src/conversation/index.ts +1 -0
- package/src/errors.ts +10 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +7 -18
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +22 -17
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +4 -3
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +7 -4
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +2 -2
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +1 -1
- package/src/extraction/quotes.test.ts +1 -1
- package/src/extraction/quotes.ts +1 -1
- package/src/functions/index.ts +5 -0
- package/src/functions/services.ts +114 -0
- package/src/index.ts +3 -5
- package/src/session/__snapshots__/session.test.ts.snap +32 -0
- package/src/session/artifact-diff.ts +37 -0
- package/src/session/format.test.ts +60 -0
- package/src/session/format.ts +139 -0
- package/src/session/index.ts +1 -0
- package/src/session/session.test.ts +87 -57
- package/src/session/session.ts +220 -523
- package/src/session/version-pin.test.ts +2 -21
- package/src/session/version-pin.ts +9 -9
- package/src/summarization/summarization.test.ts +82 -106
- package/src/templates/format.tpl +55 -0
- package/src/templates/index.ts +5 -0
- package/src/templates/system.tpl +47 -0
- package/src/templates/system.ts +32 -0
- package/src/types.ts +45 -1
- package/src/typings.d.ts +5 -0
- package/dist/types/bin/chat.d.ts +0 -2
- package/dist/types/bin/chat.d.ts.map +0 -1
- package/dist/types/src/blueprint/blueprint.d.ts +0 -41
- package/dist/types/src/blueprint/blueprint.d.ts.map +0 -1
- package/dist/types/src/blueprint/index.d.ts +0 -3
- package/dist/types/src/blueprint/index.d.ts.map +0 -1
- package/dist/types/src/blueprint/registry.d.ts +0 -7
- package/dist/types/src/blueprint/registry.d.ts.map +0 -1
- package/dist/types/src/context/binder.d.ts +0 -34
- package/dist/types/src/context/binder.d.ts.map +0 -1
- package/dist/types/src/context/binding.d.ts +0 -38
- package/dist/types/src/context/binding.d.ts.map +0 -1
- package/dist/types/src/context/index.d.ts +0 -3
- package/dist/types/src/context/index.d.ts.map +0 -1
- package/dist/types/src/research/exa.d.ts +0 -7
- package/dist/types/src/research/exa.d.ts.map +0 -1
- package/dist/types/src/research/graph.d.ts +0 -41
- package/dist/types/src/research/graph.d.ts.map +0 -1
- package/dist/types/src/research/graph.test.d.ts +0 -2
- package/dist/types/src/research/graph.test.d.ts.map +0 -1
- package/dist/types/src/research/index.d.ts +0 -4
- package/dist/types/src/research/index.d.ts.map +0 -1
- package/dist/types/src/research/research.d.ts +0 -10
- package/dist/types/src/research/research.d.ts.map +0 -1
- package/dist/types/src/research/research.test.d.ts +0 -2
- package/dist/types/src/research/research.test.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337321991.d.ts +0 -38
- package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337331526.d.ts +0 -37
- package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +0 -1
- package/dist/types/src/testing/exa-search-1748337344119.d.ts +0 -58
- package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +0 -1
- package/dist/types/src/testing/index.d.ts +0 -3
- package/dist/types/src/testing/index.d.ts.map +0 -1
- package/src/blueprint/blueprint.ts +0 -75
- package/src/blueprint/index.ts +0 -6
- package/src/blueprint/registry.ts +0 -15
- package/src/context/binding.ts +0 -31
- package/src/context/index.ts +0 -6
- package/src/research/exa.ts +0 -100
- package/src/research/graph.test.ts +0 -15
- package/src/research/graph.ts +0 -337
- package/src/research/index.ts +0 -7
- package/src/research/instructions-research.tpl +0 -97
- package/src/research/research.test.ts +0 -190
- package/src/research/research.ts +0 -90
- package/src/testing/exa-search-1748337321991.ts +0 -131
- package/src/testing/exa-search-1748337331526.ts +0 -144
- package/src/testing/exa-search-1748337344119.ts +0 -133
- package/src/testing/index.ts +0 -11
- package/src/typedefs.d.ts +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/assistant",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.fd6878d",
|
|
4
4
|
"description": "Natural language interface to DXOS",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,43 +10,67 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
+
"source": "./src/index.ts",
|
|
13
14
|
"types": "./dist/types/src/index.d.ts",
|
|
14
15
|
"browser": "./dist/lib/browser/index.mjs",
|
|
15
16
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./extraction": {
|
|
19
|
+
"source": "./src/extraction/index.ts",
|
|
20
|
+
"types": "./dist/types/src/extraction/index.d.ts",
|
|
21
|
+
"browser": "./dist/lib/browser/extraction/index.mjs",
|
|
22
|
+
"node": "./dist/lib/node-esm/extraction/index.mjs"
|
|
16
23
|
}
|
|
17
24
|
},
|
|
18
25
|
"types": "dist/types/src/index.d.ts",
|
|
26
|
+
"typesVersions": {
|
|
27
|
+
"*": {
|
|
28
|
+
"types": [
|
|
29
|
+
"dist/types/src/types/index.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"extraction": [
|
|
32
|
+
"dist/types/src/extraction/index.d.ts"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
},
|
|
19
36
|
"files": [
|
|
20
37
|
"dist",
|
|
21
38
|
"src"
|
|
22
39
|
],
|
|
23
40
|
"dependencies": {
|
|
41
|
+
"@effect/ai": "0.25.2",
|
|
42
|
+
"@effect/ai-anthropic": "^0.15.1",
|
|
43
|
+
"@effect/platform": "^0.90.2",
|
|
44
|
+
"@effect/platform-node": "^0.95.0",
|
|
24
45
|
"@preact/signals-core": "^1.9.0",
|
|
25
46
|
"@xenova/transformers": "^2.17.2",
|
|
26
47
|
"chalk": "^4.1.0",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/debug": "0.8.4-main.
|
|
33
|
-
"@dxos/echo-db": "0.8.4-main.
|
|
34
|
-
"@dxos/echo
|
|
35
|
-
"@dxos/echo-
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/functions": "0.8.4-main.
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/invariant": "0.8.4-main.
|
|
41
|
-
"@dxos/
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
44
|
-
"@dxos/
|
|
45
|
-
"@dxos/node-std": "0.8.4-main.
|
|
46
|
-
"@dxos/
|
|
48
|
+
"handlebars": "4.7.8",
|
|
49
|
+
"lodash.defaultsdeep": "^4.6.1",
|
|
50
|
+
"@dxos/async": "0.8.4-main.fd6878d",
|
|
51
|
+
"@dxos/context": "0.8.4-main.fd6878d",
|
|
52
|
+
"@dxos/blueprints": "0.8.4-main.fd6878d",
|
|
53
|
+
"@dxos/debug": "0.8.4-main.fd6878d",
|
|
54
|
+
"@dxos/echo-db": "0.8.4-main.fd6878d",
|
|
55
|
+
"@dxos/echo": "0.8.4-main.fd6878d",
|
|
56
|
+
"@dxos/echo-protocol": "0.8.4-main.fd6878d",
|
|
57
|
+
"@dxos/echo-schema": "0.8.4-main.fd6878d",
|
|
58
|
+
"@dxos/errors": "0.8.4-main.fd6878d",
|
|
59
|
+
"@dxos/functions": "0.8.4-main.fd6878d",
|
|
60
|
+
"@dxos/effect": "0.8.4-main.fd6878d",
|
|
61
|
+
"@dxos/invariant": "0.8.4-main.fd6878d",
|
|
62
|
+
"@dxos/graph": "0.8.4-main.fd6878d",
|
|
63
|
+
"@dxos/ai": "0.8.4-main.fd6878d",
|
|
64
|
+
"@dxos/keys": "0.8.4-main.fd6878d",
|
|
65
|
+
"@dxos/log": "0.8.4-main.fd6878d",
|
|
66
|
+
"@dxos/node-std": "0.8.4-main.fd6878d",
|
|
67
|
+
"@dxos/schema": "0.8.4-main.fd6878d",
|
|
68
|
+
"@dxos/util": "0.8.4-main.fd6878d",
|
|
69
|
+
"@dxos/live-object": "0.8.4-main.fd6878d"
|
|
47
70
|
},
|
|
48
71
|
"devDependencies": {
|
|
49
|
-
"
|
|
72
|
+
"@types/lodash.defaultsdeep": "^4.6.6",
|
|
73
|
+
"effect": "3.17.7",
|
|
50
74
|
"inquirer": "^12.0.0"
|
|
51
75
|
},
|
|
52
76
|
"peerDependencies": {
|
|
@@ -2,32 +2,74 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { type ReadonlySignal, computed } from '@preact/signals-core';
|
|
6
|
+
import { Schema } from 'effect';
|
|
6
7
|
import { Array, pipe } from 'effect';
|
|
7
8
|
|
|
8
|
-
import {
|
|
9
|
+
import { Blueprint } from '@dxos/blueprints';
|
|
10
|
+
import { Obj, type Ref, type Relation, Type } from '@dxos/echo';
|
|
9
11
|
import { type Queue } from '@dxos/echo-db';
|
|
10
12
|
import { ComplexSet } from '@dxos/util';
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Thread message that binds or unbinds contextual objects to a conversation.
|
|
16
|
+
*/
|
|
17
|
+
// TODO(burdon): Move to @dxos/schema ContentBlock.
|
|
18
|
+
export const ContextBinding = Schema.Struct({
|
|
19
|
+
blueprints: Schema.Struct({
|
|
20
|
+
added: Schema.Array(Type.Ref(Blueprint.Blueprint)),
|
|
21
|
+
removed: Schema.Array(Type.Ref(Blueprint.Blueprint)),
|
|
22
|
+
}),
|
|
23
|
+
|
|
24
|
+
// TODO(burdon): Type.Expando => Type.Obj (or Obj.Any?)
|
|
25
|
+
objects: Schema.Struct({
|
|
26
|
+
added: Schema.Array(Type.Ref(Type.Expando)),
|
|
27
|
+
removed: Schema.Array(Type.Ref(Type.Expando)),
|
|
28
|
+
}),
|
|
29
|
+
}).pipe(
|
|
30
|
+
Type.Obj({
|
|
31
|
+
typename: 'dxos.org/type/ContextBinding',
|
|
32
|
+
version: '0.1.0',
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export interface ContextBinding extends Schema.Schema.Type<typeof ContextBinding> {}
|
|
37
|
+
|
|
38
|
+
export type BindingProps = Partial<{
|
|
39
|
+
blueprints: Ref.Ref<Blueprint.Blueprint>[];
|
|
40
|
+
objects: Ref.Ref<Type.Expando>[];
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
export class Bindings {
|
|
44
|
+
readonly blueprints = new ComplexSet<Ref.Ref<Blueprint.Blueprint>>((ref) => ref.dxn.toString());
|
|
45
|
+
readonly objects = new ComplexSet<Ref.Ref<Type.Expando>>((ref) => ref.dxn.toString());
|
|
46
|
+
|
|
47
|
+
toJSON() {
|
|
48
|
+
return {
|
|
49
|
+
blueprints: Array.fromIterable(this.blueprints).map((ref) => ref.dxn.toString()),
|
|
50
|
+
objects: Array.fromIterable(this.objects).map((ref) => ref.dxn.toString()),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
14
54
|
|
|
15
55
|
/**
|
|
16
56
|
* Manages bindings of blueprints and objects to a conversation.
|
|
17
57
|
*/
|
|
18
|
-
export class
|
|
19
|
-
constructor(private readonly _queue: Queue) {}
|
|
20
|
-
|
|
58
|
+
export class AiContextBinder {
|
|
21
59
|
/**
|
|
22
60
|
* Reactive query of all bindings.
|
|
23
61
|
*/
|
|
24
62
|
// TODO(burdon): Cache value?
|
|
25
63
|
readonly bindings: ReadonlySignal<Bindings> = computed(() => this._reduce(this._queue.objects));
|
|
26
64
|
|
|
27
|
-
|
|
28
|
-
|
|
65
|
+
readonly blueprints: ReadonlySignal<Ref.Ref<Blueprint.Blueprint>[]> = computed(() => [
|
|
66
|
+
...this.bindings.value.blueprints,
|
|
67
|
+
]);
|
|
68
|
+
|
|
29
69
|
readonly objects: ReadonlySignal<Ref.Ref<Type.Expando>[]> = computed(() => [...this.bindings.value.objects]);
|
|
30
70
|
|
|
71
|
+
constructor(private readonly _queue: Queue) {}
|
|
72
|
+
|
|
31
73
|
/**
|
|
32
74
|
* Asynchronous query of all bindings.
|
|
33
75
|
*/
|
|
@@ -89,13 +131,3 @@ export class ContextBinder {
|
|
|
89
131
|
);
|
|
90
132
|
}
|
|
91
133
|
}
|
|
92
|
-
|
|
93
|
-
export type BindingProps = Partial<{
|
|
94
|
-
blueprints: Ref.Ref<Blueprint>[];
|
|
95
|
-
objects: Ref.Ref<Type.Expando>[];
|
|
96
|
-
}>;
|
|
97
|
-
|
|
98
|
-
export class Bindings {
|
|
99
|
-
blueprints = new ComplexSet<Ref.Ref<Blueprint>>((ref) => ref.dxn.toString());
|
|
100
|
-
objects = new ComplexSet<Ref.Ref<Type.Expando>>((ref) => ref.dxn.toString());
|
|
101
|
-
}
|
|
@@ -2,37 +2,41 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { type AiError, type AiLanguageModel, type AiTool, type AiToolkit } from '@effect/ai';
|
|
6
|
+
import { Effect } from 'effect';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
type AiInputPreprocessingError,
|
|
10
|
+
type AiToolNotFoundError,
|
|
11
|
+
type ToolExecutionService,
|
|
12
|
+
type ToolResolverService,
|
|
13
|
+
} from '@dxos/ai';
|
|
7
14
|
import { Event } from '@dxos/async';
|
|
8
|
-
import { Obj
|
|
15
|
+
import { Obj } from '@dxos/echo';
|
|
9
16
|
import { type Queue } from '@dxos/echo-db';
|
|
10
|
-
import {
|
|
17
|
+
import { DatabaseService } from '@dxos/functions';
|
|
11
18
|
import { log } from '@dxos/log';
|
|
12
|
-
import {
|
|
19
|
+
import { DataType } from '@dxos/schema';
|
|
13
20
|
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
21
|
+
import { type AiAssistantError } from '../errors';
|
|
22
|
+
import { AiSession, type GenerationObserver } from '../session';
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
systemPrompt?: string;
|
|
19
|
-
prompt: string;
|
|
20
|
-
|
|
21
|
-
tools?: ExecutableTool[];
|
|
22
|
-
artifacts?: ArtifactDefinition[];
|
|
23
|
-
extensions?: ToolContextExtensions;
|
|
24
|
-
generationOptions?: SessionRunOptions['generationOptions'];
|
|
24
|
+
import { AiContextBinder, type ContextBinding } from './context';
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
export interface AiConversationRunParams<Tools extends AiTool.Any> {
|
|
27
|
+
prompt: string;
|
|
28
|
+
system?: string;
|
|
29
|
+
toolkit?: AiToolkit.AiToolkit<Tools>;
|
|
30
|
+
observer?: GenerationObserver;
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Remove
|
|
34
|
+
*/
|
|
35
|
+
session?: AiSession;
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
export type
|
|
34
|
-
|
|
35
|
-
queue: Queue<Message | ContextBinding>;
|
|
38
|
+
export type AiConversationOptions = {
|
|
39
|
+
queue: Queue<DataType.Message | ContextBinding>;
|
|
36
40
|
};
|
|
37
41
|
|
|
38
42
|
/**
|
|
@@ -40,64 +44,82 @@ export type ConversationOptions = {
|
|
|
40
44
|
* Context + history + artifacts.
|
|
41
45
|
* Backed by a Queue.
|
|
42
46
|
*/
|
|
43
|
-
export class
|
|
44
|
-
private readonly
|
|
45
|
-
private readonly _queue: Queue<Message | ContextBinding>;
|
|
47
|
+
export class AiConversation {
|
|
48
|
+
private readonly _queue: Queue<DataType.Message | ContextBinding>;
|
|
46
49
|
|
|
47
50
|
/**
|
|
48
|
-
*
|
|
49
|
-
* This is called before the first message is sent.
|
|
51
|
+
* Blueprints bound to the conversation.
|
|
50
52
|
*/
|
|
51
|
-
public readonly
|
|
53
|
+
public readonly _context: AiContextBinder;
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
56
|
+
* Fired when the execution loop begins.
|
|
57
|
+
* This is called before the first message is sent.
|
|
58
|
+
*
|
|
59
|
+
* @deprecated Pass in a session instead.
|
|
55
60
|
*/
|
|
56
|
-
|
|
61
|
+
// TODO(burdon): Is this still deprecated?
|
|
62
|
+
public readonly onBegin = new Event<AiSession>();
|
|
57
63
|
|
|
58
|
-
constructor(options:
|
|
59
|
-
this._serviceContainer = options.serviceContainer;
|
|
64
|
+
constructor(options: AiConversationOptions) {
|
|
60
65
|
this._queue = options.queue;
|
|
61
|
-
this.
|
|
66
|
+
this._context = new AiContextBinder(this._queue);
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
this.onBegin.emit(session);
|
|
67
|
-
|
|
68
|
-
const history = await this.getHistory();
|
|
69
|
-
const context = await this.context.query();
|
|
70
|
-
const blueprints = (await Ref.Array.loadAll([...context.blueprints])).filter(isNonNullable);
|
|
71
|
-
if (blueprints.length > 1) {
|
|
72
|
-
log.warn('multiple blueprints are not yet supported');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const messages = await session.run({
|
|
76
|
-
history,
|
|
77
|
-
prompt: options.prompt,
|
|
78
|
-
systemPrompt: (options.systemPrompt ?? '') + (blueprints.at(0)?.instructions ?? ''),
|
|
79
|
-
|
|
80
|
-
// TODO(dmaretskyi): Artifacts come from the blueprint?
|
|
81
|
-
artifacts: options.artifacts ?? [],
|
|
82
|
-
tools: blueprints.at(0)?.tools ?? [],
|
|
83
|
-
executableTools: options.tools,
|
|
84
|
-
requiredArtifactIds: options.requiredArtifactIds,
|
|
85
|
-
client: this._serviceContainer.getService(AiService).client,
|
|
86
|
-
toolResolver: this._serviceContainer.getService(ToolResolverService).toolResolver,
|
|
87
|
-
extensions: {
|
|
88
|
-
serviceContainer: this._serviceContainer,
|
|
89
|
-
...options.extensions,
|
|
90
|
-
},
|
|
91
|
-
generationOptions: options.generationOptions,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
await this._queue.append(messages);
|
|
95
|
-
|
|
96
|
-
return messages;
|
|
69
|
+
get context() {
|
|
70
|
+
return this._context;
|
|
97
71
|
}
|
|
98
72
|
|
|
99
|
-
async getHistory(): Promise<Message[]> {
|
|
73
|
+
async getHistory(): Promise<DataType.Message[]> {
|
|
100
74
|
const queueItems = await this._queue.queryObjects();
|
|
101
|
-
return queueItems.filter(Obj.instanceOf(Message));
|
|
75
|
+
return queueItems.filter(Obj.instanceOf(DataType.Message));
|
|
102
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Executes a prompt.
|
|
80
|
+
* Each invocation creates a new `AiSession`, which handles potential tool calls.
|
|
81
|
+
*/
|
|
82
|
+
run = <Tools extends AiTool.Any>({
|
|
83
|
+
// TODO(burdon): Decide whether to pass in or to fully encapsulate.
|
|
84
|
+
session = new AiSession(),
|
|
85
|
+
...params
|
|
86
|
+
}: AiConversationRunParams<Tools>): Effect.Effect<
|
|
87
|
+
DataType.Message[],
|
|
88
|
+
AiAssistantError | AiInputPreprocessingError | AiError.AiError | AiToolNotFoundError,
|
|
89
|
+
AiLanguageModel.AiLanguageModel | ToolResolverService | ToolExecutionService | AiTool.ToHandler<Tools>
|
|
90
|
+
> =>
|
|
91
|
+
Effect.gen(this, function* () {
|
|
92
|
+
const history = yield* Effect.promise(() => this.getHistory());
|
|
93
|
+
const context = yield* Effect.promise(() => this.context.query());
|
|
94
|
+
const blueprints = yield* Effect.forEach(context.blueprints.values(), DatabaseService.load);
|
|
95
|
+
|
|
96
|
+
// TODO(burdon): These don't need to be loaded; just need id and typename from context.
|
|
97
|
+
const objects = yield* Effect.forEach(context.objects.values(), DatabaseService.load);
|
|
98
|
+
|
|
99
|
+
log.info('run', {
|
|
100
|
+
prompt: params.prompt,
|
|
101
|
+
system: params.system,
|
|
102
|
+
history: history.length,
|
|
103
|
+
objects: objects.length,
|
|
104
|
+
blueprints: blueprints.length,
|
|
105
|
+
toolkit: params.toolkit,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const start = Date.now();
|
|
109
|
+
this.onBegin.emit(session);
|
|
110
|
+
|
|
111
|
+
const messages = yield* session.run({
|
|
112
|
+
prompt: params.prompt,
|
|
113
|
+
system: params.system,
|
|
114
|
+
history,
|
|
115
|
+
objects,
|
|
116
|
+
blueprints,
|
|
117
|
+
toolkit: params.toolkit,
|
|
118
|
+
observer: params.observer,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
log.info('result', { messages: messages, duration: Date.now() - start });
|
|
122
|
+
yield* Effect.promise(() => this._queue.append(messages));
|
|
123
|
+
return messages;
|
|
124
|
+
}).pipe(Effect.withSpan('AiConversation.run'));
|
|
103
125
|
}
|
package/src/errors.ts
ADDED
|
@@ -2,35 +2,24 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { describe, test
|
|
5
|
+
import { beforeAll, describe, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { FunctionExecutor, ServiceContainer } from '@dxos/functions';
|
|
7
|
+
import { todo } from '@dxos/debug';
|
|
8
|
+
import { FunctionExecutor } from '@dxos/functions';
|
|
10
9
|
import { log } from '@dxos/log';
|
|
11
10
|
import { createTestData } from '@dxos/schema/testing';
|
|
12
11
|
import { range } from '@dxos/util';
|
|
13
12
|
|
|
14
|
-
import { extractionAnthropicFn } from './extraction-llm-function';
|
|
15
13
|
import { processTranscriptMessage } from '../extraction';
|
|
16
14
|
|
|
15
|
+
import { extractionAnthropicFn } from './extraction-llm-function';
|
|
16
|
+
|
|
17
|
+
// TODO(burdon): Rewrite test.
|
|
17
18
|
describe.skip('LLM EntityExtraction', () => {
|
|
18
19
|
let executor: FunctionExecutor;
|
|
19
20
|
|
|
20
21
|
beforeAll(async () => {
|
|
21
|
-
executor = new FunctionExecutor(
|
|
22
|
-
new ServiceContainer().setServices({
|
|
23
|
-
ai: {
|
|
24
|
-
client: new EdgeAiServiceClient({
|
|
25
|
-
endpoint: AI_SERVICE_ENDPOINT.REMOTE,
|
|
26
|
-
defaultGenerationOptions: {
|
|
27
|
-
// model: '@anthropic/claude-sonnet-4-20250514',
|
|
28
|
-
model: '@anthropic/claude-3-5-haiku-20241022',
|
|
29
|
-
},
|
|
30
|
-
}),
|
|
31
|
-
},
|
|
32
|
-
}),
|
|
33
|
-
);
|
|
22
|
+
executor = new FunctionExecutor(todo());
|
|
34
23
|
});
|
|
35
24
|
|
|
36
25
|
test('should process a transcript block', async () => {
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// ISSUE(burdon): defineFunction
|
|
6
|
+
// @ts-nocheck
|
|
7
|
+
|
|
8
|
+
import { AiService, ToolRegistry } from '@dxos/ai';
|
|
6
9
|
import { Obj } from '@dxos/echo';
|
|
7
10
|
import { create } from '@dxos/echo-schema';
|
|
8
|
-
import {
|
|
9
|
-
import { DataType } from '@dxos/schema';
|
|
11
|
+
import { type FunctionDefinition, defineFunction } from '@dxos/functions';
|
|
12
|
+
import { type ContentBlock, DataType } from '@dxos/schema';
|
|
10
13
|
|
|
11
|
-
import
|
|
12
|
-
import { AISession } from '../../session';
|
|
14
|
+
import { AiSession } from '../../session';
|
|
13
15
|
import { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
14
|
-
import {
|
|
16
|
+
import { ReferencedQuotes, insertReferences } from '../quotes';
|
|
17
|
+
|
|
18
|
+
import PROMPT from './instructions.tpl?raw';
|
|
15
19
|
|
|
16
20
|
export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, ExtractionOutput> = defineFunction({
|
|
17
21
|
description: 'Extract entities from the transcript message and add them to the message.',
|
|
@@ -19,8 +23,8 @@ export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, Extracti
|
|
|
19
23
|
outputSchema: ExtractionOutput,
|
|
20
24
|
handler: async ({ data: { message, objects }, context }) => {
|
|
21
25
|
const startTime = performance.now();
|
|
22
|
-
const ai = context.getService(AiService);
|
|
23
|
-
const session = new
|
|
26
|
+
const ai = context.getService(AiService.AiService);
|
|
27
|
+
const session = new AiSession({ operationModel: 'configured' });
|
|
24
28
|
const result = await session.runStructured(ReferencedQuotes, {
|
|
25
29
|
generationOptions: {
|
|
26
30
|
model: '@anthropic/claude-3-5-haiku-20241022',
|
|
@@ -28,17 +32,18 @@ export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, Extracti
|
|
|
28
32
|
client: ai.client,
|
|
29
33
|
systemPrompt: PROMPT,
|
|
30
34
|
history: [
|
|
31
|
-
Obj.make(Message, {
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
Obj.make(DataType.Message, {
|
|
36
|
+
created: new Date().toISOString(),
|
|
37
|
+
sender: { role: 'user' },
|
|
38
|
+
blocks: [
|
|
34
39
|
{
|
|
35
|
-
|
|
40
|
+
_tag: 'text',
|
|
36
41
|
text: `<context>${JSON.stringify(objects)}</context>`,
|
|
37
|
-
},
|
|
42
|
+
} satisfies ContentBlock.Text,
|
|
38
43
|
{
|
|
39
|
-
|
|
44
|
+
_tag: 'text',
|
|
40
45
|
text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`,
|
|
41
|
-
},
|
|
46
|
+
} satisfies ContentBlock.Text,
|
|
42
47
|
],
|
|
43
48
|
}),
|
|
44
49
|
],
|
|
@@ -46,13 +51,13 @@ export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, Extracti
|
|
|
46
51
|
prompt: '',
|
|
47
52
|
tools: [],
|
|
48
53
|
toolResolver: new ToolRegistry([]),
|
|
49
|
-
});
|
|
54
|
+
} as any); // TODO(burdon): Rewrite test.
|
|
50
55
|
|
|
51
56
|
return {
|
|
52
57
|
message: create(DataType.Message, {
|
|
53
58
|
...message,
|
|
54
59
|
blocks: message.blocks.map((block, i) =>
|
|
55
|
-
block.
|
|
60
|
+
block._tag !== 'transcript'
|
|
56
61
|
? block
|
|
57
62
|
: {
|
|
58
63
|
...block,
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { describe, test
|
|
5
|
+
import { beforeAll, describe, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
import { type EchoDatabase } from '@dxos/echo-db';
|
|
8
8
|
import { EchoTestBuilder } from '@dxos/echo-db/testing';
|
|
9
9
|
import { FunctionExecutor, ServiceContainer } from '@dxos/functions';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
11
|
import { DataType } from '@dxos/schema';
|
|
12
|
-
import {
|
|
12
|
+
import { Testing, createTestData } from '@dxos/schema/testing';
|
|
13
13
|
import { range } from '@dxos/util';
|
|
14
14
|
|
|
15
|
-
import { extractionNerFn } from './extraction-ner-function';
|
|
16
15
|
import { processTranscriptMessage } from '../extraction';
|
|
17
16
|
|
|
17
|
+
import { extractionNerFn } from './extraction-ner-function';
|
|
18
|
+
|
|
18
19
|
describe.skip('NER EntityExtraction', () => {
|
|
19
20
|
let builder: EchoTestBuilder;
|
|
20
21
|
let db: EchoDatabase;
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
// ISSUE(burdon): defineFunction
|
|
6
|
+
// @ts-nocheck
|
|
7
|
+
|
|
5
8
|
import { asyncTimeout } from '@dxos/async';
|
|
6
9
|
import { create } from '@dxos/echo-schema';
|
|
7
10
|
import { DatabaseService, defineFunction } from '@dxos/functions';
|
|
@@ -9,7 +12,6 @@ import { invariant } from '@dxos/invariant';
|
|
|
9
12
|
import { log } from '@dxos/log';
|
|
10
13
|
import { DataType } from '@dxos/schema';
|
|
11
14
|
|
|
12
|
-
import { extractFullEntities } from './named-entity-recognition';
|
|
13
15
|
import { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
14
16
|
import { findQuotes, insertReferences } from '../quotes';
|
|
15
17
|
|
|
@@ -22,10 +24,11 @@ export const extractionNerFn = defineFunction({
|
|
|
22
24
|
log.info('input', { message, options });
|
|
23
25
|
const startTime = performance.now();
|
|
24
26
|
const { db } = context.getService(DatabaseService);
|
|
27
|
+
const { extractFullEntities } = await import('./named-entity-recognition');
|
|
25
28
|
|
|
26
29
|
const entitiesPromise = Promise.all(
|
|
27
30
|
message.blocks.map(async (block) => {
|
|
28
|
-
invariant(block.
|
|
31
|
+
invariant(block._tag === 'transcript' || block._tag === 'text', 'Block must have text');
|
|
29
32
|
return extractFullEntities(block.text);
|
|
30
33
|
}),
|
|
31
34
|
).then((entities) => entities.flat());
|
|
@@ -36,8 +39,8 @@ export const extractionNerFn = defineFunction({
|
|
|
36
39
|
db,
|
|
37
40
|
);
|
|
38
41
|
const blocksWithReferences = message.blocks.map((block, i) => {
|
|
39
|
-
invariant(block.
|
|
40
|
-
return { ...block, text: insertReferences(block.
|
|
42
|
+
invariant(block._tag === 'transcript' || block._tag === 'text', 'Block must have text');
|
|
43
|
+
return { ...block, text: insertReferences(block._tag, quoteReferences) };
|
|
41
44
|
});
|
|
42
45
|
const messageWithReferences = create(DataType.Message, {
|
|
43
46
|
...message,
|
|
@@ -57,7 +57,7 @@ describe('NamedEntityRecognition', () => {
|
|
|
57
57
|
const { transcriptWoflram, transcriptJosiah } = await createTestData();
|
|
58
58
|
|
|
59
59
|
const blocks = [...transcriptWoflram, ...transcriptJosiah].flatMap((message) =>
|
|
60
|
-
message.blocks.flatMap((block) => (block.
|
|
60
|
+
message.blocks.flatMap((block) => (block._tag === 'transcript' ? [block.text] : [])),
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
for (const block of blocks) {
|
|
@@ -70,7 +70,7 @@ describe('NamedEntityRecognition', () => {
|
|
|
70
70
|
const { transcriptMessages } = await createTestData();
|
|
71
71
|
|
|
72
72
|
const blocks = transcriptMessages.flatMap((message) =>
|
|
73
|
-
message.blocks.flatMap((block) => (block.
|
|
73
|
+
message.blocks.flatMap((block) => (block._tag === 'transcript' ? [block.text] : [])),
|
|
74
74
|
);
|
|
75
75
|
|
|
76
76
|
for (const block of blocks) {
|
package/src/extraction/quotes.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Schema } from 'effect';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { Filter, Query } from '@dxos/echo';
|
|
8
8
|
import { type EchoDatabase } from '@dxos/echo-db';
|
|
9
9
|
import { ObjectId } from '@dxos/echo-schema';
|
|
10
10
|
import { DXN } from '@dxos/keys';
|