@dxos/assistant 0.8.4-main.69d29f4 → 0.8.4-main.6fa680abb7
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/chunk-BE6SRJ4N.mjs +193 -0
- package/dist/lib/neutral/chunk-BE6SRJ4N.mjs.map +7 -0
- package/dist/lib/{browser → neutral}/extraction/index.mjs +4 -6
- package/dist/lib/neutral/extraction/index.mjs.map +7 -0
- package/dist/lib/{node-esm → neutral}/index.mjs +546 -69
- package/dist/lib/neutral/index.mjs.map +7 -0
- package/dist/lib/neutral/meta.json +1 -0
- package/dist/lib/neutral/testing/index.mjs +38 -0
- package/dist/lib/neutral/testing/index.mjs.map +7 -0
- package/dist/types/src/conversation/context.d.ts +20 -3
- package/dist/types/src/conversation/context.d.ts.map +1 -1
- package/dist/types/src/conversation/conversation.d.ts +26 -1
- package/dist/types/src/conversation/conversation.d.ts.map +1 -1
- package/dist/types/src/diff.d.ts +3 -1
- package/dist/types/src/diff.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +13 -5
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction.d.ts +16 -12
- package/dist/types/src/extraction/extraction.d.ts.map +1 -1
- package/dist/types/src/functions/services.d.ts +5 -6
- package/dist/types/src/functions/services.d.ts.map +1 -1
- package/dist/types/src/session/index.d.ts +1 -1
- package/dist/types/src/session/index.d.ts.map +1 -1
- package/dist/types/src/session/observer.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +12 -7
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/toolkit.d.ts +6 -2
- package/dist/types/src/session/toolkit.d.ts.map +1 -1
- package/dist/types/src/testing/layer.d.ts +6 -5
- package/dist/types/src/testing/layer.d.ts.map +1 -1
- package/dist/types/src/types/artifact.d.ts +5 -5
- package/dist/types/src/types/artifact.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -33
- package/src/conversation/context.test.ts +1 -1
- package/src/conversation/context.ts +35 -8
- package/src/conversation/conversation.ts +136 -14
- package/src/diff.test.ts +35 -4
- package/src/diff.ts +13 -4
- package/src/execution-graph.test.ts +2 -2
- package/src/execution-graph.ts +2 -2
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +1 -1
- package/src/extraction/extraction-ner-function/extraction-ner-function.test.ts +1 -1
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +1 -1
- package/src/extraction/extraction.ts +2 -2
- package/src/functions/services.ts +59 -30
- package/src/functions.conversations.json +1 -1
- package/src/functions.test.ts +7 -7
- package/src/session/format.test.ts +2 -2
- package/src/session/index.ts +1 -2
- package/src/session/observer.ts +3 -2
- package/src/session/session.conversations.json +1 -1
- package/src/session/session.test.ts +52 -4
- package/src/session/session.ts +68 -51
- package/src/session/toolkit.ts +12 -7
- package/src/templates/instructions/format.tpl +0 -4
- package/src/testing/layer.ts +24 -17
- package/src/types/artifact.ts +17 -10
- package/dist/lib/browser/chunk-7CDDG6LL.mjs +0 -578
- package/dist/lib/browser/chunk-7CDDG6LL.mjs.map +0 -7
- package/dist/lib/browser/chunk-J5LGTIGS.mjs +0 -10
- package/dist/lib/browser/chunk-J5LGTIGS.mjs.map +0 -7
- package/dist/lib/browser/extraction/index.mjs.map +0 -7
- package/dist/lib/browser/index.mjs +0 -850
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/testing/index.mjs +0 -32
- package/dist/lib/browser/testing/index.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs +0 -579
- package/dist/lib/node-esm/chunk-CC7ER6Q3.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
- package/dist/lib/node-esm/extraction/index.mjs +0 -226
- package/dist/lib/node-esm/extraction/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/testing/index.mjs +0 -33
- package/dist/lib/node-esm/testing/index.mjs.map +0 -7
- package/dist/types/src/session/GenericToolkit.d.ts +0 -85
- package/dist/types/src/session/GenericToolkit.d.ts.map +0 -1
- package/src/session/GenericToolkit.ts +0 -131
package/src/session/session.ts
CHANGED
|
@@ -8,25 +8,24 @@ import type * as Tool from '@effect/ai/Tool';
|
|
|
8
8
|
import type * as Toolkit from '@effect/ai/Toolkit';
|
|
9
9
|
import * as Chunk from 'effect/Chunk';
|
|
10
10
|
import * as Effect from 'effect/Effect';
|
|
11
|
-
import type * as Schema from 'effect/Schema';
|
|
12
11
|
import * as Stream from 'effect/Stream';
|
|
13
12
|
|
|
14
13
|
import {
|
|
15
14
|
AiParser,
|
|
16
15
|
AiPreprocessor,
|
|
16
|
+
AiSummarizer,
|
|
17
17
|
type AiToolNotFoundError,
|
|
18
18
|
type PromptPreprocessingError,
|
|
19
19
|
type ToolExecutionService,
|
|
20
20
|
type ToolResolverService,
|
|
21
21
|
callTool,
|
|
22
|
-
|
|
22
|
+
withoutToolCallParising,
|
|
23
23
|
} from '@dxos/ai';
|
|
24
24
|
import { type Blueprint } from '@dxos/blueprints';
|
|
25
|
-
import { todo } from '@dxos/debug';
|
|
26
25
|
import { Obj } from '@dxos/echo';
|
|
27
26
|
import { type FunctionInvocationService, TracingService } from '@dxos/functions';
|
|
28
27
|
import { log } from '@dxos/log';
|
|
29
|
-
import { Message } from '@dxos/types';
|
|
28
|
+
import { type ContentBlock, Message } from '@dxos/types';
|
|
30
29
|
|
|
31
30
|
import { type AiAssistantError } from '../errors';
|
|
32
31
|
|
|
@@ -42,7 +41,12 @@ export type AiSessionRunRequirements =
|
|
|
42
41
|
| TracingService
|
|
43
42
|
| FunctionInvocationService;
|
|
44
43
|
|
|
45
|
-
export type AiSessionOptions = {
|
|
44
|
+
export type AiSessionOptions = {
|
|
45
|
+
/**
|
|
46
|
+
* Summarize before executing the prompt if the existing history exceeds this threshold.
|
|
47
|
+
*/
|
|
48
|
+
summarizationThreshold?: number;
|
|
49
|
+
};
|
|
46
50
|
|
|
47
51
|
export type AiSessionRunProps<Tools extends Record<string, Tool.Any>> = {
|
|
48
52
|
prompt: string;
|
|
@@ -53,6 +57,12 @@ export type AiSessionRunProps<Tools extends Record<string, Tool.Any>> = {
|
|
|
53
57
|
blueprints?: readonly Blueprint.Blueprint[];
|
|
54
58
|
toolkit?: Toolkit.WithHandler<Tools>;
|
|
55
59
|
observer?: GenerationObserver<Tools>;
|
|
60
|
+
/**
|
|
61
|
+
* Callback for when a message is received from the user, model, or tool.
|
|
62
|
+
* This is useful for streaming the output to a queue.
|
|
63
|
+
*/
|
|
64
|
+
// TODO(dmaretskyi): This is duplicated by generation observer. Better solution would be to convert the return type from effect to stream.
|
|
65
|
+
onOutput?: (message: Message.Message) => Effect.Effect<void, never, never>;
|
|
56
66
|
};
|
|
57
67
|
|
|
58
68
|
/**
|
|
@@ -98,28 +108,41 @@ export class AiSession {
|
|
|
98
108
|
blueprints = [],
|
|
99
109
|
toolkit,
|
|
100
110
|
observer = GenerationObserver.noop(),
|
|
111
|
+
onOutput = () => Effect.void,
|
|
101
112
|
}: AiSessionRunProps<Tools>): Effect.Effect<Message.Message[], AiSessionRunError, AiSessionRunRequirements> =>
|
|
102
113
|
Effect.gen(this, function* () {
|
|
103
114
|
this._started = Date.now();
|
|
104
115
|
this._history = [...history];
|
|
105
116
|
this._pending = [];
|
|
106
|
-
const pending = this._pending;
|
|
107
117
|
|
|
108
|
-
const submitMessage =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
const submitMessage = (message: Message.Message) =>
|
|
119
|
+
Effect.gen(this, function* () {
|
|
120
|
+
this._pending.push(message);
|
|
121
|
+
yield* observer.onMessage(message);
|
|
122
|
+
yield* TracingService.emitConverationMessage(message);
|
|
123
|
+
yield* onOutput(message);
|
|
124
|
+
return message;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const system = yield* formatSystemPrompt({ system: systemTemplate, blueprints, objects }).pipe(Effect.orDie);
|
|
128
|
+
|
|
129
|
+
if (this._options.summarizationThreshold !== undefined) {
|
|
130
|
+
const tokenCount = yield* AiPreprocessor.estimateTokens(
|
|
131
|
+
yield* AiPreprocessor.preprocessPrompt([...this._history], {
|
|
132
|
+
system,
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
if (tokenCount > this._options.summarizationThreshold) {
|
|
136
|
+
const summary = yield* AiSummarizer.summarize([...this._history]);
|
|
137
|
+
yield* submitMessage(summary);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
114
140
|
|
|
115
141
|
// Submit the prompt.
|
|
116
142
|
// TODO(burdon): Remove if cancelled?
|
|
117
143
|
const promptMessage = yield* submitMessage(yield* formatUserPrompt({ prompt, history }));
|
|
118
144
|
|
|
119
145
|
// Generate system and prompt messages.
|
|
120
|
-
const system = yield* formatSystemPrompt({ system: systemTemplate, blueprints, objects }).pipe(Effect.orDie);
|
|
121
|
-
|
|
122
|
-
// log('system', { prompt: system });
|
|
123
146
|
|
|
124
147
|
// Tool call loop.
|
|
125
148
|
do {
|
|
@@ -131,15 +154,19 @@ export class AiSession {
|
|
|
131
154
|
objects: objects?.length ?? 0,
|
|
132
155
|
});
|
|
133
156
|
|
|
134
|
-
const prompt = yield* AiPreprocessor.preprocessPrompt([...this._history, ...this._pending], {
|
|
157
|
+
const prompt = yield* AiPreprocessor.preprocessPrompt([...this._history, ...this._pending], {
|
|
158
|
+
system,
|
|
159
|
+
cacheControl: 'ephemeral',
|
|
160
|
+
});
|
|
135
161
|
|
|
136
162
|
// Execute the stream request.
|
|
137
|
-
|
|
138
|
-
const blocks = yield* LanguageModel.streamText({
|
|
163
|
+
const messages = yield* LanguageModel.streamText({
|
|
139
164
|
prompt,
|
|
140
165
|
toolkit,
|
|
141
166
|
disableToolCallResolution: true,
|
|
142
167
|
}).pipe(
|
|
168
|
+
// Disable tool call parsing so that we can handle parameter schema errors on a per-tool call basis.
|
|
169
|
+
withoutToolCallParising,
|
|
143
170
|
// TOOD(dmaretskyi): Error mapping.
|
|
144
171
|
AiParser.parseResponse({
|
|
145
172
|
onBegin: () => observer.onBegin(),
|
|
@@ -147,23 +174,29 @@ export class AiSession {
|
|
|
147
174
|
onPart: (part) => observer.onPart(part),
|
|
148
175
|
onEnd: (summary) => observer.onEnd(summary),
|
|
149
176
|
}),
|
|
177
|
+
Stream.mapEffect((block) =>
|
|
178
|
+
Effect.gen(function* () {
|
|
179
|
+
return yield* submitMessage(
|
|
180
|
+
Obj.make(Message.Message, {
|
|
181
|
+
created: new Date().toISOString(),
|
|
182
|
+
sender: { role: 'assistant' },
|
|
183
|
+
blocks: [block],
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
186
|
+
}),
|
|
187
|
+
),
|
|
150
188
|
Stream.runCollect,
|
|
151
189
|
Effect.map(Chunk.toArray),
|
|
152
190
|
);
|
|
153
191
|
|
|
154
|
-
// log('blocks', { blocks });
|
|
155
|
-
|
|
156
|
-
// Create the response message.
|
|
157
|
-
const response = yield* submitMessage(
|
|
158
|
-
Obj.make(Message.Message, {
|
|
159
|
-
created: new Date().toISOString(),
|
|
160
|
-
sender: { role: 'assistant' },
|
|
161
|
-
blocks,
|
|
162
|
-
}),
|
|
163
|
-
);
|
|
164
|
-
|
|
165
192
|
// Parse the response for tool calls.
|
|
166
|
-
const toolCalls =
|
|
193
|
+
const toolCalls = messages.flatMap((message) =>
|
|
194
|
+
message.blocks
|
|
195
|
+
.filter(
|
|
196
|
+
(block): block is ContentBlock.ToolCall => block._tag === 'toolCall' && block.providerExecuted === false,
|
|
197
|
+
)
|
|
198
|
+
.map((block) => ({ block, message })),
|
|
199
|
+
);
|
|
167
200
|
if (toolCalls.length === 0) {
|
|
168
201
|
break;
|
|
169
202
|
} else if (!toolkit) {
|
|
@@ -172,13 +205,13 @@ export class AiSession {
|
|
|
172
205
|
|
|
173
206
|
// Execute the tool calls.
|
|
174
207
|
// TODO(burdon): Retry errors? Write result when each completes individually?
|
|
175
|
-
const toolResults = yield* Effect.forEach(toolCalls, (
|
|
176
|
-
return callTool(toolkit,
|
|
208
|
+
const toolResults = yield* Effect.forEach(toolCalls, ({ block, message }) => {
|
|
209
|
+
return callTool(toolkit, block).pipe(
|
|
177
210
|
Effect.provide(
|
|
178
211
|
TracingService.layerSubframe((context) => ({
|
|
179
212
|
...context,
|
|
180
|
-
parentMessage:
|
|
181
|
-
toolCallId:
|
|
213
|
+
parentMessage: message.id,
|
|
214
|
+
toolCallId: block.toolCallId,
|
|
182
215
|
})),
|
|
183
216
|
),
|
|
184
217
|
);
|
|
@@ -187,6 +220,7 @@ export class AiSession {
|
|
|
187
220
|
// Add to queue and continue loop.
|
|
188
221
|
// TODO(wittjosiah): Sometimes tool error results are added to the queue before the tool agent statuses.
|
|
189
222
|
// This results in a broken execution graph.
|
|
223
|
+
// TODO(dmaretskyi): Stream tool results one by one.
|
|
190
224
|
yield* submitMessage(
|
|
191
225
|
Obj.make(Message.Message, {
|
|
192
226
|
created: new Date().toISOString(),
|
|
@@ -202,23 +236,6 @@ export class AiSession {
|
|
|
202
236
|
log('done', { pending: this._pending.length, duration: this.duration, tools: this._toolCalls });
|
|
203
237
|
return this._pending;
|
|
204
238
|
}).pipe(this._semaphore.withPermits(1), Effect.withSpan('AiSession.run'));
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* @deprecated
|
|
208
|
-
*/
|
|
209
|
-
// TODO(burdon): Implement or remove.
|
|
210
|
-
async runStructured<S extends Schema.Schema.AnyNoContext>(
|
|
211
|
-
_schema: S,
|
|
212
|
-
_options: AiSessionRunProps<any>,
|
|
213
|
-
): Promise<Schema.Schema.Type<S>> {
|
|
214
|
-
return todo();
|
|
215
|
-
// const parser = structuredOutputParser(schema);
|
|
216
|
-
// const result = await this.run({
|
|
217
|
-
// ...options,
|
|
218
|
-
// executableTools: [...(options.executableTools ?? []), parser.tool],
|
|
219
|
-
// });
|
|
220
|
-
// return parser.getResult(result);
|
|
221
|
-
}
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
const createSnippet = (text: string, len = 32) =>
|
package/src/session/toolkit.ts
CHANGED
|
@@ -6,13 +6,17 @@ import type * as Tool from '@effect/ai/Tool';
|
|
|
6
6
|
import * as Toolkit from '@effect/ai/Toolkit';
|
|
7
7
|
import * as Effect from 'effect/Effect';
|
|
8
8
|
|
|
9
|
-
import { type AiToolNotFoundError, ToolExecutionService, ToolResolverService } from '@dxos/ai';
|
|
9
|
+
import { type AiToolNotFoundError, GenericToolkit, ToolExecutionService, ToolResolverService } from '@dxos/ai';
|
|
10
10
|
import { type Blueprint } from '@dxos/blueprints';
|
|
11
11
|
import { isTruthy } from '@dxos/util';
|
|
12
12
|
|
|
13
13
|
export type CreateToolkitProps = {
|
|
14
14
|
toolkit?: Toolkit.Any;
|
|
15
15
|
blueprints?: readonly Blueprint.Blueprint[];
|
|
16
|
+
/**
|
|
17
|
+
* Self-contained with handlers toolkits.
|
|
18
|
+
*/
|
|
19
|
+
genericToolkits?: readonly GenericToolkit.GenericToolkit[];
|
|
16
20
|
};
|
|
17
21
|
|
|
18
22
|
/**
|
|
@@ -21,6 +25,7 @@ export type CreateToolkitProps = {
|
|
|
21
25
|
export const createToolkit = ({
|
|
22
26
|
toolkit: toolkitProp,
|
|
23
27
|
blueprints = [],
|
|
28
|
+
genericToolkits = [],
|
|
24
29
|
}: CreateToolkitProps): Effect.Effect<
|
|
25
30
|
Toolkit.WithHandler<any>,
|
|
26
31
|
AiToolNotFoundError,
|
|
@@ -29,11 +34,11 @@ export const createToolkit = ({
|
|
|
29
34
|
Effect.gen(function* () {
|
|
30
35
|
const blueprintToolkit = yield* ToolResolverService.resolveToolkit(blueprints.flatMap(({ tools }) => tools));
|
|
31
36
|
const blueprintToolHandler = yield* blueprintToolkit.toContext(ToolExecutionService.handlersFor(blueprintToolkit));
|
|
37
|
+
const genericToolkit = GenericToolkit.merge(...genericToolkits);
|
|
32
38
|
|
|
33
|
-
const toolkit = Toolkit.merge(...[toolkitProp, blueprintToolkit].filter(isTruthy));
|
|
34
|
-
return yield* toolkit.pipe(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
>;
|
|
39
|
+
const toolkit = Toolkit.merge(...[toolkitProp, blueprintToolkit, genericToolkit.toolkit].filter(isTruthy));
|
|
40
|
+
return yield* toolkit.pipe(
|
|
41
|
+
Effect.provide(blueprintToolHandler),
|
|
42
|
+
Effect.provide(genericToolkit.layer),
|
|
43
|
+
) as any as Effect.Effect<Toolkit.WithHandler<any>, never, Tool.HandlersFor<any>>;
|
|
39
44
|
});
|
|
@@ -52,10 +52,6 @@ Do not use bullets when listing suggestions.
|
|
|
52
52
|
You may ask multiple choice questions by wrapping consise options inside <option> tags inside a well formed <select> tag.
|
|
53
53
|
Example: <select><option>Yes</option><option>No</option></select>
|
|
54
54
|
|
|
55
|
-
## Toolkit
|
|
56
|
-
|
|
57
|
-
If the user asks for a list of tools, then just emit a single self-closing <toolkit/> tag instead of listing the tools.
|
|
58
|
-
|
|
59
55
|
## Context
|
|
60
56
|
|
|
61
57
|
The current date and time is {{DATETIME}}.
|
package/src/testing/layer.ts
CHANGED
|
@@ -2,50 +2,48 @@
|
|
|
2
2
|
// Copyright 2026 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { Registry } from '@effect-atom/atom';
|
|
5
6
|
import * as Layer from 'effect/Layer';
|
|
6
7
|
import * as Match from 'effect/Match';
|
|
7
8
|
|
|
8
9
|
import { AiService, type ModelName } from '@dxos/ai';
|
|
10
|
+
import { GenericToolkit } from '@dxos/ai';
|
|
9
11
|
import { TestAiService } from '@dxos/ai/testing';
|
|
10
|
-
import type
|
|
12
|
+
import { Feed, type Type } from '@dxos/echo';
|
|
11
13
|
import { CredentialsService, type FunctionDefinition, type ServiceCredential, TracingService } from '@dxos/functions';
|
|
12
14
|
import { TracingServiceExt, TriggerDispatcher, TriggerStateStore } from '@dxos/functions-runtime';
|
|
13
15
|
import { FunctionInvocationServiceLayerTest, TestDatabaseLayer } from '@dxos/functions-runtime/testing';
|
|
14
16
|
|
|
15
|
-
import {
|
|
16
|
-
import { GenericToolkit } from '../session';
|
|
17
|
+
import { ToolExecutionServices } from '../functions';
|
|
17
18
|
|
|
18
19
|
interface TestLayerOptions {
|
|
19
20
|
aiServicePreset?: 'direct' | 'edge-local' | 'edge-remote';
|
|
20
21
|
model?: ModelName;
|
|
21
22
|
functions?: FunctionDefinition.Any[];
|
|
22
23
|
toolkits?: GenericToolkit.GenericToolkit[];
|
|
23
|
-
types?: Type.
|
|
24
|
+
types?: Type.AnyEntity[];
|
|
24
25
|
credentials?: ServiceCredential[];
|
|
25
26
|
/*
|
|
26
27
|
* Tracing configuration.
|
|
27
28
|
* @default 'noop'
|
|
28
29
|
*/
|
|
29
30
|
tracing?: 'noop' | 'console' | 'pretty';
|
|
31
|
+
|
|
32
|
+
disableLlmMemoization?: boolean;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
export const AssistantTestLayer = ({
|
|
33
36
|
aiServicePreset = 'direct',
|
|
34
|
-
model = '@anthropic/claude-opus-4-
|
|
37
|
+
model = '@anthropic/claude-opus-4-6',
|
|
35
38
|
functions = [],
|
|
36
39
|
toolkits = [],
|
|
37
40
|
types = [],
|
|
38
41
|
credentials = [],
|
|
39
42
|
tracing = 'noop',
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
makeToolExecutionServiceFromFunctions(
|
|
45
|
-
GenericToolkit.merge(...toolkits).toolkit as any,
|
|
46
|
-
GenericToolkit.merge(...toolkits).layer as any,
|
|
47
|
-
),
|
|
48
|
-
).pipe(
|
|
43
|
+
disableLlmMemoization = false,
|
|
44
|
+
}: TestLayerOptions = {}) => {
|
|
45
|
+
const toolkit = GenericToolkit.merge(...toolkits);
|
|
46
|
+
return Layer.mergeAll(AiService.model(model), ToolExecutionServices).pipe(
|
|
49
47
|
Layer.provideMerge(
|
|
50
48
|
FunctionInvocationServiceLayerTest({
|
|
51
49
|
functions,
|
|
@@ -53,26 +51,35 @@ export const AssistantTestLayer = ({
|
|
|
53
51
|
),
|
|
54
52
|
Layer.provideMerge(
|
|
55
53
|
Layer.mergeAll(
|
|
56
|
-
TestAiService({ preset: aiServicePreset }),
|
|
54
|
+
TestAiService({ preset: aiServicePreset, disableMemoization: disableLlmMemoization }),
|
|
57
55
|
TestDatabaseLayer({
|
|
58
56
|
spaceKey: 'fixed',
|
|
59
57
|
types,
|
|
60
58
|
}),
|
|
61
59
|
CredentialsService.configuredLayer(credentials),
|
|
60
|
+
Feed.notAvailable,
|
|
62
61
|
Match.value(tracing).pipe(
|
|
63
62
|
Match.when('noop', () => TracingService.layerNoop),
|
|
64
63
|
Match.when('console', () => TracingServiceExt.layerLogInfo()),
|
|
65
|
-
Match.when('pretty', () =>
|
|
64
|
+
Match.when('pretty', () =>
|
|
65
|
+
TracingServiceExt.layerConsolePrettyPrint({
|
|
66
|
+
toolkit: (toolkits.length > 0 ? GenericToolkit.merge(...toolkits) : GenericToolkit.empty).toolkit as any,
|
|
67
|
+
}),
|
|
68
|
+
),
|
|
66
69
|
Match.exhaustive,
|
|
67
70
|
),
|
|
68
71
|
),
|
|
69
72
|
),
|
|
73
|
+
Layer.provideMerge(GenericToolkit.providerLayer(toolkit)),
|
|
70
74
|
);
|
|
75
|
+
};
|
|
71
76
|
|
|
72
77
|
interface TestLayerWithTriggersOptions extends TestLayerOptions {}
|
|
73
78
|
|
|
74
79
|
export const AssistantTestLayerWithTriggers = (options: TestLayerWithTriggersOptions) =>
|
|
75
80
|
Layer.mergeAll(
|
|
76
81
|
AssistantTestLayer(options),
|
|
77
|
-
TriggerDispatcher.layer({ timeControl: 'manual', startingTime: new Date('2025-09-05T15:01:00.000Z') })
|
|
82
|
+
TriggerDispatcher.layer({ timeControl: 'manual', startingTime: new Date('2025-09-05T15:01:00.000Z') }).pipe(
|
|
83
|
+
Layer.provide(Registry.layer),
|
|
84
|
+
),
|
|
78
85
|
).pipe(Layer.provideMerge(TriggerStateStore.layerMemory));
|
package/src/types/artifact.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type * as Effect from 'effect/Effect';
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
|
|
8
|
-
import { type Err, Type } from '@dxos/echo';
|
|
8
|
+
import { type Err, Obj, Ref, type Type } from '@dxos/echo';
|
|
9
9
|
import { Database } from '@dxos/echo';
|
|
10
10
|
import { EncodedReference } from '@dxos/echo-protocol';
|
|
11
11
|
import { DXN, LOCAL_SPACE_TAG, type ObjectId, type SpaceId } from '@dxos/keys';
|
|
@@ -16,16 +16,16 @@ import { trim } from '@dxos/util';
|
|
|
16
16
|
*/
|
|
17
17
|
export const createArtifactElement = (id: ObjectId) => `<artifact id=${id} />`;
|
|
18
18
|
|
|
19
|
+
// TODO(burdon): Rename RefFromLLM? -- yes -dm
|
|
19
20
|
/**
|
|
20
21
|
* A model-friendly way to reference an object.
|
|
21
22
|
* Supports vairous formats that will be normalized to a DXN.
|
|
22
23
|
*
|
|
23
|
-
* @deprecated Use `
|
|
24
|
+
* @deprecated Use `Ref.Ref(XXX)` instead.
|
|
24
25
|
*/
|
|
25
|
-
// TODO(burdon): Rename RefFromLLM? -- yes -dm
|
|
26
26
|
export const ArtifactId: Schema.Schema<string> & {
|
|
27
27
|
toDXN: (reference: ArtifactId, owningSpaceId?: SpaceId) => DXN;
|
|
28
|
-
resolve: <S extends Type.
|
|
28
|
+
resolve: <S extends Type.AnyEntity>(
|
|
29
29
|
schema: S,
|
|
30
30
|
ref: ArtifactId,
|
|
31
31
|
) => Effect.Effect<Schema.Schema.Type<S>, Err.ObjectNotFoundError, Database.Service>;
|
|
@@ -33,11 +33,16 @@ export const ArtifactId: Schema.Schema<string> & {
|
|
|
33
33
|
// TODO(dmaretskyi): This section gets overriden.
|
|
34
34
|
description: trim`
|
|
35
35
|
The ID of the referenced object. Formats accepted:
|
|
36
|
-
- DXN (dxn:echo:@:
|
|
36
|
+
- DXN (dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4). DXNs can be prepended with an @ symbol for compatibility with in-text references.
|
|
37
37
|
- space ID, object ID tuple (spaceID:objectID)
|
|
38
|
-
- Only object ID that is assumed to be in the current space (
|
|
38
|
+
- Only object ID that is assumed to be in the current space (01KG7R1ZXWFMWQ4DA1Q6TN1DG4)
|
|
39
39
|
`,
|
|
40
|
-
examples: [
|
|
40
|
+
examples: [
|
|
41
|
+
'dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4',
|
|
42
|
+
'@dxn:echo:@:01KG7R1ZXWFMWQ4DA1Q6TN1DG4',
|
|
43
|
+
'BM3FSHFOMJCHCG5QW7JTVKGYABD2GAA7G:01KG7R1ZXWFMWQ4DA1Q6TN1DG4',
|
|
44
|
+
'01KG7R1ZXWFMWQ4DA1Q6TN1DG4',
|
|
45
|
+
],
|
|
41
46
|
}) {
|
|
42
47
|
static toDXN(reference: ArtifactId, owningSpaceId?: SpaceId): DXN {
|
|
43
48
|
// Allow @dxn: prefix for compatibility with in-text references.
|
|
@@ -61,12 +66,12 @@ export const ArtifactId: Schema.Schema<string> & {
|
|
|
61
66
|
/**
|
|
62
67
|
* Resolves an artifact ID to an object.
|
|
63
68
|
*/
|
|
64
|
-
static resolve<S extends Type.
|
|
69
|
+
static resolve<S extends Type.AnyEntity>(
|
|
65
70
|
schema: S,
|
|
66
71
|
ref: ArtifactId,
|
|
67
72
|
): Effect.Effect<Schema.Schema.Type<S>, Err.ObjectNotFoundError, Database.Service> {
|
|
68
73
|
const dxn = ArtifactId.toDXN(ref);
|
|
69
|
-
return Database.
|
|
74
|
+
return Database.resolve(dxn, schema);
|
|
70
75
|
}
|
|
71
76
|
};
|
|
72
77
|
|
|
@@ -75,8 +80,10 @@ export type ArtifactId = Schema.Schema.Type<typeof ArtifactId>;
|
|
|
75
80
|
/**
|
|
76
81
|
* Schema that decodes ECHO reference object from an LLM-friendly input.
|
|
77
82
|
*/
|
|
78
|
-
export const RefFromLLM = Schema.transform(ArtifactId,
|
|
83
|
+
export const RefFromLLM = Schema.transform(ArtifactId, Ref.Ref(Obj.Unknown), {
|
|
79
84
|
decode: (fromA, fromI) => EncodedReference.fromDXN(ArtifactId.toDXN(fromA)),
|
|
80
85
|
encode: (toI, toA) => EncodedReference.toDXN(toI).toString(),
|
|
81
86
|
strict: false,
|
|
87
|
+
}).annotations({
|
|
88
|
+
description: ArtifactId.ast.annotations.description as string,
|
|
82
89
|
});
|