@dxos/assistant 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5

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.
Files changed (233) hide show
  1. package/README.md +1 -0
  2. package/dist/lib/neutral/chunk-2TBLG3XY.mjs +1793 -0
  3. package/dist/lib/neutral/chunk-2TBLG3XY.mjs.map +7 -0
  4. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  5. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  6. package/dist/lib/neutral/extraction/index.mjs +219 -0
  7. package/dist/lib/neutral/extraction/index.mjs.map +7 -0
  8. package/dist/lib/neutral/index.mjs +537 -0
  9. package/dist/lib/neutral/index.mjs.map +7 -0
  10. package/dist/lib/neutral/meta.json +1 -0
  11. package/dist/lib/neutral/testing/index.mjs +111 -0
  12. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  13. package/dist/types/src/conversation/context.d.ts +155 -0
  14. package/dist/types/src/conversation/context.d.ts.map +1 -0
  15. package/dist/types/src/conversation/context.test.d.ts +2 -0
  16. package/dist/types/src/conversation/context.test.d.ts.map +1 -0
  17. package/dist/types/src/conversation/index.d.ts +2 -1
  18. package/dist/types/src/conversation/index.d.ts.map +1 -1
  19. package/dist/types/src/conversation/session.d.ts +78 -0
  20. package/dist/types/src/conversation/session.d.ts.map +1 -0
  21. package/dist/types/src/conversation/session.test.d.ts.map +1 -0
  22. package/dist/types/src/diff.d.ts +17 -0
  23. package/dist/types/src/diff.d.ts.map +1 -0
  24. package/dist/types/src/diff.test.d.ts +2 -0
  25. package/dist/types/src/diff.test.d.ts.map +1 -0
  26. package/dist/types/src/errors.d.ts +67 -0
  27. package/dist/types/src/errors.d.ts.map +1 -0
  28. package/dist/types/src/execution-graph.d.ts +85 -0
  29. package/dist/types/src/execution-graph.d.ts.map +1 -0
  30. package/dist/types/src/execution-graph.test.d.ts +2 -0
  31. package/dist/types/src/execution-graph.test.d.ts.map +1 -0
  32. package/dist/types/src/extraction/extraction-ner-function/index.d.ts +0 -1
  33. package/dist/types/src/extraction/extraction-ner-function/index.d.ts.map +1 -1
  34. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +1 -1
  35. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
  36. package/dist/types/src/extraction/extraction.d.ts +1066 -215
  37. package/dist/types/src/extraction/extraction.d.ts.map +1 -1
  38. package/dist/types/src/extraction/index.d.ts +0 -1
  39. package/dist/types/src/extraction/index.d.ts.map +1 -1
  40. package/dist/types/src/extraction/quotes.d.ts +3 -3
  41. package/dist/types/src/extraction/quotes.d.ts.map +1 -1
  42. package/dist/types/src/functions/index.d.ts +2 -0
  43. package/dist/types/src/functions/index.d.ts.map +1 -0
  44. package/dist/types/src/functions/services.d.ts +17 -0
  45. package/dist/types/src/functions/services.d.ts.map +1 -0
  46. package/dist/types/src/functions.test.d.ts +2 -0
  47. package/dist/types/src/functions.test.d.ts.map +1 -0
  48. package/dist/types/src/index.d.ts +7 -5
  49. package/dist/types/src/index.d.ts.map +1 -1
  50. package/dist/types/src/service/AgentService.d.ts +75 -0
  51. package/dist/types/src/service/AgentService.d.ts.map +1 -0
  52. package/dist/types/src/service/AgentService.test.d.ts +2 -0
  53. package/dist/types/src/service/AgentService.test.d.ts.map +1 -0
  54. package/dist/types/src/service/agent-process.d.ts +21 -0
  55. package/dist/types/src/service/agent-process.d.ts.map +1 -0
  56. package/dist/types/src/service/index.d.ts +3 -0
  57. package/dist/types/src/service/index.d.ts.map +1 -0
  58. package/dist/types/src/session/artifact-diff.d.ts +27 -0
  59. package/dist/types/src/session/artifact-diff.d.ts.map +1 -0
  60. package/dist/types/src/session/error-handling.d.ts +4 -0
  61. package/dist/types/src/session/error-handling.d.ts.map +1 -0
  62. package/dist/types/src/session/format.d.ts +16 -0
  63. package/dist/types/src/session/format.d.ts.map +1 -0
  64. package/dist/types/src/session/format.test.d.ts +2 -0
  65. package/dist/types/src/session/format.test.d.ts.map +1 -0
  66. package/dist/types/src/session/index.d.ts +5 -1
  67. package/dist/types/src/session/index.d.ts.map +1 -1
  68. package/dist/types/src/session/observer.d.ts +23 -0
  69. package/dist/types/src/session/observer.d.ts.map +1 -0
  70. package/dist/types/src/session/request.d.ts +106 -0
  71. package/dist/types/src/session/request.d.ts.map +1 -0
  72. package/dist/types/src/session/request.test.d.ts +2 -0
  73. package/dist/types/src/session/request.test.d.ts.map +1 -0
  74. package/dist/types/src/session/session-ollama.test.d.ts +2 -0
  75. package/dist/types/src/session/session-ollama.test.d.ts.map +1 -0
  76. package/dist/types/src/session/toolkit.d.ts +16 -0
  77. package/dist/types/src/session/toolkit.d.ts.map +1 -0
  78. package/dist/types/src/session/version-pin.d.ts +5 -5
  79. package/dist/types/src/session/version-pin.d.ts.map +1 -1
  80. package/dist/types/src/templates/index.d.ts +2 -0
  81. package/dist/types/src/templates/index.d.ts.map +1 -0
  82. package/dist/types/src/templates/system.d.ts +17 -0
  83. package/dist/types/src/templates/system.d.ts.map +1 -0
  84. package/dist/types/src/testing/index.d.ts +1 -2
  85. package/dist/types/src/testing/index.d.ts.map +1 -1
  86. package/dist/types/src/testing/layer.d.ts +40 -0
  87. package/dist/types/src/testing/layer.d.ts.map +1 -0
  88. package/dist/types/src/tracing.d.ts +223 -0
  89. package/dist/types/src/tracing.d.ts.map +1 -0
  90. package/dist/types/src/types/artifact.d.ts +28 -0
  91. package/dist/types/src/types/artifact.d.ts.map +1 -0
  92. package/dist/types/src/types/index.d.ts +2 -0
  93. package/dist/types/src/types/index.d.ts.map +1 -0
  94. package/dist/types/tsconfig.tsbuildinfo +1 -1
  95. package/package.json +60 -29
  96. package/src/conversation/context.test.ts +52 -0
  97. package/src/conversation/context.ts +403 -0
  98. package/src/conversation/index.ts +2 -1
  99. package/src/conversation/session.test.ts +58 -0
  100. package/src/conversation/session.ts +300 -0
  101. package/src/diff.test.ts +74 -0
  102. package/src/diff.ts +93 -0
  103. package/src/errors.ts +15 -0
  104. package/src/execution-graph.test.ts +740 -0
  105. package/src/execution-graph.ts +509 -0
  106. package/src/extraction/extraction-ner-function/index.ts +0 -1
  107. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
  108. package/src/extraction/extraction-ner-function/named-entity-recognition.ts +3 -1
  109. package/src/extraction/extraction.ts +44 -15
  110. package/src/extraction/index.ts +0 -1
  111. package/src/extraction/quotes.test.ts +3 -3
  112. package/src/extraction/quotes.ts +6 -7
  113. package/src/functions/index.ts +5 -0
  114. package/src/functions/services.ts +214 -0
  115. package/src/functions.conversations.json +1 -0
  116. package/src/functions.test.ts +88 -0
  117. package/src/index.ts +7 -5
  118. package/src/service/AgentService.conversations.json +1 -0
  119. package/src/service/AgentService.test.ts +169 -0
  120. package/src/service/AgentService.ts +184 -0
  121. package/src/service/agent-process.ts +364 -0
  122. package/src/service/index.ts +6 -0
  123. package/src/session/artifact-diff.ts +41 -0
  124. package/src/session/error-handling.ts +41 -0
  125. package/src/session/format.test.ts +132 -0
  126. package/src/session/format.ts +149 -0
  127. package/src/session/index.ts +5 -1
  128. package/src/session/observer.ts +62 -0
  129. package/src/session/request.conversations.json +1 -0
  130. package/src/session/request.test.ts +195 -0
  131. package/src/session/request.ts +344 -0
  132. package/src/session/session-ollama.test.ts +81 -0
  133. package/src/session/toolkit.ts +47 -0
  134. package/src/session/version-pin.ts +12 -12
  135. package/src/templates/index.ts +5 -0
  136. package/src/templates/instructions/format.tpl +57 -0
  137. package/src/templates/instructions/system.tpl +85 -0
  138. package/src/templates/system.ts +42 -0
  139. package/src/testing/index.ts +2 -8
  140. package/src/testing/layer.ts +236 -0
  141. package/src/tracing.ts +43 -0
  142. package/src/types/artifact.ts +89 -0
  143. package/src/types/index.ts +5 -0
  144. package/src/typings.d.ts +5 -0
  145. package/dist/lib/browser/index.mjs +0 -2019
  146. package/dist/lib/browser/index.mjs.map +0 -7
  147. package/dist/lib/browser/meta.json +0 -1
  148. package/dist/lib/node-esm/index.mjs +0 -2021
  149. package/dist/lib/node-esm/index.mjs.map +0 -7
  150. package/dist/lib/node-esm/meta.json +0 -1
  151. package/dist/types/bin/chat.d.ts +0 -2
  152. package/dist/types/bin/chat.d.ts.map +0 -1
  153. package/dist/types/src/blueprint/blueprint.d.ts +0 -41
  154. package/dist/types/src/blueprint/blueprint.d.ts.map +0 -1
  155. package/dist/types/src/blueprint/index.d.ts +0 -3
  156. package/dist/types/src/blueprint/index.d.ts.map +0 -1
  157. package/dist/types/src/blueprint/registry.d.ts +0 -7
  158. package/dist/types/src/blueprint/registry.d.ts.map +0 -1
  159. package/dist/types/src/context/binder.d.ts +0 -34
  160. package/dist/types/src/context/binder.d.ts.map +0 -1
  161. package/dist/types/src/context/binding.d.ts +0 -38
  162. package/dist/types/src/context/binding.d.ts.map +0 -1
  163. package/dist/types/src/context/index.d.ts +0 -3
  164. package/dist/types/src/context/index.d.ts.map +0 -1
  165. package/dist/types/src/conversation/conversation.d.ts +0 -44
  166. package/dist/types/src/conversation/conversation.d.ts.map +0 -1
  167. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +0 -4
  168. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +0 -1
  169. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts +0 -2
  170. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.test.d.ts.map +0 -1
  171. package/dist/types/src/extraction/extraction-llm-function/index.d.ts +0 -2
  172. package/dist/types/src/extraction/extraction-llm-function/index.d.ts.map +0 -1
  173. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +0 -208
  174. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +0 -1
  175. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts +0 -2
  176. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.test.d.ts.map +0 -1
  177. package/dist/types/src/research/exa.d.ts +0 -7
  178. package/dist/types/src/research/exa.d.ts.map +0 -1
  179. package/dist/types/src/research/graph.d.ts +0 -41
  180. package/dist/types/src/research/graph.d.ts.map +0 -1
  181. package/dist/types/src/research/graph.test.d.ts +0 -2
  182. package/dist/types/src/research/graph.test.d.ts.map +0 -1
  183. package/dist/types/src/research/index.d.ts +0 -4
  184. package/dist/types/src/research/index.d.ts.map +0 -1
  185. package/dist/types/src/research/research.d.ts +0 -10
  186. package/dist/types/src/research/research.d.ts.map +0 -1
  187. package/dist/types/src/research/research.test.d.ts +0 -2
  188. package/dist/types/src/research/research.test.d.ts.map +0 -1
  189. package/dist/types/src/session/session.d.ts +0 -283
  190. package/dist/types/src/session/session.d.ts.map +0 -1
  191. package/dist/types/src/session/session.test.d.ts.map +0 -1
  192. package/dist/types/src/session/version-pin.test.d.ts +0 -2
  193. package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
  194. package/dist/types/src/summarization/summarization.test.d.ts +0 -2
  195. package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
  196. package/dist/types/src/testing/exa-search-1748337321991.d.ts +0 -38
  197. package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +0 -1
  198. package/dist/types/src/testing/exa-search-1748337331526.d.ts +0 -37
  199. package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +0 -1
  200. package/dist/types/src/testing/exa-search-1748337344119.d.ts +0 -58
  201. package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +0 -1
  202. package/dist/types/src/types.d.ts +0 -3
  203. package/dist/types/src/types.d.ts.map +0 -1
  204. package/src/blueprint/blueprint.ts +0 -75
  205. package/src/blueprint/index.ts +0 -6
  206. package/src/blueprint/registry.ts +0 -15
  207. package/src/context/binder.ts +0 -101
  208. package/src/context/binding.ts +0 -31
  209. package/src/context/index.ts +0 -6
  210. package/src/conversation/conversation.ts +0 -103
  211. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +0 -95
  212. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +0 -66
  213. package/src/extraction/extraction-llm-function/index.ts +0 -5
  214. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +0 -115
  215. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +0 -54
  216. package/src/research/exa.ts +0 -100
  217. package/src/research/graph.test.ts +0 -15
  218. package/src/research/graph.ts +0 -337
  219. package/src/research/index.ts +0 -7
  220. package/src/research/instructions-research.tpl +0 -97
  221. package/src/research/research.test.ts +0 -190
  222. package/src/research/research.ts +0 -90
  223. package/src/session/session.test.ts +0 -275
  224. package/src/session/session.ts +0 -582
  225. package/src/session/version-pin.test.ts +0 -26
  226. package/src/summarization/summarization.test.ts +0 -221
  227. package/src/testing/exa-search-1748337321991.ts +0 -131
  228. package/src/testing/exa-search-1748337331526.ts +0 -144
  229. package/src/testing/exa-search-1748337344119.ts +0 -133
  230. package/src/typedefs.d.ts +0 -8
  231. package/src/types.ts +0 -8
  232. /package/dist/types/src/{session → conversation}/session.test.d.ts +0 -0
  233. /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
