@dxos/assistant 0.8.4-main.b97322e → 0.8.4-main.bc674ce

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 (189) hide show
  1. package/dist/lib/browser/chunk-7CDDG6LL.mjs +578 -0
  2. package/dist/lib/browser/chunk-7CDDG6LL.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  4. package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
  5. package/dist/lib/browser/extraction/index.mjs +225 -0
  6. package/dist/lib/browser/extraction/index.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +723 -1704
  8. package/dist/lib/browser/index.mjs.map +4 -4
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/testing/index.mjs +32 -0
  11. package/dist/lib/browser/testing/index.mjs.map +7 -0
  12. package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs +579 -0
  13. package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs.map +7 -0
  14. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  15. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  16. package/dist/lib/node-esm/extraction/index.mjs +226 -0
  17. package/dist/lib/node-esm/extraction/index.mjs.map +7 -0
  18. package/dist/lib/node-esm/index.mjs +723 -1705
  19. package/dist/lib/node-esm/index.mjs.map +4 -4
  20. package/dist/lib/node-esm/meta.json +1 -1
  21. package/dist/lib/node-esm/testing/index.mjs +33 -0
  22. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  23. package/dist/types/src/conversation/context.d.ts +129 -0
  24. package/dist/types/src/conversation/context.d.ts.map +1 -0
  25. package/dist/types/src/conversation/context.test.d.ts +2 -0
  26. package/dist/types/src/conversation/context.test.d.ts.map +1 -0
  27. package/dist/types/src/conversation/conversation.d.ts +29 -26
  28. package/dist/types/src/conversation/conversation.d.ts.map +1 -1
  29. package/dist/types/src/conversation/conversation.test.d.ts +2 -0
  30. package/dist/types/src/conversation/conversation.test.d.ts.map +1 -0
  31. package/dist/types/src/conversation/index.d.ts +1 -0
  32. package/dist/types/src/conversation/index.d.ts.map +1 -1
  33. package/dist/types/src/diff.d.ts +15 -0
  34. package/dist/types/src/diff.d.ts.map +1 -0
  35. package/dist/types/src/diff.test.d.ts +2 -0
  36. package/dist/types/src/diff.test.d.ts.map +1 -0
  37. package/dist/types/src/errors.d.ts +47 -18
  38. package/dist/types/src/errors.d.ts.map +1 -1
  39. package/dist/types/src/execution-graph.d.ts +85 -0
  40. package/dist/types/src/execution-graph.d.ts.map +1 -0
  41. package/dist/types/src/execution-graph.test.d.ts +2 -0
  42. package/dist/types/src/execution-graph.test.d.ts.map +1 -0
  43. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts +1 -1
  44. package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -1
  45. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +258 -213
  46. package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
  47. package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
  48. package/dist/types/src/extraction/extraction.d.ts +345 -270
  49. package/dist/types/src/extraction/extraction.d.ts.map +1 -1
  50. package/dist/types/src/extraction/quotes.d.ts +3 -3
  51. package/dist/types/src/extraction/quotes.d.ts.map +1 -1
  52. package/dist/types/src/functions/services.d.ts +18 -4
  53. package/dist/types/src/functions/services.d.ts.map +1 -1
  54. package/dist/types/src/functions.test.d.ts +2 -0
  55. package/dist/types/src/functions.test.d.ts.map +1 -0
  56. package/dist/types/src/index.d.ts +3 -3
  57. package/dist/types/src/index.d.ts.map +1 -1
  58. package/dist/types/src/session/GenericToolkit.d.ts +85 -0
  59. package/dist/types/src/session/GenericToolkit.d.ts.map +1 -0
  60. package/dist/types/src/session/artifact-diff.d.ts +27 -0
  61. package/dist/types/src/session/artifact-diff.d.ts.map +1 -0
  62. package/dist/types/src/session/error-handling.d.ts +4 -0
  63. package/dist/types/src/session/error-handling.d.ts.map +1 -0
  64. package/dist/types/src/session/format.d.ts +12 -0
  65. package/dist/types/src/session/format.d.ts.map +1 -0
  66. package/dist/types/src/session/format.test.d.ts +2 -0
  67. package/dist/types/src/session/format.test.d.ts.map +1 -0
  68. package/dist/types/src/session/index.d.ts +4 -0
  69. package/dist/types/src/session/index.d.ts.map +1 -1
  70. package/dist/types/src/session/observer.d.ts +23 -0
  71. package/dist/types/src/session/observer.d.ts.map +1 -0
  72. package/dist/types/src/session/session.d.ts +33 -237
  73. package/dist/types/src/session/session.d.ts.map +1 -1
  74. package/dist/types/src/session/toolkit.d.ts +14 -0
  75. package/dist/types/src/session/toolkit.d.ts.map +1 -0
  76. package/dist/types/src/session/version-pin.d.ts +4 -4
  77. package/dist/types/src/session/version-pin.d.ts.map +1 -1
  78. package/dist/types/src/templates/index.d.ts +1 -1
  79. package/dist/types/src/templates/system.d.ts +18 -0
  80. package/dist/types/src/templates/system.d.ts.map +1 -0
  81. package/dist/types/src/testing/index.d.ts +1 -2
  82. package/dist/types/src/testing/index.d.ts.map +1 -1
  83. package/dist/types/src/testing/layer.d.ts +21 -0
  84. package/dist/types/src/testing/layer.d.ts.map +1 -0
  85. package/dist/types/src/types/artifact.d.ts +28 -0
  86. package/dist/types/src/types/artifact.d.ts.map +1 -0
  87. package/dist/types/src/types/index.d.ts +2 -0
  88. package/dist/types/src/types/index.d.ts.map +1 -0
  89. package/dist/types/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +56 -33
  91. package/src/conversation/context.test.ts +46 -0
  92. package/src/conversation/context.ts +303 -0
  93. package/src/conversation/conversation.test.ts +65 -0
  94. package/src/conversation/conversation.ts +93 -64
  95. package/src/conversation/index.ts +1 -0
  96. package/src/diff.test.ts +43 -0
  97. package/src/diff.ts +84 -0
  98. package/src/errors.ts +6 -1
  99. package/src/execution-graph.test.ts +740 -0
  100. package/src/execution-graph.ts +509 -0
  101. package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +10 -9
  102. package/src/extraction/extraction-llm-function/extraction-llm-function.ts +48 -56
  103. package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +22 -21
  104. package/src/extraction/extraction-ner-function/extraction-ner-function.ts +42 -43
  105. package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
  106. package/src/extraction/extraction-ner-function/named-entity-recognition.ts +2 -0
  107. package/src/extraction/extraction.ts +10 -9
  108. package/src/extraction/quotes.test.ts +3 -3
  109. package/src/extraction/quotes.ts +6 -7
  110. package/src/functions/services.ts +138 -97
  111. package/src/functions.conversations.json +1 -0
  112. package/src/functions.test.ts +74 -0
  113. package/src/index.ts +3 -3
  114. package/src/session/GenericToolkit.ts +131 -0
  115. package/src/session/artifact-diff.ts +41 -0
  116. package/src/session/error-handling.ts +41 -0
  117. package/src/session/format.test.ts +124 -0
  118. package/src/session/format.ts +143 -0
  119. package/src/session/index.ts +5 -0
  120. package/src/session/observer.ts +61 -0
  121. package/src/session/session.conversations.json +1 -0
  122. package/src/session/session.test.ts +34 -201
  123. package/src/session/session.ts +146 -248
  124. package/src/session/toolkit.ts +39 -0
  125. package/src/session/version-pin.ts +8 -8
  126. package/src/templates/index.ts +1 -1
  127. package/src/templates/instructions/format.tpl +61 -0
  128. package/src/templates/instructions/system.tpl +48 -0
  129. package/src/templates/system.ts +41 -0
  130. package/src/testing/index.ts +2 -8
  131. package/src/testing/layer.ts +78 -0
  132. package/src/types/artifact.ts +82 -0
  133. package/src/types/index.ts +5 -0
  134. package/src/typings.d.ts +5 -0
  135. package/dist/types/bin/chat.d.ts +0 -2
  136. package/dist/types/bin/chat.d.ts.map +0 -1
  137. package/dist/types/src/context/binder.d.ts +0 -34
  138. package/dist/types/src/context/binder.d.ts.map +0 -1
  139. package/dist/types/src/context/binding.d.ts +0 -56
  140. package/dist/types/src/context/binding.d.ts.map +0 -1
  141. package/dist/types/src/context/index.d.ts +0 -3
  142. package/dist/types/src/context/index.d.ts.map +0 -1
  143. package/dist/types/src/research/exa.d.ts +0 -12
  144. package/dist/types/src/research/exa.d.ts.map +0 -1
  145. package/dist/types/src/research/graph.d.ts +0 -51
  146. package/dist/types/src/research/graph.d.ts.map +0 -1
  147. package/dist/types/src/research/graph.test.d.ts +0 -2
  148. package/dist/types/src/research/graph.test.d.ts.map +0 -1
  149. package/dist/types/src/research/index.d.ts +0 -4
  150. package/dist/types/src/research/index.d.ts.map +0 -1
  151. package/dist/types/src/research/research.d.ts +0 -10
  152. package/dist/types/src/research/research.d.ts.map +0 -1
  153. package/dist/types/src/research/research.test.d.ts +0 -2
  154. package/dist/types/src/research/research.test.d.ts.map +0 -1
  155. package/dist/types/src/session/version-pin.test.d.ts +0 -2
  156. package/dist/types/src/session/version-pin.test.d.ts.map +0 -1
  157. package/dist/types/src/summarization/summarization.test.d.ts +0 -2
  158. package/dist/types/src/summarization/summarization.test.d.ts.map +0 -1
  159. package/dist/types/src/templates/prompt.d.ts +0 -30
  160. package/dist/types/src/templates/prompt.d.ts.map +0 -1
  161. package/dist/types/src/testing/exa-search-1748337321991.d.ts +0 -38
  162. package/dist/types/src/testing/exa-search-1748337321991.d.ts.map +0 -1
  163. package/dist/types/src/testing/exa-search-1748337331526.d.ts +0 -37
  164. package/dist/types/src/testing/exa-search-1748337331526.d.ts.map +0 -1
  165. package/dist/types/src/testing/exa-search-1748337344119.d.ts +0 -58
  166. package/dist/types/src/testing/exa-search-1748337344119.d.ts.map +0 -1
  167. package/dist/types/src/types.d.ts +0 -13
  168. package/dist/types/src/types.d.ts.map +0 -1
  169. package/src/context/binder.ts +0 -103
  170. package/src/context/binding.ts +0 -32
  171. package/src/context/index.ts +0 -6
  172. package/src/research/exa.ts +0 -97
  173. package/src/research/graph.test.ts +0 -64
  174. package/src/research/graph.ts +0 -369
  175. package/src/research/index.ts +0 -7
  176. package/src/research/instructions-research.tpl +0 -98
  177. package/src/research/research.test.ts +0 -190
  178. package/src/research/research.ts +0 -87
  179. package/src/session/__snapshots__/session.test.ts.snap +0 -32
  180. package/src/session/version-pin.test.ts +0 -7
  181. package/src/summarization/summarization.test.ts +0 -208
  182. package/src/templates/assistant.tpl +0 -111
  183. package/src/templates/prompt.ts +0 -45
  184. package/src/testing/exa-search-1748337321991.ts +0 -131
  185. package/src/testing/exa-search-1748337331526.ts +0 -144
  186. package/src/testing/exa-search-1748337344119.ts +0 -133
  187. package/src/typedefs.d.ts +0 -8
  188. package/src/types.ts +0 -47
  189. /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
