@dxos/assistant 0.8.4-main.dedc0f3 → 0.8.4-main.dfabb4ec29
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/README.md +1 -0
- package/dist/lib/neutral/extraction/index.mjs +202 -0
- package/dist/lib/neutral/extraction/index.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +1736 -0
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/types/src/conversation/context.d.ts +124 -64
- package/dist/types/src/conversation/context.d.ts.map +1 -1
- package/dist/types/src/conversation/context.test.d.ts +2 -0
- package/dist/types/src/conversation/context.test.d.ts.map +1 -0
- package/dist/types/src/conversation/index.d.ts +1 -1
- package/dist/types/src/conversation/index.d.ts.map +1 -1
- package/dist/types/src/conversation/session.d.ts +73 -0
- package/dist/types/src/conversation/session.d.ts.map +1 -0
- package/dist/types/src/diff.d.ts +3 -1
- package/dist/types/src/diff.d.ts.map +1 -1
- package/dist/types/src/errors.d.ts +40 -48
- package/dist/types/src/errors.d.ts.map +1 -1
- package/dist/types/src/execution-graph.d.ts +85 -0
- package/dist/types/src/execution-graph.d.ts.map +1 -0
- package/dist/types/src/execution-graph.test.d.ts +2 -0
- package/dist/types/src/execution-graph.test.d.ts.map +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 -303
- 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 -5
- package/dist/types/src/functions/services.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +3 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/session/artifact-diff.d.ts +2 -2
- package/dist/types/src/session/artifact-diff.d.ts.map +1 -1
- package/dist/types/src/session/error-handling.d.ts +2 -2
- package/dist/types/src/session/error-handling.d.ts.map +1 -1
- package/dist/types/src/session/format.d.ts +8 -175
- package/dist/types/src/session/format.d.ts.map +1 -1
- package/dist/types/src/session/index.d.ts +2 -1
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/observer.d.ts +7 -6
- package/dist/types/src/session/observer.d.ts.map +1 -1
- package/dist/types/src/session/request.d.ts +104 -0
- package/dist/types/src/session/request.d.ts.map +1 -0
- package/dist/types/src/session/toolkit.d.ts +11 -9
- package/dist/types/src/session/toolkit.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/system.d.ts +1 -2
- package/dist/types/src/templates/system.d.ts.map +1 -1
- package/dist/types/src/tracing.d.ts +233 -0
- package/dist/types/src/tracing.d.ts.map +1 -0
- package/dist/types/src/types/artifact.d.ts +28 -0
- package/dist/types/src/types/artifact.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -46
- package/src/conversation/context.test.ts +52 -0
- package/src/conversation/context.ts +324 -75
- package/src/conversation/index.ts +1 -1
- package/src/conversation/session.ts +323 -0
- package/src/diff.test.ts +37 -6
- package/src/diff.ts +18 -4
- package/src/errors.ts +4 -4
- package/src/execution-graph.test.ts +740 -0
- package/src/execution-graph.ts +519 -0
- 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.ts +44 -15
- package/src/extraction/index.ts +0 -1
- package/src/extraction/quotes.test.ts +2 -2
- package/src/extraction/quotes.ts +6 -7
- package/src/functions/services.ts +156 -61
- package/src/index.ts +3 -1
- package/src/session/artifact-diff.ts +2 -2
- package/src/session/error-handling.ts +11 -6
- package/src/session/format.ts +35 -27
- package/src/session/index.ts +2 -1
- package/src/session/observer.ts +8 -4
- package/src/session/request.ts +347 -0
- package/src/session/toolkit.ts +32 -27
- package/src/session/version-pin.ts +7 -7
- package/src/templates/{format.tpl → instructions/format.tpl} +1 -4
- package/src/templates/instructions/system.tpl +96 -0
- package/src/templates/system.ts +9 -8
- package/src/tracing.ts +57 -0
- package/src/{types.ts → types/artifact.ts} +44 -7
- package/src/types/index.ts +5 -0
- package/dist/lib/browser/chunk-5GJYG2ML.mjs +0 -396
- package/dist/lib/browser/chunk-5GJYG2ML.mjs.map +0 -7
- package/dist/lib/browser/chunk-UB26N5UF.mjs +0 -89
- package/dist/lib/browser/chunk-UB26N5UF.mjs.map +0 -7
- package/dist/lib/browser/extraction/index.mjs +0 -268
- package/dist/lib/browser/extraction/index.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -469
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/named-entity-recognition-QPYHML66.mjs +0 -13
- package/dist/lib/browser/named-entity-recognition-QPYHML66.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-BCFXTNSK.mjs +0 -91
- package/dist/lib/node-esm/chunk-BCFXTNSK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FLFCEB4P.mjs +0 -398
- package/dist/lib/node-esm/chunk-FLFCEB4P.mjs.map +0 -7
- package/dist/lib/node-esm/extraction/index.mjs +0 -269
- package/dist/lib/node-esm/extraction/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -470
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/named-entity-recognition-2HDF46YX.mjs +0 -14
- package/dist/lib/node-esm/named-entity-recognition-2HDF46YX.mjs.map +0 -7
- package/dist/types/src/conversation/conversation.d.ts +0 -42
- package/dist/types/src/conversation/conversation.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 -337
- 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/session/format.test.d.ts +0 -2
- package/dist/types/src/session/format.test.d.ts.map +0 -1
- package/dist/types/src/session/session.d.ts +0 -47
- 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.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/types.d.ts +0 -16
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/conversation/conversation.ts +0 -123
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +0 -84
- 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 -62
- package/src/session/__snapshots__/session.test.ts.snap +0 -32
- package/src/session/format.test.ts +0 -60
- package/src/session/session.test.ts +0 -308
- package/src/session/session.ts +0 -201
- package/src/session/version-pin.test.ts +0 -7
- package/src/summarization/summarization.test.ts +0 -197
- package/src/templates/system.tpl +0 -50
- /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { type AiTool, type AiToolkit } from '@effect/ai';
|
|
6
|
-
import { Array, Effect, Option } from 'effect';
|
|
7
|
-
|
|
8
|
-
import { Obj } from '@dxos/echo';
|
|
9
|
-
import { type Queue } from '@dxos/echo-db';
|
|
10
|
-
import { DatabaseService } from '@dxos/functions';
|
|
11
|
-
import { log } from '@dxos/log';
|
|
12
|
-
import { DataType } from '@dxos/schema';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
AiSession,
|
|
16
|
-
type AiSessionRunError,
|
|
17
|
-
type AiSessionRunRequirements,
|
|
18
|
-
type GenerationObserver,
|
|
19
|
-
createToolkit,
|
|
20
|
-
} from '../session';
|
|
21
|
-
|
|
22
|
-
import { AiContextBinder, AiContextService, type ContextBinding } from './context';
|
|
23
|
-
|
|
24
|
-
export type AiConversationRunRequirements<Tools extends AiTool.Any> =
|
|
25
|
-
| AiSessionRunRequirements
|
|
26
|
-
| AiTool.ToHandler<Tools>;
|
|
27
|
-
|
|
28
|
-
export interface AiConversationRunParams {
|
|
29
|
-
prompt: string;
|
|
30
|
-
system?: string;
|
|
31
|
-
observer?: GenerationObserver;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type AiConversationOptions = {
|
|
35
|
-
queue: Queue<DataType.Message | ContextBinding>;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Durable conversation state (initiated by users and agents) backed by a Queue.
|
|
40
|
-
* Executes tools based on AI responses and supports cancellation of in-progress requests.
|
|
41
|
-
*/
|
|
42
|
-
export class AiConversation {
|
|
43
|
-
/**
|
|
44
|
-
* Message and binding queue.
|
|
45
|
-
*/
|
|
46
|
-
private readonly _queue: Queue<DataType.Message | ContextBinding>;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Blueprints bound to the conversation.
|
|
50
|
-
*/
|
|
51
|
-
private readonly _context: AiContextBinder;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Toolkit from the current session request.
|
|
55
|
-
*/
|
|
56
|
-
private _toolkit: AiToolkit.ToHandler<AiTool.Any> | undefined;
|
|
57
|
-
|
|
58
|
-
public constructor(options: AiConversationOptions) {
|
|
59
|
-
this._queue = options.queue;
|
|
60
|
-
this._context = new AiContextBinder(this._queue);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public get context() {
|
|
64
|
-
return this._context;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public get toolkit() {
|
|
68
|
-
return this._toolkit;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
public async getHistory(): Promise<DataType.Message[]> {
|
|
72
|
-
const queueItems = await this._queue.queryObjects();
|
|
73
|
-
return queueItems.filter(Obj.instanceOf(DataType.Message));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Creates a new cancelable request effect.
|
|
78
|
-
*/
|
|
79
|
-
createRequest<Tools extends AiTool.Any>(
|
|
80
|
-
params: AiConversationRunParams,
|
|
81
|
-
): Effect.Effect<DataType.Message[], AiSessionRunError, AiConversationRunRequirements<Tools>> {
|
|
82
|
-
return Effect.gen(this, function* () {
|
|
83
|
-
const session = new AiSession();
|
|
84
|
-
const history = yield* Effect.promise(() => this.getHistory());
|
|
85
|
-
|
|
86
|
-
// Get context objects.
|
|
87
|
-
const context = yield* Effect.promise(() => this.context.query());
|
|
88
|
-
const blueprints = yield* Effect.forEach(context.blueprints.values(), DatabaseService.loadOption).pipe(
|
|
89
|
-
Effect.map(Array.filter(Option.isSome)),
|
|
90
|
-
Effect.map(Array.map((option) => option.value)),
|
|
91
|
-
);
|
|
92
|
-
const objects = yield* Effect.forEach(context.objects.values(), DatabaseService.loadOption).pipe(
|
|
93
|
-
Effect.map(Array.filter(Option.isSome)),
|
|
94
|
-
Effect.map(Array.map((option) => option.value)),
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
// Create toolkit.
|
|
98
|
-
const toolkit = yield* createToolkit<Tools>({ blueprints });
|
|
99
|
-
this._toolkit = toolkit;
|
|
100
|
-
|
|
101
|
-
const start = Date.now();
|
|
102
|
-
log('run', {
|
|
103
|
-
history: history.length,
|
|
104
|
-
blueprints: blueprints.length,
|
|
105
|
-
objects: objects.length,
|
|
106
|
-
tools: this._toolkit?.tools.length ?? 0,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Process request.
|
|
110
|
-
const messages = yield* session.run<Tools>({ history, blueprints, objects, toolkit, ...params }).pipe(
|
|
111
|
-
Effect.provideService(AiContextService, {
|
|
112
|
-
binder: this.context,
|
|
113
|
-
}),
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
log('result', { messages: messages.length, duration: Date.now() - start });
|
|
117
|
-
|
|
118
|
-
// Append to queue.
|
|
119
|
-
yield* Effect.promise(() => this._queue.append(messages));
|
|
120
|
-
return messages;
|
|
121
|
-
}).pipe(Effect.withSpan('AiConversation.request'));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,84 +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
|
-
|
|
15
|
-
import { extractionAnthropicFunction } from './extraction-llm-function';
|
|
16
|
-
|
|
17
|
-
// TODO(burdon): Rewrite test.
|
|
18
|
-
describe.skip('LLM EntityExtraction', () => {
|
|
19
|
-
let executor: FunctionExecutor;
|
|
20
|
-
|
|
21
|
-
beforeAll(async () => {
|
|
22
|
-
executor = new FunctionExecutor(todo());
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test('should process a transcript block', async () => {
|
|
26
|
-
const { transcriptMessages, documents, contacts } = createTestData();
|
|
27
|
-
log.info('context', { documents, contacts });
|
|
28
|
-
|
|
29
|
-
for (const message of transcriptMessages.slice(0, 1)) {
|
|
30
|
-
log.info('input', message);
|
|
31
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
32
|
-
input: {
|
|
33
|
-
message,
|
|
34
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
35
|
-
},
|
|
36
|
-
function: extractionAnthropicFunction,
|
|
37
|
-
executor,
|
|
38
|
-
});
|
|
39
|
-
log.info('output', enhancedMessage);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('computational irreducibility', async () => {
|
|
44
|
-
const { transcriptWoflram, documents, contacts } = createTestData();
|
|
45
|
-
log.info('context', { documents, contacts });
|
|
46
|
-
|
|
47
|
-
const message = transcriptWoflram[0];
|
|
48
|
-
log.info('input', message);
|
|
49
|
-
|
|
50
|
-
await Promise.all(
|
|
51
|
-
range(10).map(async () => {
|
|
52
|
-
const { message: enhancedMessage, timeElapsed } = await processTranscriptMessage({
|
|
53
|
-
input: {
|
|
54
|
-
message,
|
|
55
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
56
|
-
},
|
|
57
|
-
function: extractionAnthropicFunction,
|
|
58
|
-
executor,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
log.info('output', { message: enhancedMessage.blocks[0], timeElapsed });
|
|
62
|
-
}),
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('org and document linking', async () => {
|
|
67
|
-
const { transcriptJosiah, documents, contacts, organizations } = createTestData();
|
|
68
|
-
log.info('context', { contacts, organizations, documents });
|
|
69
|
-
|
|
70
|
-
for (const message of transcriptJosiah) {
|
|
71
|
-
log.info('input', message);
|
|
72
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
73
|
-
input: {
|
|
74
|
-
message,
|
|
75
|
-
objects: [...documents, ...Object.values(contacts), ...Object.values(organizations)],
|
|
76
|
-
},
|
|
77
|
-
function: extractionAnthropicFunction,
|
|
78
|
-
executor,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
log.info('output', enhancedMessage);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// ISSUE(burdon): defineFunction
|
|
6
|
-
// @ts-nocheck
|
|
7
|
-
|
|
8
|
-
import { AiService } from '@dxos/ai';
|
|
9
|
-
import { Obj } from '@dxos/echo';
|
|
10
|
-
import { create } from '@dxos/echo-schema';
|
|
11
|
-
import { type FunctionDefinition, defineFunction } from '@dxos/functions';
|
|
12
|
-
import { type ContentBlock, DataType } from '@dxos/schema';
|
|
13
|
-
|
|
14
|
-
import { AiSession } from '../../session';
|
|
15
|
-
import { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
16
|
-
import { ReferencedQuotes, insertReferences } from '../quotes';
|
|
17
|
-
|
|
18
|
-
import PROMPT from './instructions.tpl?raw';
|
|
19
|
-
|
|
20
|
-
export const extractionAnthropicFunction: FunctionDefinition<ExtractionInput, ExtractionOutput> = defineFunction({
|
|
21
|
-
description: 'Extract entities from the transcript message and add them to the message.',
|
|
22
|
-
inputSchema: ExtractionInput,
|
|
23
|
-
outputSchema: ExtractionOutput,
|
|
24
|
-
handler: async ({ data: { message, objects }, context }) => {
|
|
25
|
-
const startTime = performance.now();
|
|
26
|
-
const ai = context.getService(AiService.AiService);
|
|
27
|
-
const session = new AiSession({ operationModel: 'configured' });
|
|
28
|
-
const result = await session.runStructured(ReferencedQuotes, {
|
|
29
|
-
generationOptions: {
|
|
30
|
-
model: '@anthropic/claude-3-5-haiku-20241022',
|
|
31
|
-
},
|
|
32
|
-
client: ai.client,
|
|
33
|
-
systemPrompt: PROMPT,
|
|
34
|
-
history: [
|
|
35
|
-
Obj.make(DataType.Message, {
|
|
36
|
-
created: new Date().toISOString(),
|
|
37
|
-
sender: { role: 'user' },
|
|
38
|
-
blocks: [
|
|
39
|
-
{
|
|
40
|
-
_tag: 'text',
|
|
41
|
-
text: `<context>${JSON.stringify(objects)}</context>`,
|
|
42
|
-
} satisfies ContentBlock.Text,
|
|
43
|
-
{
|
|
44
|
-
_tag: 'text',
|
|
45
|
-
text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`,
|
|
46
|
-
} satisfies ContentBlock.Text,
|
|
47
|
-
],
|
|
48
|
-
}),
|
|
49
|
-
],
|
|
50
|
-
artifacts: [],
|
|
51
|
-
prompt: '',
|
|
52
|
-
tools: [],
|
|
53
|
-
} as any); // TODO(burdon): Rewrite test.
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
timeElapsed: performance.now() - startTime,
|
|
57
|
-
message: create(DataType.Message, {
|
|
58
|
-
...message,
|
|
59
|
-
blocks: message.blocks.map((block) =>
|
|
60
|
-
block._tag !== 'transcript'
|
|
61
|
-
? block
|
|
62
|
-
: {
|
|
63
|
-
...block,
|
|
64
|
-
text: insertReferences(block.text, result),
|
|
65
|
-
},
|
|
66
|
-
),
|
|
67
|
-
}),
|
|
68
|
-
};
|
|
69
|
-
},
|
|
70
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { beforeAll, describe, test } 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 { Testing, createTestData } from '@dxos/schema/testing';
|
|
13
|
-
import { range } from '@dxos/util';
|
|
14
|
-
|
|
15
|
-
import { processTranscriptMessage } from '../extraction';
|
|
16
|
-
|
|
17
|
-
import { extractionNerFunction } from './extraction-ner-function';
|
|
18
|
-
|
|
19
|
-
describe.skip('NER EntityExtraction', () => {
|
|
20
|
-
let builder: EchoTestBuilder;
|
|
21
|
-
let db: EchoDatabase;
|
|
22
|
-
let executor: FunctionExecutor;
|
|
23
|
-
let testData: {
|
|
24
|
-
transcriptJosiah: DataType.Message[];
|
|
25
|
-
transcriptWoflram: DataType.Message[];
|
|
26
|
-
transcriptMessages: DataType.Message[];
|
|
27
|
-
documents: Testing.DocumentType[];
|
|
28
|
-
contacts: Record<string, DataType.Person>;
|
|
29
|
-
organizations: Record<string, DataType.Organization>;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const TYPES = [DataType.Organization, DataType.Person, Testing.Contact, Testing.DocumentType];
|
|
33
|
-
|
|
34
|
-
beforeAll(async () => {
|
|
35
|
-
// TODO(dmaretskyi): Helper to scaffold this from a config.
|
|
36
|
-
builder = await new EchoTestBuilder().open();
|
|
37
|
-
const { db: db1 } = await builder.createDatabase({ indexing: { vector: true } });
|
|
38
|
-
db = db1;
|
|
39
|
-
db.graph.schemaRegistry.addSchema(TYPES);
|
|
40
|
-
const data = createTestData();
|
|
41
|
-
testData = {
|
|
42
|
-
transcriptJosiah: data.transcriptJosiah,
|
|
43
|
-
transcriptWoflram: data.transcriptWoflram,
|
|
44
|
-
transcriptMessages: data.transcriptMessages,
|
|
45
|
-
documents: data.documents.map((document) => db.add(document)),
|
|
46
|
-
contacts: Object.fromEntries(Object.entries(data.contacts).map(([key, value]) => [key, db.add(value)])),
|
|
47
|
-
organizations: Object.fromEntries(Object.entries(data.organizations).map(([key, value]) => [key, db.add(value)])),
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
await db.flush();
|
|
51
|
-
executor = new FunctionExecutor(
|
|
52
|
-
new ServiceContainer().setServices({
|
|
53
|
-
database: { db },
|
|
54
|
-
}),
|
|
55
|
-
);
|
|
56
|
-
}, 30_000);
|
|
57
|
-
|
|
58
|
-
test('should process a transcript block', async () => {
|
|
59
|
-
const { transcriptMessages, documents, contacts } = testData;
|
|
60
|
-
log.info('context', { documents, contacts });
|
|
61
|
-
|
|
62
|
-
for (const message of transcriptMessages) {
|
|
63
|
-
log.info('input', message);
|
|
64
|
-
const { message: enhancedMessage } = await processTranscriptMessage({
|
|
65
|
-
input: {
|
|
66
|
-
message,
|
|
67
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
68
|
-
},
|
|
69
|
-
function: extractionNerFunction,
|
|
70
|
-
executor,
|
|
71
|
-
});
|
|
72
|
-
log.info('output', enhancedMessage);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('computational irreducibility', async () => {
|
|
77
|
-
const { transcriptWoflram, documents, contacts } = testData;
|
|
78
|
-
log.info('context', { documents, contacts });
|
|
79
|
-
const message = transcriptWoflram[0];
|
|
80
|
-
log.info('input', message);
|
|
81
|
-
|
|
82
|
-
await Promise.all(
|
|
83
|
-
range(10).map(async () => {
|
|
84
|
-
const { message: enhancedMessage, timeElapsed } = await processTranscriptMessage({
|
|
85
|
-
input: {
|
|
86
|
-
message,
|
|
87
|
-
objects: [...documents, ...Object.values(contacts)],
|
|
88
|
-
},
|
|
89
|
-
function: extractionNerFunction,
|
|
90
|
-
executor,
|
|
91
|
-
});
|
|
92
|
-
log.info('output', { message: enhancedMessage.blocks[0], timeElapsed });
|
|
93
|
-
}),
|
|
94
|
-
);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test('org and document linking', async () => {
|
|
98
|
-
const { transcriptJosiah, documents, contacts, organizations } = testData;
|
|
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: extractionNerFunction,
|
|
110
|
-
executor,
|
|
111
|
-
});
|
|
112
|
-
log.info('output', enhancedMessage);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
// ISSUE(burdon): defineFunction
|
|
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 { ExtractionInput, ExtractionOutput } from '../extraction';
|
|
16
|
-
import { findQuotes, insertReferences } from '../quotes';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Named Entity Recognition model
|
|
20
|
-
*/
|
|
21
|
-
// TODO(mykola): Make it use vector index to query objects and not pass objects as input.
|
|
22
|
-
export const extractionNerFunction = defineFunction({
|
|
23
|
-
description: 'Extracts named entities from a text',
|
|
24
|
-
inputSchema: ExtractionInput,
|
|
25
|
-
outputSchema: ExtractionOutput,
|
|
26
|
-
handler: async ({ data: { message, options }, context }) => {
|
|
27
|
-
log.info('input', { message, options });
|
|
28
|
-
const startTime = performance.now();
|
|
29
|
-
const { db } = context.getService(DatabaseService);
|
|
30
|
-
const { extractFullEntities } = await import('./named-entity-recognition');
|
|
31
|
-
|
|
32
|
-
const entitiesPromise = Promise.all(
|
|
33
|
-
message.blocks.map(async (block) => {
|
|
34
|
-
invariant(block._tag === 'transcript' || block._tag === 'text');
|
|
35
|
-
return extractFullEntities(block.text);
|
|
36
|
-
}),
|
|
37
|
-
).then((entities) => entities.flat());
|
|
38
|
-
const entities = options?.timeout ? await asyncTimeout(entitiesPromise, options.timeout) : await entitiesPromise;
|
|
39
|
-
|
|
40
|
-
log.info('entities', { entities });
|
|
41
|
-
const quoteReferences = await findQuotes(
|
|
42
|
-
entities.map((entity) => entity.word),
|
|
43
|
-
db,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const blocksWithReferences = message.blocks.map((block) => {
|
|
47
|
-
invariant(block._tag === 'transcript' || block._tag === 'text');
|
|
48
|
-
return { ...block, text: insertReferences(block._tag, quoteReferences) };
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const messageWithReferences = create(DataType.Message, {
|
|
52
|
-
...message,
|
|
53
|
-
blocks: blocksWithReferences,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
log.info('output', { messageWithReferences });
|
|
57
|
-
return {
|
|
58
|
-
message: messageWithReferences,
|
|
59
|
-
timeElapsed: performance.now() - startTime,
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
-
|
|
3
|
-
exports[`AiSession > no tools 1`] = `
|
|
4
|
-
[
|
|
5
|
-
{
|
|
6
|
-
"blocks": ReactiveArray [
|
|
7
|
-
{
|
|
8
|
-
"_tag": "text",
|
|
9
|
-
"text": "Hello world!",
|
|
10
|
-
},
|
|
11
|
-
],
|
|
12
|
-
"created": "Sun, 20 Jul 2025 10:54:08 GMT",
|
|
13
|
-
"id": "01K0KQGFTFV3GBKGEWZW67K8HK",
|
|
14
|
-
"sender": {
|
|
15
|
-
"role": "user",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"blocks": ReactiveArray [
|
|
20
|
-
{
|
|
21
|
-
"_tag": "text",
|
|
22
|
-
"text": "Hi there! How can I help you today?",
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
"created": "2025-07-20T10:54:10.801Z",
|
|
26
|
-
"id": "01K0KQGHVHJ37D4YG45WG090WV",
|
|
27
|
-
"sender": {
|
|
28
|
-
"role": "assistant",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
]
|
|
32
|
-
`;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { beforeAll, describe, it } from '@effect/vitest';
|
|
6
|
-
import { Effect } from 'effect';
|
|
7
|
-
|
|
8
|
-
import { Blueprint, Template } from '@dxos/blueprints';
|
|
9
|
-
import { Obj } from '@dxos/echo';
|
|
10
|
-
import { type EchoDatabase } from '@dxos/echo-db';
|
|
11
|
-
import { EchoTestBuilder } from '@dxos/echo-db/testing';
|
|
12
|
-
import { DataType } from '@dxos/schema';
|
|
13
|
-
import { trim } from '@dxos/util';
|
|
14
|
-
|
|
15
|
-
import { createSystemPrompt } from '../templates/system';
|
|
16
|
-
|
|
17
|
-
import { formatSystemPrompt } from './format';
|
|
18
|
-
|
|
19
|
-
describe('format', () => {
|
|
20
|
-
let db: EchoDatabase;
|
|
21
|
-
beforeAll(async () => {
|
|
22
|
-
const builder = await new EchoTestBuilder().open();
|
|
23
|
-
({ db } = await builder.createDatabase({
|
|
24
|
-
types: [DataType.Text, DataType.Organization, Blueprint.Blueprint],
|
|
25
|
-
}));
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it.effect(
|
|
29
|
-
'should format',
|
|
30
|
-
Effect.fn(function* () {
|
|
31
|
-
const object = db.add(
|
|
32
|
-
Obj.make(DataType.Organization, {
|
|
33
|
-
name: 'Test',
|
|
34
|
-
website: 'https://www.test.com',
|
|
35
|
-
}),
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
const blueprint = db.add(
|
|
39
|
-
Blueprint.make({
|
|
40
|
-
key: 'example.com/blueprint/test',
|
|
41
|
-
name: 'Test',
|
|
42
|
-
instructions: Template.make({
|
|
43
|
-
source: trim`
|
|
44
|
-
Test
|
|
45
|
-
This is the test blueprint.
|
|
46
|
-
`,
|
|
47
|
-
}),
|
|
48
|
-
}),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const output = yield* formatSystemPrompt({
|
|
52
|
-
system: createSystemPrompt({}),
|
|
53
|
-
blueprints: [blueprint, blueprint],
|
|
54
|
-
objects: [object, object],
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
console.log(output);
|
|
58
|
-
}),
|
|
59
|
-
);
|
|
60
|
-
});
|