@@ -1,31 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Schema } from 'effect';
6
-
7
- import { Type } from '@dxos/echo';
8
-
9
- import { Blueprint } from '../blueprint';
10
- /**
11
- * Thread message that binds or unbinds contextual objects to a conversation.
12
- */
13
- export const ContextBinding = Schema.Struct({
14
- blueprints: Schema.Struct({
15
- added: Schema.Array(Type.Ref(Blueprint)),
16
- removed: Schema.Array(Type.Ref(Blueprint)),
17
- }),
18
-
19
- // TODO(burdon): Type.Expando => Type.Obj (or Obj.Any?)
20
- objects: Schema.Struct({
21
- added: Schema.Array(Type.Ref(Type.Expando)),
22
- removed: Schema.Array(Type.Ref(Type.Expando)),
23
- }),
24
- }).pipe(
25
- Type.Obj({
26
- typename: 'dxos.org/type/ContextBinding',
27
- version: '0.1.0',
28
- }),
29
- );
30
-
31
- export interface ContextBinding extends Schema.Schema.Type<typeof ContextBinding> {}
@@ -1,6 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export * from './binder';
6
- export * from './binding';
@@ -1,103 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Message, type ExecutableTool } from '@dxos/ai';
6
- import { type ArtifactDefinition } from '@dxos/artifact';
7
- import { Event } from '@dxos/async';
8
- import { Obj, Ref } from '@dxos/echo';
9
- import { type Queue } from '@dxos/echo-db';
10
- import { AiService, ToolResolverService, type ServiceContainer } from '@dxos/functions';
11
- import { log } from '@dxos/log';
12
- import { isNonNullable } from '@dxos/util';
13
-
14
- import { ContextBinder, type ContextBinding } from '../context';
15
- import { AISession, type SessionRunOptions } from '../session';
16
-
17
- export interface ConversationRunOptions {
18
- systemPrompt?: string;
19
- prompt: string;
20
-
21
- tools?: ExecutableTool[];
22
- artifacts?: ArtifactDefinition[];
23
- extensions?: ToolContextExtensions;
24
- generationOptions?: SessionRunOptions['generationOptions'];
25
-
26
- /** @depreacated Should be managed by the conversation. */
27
- requiredArtifactIds?: string[];
28
-
29
- // TODO(dmaretskyi): Move into conversation.
30
- artifactDiffResolver?: SessionRunOptions['artifactDiffResolver'];
31
- }
32
-
33
- export type ConversationOptions = {
34
- serviceContainer: ServiceContainer;
35
- queue: Queue<Message | ContextBinding>;
36
- };
37
-
38
- /**
39
- * Persistent conversation state.
40
- * Context + history + artifacts.
41
- * Backed by a Queue.
42
- */
43
- export class Conversation {
44
- private readonly _serviceContainer: ServiceContainer;
45
- private readonly _queue: Queue<Message | ContextBinding>;
46
-
47
- /**
48
- * Fired when the execution loop begins.
49
- * This is called before the first message is sent.
50
- */
51
- public readonly onBegin = new Event<AISession>();
52
-
53
- /**
54
- * Blueprints bound to the conversation.
55
- */
56
- public readonly context: ContextBinder;
57
-
58
- constructor(options: ConversationOptions) {
59
- this._serviceContainer = options.serviceContainer;
60
- this._queue = options.queue;
61
- this.context = new ContextBinder(this._queue);
62
- }
63
-
64
- async run(options: ConversationRunOptions): Promise<Message[]> {
65
- const session = new AISession({ operationModel: 'configured' });
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;
97
- }
98
-
99
- async getHistory(): Promise<Message[]> {
100
- const queueItems = await this._queue.queryObjects();
101
- return queueItems.filter(Obj.instanceOf(Message));
102
- }
103
- }
@@ -1,95 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { describe, test, beforeAll } from 'vitest';
6
-
7
- import { EdgeAiServiceClient } from '@dxos/ai';
8
- import { AI_SERVICE_ENDPOINT } from '@dxos/ai/testing';
9
- import { FunctionExecutor, ServiceContainer } from '@dxos/functions';
10
- import { log } from '@dxos/log';
11
- import { createTestData } from '@dxos/schema/testing';
12
- import { range } from '@dxos/util';
13
-
14
- import { extractionAnthropicFn } from './extraction-llm-function';
15
- import { processTranscriptMessage } from '../extraction';
16
-
17
- describe.skip('LLM EntityExtraction', () => {
18
- let executor: FunctionExecutor;
19
-
20
- 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
- );
34
- });
35
-
36
- test('should process a transcript block', async () => {
37
- const { transcriptMessages, documents, contacts } = createTestData();
38
- log.info('context', { documents, contacts });
39
-
40
- for (const message of transcriptMessages.slice(0, 1)) {
41
- log.info('input', message);
42
- const { message: enhancedMessage } = await processTranscriptMessage({
43
- input: {
44
- message,
45
- objects: [...documents, ...Object.values(contacts)],
46
- },
47
- function: extractionAnthropicFn,
48
- executor,
49
- });
50
- log.info('output', enhancedMessage);
51
- }
52
- });
53
-
54
- test('computational irreducibility', async () => {
55
- const { transcriptWoflram, documents, contacts } = createTestData();
56
-
57
- log.info('context', { documents, contacts });
58
- const message = transcriptWoflram[0];
59
- log.info('input', message);
60
-
61
- await Promise.all(
62
- range(10).map(async () => {
63
- const { message: enhancedMessage, timeElapsed } = await processTranscriptMessage({
64
- input: {
65
- message,
66
- objects: [...documents, ...Object.values(contacts)],
67
- },
68
- function: extractionAnthropicFn,
69
- executor,
70
- });
71
- log.info('output', { message: enhancedMessage.blocks[0], timeElapsed });
72
- }),
73
- );
74
- });
75
-
76
- test('org and document linking', async () => {
77
- const { transcriptJosiah, documents, contacts, organizations } = createTestData();
78
-
79
- log.info('context', { contacts, organizations, documents });
80
-
81
- for (const message of transcriptJosiah) {
82
- log.info('input', message);
83
-
84
- const { message: enhancedMessage } = await processTranscriptMessage({
85
- input: {
86
- message,
87
- objects: [...documents, ...Object.values(contacts), ...Object.values(organizations)],
88
- },
89
- function: extractionAnthropicFn,
90
- executor,
91
- });
92
- log.info('output', enhancedMessage);
93
- }
94
- });
95
- });
@@ -1,66 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Message, ToolRegistry } from '@dxos/ai';
6
- import { Obj } from '@dxos/echo';
7
- import { create } from '@dxos/echo-schema';
8
- import { AiService, defineFunction, type FunctionDefinition } from '@dxos/functions';
9
- import { DataType } from '@dxos/schema';
10
-
11
- import PROMPT from './instructions.tpl?raw';
12
- import { AISession } from '../../session';
13
- import { ExtractionInput, ExtractionOutput } from '../extraction';
14
- import { insertReferences, ReferencedQuotes } from '../quotes';
15
-
16
- export const extractionAnthropicFn: FunctionDefinition<ExtractionInput, ExtractionOutput> = defineFunction({
17
- description: 'Extract entities from the transcript message and add them to the message.',
18
- inputSchema: ExtractionInput,
19
- outputSchema: ExtractionOutput,
20
- handler: async ({ data: { message, objects }, context }) => {
21
- const startTime = performance.now();
22
- const ai = context.getService(AiService);
23
- const session = new AISession({ operationModel: 'configured' });
24
- const result = await session.runStructured(ReferencedQuotes, {
25
- generationOptions: {
26
- model: '@anthropic/claude-3-5-haiku-20241022',
27
- },
28
- client: ai.client,
29
- systemPrompt: PROMPT,
30
- history: [
31
- Obj.make(Message, {
32
- role: 'user',
33
- content: [
34
- {
35
- type: 'text',
36
- text: `<context>${JSON.stringify(objects)}</context>`,
37
- },
38
- {
39
- type: 'text',
40
- text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`,
41
- },
42
- ],
43
- }),
44
- ],
45
- artifacts: [],
46
- prompt: '',
47
- tools: [],
48
- toolResolver: new ToolRegistry([]),
49
- });
50
-
51
- return {
52
- message: create(DataType.Message, {
53
- ...message,
54
- blocks: message.blocks.map((block, i) =>
55
- block.type !== 'transcription'
56
- ? block
57
- : {
58
- ...block,
59
- text: insertReferences(block.text, result),
60
- },
61
- ),
62
- }),
63
- timeElapsed: performance.now() - startTime,
64
- };
65
- },
66
- });
@@ -1,5 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export * from './extraction-llm-function';
@@ -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,54 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { asyncTimeout } from '@dxos/async';
6
- import { create } from '@dxos/echo-schema';
7
- import { DatabaseService, defineFunction } from '@dxos/functions';
8
- import { invariant } from '@dxos/invariant';
9
- import { log } from '@dxos/log';
10
- import { DataType } from '@dxos/schema';
11
-
12
- import { extractFullEntities } from './named-entity-recognition';
13
- import { ExtractionInput, ExtractionOutput } from '../extraction';
14
- import { findQuotes, insertReferences } from '../quotes';
15
-
16
- // TODO(mykola): Make it use vector index to query objects and not pass objects as input.
17
- export const extractionNerFn = defineFunction({
18
- description: 'Extracts named entities from a text',
19
- inputSchema: ExtractionInput,
20
- outputSchema: ExtractionOutput,
21
- handler: async ({ data: { message, options }, context }) => {
22
- log.info('input', { message, options });
23
- const startTime = performance.now();
24
- const { db } = context.getService(DatabaseService);
25
-
26
- const entitiesPromise = Promise.all(
27
- message.blocks.map(async (block) => {
28
- invariant(block.type === 'transcription' || block.type === 'text', 'Block must have text');
29
- return extractFullEntities(block.text);
30
- }),
31
- ).then((entities) => entities.flat());
32
- const entities = options?.timeout ? await asyncTimeout(entitiesPromise, options.timeout) : await entitiesPromise;
33
- log.info('entities', { entities });
34
- const quoteReferences = await findQuotes(
35
- entities.map((entity) => entity.word),
36
- db,
37
- );
38
- const blocksWithReferences = message.blocks.map((block, i) => {
39
- invariant(block.type === 'transcription' || block.type === 'text', 'Block must have text');
40
- return { ...block, text: insertReferences(block.text, quoteReferences) };
41
- });
42
- const messageWithReferences = create(DataType.Message, {
43
- ...message,
44
- blocks: blocksWithReferences,
45
- });
46
-
47
- log.info('output', { messageWithReferences });
48
-
49
- return {
50
- message: messageWithReferences,
51
- timeElapsed: performance.now() - startTime,
52
- };
53
- },
54
- });
@@ -1,100 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { Schema } from 'effect';
6
- import Exa from 'exa-js';
7
-
8
- import { createTool, ToolResult } from '@dxos/ai';
9
- import { log } from '@dxos/log';
10
-
11
- import { SEARCH_RESULTS } from '../testing';
12
-
13
- type CreateExaToolOptions = {
14
- apiKey: string;
15
- };
16
-
17
- export const createExaTool = ({ apiKey }: CreateExaToolOptions) => {
18
- const exa = new Exa(apiKey);
19
-
20
- return createTool('search', {
21
- name: 'web_search',
22
- description: 'Search the web for information',
23
- schema: Schema.Struct({
24
- query: Schema.String.annotations({ description: 'The query to search for' }),
25
- }),
26
- execute: async ({ query }) => {
27
- const context = await exa.searchAndContents(query, {
28
- type: 'auto',
29
- text: {
30
- maxCharacters: 3_000,
31
- },
32
- livecrawl: 'always',
33
- });
34
-
35
- log.info('exa search', { query, costDollars: context.costDollars });
36
-
37
- return ToolResult.Success(context);
38
- },
39
- });
40
- };
41
-
42
- export const createMockExaTool = () => {
43
- return createTool('search', {
44
- name: 'web_search',
45
- description: 'Search the web for information',
46
- schema: Schema.Struct({
47
- query: Schema.String.annotations({ description: 'The query to search for' }),
48
- }),
49
- execute: async ({ query }) => {
50
- // Find result with closest matching autoprompt using weighted Levenshtein distance
51
- const result = SEARCH_RESULTS.reduce(
52
- (closest, current) => {
53
- if (!current.autopromptString) {
54
- return closest;
55
- }
56
- if (!closest) {
57
- return current;
58
- }
59
-
60
- // Calculate Levenshtein distance
61
- const dist1 = levenshteinDistance(query, current.autopromptString);
62
- const dist2 = levenshteinDistance(query, closest.autopromptString || '');
63
-
64
- // Weight by length of the longer string to normalize
65
- const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
66
- const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
67
-
68
- return weight1 < weight2 ? current : closest;
69
- },
70
- null as (typeof SEARCH_RESULTS)[0] | null,
71
- );
72
-
73
- return ToolResult.Success(result);
74
- },
75
- });
76
- };
77
-
78
- const levenshteinDistance = (str1: string, str2: string): number => {
79
- const m = str1.length;
80
- const n = str2.length;
81
- const dp: number[][] = Array(m + 1)
82
- .fill(null)
83
- .map(() => Array(n + 1).fill(0));
84
-
85
- for (let i = 0; i <= m; i++) {
86
- dp[i][0] = i;
87
- }
88
- for (let j = 0; j <= n; j++) {
89
- dp[0][j] = j;
90
- }
91
-
92
- for (let i = 1; i <= m; i++) {
93
- for (let j = 1; j <= n; j++) {
94
- dp[i][j] =
95
- 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;
96
- }
97
- }
98
-
99
- return dp[m][n];
100
- };
@@ -1,15 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { describe } from 'vitest';
6
-
7
- // import { type EchoTestBuilder } from '@dxos/echo-db/testing';
8
-
9
- describe('graph', () => {
10
- // let builder: EchoTestBuilder;
11
- // test('findRelatedSchema', async () => {
12
- // const db = await createEchoDatabase();
13
- // const relatedSchemas = await findRelatedSchema(db, Schema.Struct({}));
14
- // });
15
- });