@@ -2,95 +2,124 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type AiError, type AiLanguageModel, type AiTool, type AiToolkit } from '@effect/ai';
6
- import { Effect } from 'effect';
5
+ import type * as Toolkit from '@effect/ai/Toolkit';
6
+ import type { Registry } from '@effect-atom/atom-react';
7
+ import * as Effect from 'effect/Effect';
7
8
 
8
- import {
9
- type ToolExecutionService,
10
- type ToolResolverService,
11
- type AiInputPreprocessingError,
12
- type AiToolNotFoundError,
13
- } from '@dxos/ai';
14
- import { Event } from '@dxos/async';
9
+ import { Resource } from '@dxos/context';
15
10
  import { Obj } from '@dxos/echo';
16
11
  import { type Queue } from '@dxos/echo-db';
17
- import { DatabaseService } from '@dxos/functions';
18
- import { DataType } from '@dxos/schema';
12
+ import { invariant } from '@dxos/invariant';
13
+ import { log } from '@dxos/log';
14
+ import { Message } from '@dxos/types';
19
15
 
20
- import { ContextBinder, type ContextBinding } from '../context';
21
- import type { AiAssistantError } from '../errors';
22
- import { AiSession } from '../session';
16
+ import {
17
+ AiSession,
18
+ type AiSessionRunError,
19
+ type AiSessionRunRequirements,
20
+ type GenerationObserver,
21
+ createToolkit,
22
+ } from '../session';
23
23
 
