@dxos/assistant 0.8.4-main.84f28bd → 0.8.4-main.9735255
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/chunk-7CDDG6LL.mjs +578 -0
- package/dist/lib/browser/chunk-7CDDG6LL.mjs.map +7 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +7 -0
- package/dist/lib/browser/extraction/index.mjs +225 -0
- package/dist/lib/browser/extraction/index.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +723 -1892
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +32 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs +579 -0
- package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/extraction/index.mjs +226 -0
- package/dist/lib/node-esm/extraction/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +723 -1893
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +33 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/conversation/context.d.ts +129 -0
- package/dist/types/src/conversation/context.d.ts.map +1 -0
- 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/conversation.d.ts +29 -32
- package/dist/types/src/conversation/conversation.d.ts.map +1 -1
- package/dist/types/src/conversation/conversation.test.d.ts +2 -0
- package/dist/types/src/conversation/conversation.test.d.ts.map +1 -0
- package/dist/types/src/conversation/index.d.ts +1 -0
- package/dist/types/src/conversation/index.d.ts.map +1 -1
- package/dist/types/src/diff.d.ts +15 -0
- package/dist/types/src/diff.d.ts.map +1 -0
- package/dist/types/src/diff.test.d.ts +2 -0
- package/dist/types/src/diff.test.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +67 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- 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-llm-function/extraction-llm-function.d.ts +1 -1
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +279 -140
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction.d.ts +345 -212
- package/dist/types/src/extraction/extraction.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/index.d.ts +2 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/services.d.ts +20 -0
- package/dist/types/src/functions/services.d.ts.map +1 -0
- package/dist/types/src/functions.test.d.ts +2 -0
- package/dist/types/src/functions.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/session/GenericToolkit.d.ts +85 -0
- package/dist/types/src/session/GenericToolkit.d.ts.map +1 -0
- package/dist/types/src/session/artifact-diff.d.ts +27 -0
- package/dist/types/src/session/artifact-diff.d.ts.map +1 -0
- package/dist/types/src/session/error-handling.d.ts +4 -0
- package/dist/types/src/session/error-handling.d.ts.map +1 -0
- package/dist/types/src/session/format.d.ts +12 -0
- package/dist/types/src/session/format.d.ts.map +1 -0
- package/dist/types/src/session/format.test.d.ts +2 -0
- package/dist/types/src/session/format.test.d.ts.map +1 -0
- package/dist/types/src/session/index.d.ts +4 -0
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/observer.d.ts +23 -0
- package/dist/types/src/session/observer.d.ts.map +1 -0
- package/dist/types/src/session/session.d.ts +41 -268
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/toolkit.d.ts +14 -0
- package/dist/types/src/session/toolkit.d.ts.map +1 -0
- package/dist/types/src/session/version-pin.d.ts +5 -5
- package/dist/types/src/session/version-pin.d.ts.map +1 -1
- package/dist/types/src/templates/index.d.ts +2 -0
- package/dist/types/src/templates/index.d.ts.map +1 -0
- package/dist/types/src/templates/system.d.ts +18 -0
- package/dist/types/src/templates/system.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +1 -2
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/layer.d.ts +21 -0
- package/dist/types/src/testing/layer.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 +58 -27
- package/src/conversation/context.test.ts +46 -0
- package/src/conversation/context.ts +303 -0
- package/src/conversation/conversation.test.ts +65 -0
- package/src/conversation/conversation.ts +98 -76
- package/src/conversation/index.ts +1 -0
- package/src/diff.test.ts +43 -0
- package/src/diff.ts +84 -0
- package/src/errors.ts +15 -0
- package/src/execution-graph.test.ts +740 -0
- package/src/execution-graph.ts +509 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +14 -25
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +48 -52
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +22 -21
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +43 -41
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +12 -6
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +3 -1
- package/src/extraction/extraction.ts +10 -9
- package/src/extraction/quotes.test.ts +3 -3
- package/src/extraction/quotes.ts +6 -7
- package/src/functions/index.ts +5 -0
- package/src/functions/services.ts +180 -0
- package/src/functions.conversations.json +1 -0
- package/src/functions.test.ts +74 -0
- package/src/index.ts +5 -5
- package/src/session/GenericToolkit.ts +131 -0
- package/src/session/artifact-diff.ts +41 -0
- package/src/session/error-handling.ts +41 -0
- package/src/session/format.test.ts +124 -0
- package/src/session/format.ts +143 -0
- package/src/session/index.ts +5 -0
- package/src/session/observer.ts +61 -0
- package/src/session/session.conversations.json +1 -0
- package/src/session/session.test.ts +83 -215
- package/src/session/session.ts +181 -529
- package/src/session/toolkit.ts +39 -0
- package/src/session/version-pin.ts +12 -12
- package/src/templates/index.ts +5 -0
- package/src/templates/instructions/format.tpl +61 -0
- package/src/templates/instructions/system.tpl +48 -0
- package/src/templates/system.ts +41 -0
- package/src/testing/index.ts +2 -8
- package/src/testing/layer.ts +78 -0
- package/src/types/artifact.ts +82 -0
- package/src/types/index.ts +5 -0
- package/src/typings.d.ts +5 -0
- package/dist/types/bin/chat.d.ts +0 -2
- package/dist/types/bin/chat.d.ts.map +0 -1
- package/dist/types/src/blueprint/blueprint.d.ts +0 -41
- package/dist/types/src/blueprint/blueprint.d.ts.map +0 -1
- package/dist/types/src/blueprint/index.d.ts +0 -3
- package/dist/types/src/blueprint/index.d.ts.map +0 -1
- package/dist/types/src/blueprint/registry.d.ts +0 -7
- package/dist/types/src/blueprint/registry.d.ts.map +0 -1
- package/dist/types/src/context/binder.d.ts +0 -34
- package/dist/types/src/context/binder.d.ts.map +0 -1
- package/dist/types/src/context/binding.d.ts +0 -38
- package/dist/types/src/context/binding.d.ts.map +0 -1
- package/dist/types/src/context/index.d.ts +0 -3
- package/dist/types/src/context/index.d.ts.map +0 -1
- package/dist/types/src/research/exa.d.ts +0 -7
- package/dist/types/src/research/exa.d.ts.map +0 -1
- package/dist/types/src/research/graph.d.ts +0 -41
- package/dist/types/src/research/graph.d.ts.map +0 -1
- package/dist/types/src/research/graph.test.d.ts +0 -2
- package/dist/types/src/research/graph.test.d.ts.map +0 -1
- package/dist/types/src/research/index.d.ts +0 -4
- package/dist/types/src/research/index.d.ts.map +0 -1
- package/dist/types/src/research/research.d.ts +0 -10
- package/dist/types/src/research/research.d.ts.map +0 -1
- package/dist/types/src/research/research.test.d.ts +0 -2
- package/dist/types/src/research/research.test.d.ts.map +0 -1
- package/dist/types/src/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/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/types.d.ts +0 -3
- package/dist/types/src/types.d.ts.map +0 -1
- package/src/blueprint/blueprint.ts +0 -75
- package/src/blueprint/index.ts +0 -6
- package/src/blueprint/registry.ts +0 -15
- package/src/context/binder.ts +0 -101
- package/src/context/binding.ts +0 -31
- package/src/context/index.ts +0 -6
- package/src/research/exa.ts +0 -100
- package/src/research/graph.test.ts +0 -15
- package/src/research/graph.ts +0 -337
- package/src/research/index.ts +0 -7
- package/src/research/instructions-research.tpl +0 -97
- package/src/research/research.test.ts +0 -190
- package/src/research/research.ts +0 -90
- package/src/session/version-pin.test.ts +0 -26
- package/src/summarization/summarization.test.ts +0 -221
- 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/typedefs.d.ts +0 -8
- package/src/types.ts +0 -8
- /package/src/extraction/extraction-llm-function/{instructions.tpl → transcription-instructions.tpl} +0 -0
|
@@ -2,102 +2,124 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
|
|
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';
|
|
8
|
+
|
|
9
|
+
import { Resource } from '@dxos/context';
|
|
10
|
+
import { Obj } from '@dxos/echo';
|
|
9
11
|
import { type Queue } from '@dxos/echo-db';
|
|
10
|
-
import {
|
|
12
|
+
import { invariant } from '@dxos/invariant';
|
|
11
13
|
import { log } from '@dxos/log';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
import { ContextBinder, type ContextBinding } from '../context';
|
|
15
|
-
import { AISession, type SessionRunOptions } from '../session';
|
|
14
|
+
import { Message } from '@dxos/types';
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
import {
|
|
17
|
+
AiSession,
|
|
18
|
+
type AiSessionRunError,
|
|
19
|
+
type AiSessionRunRequirements,
|
|
20
|
+
type GenerationObserver,
|
|
21
|
+
createToolkit,
|
|
22
|
+
} from '../session';
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
artifacts?: ArtifactDefinition[];
|
|
23
|
-
extensions?: ToolContextExtensions;
|
|
24
|
-
generationOptions?: SessionRunOptions['generationOptions'];
|
|
24
|
+
import { AiContextBinder, AiContextService, type ContextBinding } from './context';
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
artifactDiffResolver?: SessionRunOptions['artifactDiffResolver'];
|
|
26
|
+
export interface AiConversationRunProps {
|
|
27
|
+
prompt: string;
|
|
28
|
+
system?: string;
|
|
29
|
+
observer?: GenerationObserver;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export type
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
export type AiConversationOptions = {
|
|
33
|
+
queue: Queue<Message.Message | ContextBinding>;
|
|
34
|
+
toolkit?: Toolkit.Any;
|
|
35
|
+
registry?: Registry.Registry;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* 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.
|
|
42
41
|
*/
|
|
43
|
-
export class
|
|
44
|
-
private readonly _serviceContainer: ServiceContainer;
|
|
45
|
-
private readonly _queue: Queue<Message | ContextBinding>;
|
|
46
|
-
|
|
42
|
+
export class AiConversation extends Resource {
|
|
47
43
|
/**
|
|
48
|
-
*
|
|
49
|
-
* This is called before the first message is sent.
|
|
44
|
+
* Blueprints and objects bound to the conversation.
|
|
50
45
|
*/
|
|
51
|
-
|
|
46
|
+
private readonly _binder: AiContextBinder;
|
|
47
|
+
private readonly _queue: Queue<Message.Message | ContextBinding>;
|
|
48
|
+
private readonly _toolkit?: Toolkit.Any;
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
-
public readonly context: ContextBinder;
|
|
57
|
-
|
|
58
|
-
constructor(options: ConversationOptions) {
|
|
59
|
-
this._serviceContainer = options.serviceContainer;
|
|
50
|
+
public constructor(options: AiConversationOptions) {
|
|
51
|
+
super();
|
|
60
52
|
this._queue = options.queue;
|
|
61
|
-
this.
|
|
53
|
+
this._toolkit = options.toolkit;
|
|
54
|
+
invariant(this._queue);
|
|
55
|
+
this._binder = new AiContextBinder({ queue: this._queue, registry: options.registry });
|
|
62
56
|
}
|
|
63
57
|
|
|
64
|
-
async
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
});
|
|
58
|
+
protected override async _open(): Promise<void> {
|
|
59
|
+
await this._binder.open(this._ctx);
|
|
60
|
+
}
|
|
93
61
|
|
|
94
|
-
|
|
62
|
+
public get queue() {
|
|
63
|
+
return this._queue;
|
|
64
|
+
}
|
|
95
65
|
|
|
96
|
-
|
|
66
|
+
public get context() {
|
|
67
|
+
return this._binder;
|
|
97
68
|
}
|
|
98
69
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
70
|
+
public get toolkit() {
|
|
71
|
+
return this._toolkit;
|
|
72
|
+
}
|
|
73
|
+
|
|
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
|
+
}
|
|
78
|
+
|
|
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,
|
|
93
|
+
blueprints,
|
|
94
|
+
});
|
|
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));
|
|
122
|
+
return messages;
|
|
123
|
+
});
|
|
102
124
|
}
|
|
103
125
|
}
|
package/src/diff.test.ts
ADDED
|
@@ -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
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { BaseError } from '@dxos/errors';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generic error from AI model.
|
|
9
|
+
*/
|
|
10
|
+
export class AiModelError extends BaseError.extend('AiModelError', 'AI model error') {}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generic error for AI agent execution.
|
|
14
|
+
*/
|
|
15
|
+
export class AiAssistantError extends BaseError.extend('AiAssistantError', 'AI assistant error') {}
|