@dxos/assistant 0.8.4-main.b97322e → 0.8.4-main.bc2380dfbc
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/LICENSE +102 -5
- package/README.md +2 -1
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/neutral/extraction/index.mjs +204 -0
- package/dist/lib/neutral/extraction/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +1755 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts +0 -1
- package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +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 +1066 -273
- package/dist/types/src/extraction/extraction.d.ts.map +1 -1
- package/dist/types/src/extraction/index.d.ts +0 -1
- package/dist/types/src/extraction/index.d.ts.map +1 -1
- package/dist/types/src/extraction/quotes.d.ts +3 -3
- package/dist/types/src/extraction/quotes.d.ts.map +1 -1
- package/dist/types/src/functions/services.d.ts +15 -4
- package/dist/types/src/functions/services.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/request/AiRequest.d.ts +104 -0
- package/dist/types/src/request/AiRequest.d.ts.map +1 -0
- package/dist/types/src/request/artifact-diff.d.ts +27 -0
- package/dist/types/src/request/artifact-diff.d.ts.map +1 -0
- package/dist/types/src/request/format.d.ts +15 -0
- package/dist/types/src/request/format.d.ts.map +1 -0
- package/dist/types/src/request/index.d.ts +4 -0
- package/dist/types/src/request/index.d.ts.map +1 -0
- package/dist/types/src/request/observer.d.ts +23 -0
- package/dist/types/src/request/observer.d.ts.map +1 -0
- package/dist/types/src/{session → request}/version-pin.d.ts +4 -4
- package/dist/types/src/request/version-pin.d.ts.map +1 -0
- package/dist/types/src/session/AiContext.d.ts +154 -0
- package/dist/types/src/session/AiContext.d.ts.map +1 -0
- package/dist/types/src/session/AiContext.test.d.ts +2 -0
- package/dist/types/src/session/AiContext.test.d.ts.map +1 -0
- package/dist/types/src/session/AiSession.d.ts +73 -0
- package/dist/types/src/session/AiSession.d.ts.map +1 -0
- package/dist/types/src/session/index.d.ts +3 -2
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/toolkit.d.ts +16 -0
- package/dist/types/src/session/toolkit.d.ts.map +1 -0
- package/dist/types/src/templates/index.d.ts +1 -1
- package/dist/types/src/templates/system.d.ts +17 -0
- package/dist/types/src/templates/system.d.ts.map +1 -0
- package/dist/types/src/util/artifact.d.ts +27 -0
- package/dist/types/src/util/artifact.d.ts.map +1 -0
- package/dist/types/src/util/diff.d.ts +17 -0
- package/dist/types/src/util/diff.d.ts.map +1 -0
- package/dist/types/src/util/diff.test.d.ts +2 -0
- package/dist/types/src/util/diff.test.d.ts.map +1 -0
- package/dist/types/src/util/error-handling.d.ts +4 -0
- package/dist/types/src/util/error-handling.d.ts.map +1 -0
- package/dist/types/src/util/errors.d.ts +67 -0
- package/dist/types/src/util/errors.d.ts.map +1 -0
- package/dist/types/src/util/execution-graph.d.ts +85 -0
- package/dist/types/src/util/execution-graph.d.ts.map +1 -0
- package/dist/types/src/util/execution-graph.test.d.ts +2 -0
- package/dist/types/src/util/execution-graph.test.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +7 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/tracing.d.ts +233 -0
- package/dist/types/src/util/tracing.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -36
- package/src/extraction/extraction-ner-function/index.ts +0 -1
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +2 -0
- package/src/extraction/extraction.ts +44 -15
- package/src/extraction/index.ts +0 -1
- package/src/extraction/quotes.test.ts +3 -3
- package/src/extraction/quotes.ts +6 -7
- package/src/functions/services.ts +173 -98
- package/src/index.ts +2 -5
- package/src/request/AiRequest.ts +348 -0
- package/src/request/artifact-diff.ts +41 -0
- package/src/request/format.ts +147 -0
- package/src/request/index.ts +8 -0
- package/src/request/observer.ts +62 -0
- package/src/{session → request}/version-pin.ts +8 -8
- package/src/session/AiContext.test.ts +53 -0
- package/src/session/AiContext.ts +403 -0
- package/src/session/AiSession.ts +324 -0
- package/src/session/index.ts +4 -2
- package/src/session/toolkit.ts +47 -0
- package/src/templates/index.ts +1 -1
- package/src/templates/instructions/format.tpl +57 -0
- package/src/templates/instructions/system.tpl +96 -0
- package/src/templates/system.ts +42 -0
- package/src/typings.d.ts +5 -0
- package/src/util/artifact.ts +88 -0
- package/src/util/diff.test.ts +74 -0
- package/src/util/diff.ts +93 -0
- package/src/util/error-handling.ts +42 -0
- package/src/util/errors.ts +15 -0
- package/src/util/execution-graph.test.ts +740 -0
- package/src/util/execution-graph.ts +519 -0
- package/src/util/index.ts +10 -0
- package/src/util/tracing.ts +57 -0
- package/dist/lib/browser/index.mjs +0 -1831
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/node-esm/index.mjs +0 -1833
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/types/bin/chat.d.ts +0 -2
- package/dist/types/bin/chat.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 -56
- 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/conversation/conversation.d.ts +0 -38
- package/dist/types/src/conversation/conversation.d.ts.map +0 -1
- package/dist/types/src/conversation/index.d.ts +0 -2
- package/dist/types/src/conversation/index.d.ts.map +0 -1
- package/dist/types/src/errors.d.ts +0 -38
- package/dist/types/src/errors.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +0 -4
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +0 -2
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts +0 -2
- package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +0 -302
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +0 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +0 -2
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +0 -1
- package/dist/types/src/research/exa.d.ts +0 -12
- package/dist/types/src/research/exa.d.ts.map +0 -1
- package/dist/types/src/research/graph.d.ts +0 -51
- 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/session/session.d.ts +0 -260
- package/dist/types/src/session/session.d.ts.map +0 -1
- package/dist/types/src/session/session.test.d.ts +0 -2
- package/dist/types/src/session/session.test.d.ts.map +0 -1
- 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/dist/types/src/summarization/summarization.test.d.ts +0 -2
- package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
- package/dist/types/src/templates/prompt.d.ts +0 -30
- package/dist/types/src/templates/prompt.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/dist/types/src/types.d.ts +0 -13
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/context/binder.ts +0 -103
- package/src/context/binding.ts +0 -32
- package/src/context/index.ts +0 -6
- package/src/conversation/conversation.ts +0 -96
- package/src/conversation/index.ts +0 -5
- package/src/errors.ts +0 -10
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +0 -83
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +0 -70
- package/src/extraction/extraction-llm-function/index.ts +0 -5
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +0 -115
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +0 -57
- package/src/research/exa.ts +0 -97
- package/src/research/graph.test.ts +0 -64
- package/src/research/graph.ts +0 -369
- package/src/research/index.ts +0 -7
- package/src/research/instructions-research.tpl +0 -98
- package/src/research/research.test.ts +0 -190
- package/src/research/research.ts +0 -87
- package/src/session/__snapshots__/session.test.ts.snap +0 -32
- package/src/session/session.test.ts +0 -310
- package/src/session/session.ts +0 -336
- package/src/session/version-pin.test.ts +0 -7
- package/src/summarization/summarization.test.ts +0 -208
- package/src/templates/assistant.tpl +0 -111
- package/src/templates/prompt.ts +0 -45
- 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/src/types.ts +0 -47
- /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
package/src/context/binder.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { computed, type ReadonlySignal } from '@preact/signals-core';
|
|
6
|
-
import { Array, pipe } from 'effect';
|
|
7
|
-
|
|
8
|
-
import { type Blueprint } from '@dxos/blueprints';
|
|
9
|
-
import { Obj, type Type, type Ref, type Relation } from '@dxos/echo';
|
|
10
|
-
import { type Queue } from '@dxos/echo-db';
|
|
11
|
-
import { ComplexSet } from '@dxos/util';
|
|
12
|
-
|
|
13
|
-
import { ContextBinding } from './binding';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Manages bindings of blueprints and objects to a conversation.
|
|
17
|
-
*/
|
|
18
|
-
export class ContextBinder {
|
|
19
|
-
constructor(private readonly _queue: Queue) {}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Reactive query of all bindings.
|
|
23
|
-
*/
|
|
24
|
-
// TODO(burdon): Cache value?
|
|
25
|
-
readonly bindings: ReadonlySignal<Bindings> = computed(() => this._reduce(this._queue.objects));
|
|
26
|
-
|
|
27
|
-
// TODO(burdon): load refs?
|
|
28
|
-
readonly blueprints: ReadonlySignal<Ref.Ref<Blueprint.Blueprint>[]> = computed(() => [
|
|
29
|
-
...this.bindings.value.blueprints,
|
|
30
|
-
]);
|
|
31
|
-
readonly objects: ReadonlySignal<Ref.Ref<Type.Expando>[]> = computed(() => [...this.bindings.value.objects]);
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Asynchronous query of all bindings.
|
|
35
|
-
*/
|
|
36
|
-
async query(): Promise<Bindings> {
|
|
37
|
-
const queueItems = await this._queue.queryObjects();
|
|
38
|
-
return this._reduce(queueItems);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// TODO(burdon): Pass in Blueprint obj (from registry?) and create reference.
|
|
42
|
-
async bind(props: BindingProps): Promise<void> {
|
|
43
|
-
if (!props.blueprints?.length && !props.objects?.length) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
await this._queue.append([
|
|
48
|
-
Obj.make(ContextBinding, {
|
|
49
|
-
blueprints: {
|
|
50
|
-
added: props.blueprints ?? [],
|
|
51
|
-
removed: [],
|
|
52
|
-
},
|
|
53
|
-
objects: {
|
|
54
|
-
added: props.objects ?? [],
|
|
55
|
-
removed: [],
|
|
56
|
-
},
|
|
57
|
-
}),
|
|
58
|
-
]);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async unbind(props: BindingProps): Promise<void> {
|
|
62
|
-
if (!props.blueprints?.length && !props.objects?.length) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
await this._queue.append([
|
|
67
|
-
Obj.make(ContextBinding, {
|
|
68
|
-
blueprints: {
|
|
69
|
-
added: [],
|
|
70
|
-
removed: props.blueprints ?? [],
|
|
71
|
-
},
|
|
72
|
-
objects: {
|
|
73
|
-
added: [],
|
|
74
|
-
removed: props.objects ?? [],
|
|
75
|
-
},
|
|
76
|
-
}),
|
|
77
|
-
]);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private _reduce(items: (Obj.Any | Relation.Any)[]): Bindings {
|
|
81
|
-
return pipe(
|
|
82
|
-
items,
|
|
83
|
-
Array.filter(Obj.instanceOf(ContextBinding)),
|
|
84
|
-
Array.reduce(new Bindings(), (context, item) => {
|
|
85
|
-
item.blueprints.removed.forEach((item) => context.blueprints.delete(item));
|
|
86
|
-
item.blueprints.added.forEach((item) => context.blueprints.add(item));
|
|
87
|
-
item.objects.removed.forEach((item) => context.objects.delete(item));
|
|
88
|
-
item.objects.added.forEach((item) => context.objects.add(item));
|
|
89
|
-
return context;
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export type BindingProps = Partial<{
|
|
96
|
-
blueprints: Ref.Ref<Blueprint.Blueprint>[];
|
|
97
|
-
objects: Ref.Ref<Type.Expando>[];
|
|
98
|
-
}>;
|
|
99
|
-
|
|
100
|
-
export class Bindings {
|
|
101
|
-
blueprints = new ComplexSet<Ref.Ref<Blueprint.Blueprint>>((ref) => ref.dxn.toString());
|
|
102
|
-
objects = new ComplexSet<Ref.Ref<Type.Expando>>((ref) => ref.dxn.toString());
|
|
103
|
-
}
|
package/src/context/binding.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { Schema } from 'effect';
|
|
6
|
-
|
|
7
|
-
import { Blueprint } from '@dxos/blueprints';
|
|
8
|
-
import { Type } from '@dxos/echo';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Thread message that binds or unbinds contextual objects to a conversation.
|
|
12
|
-
*/
|
|
13
|
-
// TODO(burdon): Make ContentBlock.
|
|
14
|
-
export const ContextBinding = Schema.Struct({
|
|
15
|
-
blueprints: Schema.Struct({
|
|
16
|
-
added: Schema.Array(Type.Ref(Blueprint.Blueprint)),
|
|
17
|
-
removed: Schema.Array(Type.Ref(Blueprint.Blueprint)),
|
|
18
|
-
}),
|
|
19
|
-
|
|
20
|
-
// TODO(burdon): Type.Expando => Type.Obj (or Obj.Any?)
|
|
21
|
-
objects: Schema.Struct({
|
|
22
|
-
added: Schema.Array(Type.Ref(Type.Expando)),
|
|
23
|
-
removed: Schema.Array(Type.Ref(Type.Expando)),
|
|
24
|
-
}),
|
|
25
|
-
}).pipe(
|
|
26
|
-
Type.Obj({
|
|
27
|
-
typename: 'dxos.org/type/ContextBinding',
|
|
28
|
-
version: '0.1.0',
|
|
29
|
-
}),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
export interface ContextBinding extends Schema.Schema.Type<typeof ContextBinding> {}
|
package/src/context/index.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type AiError, type AiLanguageModel, type AiTool, type AiToolkit } from '@effect/ai';
|
|
6
|
-
import { Effect } from 'effect';
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
type ToolExecutionService,
|
|
10
|
-
type ToolResolverService,
|
|
11
|
-
type AiInputPreprocessingError,
|
|
12
|
-
type AiToolNotFoundError,
|
|
13
|
-
} from '@dxos/ai';
|
|
14
|
-
import { Event } from '@dxos/async';
|
|
15
|
-
import { Obj } from '@dxos/echo';
|
|
16
|
-
import { type Queue } from '@dxos/echo-db';
|
|
17
|
-
import { DatabaseService } from '@dxos/functions';
|
|
18
|
-
import { DataType } from '@dxos/schema';
|
|
19
|
-
|
|
20
|
-
import { ContextBinder, type ContextBinding } from '../context';
|
|
21
|
-
import type { AiAssistantError } from '../errors';
|
|
22
|
-
import { AiSession } from '../session';
|
|
23
|
-
|
|
24
|
-
export interface ConversationRunOptions<Tools extends AiTool.Any> {
|
|
25
|
-
systemPrompt?: string;
|
|
26
|
-
prompt: string;
|
|
27
|
-
|
|
28
|
-
toolkit?: AiToolkit.AiToolkit<Tools>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type ConversationOptions = {
|
|
32
|
-
queue: Queue<DataType.Message | ContextBinding>;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Persistent conversation state.
|
|
37
|
-
* Context + history + artifacts.
|
|
38
|
-
* Backed by a Queue.
|
|
39
|
-
*/
|
|
40
|
-
export class Conversation {
|
|
41
|
-
private readonly _queue: Queue<DataType.Message | ContextBinding>;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Fired when the execution loop begins.
|
|
45
|
-
* This is called before the first message is sent.
|
|
46
|
-
*/
|
|
47
|
-
public readonly onBegin = new Event<AiSession>();
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Blueprints bound to the conversation.
|
|
51
|
-
*/
|
|
52
|
-
public readonly context: ContextBinder;
|
|
53
|
-
|
|
54
|
-
constructor(options: ConversationOptions) {
|
|
55
|
-
this._queue = options.queue;
|
|
56
|
-
this.context = new ContextBinder(this._queue);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async getHistory(): Promise<DataType.Message[]> {
|
|
60
|
-
const queueItems = await this._queue.queryObjects();
|
|
61
|
-
return queueItems.filter(Obj.instanceOf(DataType.Message));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
run = <Tools extends AiTool.Any>(
|
|
65
|
-
options: ConversationRunOptions<Tools>,
|
|
66
|
-
): Effect.Effect<
|
|
67
|
-
DataType.Message[],
|
|
68
|
-
AiAssistantError | AiInputPreprocessingError | AiError.AiError | AiToolNotFoundError,
|
|
69
|
-
AiLanguageModel.AiLanguageModel | ToolResolverService | ToolExecutionService | AiTool.ToHandler<Tools>
|
|
70
|
-
> =>
|
|
71
|
-
Effect.gen(this, function* () {
|
|
72
|
-
const session = new AiSession();
|
|
73
|
-
this.onBegin.emit(session);
|
|
74
|
-
|
|
75
|
-
const history = yield* Effect.promise(() => this.getHistory());
|
|
76
|
-
const context = yield* Effect.promise(() => this.context.query());
|
|
77
|
-
const blueprints = yield* Effect.forEach(context.blueprints.values(), DatabaseService.loadRef);
|
|
78
|
-
|
|
79
|
-
const contextObjects = yield* Effect.forEach(context.objects.values(), DatabaseService.loadRef);
|
|
80
|
-
|
|
81
|
-
const systemPrompt =
|
|
82
|
-
(options.systemPrompt ?? '') +
|
|
83
|
-
'\n\n' +
|
|
84
|
-
contextObjects.map((obj) => `<object>${Obj.getDXN(obj)}</object>`).join('\n');
|
|
85
|
-
|
|
86
|
-
const messages = yield* session.run({
|
|
87
|
-
prompt: options.prompt,
|
|
88
|
-
history,
|
|
89
|
-
systemPrompt,
|
|
90
|
-
toolkit: options.toolkit,
|
|
91
|
-
blueprints,
|
|
92
|
-
});
|
|
93
|
-
yield* Effect.promise(() => this._queue.append(messages));
|
|
94
|
-
return messages;
|
|
95
|
-
}).pipe(Effect.withSpan('Conversation.run'));
|
|
96
|
-
}
|
package/src/errors.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { beforeAll, describe, test } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { todo } from '@dxos/debug';
|
|
8
|
-
import { FunctionExecutor } from '@dxos/functions';
|
|
9
|
-
import { log } from '@dxos/log';
|
|
10
|
-
import { createTestData } from '@dxos/schema/testing';
|
|
11
|
-
import { range } from '@dxos/util';
|
|
12
|
-
|
|
13
|
-
import { processTranscriptMessage } from '../extraction';
|
|
14
|
-
import { extractionAnthropicFn } from './extraction-llm-function';
|
|
15
|
-
|
|
16
|
-
// TODO(burdon): Rewrite test.
|
|
17
|
-
describe.skip('LLM EntityExtraction', () => {
|
|
18
|
-
let executor: FunctionExecutor;
|
|
19
|
-
|
|
20
|
-
beforeAll(async () => {
|
|
21
|
-
executor = new FunctionExecutor(todo());
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
test('should process a transcript block', async () => {
|
|
25
|
-
const { transcriptMessages, documents, contacts } = createTestData();
|
|
26
|
-
log.info('context', { documents, contacts });
|
|
27
|
-
|
|
28
|
-
for (const message of transcriptMessages.slice(0, 1)) {
|
|
29
|
-
log.info('input', message);
|
|
30
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
31
|
-
input: {
|
|
32
|
-
message,
|
|
33
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
34
|
-
},
|
|
35
|
-
function: extractionAnthropicFn,
|
|
36
|
-
executor,
|
|
37
|
-
});
|
|
38
|
-
log.info('output', enhancedMessage);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('computational irreducibility', async () => {
|
|
43
|
-
const { transcriptWoflram, documents, contacts } = createTestData();
|
|
44
|
-
|
|
45
|
-
log.info('context', { documents, contacts });
|
|
46
|
-
const message = transcriptWoflram[0];
|
|
47
|
-
log.info('input', message);
|
|
48
|
-
|
|
49
|
-
await Promise.all(
|
|
50
|
-
range(10).map(async () => {
|
|
51
|
-
const { message: enhancedMessage, timeElapsed } = await processTranscriptMessage({
|
|
52
|
-
input: {
|
|
53
|
-
message,
|
|
54
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
55
|
-
},
|
|
56
|
-
function: extractionAnthropicFn,
|
|
57
|
-
executor,
|
|
58
|
-
});
|
|
59
|
-
log.info('output', { message: enhancedMessage.blocks[0], timeElapsed });
|
|
60
|
-
}),
|
|
61
|
-
);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test('org and document linking', async () => {
|
|
65
|
-
const { transcriptJosiah, documents, contacts, organizations } = createTestData();
|
|
66
|
-
|
|
67
|
-
log.info('context', { contacts, organizations, documents });
|
|
68
|
-
|
|
69
|
-
for (const message of transcriptJosiah) {
|
|
70
|
-
log.info('input', message);
|
|
71
|
-
|
|
72
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
73
|
-
input: {
|
|
74
|
-
message,
|
|
75
|
-
objects: [...documents, ...Object.values(contacts), ...Object.values(organizations)],
|
|
76
|
-
},
|
|
77
|
-
function: extractionAnthropicFn,
|
|
78
|
-
executor,
|
|
79
|
-
});
|
|
80
|
-
log.info('output', enhancedMessage);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
});
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// TODO(burdon): Fix.
|
|
6
|
-
// @ts-nocheck
|
|
7
|
-
|
|
8
|
-
import { ToolRegistry, AiService } from '@dxos/ai';
|
|
9
|
-
import { Obj } from '@dxos/echo';
|
|
10
|
-
import { create } from '@dxos/echo-schema';
|
|
11
|
-
import { defineFunction, type FunctionDefinition } from '@dxos/functions';
|
|
12
|
-
import { type ContentBlock, DataType } from '@dxos/schema';
|
|
13
|
-
|
|
14
|
-
import PROMPT from './instructions.tpl?raw';
|
|
15
|
-
import { AiSession } from '../../session';
|
|
16
|
-
import { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
17
|
-
import { insertReferences, ReferencedQuotes } from '../quotes';
|
|
18
|
-
|
|
19
|
-
export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, ExtractionOutput> = defineFunction({
|
|
20
|
-
description: 'Extract entities from the transcript message and add them to the message.',
|
|
21
|
-
inputSchema: ExtractionInput,
|
|
22
|
-
outputSchema: ExtractionOutput,
|
|
23
|
-
handler: async ({ data: { message, objects }, context }) => {
|
|
24
|
-
const startTime = performance.now();
|
|
25
|
-
const ai = context.getService(AiService);
|
|
26
|
-
const session = new AiSession({ operationModel: 'configured' });
|
|
27
|
-
const result = await session.runStructured(ReferencedQuotes, {
|
|
28
|
-
generationOptions: {
|
|
29
|
-
model: '@anthropic/claude-3-5-haiku-20241022',
|
|
30
|
-
},
|
|
31
|
-
client: ai.client,
|
|
32
|
-
systemPrompt: PROMPT,
|
|
33
|
-
history: [
|
|
34
|
-
Obj.make(DataType.Message, {
|
|
35
|
-
created: new Date().toISOString(),
|
|
36
|
-
sender: { role: 'user' },
|
|
37
|
-
blocks: [
|
|
38
|
-
{
|
|
39
|
-
_tag: 'text',
|
|
40
|
-
text: `<context>${JSON.stringify(objects)}</context>`,
|
|
41
|
-
} satisfies ContentBlock.Text,
|
|
42
|
-
{
|
|
43
|
-
_tag: 'text',
|
|
44
|
-
text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`,
|
|
45
|
-
} satisfies ContentBlock.Text,
|
|
46
|
-
],
|
|
47
|
-
}),
|
|
48
|
-
],
|
|
49
|
-
artifacts: [],
|
|
50
|
-
prompt: '',
|
|
51
|
-
tools: [],
|
|
52
|
-
toolResolver: new ToolRegistry([]),
|
|
53
|
-
} as any); // TODO(burdon): Rewrite test.
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
message: create(DataType.Message, {
|
|
57
|
-
...message,
|
|
58
|
-
blocks: message.blocks.map((block, i) =>
|
|
59
|
-
block._tag !== 'transcript'
|
|
60
|
-
? block
|
|
61
|
-
: {
|
|
62
|
-
...block,
|
|
63
|
-
text: insertReferences(block.text, result),
|
|
64
|
-
},
|
|
65
|
-
),
|
|
66
|
-
}),
|
|
67
|
-
timeElapsed: performance.now() - startTime,
|
|
68
|
-
};
|
|
69
|
-
},
|
|
70
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { describe, test, beforeAll } from 'vitest';
|
|
6
|
-
|
|
7
|
-
import { type EchoDatabase } from '@dxos/echo-db';
|
|
8
|
-
import { EchoTestBuilder } from '@dxos/echo-db/testing';
|
|
9
|
-
import { FunctionExecutor, ServiceContainer } from '@dxos/functions';
|
|
10
|
-
import { log } from '@dxos/log';
|
|
11
|
-
import { DataType } from '@dxos/schema';
|
|
12
|
-
import { createTestData, Testing } from '@dxos/schema/testing';
|
|
13
|
-
import { range } from '@dxos/util';
|
|
14
|
-
|
|
15
|
-
import { extractionNerFn } from './extraction-ner-function';
|
|
16
|
-
import { processTranscriptMessage } from '../extraction';
|
|
17
|
-
|
|
18
|
-
describe.skip('NER EntityExtraction', () => {
|
|
19
|
-
let builder: EchoTestBuilder;
|
|
20
|
-
let db: EchoDatabase;
|
|
21
|
-
let executor: FunctionExecutor;
|
|
22
|
-
let testData: {
|
|
23
|
-
transcriptJosiah: DataType.Message[];
|
|
24
|
-
transcriptWoflram: DataType.Message[];
|
|
25
|
-
transcriptMessages: DataType.Message[];
|
|
26
|
-
documents: Testing.DocumentType[];
|
|
27
|
-
contacts: Record<string, DataType.Person>;
|
|
28
|
-
organizations: Record<string, DataType.Organization>;
|
|
29
|
-
};
|
|
30
|
-
const TYPES = [DataType.Organization, DataType.Person, Testing.Contact, Testing.DocumentType];
|
|
31
|
-
|
|
32
|
-
beforeAll(async () => {
|
|
33
|
-
// TODO(dmaretskyi): Helper to scaffold this from a config.
|
|
34
|
-
builder = await new EchoTestBuilder().open();
|
|
35
|
-
const { db: db1 } = await builder.createDatabase({ indexing: { vector: true } });
|
|
36
|
-
db = db1;
|
|
37
|
-
db.graph.schemaRegistry.addSchema(TYPES);
|
|
38
|
-
const data = createTestData();
|
|
39
|
-
testData = {
|
|
40
|
-
transcriptJosiah: data.transcriptJosiah,
|
|
41
|
-
transcriptWoflram: data.transcriptWoflram,
|
|
42
|
-
transcriptMessages: data.transcriptMessages,
|
|
43
|
-
documents: data.documents.map((document) => db.add(document)),
|
|
44
|
-
contacts: Object.fromEntries(Object.entries(data.contacts).map(([key, value]) => [key, db.add(value)])),
|
|
45
|
-
organizations: Object.fromEntries(Object.entries(data.organizations).map(([key, value]) => [key, db.add(value)])),
|
|
46
|
-
};
|
|
47
|
-
await db.flush();
|
|
48
|
-
|
|
49
|
-
executor = new FunctionExecutor(
|
|
50
|
-
new ServiceContainer().setServices({
|
|
51
|
-
database: { db },
|
|
52
|
-
}),
|
|
53
|
-
);
|
|
54
|
-
}, 30_000);
|
|
55
|
-
|
|
56
|
-
test('should process a transcript block', async () => {
|
|
57
|
-
const { transcriptMessages, documents, contacts } = testData;
|
|
58
|
-
log.info('context', { documents, contacts });
|
|
59
|
-
|
|
60
|
-
for (const message of transcriptMessages) {
|
|
61
|
-
log.info('input', message);
|
|
62
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
63
|
-
input: {
|
|
64
|
-
message,
|
|
65
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
66
|
-
},
|
|
67
|
-
function: extractionNerFn,
|
|
68
|
-
executor,
|
|
69
|
-
});
|
|
70
|
-
log.info('output', enhancedMessage);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test('computational irreducibility', async () => {
|
|
75
|
-
const { transcriptWoflram, documents, contacts } = testData;
|
|
76
|
-
|
|
77
|
-
log.info('context', { documents, contacts });
|
|
78
|
-
const message = transcriptWoflram[0];
|
|
79
|
-
log.info('input', message);
|
|
80
|
-
|
|
81
|
-
await Promise.all(
|
|
82
|
-
range(10).map(async () => {
|
|
83
|
-
const { message: enhancedMessage, timeElapsed } = await processTranscriptMessage({
|
|
84
|
-
input: {
|
|
85
|
-
message,
|
|
86
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
87
|
-
},
|
|
88
|
-
function: extractionNerFn,
|
|
89
|
-
executor,
|
|
90
|
-
});
|
|
91
|
-
log.info('output', { message: enhancedMessage.blocks[0], timeElapsed });
|
|
92
|
-
}),
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test('org and document linking', async () => {
|
|
97
|
-
const { transcriptJosiah, documents, contacts, organizations } = testData;
|
|
98
|
-
|
|
99
|
-
log.info('context', { contacts, organizations, documents });
|
|
100
|
-
|
|
101
|
-
for (const message of transcriptJosiah) {
|
|
102
|
-
log.info('input', message);
|
|
103
|
-
|
|
104
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
105
|
-
input: {
|
|
106
|
-
message,
|
|
107
|
-
objects: [...documents, ...Object.values(contacts), ...Object.values(organizations)],
|
|
108
|
-
},
|
|
109
|
-
function: extractionNerFn,
|
|
110
|
-
executor,
|
|
111
|
-
});
|
|
112
|
-
log.info('output', enhancedMessage);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// TODO(burdon): Fix.
|
|
6
|
-
// @ts-nocheck
|
|
7
|
-
|
|
8
|
-
import { asyncTimeout } from '@dxos/async';
|
|
9
|
-
import { create } from '@dxos/echo-schema';
|
|
10
|
-
import { DatabaseService, defineFunction } from '@dxos/functions';
|
|
11
|
-
import { invariant } from '@dxos/invariant';
|
|
12
|
-
import { log } from '@dxos/log';
|
|
13
|
-
import { DataType } from '@dxos/schema';
|
|
14
|
-
|
|
15
|
-
import { extractFullEntities } from './named-entity-recognition';
|
|
16
|
-
import { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
17
|
-
import { findQuotes, insertReferences } from '../quotes';
|
|
18
|
-
|
|
19
|
-
// TODO(mykola): Make it use vector index to query objects and not pass objects as input.
|
|
20
|
-
export const extractionNerFn = defineFunction({
|
|
21
|
-
description: 'Extracts named entities from a text',
|
|
22
|
-
inputSchema: ExtractionInput,
|
|
23
|
-
outputSchema: ExtractionOutput,
|
|
24
|
-
handler: async ({ data: { message, options }, context }) => {
|
|
25
|
-
log.info('input', { message, options });
|
|
26
|
-
const startTime = performance.now();
|
|
27
|
-
const { db } = context.getService(DatabaseService);
|
|
28
|
-
|
|
29
|
-
const entitiesPromise = Promise.all(
|
|
30
|
-
message.blocks.map(async (block) => {
|
|
31
|
-
invariant(block._tag === 'transcript' || block._tag === 'text', 'Block must have text');
|
|
32
|
-
return extractFullEntities(block.text);
|
|
33
|
-
}),
|
|
34
|
-
).then((entities) => entities.flat());
|
|
35
|
-
const entities = options?.timeout ? await asyncTimeout(entitiesPromise, options.timeout) : await entitiesPromise;
|
|
36
|
-
log.info('entities', { entities });
|
|
37
|
-
const quoteReferences = await findQuotes(
|
|
38
|
-
entities.map((entity) => entity.word),
|
|
39
|
-
db,
|
|
40
|
-
);
|
|
41
|
-
const blocksWithReferences = message.blocks.map((block, i) => {
|
|
42
|
-
invariant(block._tag === 'transcript' || block._tag === 'text', 'Block must have text');
|
|
43
|
-
return { ...block, text: insertReferences(block._tag, quoteReferences) };
|
|
44
|
-
});
|
|
45
|
-
const messageWithReferences = create(DataType.Message, {
|
|
46
|
-
...message,
|
|
47
|
-
blocks: blocksWithReferences,
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
log.info('output', { messageWithReferences });
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
message: messageWithReferences,
|
|
54
|
-
timeElapsed: performance.now() - startTime,
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
});
|
package/src/research/exa.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { AiTool, AiToolkit } from '@effect/ai';
|
|
6
|
-
import { Effect, Schema } from 'effect';
|
|
7
|
-
import Exa from 'exa-js';
|
|
8
|
-
|
|
9
|
-
import { CredentialsService } from '@dxos/functions';
|
|
10
|
-
import { log } from '@dxos/log';
|
|
11
|
-
|
|
12
|
-
import { SEARCH_RESULTS } from '../testing';
|
|
13
|
-
|
|
14
|
-
export class ExaToolkit extends AiToolkit.make(
|
|
15
|
-
AiTool.make('exa_search', {
|
|
16
|
-
description: 'Search the web for information',
|
|
17
|
-
parameters: {
|
|
18
|
-
query: Schema.String.annotations({ description: 'The query to search for' }),
|
|
19
|
-
},
|
|
20
|
-
success: Schema.Unknown,
|
|
21
|
-
failure: Schema.Never,
|
|
22
|
-
}).addRequirement<CredentialsService>(),
|
|
23
|
-
) {}
|
|
24
|
-
|
|
25
|
-
export const LiveExaHandler = ExaToolkit.toLayer({
|
|
26
|
-
exa_search: Effect.fn(function* ({ query }) {
|
|
27
|
-
const credential = yield* CredentialsService.getCredential({ service: 'exa.ai' });
|
|
28
|
-
const exa = new Exa(credential.apiKey);
|
|
29
|
-
|
|
30
|
-
const context = yield* Effect.promise(async () =>
|
|
31
|
-
exa.searchAndContents(query, {
|
|
32
|
-
type: 'auto',
|
|
33
|
-
text: {
|
|
34
|
-
maxCharacters: 3_000,
|
|
35
|
-
},
|
|
36
|
-
livecrawl: 'always',
|
|
37
|
-
}),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
log.info('exa search', { query, costDollars: context.costDollars });
|
|
41
|
-
|
|
42
|
-
return context;
|
|
43
|
-
}),
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export const MockExaHandler = ExaToolkit.toLayer({
|
|
47
|
-
exa_search: Effect.fn(function* ({ query }) {
|
|
48
|
-
// Find result with closest matching autoprompt using weighted Levenshtein distance
|
|
49
|
-
const result = SEARCH_RESULTS.reduce(
|
|
50
|
-
(closest, current) => {
|
|
51
|
-
if (!current.autopromptString) {
|
|
52
|
-
return closest;
|
|
53
|
-
}
|
|
54
|
-
if (!closest) {
|
|
55
|
-
return current;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Calculate Levenshtein distance
|
|
59
|
-
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
60
|
-
const dist2 = levenshteinDistance(query, closest.autopromptString || '');
|
|
61
|
-
|
|
62
|
-
// Weight by length of the longer string to normalize
|
|
63
|
-
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
64
|
-
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
65
|
-
|
|
66
|
-
return weight1 < weight2 ? current : closest;
|
|
67
|
-
},
|
|
68
|
-
null as (typeof SEARCH_RESULTS)[0] | null,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
return result;
|
|
72
|
-
}),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const levenshteinDistance = (str1: string, str2: string): number => {
|
|
76
|
-
const m = str1.length;
|
|
77
|
-
const n = str2.length;
|
|
78
|
-
const dp: number[][] = Array(m + 1)
|
|
79
|
-
.fill(null)
|
|
80
|
-
.map(() => Array(n + 1).fill(0));
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i <= m; i++) {
|
|
83
|
-
dp[i][0] = i;
|
|
84
|
-
}
|
|
85
|
-
for (let j = 0; j <= n; j++) {
|
|
86
|
-
dp[0][j] = j;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
for (let i = 1; i <= m; i++) {
|
|
90
|
-
for (let j = 1; j <= n; j++) {
|
|
91
|
-
dp[i][j] =
|
|
92
|
-
str1[i - 1] === str2[j - 1] ? dp[i - 1][j - 1] : Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return dp[m][n];
|
|
97
|
-
};
|