24
- export interface ConversationRunOptions<Tools extends AiTool.Any> {
25
- systemPrompt?: string;
26
- prompt: string;
24
+ import { AiContextBinder, AiContextService, type ContextBinding } from './context';
27
25
 
28
- toolkit?: AiToolkit.AiToolkit<Tools>;
26
+ export interface AiConversationRunProps {
27
+ prompt: string;
28
+ system?: string;
29
+ observer?: GenerationObserver;
29
30
  }
30
31
 
31
- export type ConversationOptions = {
32
- queue: Queue<DataType.Message | ContextBinding>;
32
+ export type AiConversationOptions = {
33
+ queue: Queue<Message.Message | ContextBinding>;
34
+ toolkit?: Toolkit.Any;
35
+ registry?: Registry.Registry;
33
36
  };
34
37
 
35
38
  /**
36
- * Persistent conversation state.
37
- * Context + history + artifacts.
38
- * Backed by a Queue.
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.
39
41
  */
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
-
42
+ export class AiConversation extends Resource {
49
43
  /**
50
- * Blueprints bound to the conversation.
44
+ * Blueprints and objects bound to the conversation.
51
45
  */
52
- public readonly context: ContextBinder;
46
+ private readonly _binder: AiContextBinder;
47
+ private readonly _queue: Queue<Message.Message | ContextBinding>;
48
+ private readonly _toolkit?: Toolkit.Any;
53
49
 
54
- constructor(options: ConversationOptions) {
50
+ public constructor(options: AiConversationOptions) {
51
+ super();
55
52
  this._queue = options.queue;
56
- this.context = new ContextBinder(this._queue);
53
+ this._toolkit = options.toolkit;
54
+ invariant(this._queue);
55
+ this._binder = new AiContextBinder({ queue: this._queue, registry: options.registry });
57
56
  }
58
57
 
59
- async getHistory(): Promise<DataType.Message[]> {
60
- const queueItems = await this._queue.queryObjects();
61
- return queueItems.filter(Obj.instanceOf(DataType.Message));
58
+ protected override async _open(): Promise<void> {
59
+ await this._binder.open(this._ctx);
62
60
  }
63
61
 
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);
62
+ public get queue() {
63
+ return this._queue;
64
+ }
74
65
 
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);
66
+ public get context() {
67
+ return this._binder;
68
+ }
78
69
 
79
- const contextObjects = yield* Effect.forEach(context.objects.values(), DatabaseService.loadRef);
70
+ public get toolkit() {
71
+ return this._toolkit;
72
+ }
80
73
 
81
- const systemPrompt =
82
- (options.systemPrompt ?? '') +
83
- '\n\n' +
84
- contextObjects.map((obj) => `<object>${Obj.getDXN(obj)}</object>`).join('\n');
74
+ public async getHistory(): Promise<Message.Message[]> {
75
+ const queueItems = await this._queue.queryObjects(); // TODO(burdon): Update.
76
+ return queueItems.filter(Obj.instanceOf(Message.Message));
77
+ }
85
78
 
86
- const messages = yield* session.run({
87
- prompt: options.prompt,
88
- history,
89
- systemPrompt,
90
- toolkit: options.toolkit,
79
+ /**
80
+ * Creates a new cancelable request effect.
81
+ */
82
+ public createRequest(
83
+ params: AiConversationRunProps,
84
+ ): Effect.Effect<Message.Message[], AiSessionRunError, AiSessionRunRequirements> {
85
+ const self = this;
86
+ return Effect.gen(function* () {
87
+ const history = yield* Effect.promise(() => self.getHistory());
88
+
89
+ // Create toolkit.
90
+ const blueprints = self.context.getBlueprints();
91
+ const toolkit = yield* createToolkit({
92
+ toolkit: self._toolkit,
91
93
  blueprints,
92
94
  });
93
- yield* Effect.promise(() => this._queue.append(messages));
95
+
96
+ // Context objects.
97
+ const objects = self.context.getObjects();
98
+
99
+ log('run', {
100
+ history: history.length,
101
+ blueprints: blueprints.length,
102
+ tools: Object.keys(toolkit.tools).length,
103
+ objects: objects.length,
104
+ });
105
+
106
+ // Process request.
107
+ const session = new AiSession();
108
+ const messages = yield* session.run({ history, blueprints, toolkit, objects, ...params }).pipe(
109
+ Effect.provideService(AiContextService, {
110
+ binder: self.context,
111
+ }),
112
+ );
113
+
114
+ log('result', {
115
+ messages: messages.length,
116
+ duration: session.duration,
117
+ toolCalls: session.toolCalls,
118
+ });
119
+
120
+ // Append to queue.
121
+ yield* Effect.promise(() => self._queue.append(messages));
94
122
  return messages;
95
- }).pipe(Effect.withSpan('Conversation.run'));
123
+ });
124
+ }
96
125
  }
@@ -2,4 +2,5 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ export * from './context';
5
6
  export * from './conversation';
@@ -0,0 +1,43 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, it } from 'vitest';
6
+
7
+ import { createDocAccessor } from '@dxos/echo-db';
8
+ import { EchoTestBuilder } from '@dxos/echo-db/testing';
9
+ import { Text } from '@dxos/schema';
10
+ import { trim } from '@dxos/util';
11
+
12
+ import { applyDiffs } from './diff';
13
+
14
+ describe('diff', () => {
15
+ it('should apply diffs', async () => {
16
+ const builder = new EchoTestBuilder();
17
+ const { db, graph } = await builder.createDatabase();
18
+ await graph.schemaRegistry.register([Text.Text]);
19
+
20
+ const document = trim`
21
+ # Hello World
22
+ There'z a typo in this sentence.
23
+ And another oon here.
24
+ But not this one.
25
+ `;
26
+
27
+ const text = db.add(Text.make(document));
28
+ const accessor = createDocAccessor(text, ['content']);
29
+ const result = applyDiffs(accessor, [
30
+ `- There'z a typo in this sentence.`,
31
+ `+ There is a typo in this sentence.`,
32
+ `- And another oon here.`,
33
+ `+ And another one here.`,
34
+ ]);
35
+
36
+ expect(result).toBe(trim`
37
+ # Hello World
38
+ There is a typo in this sentence.
39
+ And another one here.
40
+ But not this one.
41
+ `);
42
+ });
43
+ });
package/src/diff.ts ADDED
@@ -0,0 +1,84 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { next as A, type Doc } from '@automerge/automerge';
6
+
7
+ import { DocAccessor, toCursorRange } from '@dxos/echo-db';
8
+ import { log } from '@dxos/log';
9
+ import { isNonNullable } from '@dxos/util';
10
+
11
+ // Relevant info:
12
+ // https://github.com/Minahil-official/GPT-4.1-Promting-Guide?tab=readme-ov-file#-apply-patch-tool-format-v4a-diff
13
+
14
+ // TODO(burdon): Anthropic only.
15
+ // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/text-editor-tool#example-str-replace-command
16
+ // AI_TOOL_NOT_FOUND: str_replace_based_edit_tool
17
+ // 'str_replace_based_edit_tool',
18
+
19
+ // TOOD(burdon): Support append to end (no "-").
20
+
21
+ export type Diff = {
22
+ match: string;
23
+ replace: string;
24
+ };
25
+
26
+ /**
27
+ * Convert a list of diffs into a list of operations.
28
+ */
29
+ export const reduceDiffs = (diffs: readonly string[]): Diff[] => {
30
+ return diffs.reduce<Diff[]>((acc, diff) => {
31
+ const current = acc[acc.length - 1];
32
+ const [op, ...rest] = diff.split(' ');
33
+ switch (op) {
34
+ case '-': {
35
+ if (current && !current.match) {
36
+ current.match += rest.join(' ');
37
+ } else {
38
+ acc.push({ match: rest.join(' '), replace: '' });
39
+ }
40
+ return acc;
41
+ }
42
+ case '+': {
43
+ if (current && !current.replace) {
44
+ current.replace += rest.join(' ');
45
+ } else {
46
+ acc.push({ match: '', replace: rest.join(' ') });
47
+ }
48
+ return acc;
49
+ }
50
+ }
51
+
52
+ return acc;
53
+ }, []);
54
+ };
55
+
56
+ export const computeDiffsWithCursors = <T>(accessor: DocAccessor<T>, diffs: readonly string[]) => {
57
+ return reduceDiffs(diffs)
58
+ .map((diff) => {
59
+ const text = DocAccessor.getValue<string>(accessor);
60
+ const idx = text.indexOf(diff.match);
61
+ if (idx !== -1) {
62
+ return { cursor: toCursorRange(accessor, idx, idx + diff.match.length), text: diff.replace };
63
+ }
64
+ })
65
+ .filter(isNonNullable);
66
+ };
67
+
68
+ export const applyDiffs = <T>(accessor: DocAccessor<T>, diffs: readonly string[]): string => {
69
+ for (const diff of reduceDiffs(diffs)) {
70
+ accessor.handle.change((doc: Doc<T>) => {
71
+ const text = DocAccessor.getValue<string>(accessor);
72
+ const idx = text.indexOf(diff.match);
73
+ if (idx !== -1) {
74
+ // TODO(burdon): Replace smallest substring.
75
+ // NOTE: This only replaces the first match.
76
+ A.splice(doc, accessor.path as A.Prop[], idx, diff.match.length, diff.replace);
77
+ } else {
78
+ log.warn('diff not found', diff);
79
+ }
80
+ });
81
+ }
82
+
83
+ return DocAccessor.getValue<string>(accessor);
84
+ };
package/src/errors.ts CHANGED
@@ -4,7 +4,12 @@
4
4
 
5
5
  import { BaseError } from '@dxos/errors';
6
6
 
7
+ /**
8
+ * Generic error from AI model.
9
+ */
10
+ export class AiModelError extends BaseError.extend('AiModelError', 'AI model error') {}
11
+
7
12
  /**
8
13
  * Generic error for AI agent execution.
9
14
  */
10
- export class AiAssistantError extends BaseError.extend('AI_ASSISTANT_ERROR') {}
15
+ export class AiAssistantError extends BaseError.extend('AiAssistantError', 'AI assistant error') {}