@dxos/assistant 0.8.4-main.5acf9ea → 0.8.4-main.67995b8
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-6WRGDEMH.mjs +89 -0
- package/dist/lib/browser/chunk-6WRGDEMH.mjs.map +7 -0
- package/dist/lib/browser/chunk-SIXTNSGV.mjs +250 -0
- package/dist/lib/browser/chunk-SIXTNSGV.mjs.map +7 -0
- package/dist/lib/browser/extraction/index.mjs +269 -0
- package/dist/lib/browser/extraction/index.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +125 -705
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/named-entity-recognition-O46UTCLR.mjs +13 -0
- package/dist/lib/browser/named-entity-recognition-O46UTCLR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-3UU5V4FS.mjs +91 -0
- package/dist/lib/node-esm/chunk-3UU5V4FS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-FD5NXKDP.mjs +252 -0
- package/dist/lib/node-esm/chunk-FD5NXKDP.mjs.map +7 -0
- package/dist/lib/node-esm/extraction/index.mjs +270 -0
- package/dist/lib/node-esm/extraction/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +124 -705
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs +14 -0
- package/dist/lib/node-esm/named-entity-recognition-W4VMRCH6.mjs.map +7 -0
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -21
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +1 -1
- package/src/index.ts +0 -1
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AiSession,
|
|
3
|
+
ArtifactDiffResolver,
|
|
4
|
+
VersionPin
|
|
5
|
+
} from "./chunk-SIXTNSGV.mjs";
|
|
6
|
+
|
|
1
7
|
// src/context/binder.ts
|
|
2
8
|
import { computed } from "@preact/signals-core";
|
|
3
9
|
import { Array as Array2, pipe } from "effect";
|
|
@@ -95,272 +101,26 @@ var Bindings = class {
|
|
|
95
101
|
};
|
|
96
102
|
|
|
97
103
|
// src/conversation/conversation.ts
|
|
98
|
-
import { Effect
|
|
99
|
-
import { Event as Event2 } from "@dxos/async";
|
|
100
|
-
import { Obj as Obj3 } from "@dxos/echo";
|
|
101
|
-
import { DatabaseService as DatabaseService2 } from "@dxos/functions";
|
|
102
|
-
import { DataType as DataType2 } from "@dxos/schema";
|
|
103
|
-
|
|
104
|
-
// src/session/session.ts
|
|
105
|
-
import { AiLanguageModel, AiToolkit } from "@effect/ai";
|
|
106
|
-
import { Chunk, Context, Effect, Option, pipe as pipe2, Stream } from "effect";
|
|
107
|
-
import { Array as Array3, String } from "effect";
|
|
108
|
-
import { AiParser, AiPreprocessor, getToolCalls, runTool, ToolExecutionService, ToolResolverService } from "@dxos/ai";
|
|
104
|
+
import { Effect } from "effect";
|
|
109
105
|
import { Event } from "@dxos/async";
|
|
110
|
-
import { todo } from "@dxos/debug";
|
|
111
106
|
import { Obj as Obj2 } from "@dxos/echo";
|
|
112
|
-
import { ObjectVersion } from "@dxos/echo-db";
|
|
113
107
|
import { DatabaseService } from "@dxos/functions";
|
|
114
|
-
import { log } from "@dxos/log";
|
|
115
108
|
import { DataType } from "@dxos/schema";
|
|
116
|
-
|
|
117
|
-
// src/errors.ts
|
|
118
|
-
import { BaseError } from "@dxos/errors";
|
|
119
|
-
var AiAssistantError = class extends BaseError.extend("AI_ASSISTANT_ERROR") {
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
// src/session/session.ts
|
|
123
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant/src/session/session.ts";
|
|
124
|
-
var AiSession = class {
|
|
125
|
-
constructor(_options = {}) {
|
|
126
|
-
this._options = _options;
|
|
127
|
-
this._semaphore = Effect.runSync(Effect.makeSemaphore(1));
|
|
128
|
-
this._pending = [];
|
|
129
|
-
this._history = [];
|
|
130
|
-
this.message = new Event();
|
|
131
|
-
this.block = new Event();
|
|
132
|
-
this.update = new Event();
|
|
133
|
-
this.streamEvent = new Event();
|
|
134
|
-
this.userMessage = new Event();
|
|
135
|
-
this.statusReport = new Event();
|
|
136
|
-
this.done = new Event();
|
|
137
|
-
this.run = (options) => Effect.gen(this, function* () {
|
|
138
|
-
this._history = [
|
|
139
|
-
...options.history
|
|
140
|
-
];
|
|
141
|
-
const promptMessages = yield* this._formatUserPrompt(options.prompt, options.history);
|
|
142
|
-
this._pending = [
|
|
143
|
-
promptMessages
|
|
144
|
-
];
|
|
145
|
-
this.userMessage.emit(promptMessages);
|
|
146
|
-
do {
|
|
147
|
-
log("request", {
|
|
148
|
-
pending: this._pending.length,
|
|
149
|
-
history: this._history.length,
|
|
150
|
-
tools: Object.values(options.toolkit?.tools ?? {}).map((tool) => tool.name)
|
|
151
|
-
}, {
|
|
152
|
-
F: __dxlog_file,
|
|
153
|
-
L: 126,
|
|
154
|
-
S: this,
|
|
155
|
-
C: (f, a) => f(...a)
|
|
156
|
-
});
|
|
157
|
-
const prompt = yield* AiPreprocessor.preprocessAiInput([
|
|
158
|
-
...this._history,
|
|
159
|
-
...this._pending
|
|
160
|
-
]);
|
|
161
|
-
const blueprints = options.blueprints ?? [];
|
|
162
|
-
const systemPrompt = yield* pipe2(blueprints, Effect.forEach((blueprint) => Effect.succeed(blueprint.instructions)), Effect.flatMap(Effect.forEach((template) => DatabaseService.loadRef(template.source))), Effect.map(Array3.map((template) => `
|
|
163
|
-
|
|
164
|
-
<blueprint>${template.content}</blueprint>`)), Effect.map(Array3.reduce(options.systemPrompt ?? "", String.concat)));
|
|
165
|
-
const blueprintToolkit = yield* ToolResolverService.resolveToolkit(blueprints.flatMap((bp) => bp.tools));
|
|
166
|
-
const blueprintToolkitHandler = yield* blueprintToolkit.toContext(yield* ToolExecutionService.handlersFor(blueprintToolkit));
|
|
167
|
-
const toolkit = options.toolkit != null ? AiToolkit.merge(options.toolkit, blueprintToolkit) : blueprintToolkit;
|
|
168
|
-
const toolkitWithBlueprintHandlers = yield* toolkit.pipe(Effect.provide(blueprintToolkitHandler));
|
|
169
|
-
log.info("run", {
|
|
170
|
-
systemPrompt: [
|
|
171
|
-
systemPrompt.slice(0, 32),
|
|
172
|
-
"...",
|
|
173
|
-
systemPrompt.slice(-32),
|
|
174
|
-
systemPrompt.length
|
|
175
|
-
].join(" "),
|
|
176
|
-
tools: Object.keys(blueprintToolkit.tools)
|
|
177
|
-
}, {
|
|
178
|
-
F: __dxlog_file,
|
|
179
|
-
L: 155,
|
|
180
|
-
S: this,
|
|
181
|
-
C: (f, a) => f(...a)
|
|
182
|
-
});
|
|
183
|
-
const blocks = yield* AiLanguageModel.streamText({
|
|
184
|
-
prompt,
|
|
185
|
-
system: systemPrompt,
|
|
186
|
-
toolkit: toolkitWithBlueprintHandlers,
|
|
187
|
-
disableToolCallResolution: true
|
|
188
|
-
}).pipe(AiParser.parseGptStream({
|
|
189
|
-
onBlock: (block) => Effect.gen(this, function* () {
|
|
190
|
-
if (block.pending) {
|
|
191
|
-
this.update.emit(block);
|
|
192
|
-
} else {
|
|
193
|
-
this.block.emit(block);
|
|
194
|
-
}
|
|
195
|
-
}),
|
|
196
|
-
onPart: (part) => Effect.gen(this, function* () {
|
|
197
|
-
this.streamEvent.emit(part);
|
|
198
|
-
})
|
|
199
|
-
}), Stream.runCollect, Effect.map(Chunk.toArray));
|
|
200
|
-
const response = Obj2.make(DataType.Message, {
|
|
201
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
202
|
-
sender: {
|
|
203
|
-
role: "assistant"
|
|
204
|
-
},
|
|
205
|
-
blocks
|
|
206
|
-
});
|
|
207
|
-
this._pending.push(response);
|
|
208
|
-
this.message.emit(response);
|
|
209
|
-
const toolCalls = getToolCalls(response);
|
|
210
|
-
if (toolCalls.length === 0) {
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
const toolResults = yield* runTools(toolCalls, toolkitWithBlueprintHandlers);
|
|
214
|
-
this._pending.push(Obj2.make(DataType.Message, {
|
|
215
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
216
|
-
sender: {
|
|
217
|
-
role: "user"
|
|
218
|
-
},
|
|
219
|
-
blocks: toolResults
|
|
220
|
-
}));
|
|
221
|
-
} while (true);
|
|
222
|
-
return this._pending;
|
|
223
|
-
}).pipe(this._semaphore.withPermits(1), Effect.withSpan("AiSession.run"));
|
|
224
|
-
this._formatUserPrompt = (prompt, history) => Effect.gen(function* () {
|
|
225
|
-
const prelude = [];
|
|
226
|
-
const artifactDiffResolver = yield* Effect.serviceOption(ArtifactDiffResolver);
|
|
227
|
-
if (Option.isSome(artifactDiffResolver)) {
|
|
228
|
-
const versions = gatherObjectVersions(history);
|
|
229
|
-
const artifactDiff = yield* Effect.tryPromise({
|
|
230
|
-
try: () => artifactDiffResolver.value.resolve([
|
|
231
|
-
...versions.entries()
|
|
232
|
-
].map(([id, version]) => ({
|
|
233
|
-
id,
|
|
234
|
-
lastVersion: version
|
|
235
|
-
}))),
|
|
236
|
-
catch: AiAssistantError.wrap("Artifact diff resolution error")
|
|
237
|
-
});
|
|
238
|
-
log.info("vision", {
|
|
239
|
-
artifactDiff,
|
|
240
|
-
versions
|
|
241
|
-
}, {
|
|
242
|
-
F: __dxlog_file,
|
|
243
|
-
L: 240,
|
|
244
|
-
S: this,
|
|
245
|
-
C: (f, a) => f(...a)
|
|
246
|
-
});
|
|
247
|
-
for (const [id, { version }] of [
|
|
248
|
-
...artifactDiff.entries()
|
|
249
|
-
]) {
|
|
250
|
-
if (ObjectVersion.equals(version, versions.get(id))) {
|
|
251
|
-
artifactDiff.delete(id);
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
prelude.push({
|
|
255
|
-
_tag: "anchor",
|
|
256
|
-
objectId: id,
|
|
257
|
-
version
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
if (artifactDiff.size > 0) {
|
|
261
|
-
prelude.push(createArtifactUpdateBlock(artifactDiff));
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return Obj2.make(DataType.Message, {
|
|
265
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
266
|
-
sender: {
|
|
267
|
-
role: "user"
|
|
268
|
-
},
|
|
269
|
-
blocks: [
|
|
270
|
-
...prelude,
|
|
271
|
-
{
|
|
272
|
-
_tag: "text",
|
|
273
|
-
text: prompt
|
|
274
|
-
}
|
|
275
|
-
]
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
async runStructured(schema, options) {
|
|
280
|
-
return todo();
|
|
281
|
-
}
|
|
282
|
-
abort() {
|
|
283
|
-
this._stream?.abort();
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
var gatherObjectVersions = (messages) => {
|
|
287
|
-
const artifactIds = /* @__PURE__ */ new Map();
|
|
288
|
-
for (const message of messages) {
|
|
289
|
-
for (const block of message.blocks) {
|
|
290
|
-
if (block._tag === "anchor") {
|
|
291
|
-
artifactIds.set(block.objectId, block.version);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return artifactIds;
|
|
296
|
-
};
|
|
297
|
-
var createArtifactUpdateBlock = (artifactDiff) => {
|
|
298
|
-
return {
|
|
299
|
-
_tag: "text",
|
|
300
|
-
// TODO(dmaretskyi): Does this need to be a special content-block?
|
|
301
|
-
disposition: "artifact-update",
|
|
302
|
-
text: `
|
|
303
|
-
The following artifacts have been updated since the last message:
|
|
304
|
-
${[
|
|
305
|
-
...artifactDiff.entries()
|
|
306
|
-
].map(([id, { diff }]) => `<changed-artifact id="${id}">${diff ? `
|
|
307
|
-
${diff}` : ""}</changed-artifact>`).join("\n")}
|
|
308
|
-
`
|
|
309
|
-
};
|
|
310
|
-
};
|
|
311
|
-
var ArtifactDiffResolver = class extends Context.Tag("@dxos/assistant/ArtifactDiffResolver")() {
|
|
312
|
-
};
|
|
313
|
-
var runTools = Effect.fn("runTools")(function* (toolCalls, toolkit) {
|
|
314
|
-
const toolkitWithHandlers = Effect.isEffect(toolkit) ? yield* toolkit : toolkit;
|
|
315
|
-
return yield* Effect.forEach(toolCalls, (toolCall) => runTool(toolkitWithHandlers, toolCall));
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// src/session/version-pin.ts
|
|
319
|
-
import { Schema as Schema2 } from "effect";
|
|
320
|
-
import { getVersion } from "@dxos/echo-db";
|
|
321
|
-
import { ObjectId } from "@dxos/echo-schema";
|
|
322
|
-
var ObjectVersionSchema = Schema2.Unknown;
|
|
323
|
-
var VersionPinSchema = Schema2.Struct({
|
|
324
|
-
// TODO(dmaretskyi): Use Ref when those support encoding.
|
|
325
|
-
objectId: ObjectId,
|
|
326
|
-
// TODO(dmaretskyi): Could be opaque
|
|
327
|
-
version: ObjectVersionSchema
|
|
328
|
-
});
|
|
329
|
-
var VersionPin = class extends VersionPinSchema {
|
|
330
|
-
static {
|
|
331
|
-
this.DISPOSITION = "version-pin";
|
|
332
|
-
}
|
|
333
|
-
static fromObject(object) {
|
|
334
|
-
return VersionPin.make({
|
|
335
|
-
objectId: object.id,
|
|
336
|
-
version: getVersion(object)
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
static createBlock(pin) {
|
|
340
|
-
return {
|
|
341
|
-
_tag: "json",
|
|
342
|
-
disposition: VersionPin.DISPOSITION,
|
|
343
|
-
data: JSON.stringify(pin)
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// src/conversation/conversation.ts
|
|
349
109
|
var Conversation = class {
|
|
350
110
|
constructor(options) {
|
|
351
111
|
/**
|
|
352
112
|
* Fired when the execution loop begins.
|
|
353
113
|
* This is called before the first message is sent.
|
|
354
114
|
*/
|
|
355
|
-
this.onBegin = new
|
|
356
|
-
this.run = (options) =>
|
|
115
|
+
this.onBegin = new Event();
|
|
116
|
+
this.run = (options) => Effect.gen(this, function* () {
|
|
357
117
|
const session = new AiSession();
|
|
358
118
|
this.onBegin.emit(session);
|
|
359
|
-
const history = yield*
|
|
360
|
-
const context = yield*
|
|
361
|
-
const blueprints = yield*
|
|
362
|
-
const contextObjects = yield*
|
|
363
|
-
const systemPrompt = (options.systemPrompt ?? "") + "\n\n" + contextObjects.map((obj) => `<object>${
|
|
119
|
+
const history = yield* Effect.promise(() => this.getHistory());
|
|
120
|
+
const context = yield* Effect.promise(() => this.context.query());
|
|
121
|
+
const blueprints = yield* Effect.forEach(context.blueprints.values(), DatabaseService.loadRef);
|
|
122
|
+
const contextObjects = yield* Effect.forEach(context.objects.values(), DatabaseService.loadRef);
|
|
123
|
+
const systemPrompt = (options.systemPrompt ?? "") + "\n\n" + contextObjects.map((obj) => `<object>${Obj2.getDXN(obj)}</object>`).join("\n");
|
|
364
124
|
const messages = yield* session.run({
|
|
365
125
|
prompt: options.prompt,
|
|
366
126
|
history,
|
|
@@ -368,377 +128,49 @@ var Conversation = class {
|
|
|
368
128
|
toolkit: options.toolkit,
|
|
369
129
|
blueprints
|
|
370
130
|
});
|
|
371
|
-
yield*
|
|
131
|
+
yield* Effect.promise(() => this._queue.append(messages));
|
|
372
132
|
return messages;
|
|
373
|
-
}).pipe(
|
|
133
|
+
}).pipe(Effect.withSpan("Conversation.run"));
|
|
374
134
|
this._queue = options.queue;
|
|
375
135
|
this.context = new ContextBinder(this._queue);
|
|
376
136
|
}
|
|
377
137
|
async getHistory() {
|
|
378
138
|
const queueItems = await this._queue.queryObjects();
|
|
379
|
-
return queueItems.filter(
|
|
380
|
-
}
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
// src/extraction/extraction.ts
|
|
384
|
-
import { Schema as Schema3 } from "effect";
|
|
385
|
-
import { asyncTimeout } from "@dxos/async";
|
|
386
|
-
import { Expando } from "@dxos/echo-schema";
|
|
387
|
-
import { log as log2 } from "@dxos/log";
|
|
388
|
-
import { DataType as DataType3 } from "@dxos/schema";
|
|
389
|
-
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction.ts";
|
|
390
|
-
var ExtractionInput = Schema3.Struct({
|
|
391
|
-
message: DataType3.Message,
|
|
392
|
-
objects: Schema3.optional(Schema3.Array(Expando)),
|
|
393
|
-
options: Schema3.optional(Schema3.Struct({
|
|
394
|
-
timeout: Schema3.optional(Schema3.Number),
|
|
395
|
-
fallbackToRaw: Schema3.optional(Schema3.Boolean)
|
|
396
|
-
}))
|
|
397
|
-
});
|
|
398
|
-
var ExtractionOutput = Schema3.Struct({
|
|
399
|
-
message: DataType3.Message,
|
|
400
|
-
timeElapsed: Schema3.Number
|
|
401
|
-
});
|
|
402
|
-
var processTranscriptMessage = async (params) => {
|
|
403
|
-
try {
|
|
404
|
-
if (params.options?.timeout && params.options.timeout > 0) {
|
|
405
|
-
return await asyncTimeout(params.executor.invoke(params.function, params.input), params.options.timeout);
|
|
406
|
-
} else {
|
|
407
|
-
return await params.executor.invoke(params.function, params.input);
|
|
408
|
-
}
|
|
409
|
-
} catch (error) {
|
|
410
|
-
if (params.options?.fallbackToRaw) {
|
|
411
|
-
log2.warn("failed to process message, falling back to raw text", {
|
|
412
|
-
error
|
|
413
|
-
}, {
|
|
414
|
-
F: __dxlog_file2,
|
|
415
|
-
L: 66,
|
|
416
|
-
S: void 0,
|
|
417
|
-
C: (f, a) => f(...a)
|
|
418
|
-
});
|
|
419
|
-
return {
|
|
420
|
-
message: params.input.message,
|
|
421
|
-
timeElapsed: 0
|
|
422
|
-
};
|
|
423
|
-
} else {
|
|
424
|
-
throw error;
|
|
425
|
-
}
|
|
139
|
+
return queueItems.filter(Obj2.instanceOf(DataType.Message));
|
|
426
140
|
}
|
|
427
141
|
};
|
|
428
142
|
|
|
429
|
-
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
430
|
-
import { ToolRegistry, AiService } from "@dxos/ai";
|
|
431
|
-
import { Obj as Obj4 } from "@dxos/echo";
|
|
432
|
-
import { create } from "@dxos/echo-schema";
|
|
433
|
-
import { defineFunction } from "@dxos/functions";
|
|
434
|
-
import { DataType as DataType4 } from "@dxos/schema";
|
|
435
|
-
|
|
436
|
-
// raw-loader:./instructions.tpl?raw
|
|
437
|
-
var instructions_default = 'You are an AI assistant specialized in processing and enhancing transcripts with contextual information.\nYour task is to analyze a given transcript and extract references to the context objects.\n\nThe context and transcript are provided in the user message in `context` and `transcript` XML tags.\n\nHere are your instructions:\n\n1. Read the transcript and context information provided above.\n\n2. Process each segment of the transcript separately.\n\n3. For each segment:\n a. Analyze the content and identify relevant information from the context.\n b. Extract a number of references to the context objects that are mentioned in the segment.\n c. Output the references in the format `{ "quote": "earnings report", "id": "01JT0JP9AX0XKGZX4MV4B69VT6" }`.\n d. If there are no references, just output an empty array.\n\n4. Maintain the exact order and structure of the original transcript segments.\n\nOutput Format:\nYou have been provided with a tool that specifies output format\n\nRemember:\n- Only quote the text that is in the transcript.\n- Analyze each segment carefully before processing it.\n- Only reference objects that appear in the context and exactly by their id, If the object is not in the context, do not insert a reference. \n\nNow, process the transcript and context provided below according to these instructions.';
|
|
438
|
-
|
|
439
|
-
// src/extraction/quotes.ts
|
|
440
|
-
import { Schema as Schema4 } from "effect";
|
|
441
|
-
import { Query, Filter } from "@dxos/echo";
|
|
442
|
-
import { ObjectId as ObjectId2 } from "@dxos/echo-schema";
|
|
443
|
-
import { DXN } from "@dxos/keys";
|
|
444
|
-
import { log as log3 } from "@dxos/log";
|
|
445
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/quotes.ts";
|
|
446
|
-
var ReferencedQuotes = Schema4.Struct({
|
|
447
|
-
references: Schema4.Array(Schema4.Struct({
|
|
448
|
-
id: Schema4.String,
|
|
449
|
-
quote: Schema4.String
|
|
450
|
-
})).pipe(Schema4.mutable).annotations({
|
|
451
|
-
// TODO(burdon): Does this description make sense?
|
|
452
|
-
description: `
|
|
453
|
-
The references to the context objects that are mentioned in the transcript.
|
|
454
|
-
Quote should match the original transcript text exactly, while id is the id of the context object.
|
|
455
|
-
`
|
|
456
|
-
})
|
|
457
|
-
});
|
|
458
|
-
var findQuotes = async (quotes, db) => {
|
|
459
|
-
const references = await Promise.all(quotes.map(async (quote) => {
|
|
460
|
-
const { objects } = await db.query(Query.select(Filter.text(quote, {
|
|
461
|
-
type: "vector"
|
|
462
|
-
}))).run();
|
|
463
|
-
log3.info("found quotes in vector index", {
|
|
464
|
-
objects,
|
|
465
|
-
quote
|
|
466
|
-
}, {
|
|
467
|
-
F: __dxlog_file3,
|
|
468
|
-
L: 35,
|
|
469
|
-
S: void 0,
|
|
470
|
-
C: (f, a) => f(...a)
|
|
471
|
-
});
|
|
472
|
-
return objects.length > 0 ? [
|
|
473
|
-
{
|
|
474
|
-
id: objects[0].id.toString(),
|
|
475
|
-
quote
|
|
476
|
-
}
|
|
477
|
-
] : [];
|
|
478
|
-
}));
|
|
479
|
-
return {
|
|
480
|
-
references: references.flat()
|
|
481
|
-
};
|
|
482
|
-
};
|
|
483
|
-
var insertReferences = (text, quotes) => {
|
|
484
|
-
for (const quote of quotes.references) {
|
|
485
|
-
if (!ObjectId2.isValid(quote.id)) {
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
const regex = new RegExp(quote.quote.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
489
|
-
text = text.replace(regex, `[${quote.quote}][${DXN.fromLocalObjectId(quote.id).toString()}]`);
|
|
490
|
-
}
|
|
491
|
-
return text;
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
495
|
-
var extractionAnthropicFn = defineFunction({
|
|
496
|
-
description: "Extract entities from the transcript message and add them to the message.",
|
|
497
|
-
inputSchema: ExtractionInput,
|
|
498
|
-
outputSchema: ExtractionOutput,
|
|
499
|
-
handler: async ({ data: { message, objects }, context }) => {
|
|
500
|
-
const startTime = performance.now();
|
|
501
|
-
const ai = context.getService(AiService);
|
|
502
|
-
const session = new AiSession({
|
|
503
|
-
operationModel: "configured"
|
|
504
|
-
});
|
|
505
|
-
const result = await session.runStructured(ReferencedQuotes, {
|
|
506
|
-
generationOptions: {
|
|
507
|
-
model: "@anthropic/claude-3-5-haiku-20241022"
|
|
508
|
-
},
|
|
509
|
-
client: ai.client,
|
|
510
|
-
systemPrompt: instructions_default,
|
|
511
|
-
history: [
|
|
512
|
-
Obj4.make(DataType4.Message, {
|
|
513
|
-
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
514
|
-
sender: {
|
|
515
|
-
role: "user"
|
|
516
|
-
},
|
|
517
|
-
blocks: [
|
|
518
|
-
{
|
|
519
|
-
_tag: "text",
|
|
520
|
-
text: `<context>${JSON.stringify(objects)}</context>`
|
|
521
|
-
},
|
|
522
|
-
{
|
|
523
|
-
_tag: "text",
|
|
524
|
-
text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`
|
|
525
|
-
}
|
|
526
|
-
]
|
|
527
|
-
})
|
|
528
|
-
],
|
|
529
|
-
artifacts: [],
|
|
530
|
-
prompt: "",
|
|
531
|
-
tools: [],
|
|
532
|
-
toolResolver: new ToolRegistry([])
|
|
533
|
-
});
|
|
534
|
-
return {
|
|
535
|
-
message: create(DataType4.Message, {
|
|
536
|
-
...message,
|
|
537
|
-
blocks: message.blocks.map((block, i) => block._tag !== "transcript" ? block : {
|
|
538
|
-
...block,
|
|
539
|
-
text: insertReferences(block.text, result)
|
|
540
|
-
})
|
|
541
|
-
}),
|
|
542
|
-
timeElapsed: performance.now() - startTime
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
548
|
-
import { asyncTimeout as asyncTimeout2 } from "@dxos/async";
|
|
549
|
-
import { create as create2 } from "@dxos/echo-schema";
|
|
550
|
-
import { DatabaseService as DatabaseService3, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
551
|
-
import { invariant } from "@dxos/invariant";
|
|
552
|
-
import { log as log5 } from "@dxos/log";
|
|
553
|
-
import { DataType as DataType5 } from "@dxos/schema";
|
|
554
|
-
|
|
555
|
-
// src/extraction/extraction-ner-function/named-entity-recognition.ts
|
|
556
|
-
import { pipeline } from "@xenova/transformers";
|
|
557
|
-
import { log as log4 } from "@dxos/log";
|
|
558
|
-
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/named-entity-recognition.ts";
|
|
559
|
-
var _ner;
|
|
560
|
-
var getNer = () => {
|
|
561
|
-
if (!_ner) {
|
|
562
|
-
_ner = pipeline("ner", "Xenova/bert-base-NER").then((ner) => {
|
|
563
|
-
log4.info("NER model is ready", void 0, {
|
|
564
|
-
F: __dxlog_file4,
|
|
565
|
-
L: 23,
|
|
566
|
-
S: void 0,
|
|
567
|
-
C: (f, a) => f(...a)
|
|
568
|
-
});
|
|
569
|
-
return ner;
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
return _ner;
|
|
573
|
-
};
|
|
574
|
-
var extractFullEntities = async (text) => {
|
|
575
|
-
const ner = await getNer();
|
|
576
|
-
const entities = await ner(text);
|
|
577
|
-
const tokenGroups = createTokenGroups(entities);
|
|
578
|
-
const combinedEntities = tokenGroups.map(combineNerTokens);
|
|
579
|
-
return combinedEntities;
|
|
580
|
-
};
|
|
581
|
-
var createTokenGroups = (tokens) => {
|
|
582
|
-
const tokenGroups = [];
|
|
583
|
-
const canBeCombined = (prevToken, currentToken) => {
|
|
584
|
-
const [currentState, currentEntity] = currentToken.entity.split("-");
|
|
585
|
-
const [prevState, prevEntity] = prevToken.entity.split("-");
|
|
586
|
-
if (prevEntity !== currentEntity) {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
|
-
if (prevState === "O") {
|
|
590
|
-
return false;
|
|
591
|
-
}
|
|
592
|
-
if (currentState === "I") {
|
|
593
|
-
return true;
|
|
594
|
-
}
|
|
595
|
-
if ((prevState === "B" || prevState === "I") && currentState === "B") {
|
|
596
|
-
return currentToken.word.startsWith("#");
|
|
597
|
-
}
|
|
598
|
-
return false;
|
|
599
|
-
};
|
|
600
|
-
for (const token of tokens) {
|
|
601
|
-
if (tokenGroups.length === 0) {
|
|
602
|
-
tokenGroups.push([
|
|
603
|
-
token
|
|
604
|
-
]);
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
|
-
const lastTokenGroup = tokenGroups.at(-1);
|
|
608
|
-
if (canBeCombined(lastTokenGroup.at(-1), token)) {
|
|
609
|
-
lastTokenGroup.push(token);
|
|
610
|
-
continue;
|
|
611
|
-
}
|
|
612
|
-
tokenGroups.push([
|
|
613
|
-
token
|
|
614
|
-
]);
|
|
615
|
-
}
|
|
616
|
-
return tokenGroups;
|
|
617
|
-
};
|
|
618
|
-
var combineNerTokens = (group) => {
|
|
619
|
-
const combinedToken = {
|
|
620
|
-
entity: group.at(0).entity.split("-")[1],
|
|
621
|
-
score: group.reduce((acc, token) => acc + token.score, 0) / group.length,
|
|
622
|
-
index: group.at(0).index,
|
|
623
|
-
word: group.at(0).word,
|
|
624
|
-
start: group.at(0).start,
|
|
625
|
-
end: group.at(-1).end
|
|
626
|
-
};
|
|
627
|
-
for (const token of group.slice(1)) {
|
|
628
|
-
if (token.word.startsWith("#")) {
|
|
629
|
-
combinedToken.word += token.word.replace(/^#+/, "");
|
|
630
|
-
} else {
|
|
631
|
-
combinedToken.word += " " + token.word;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
return combinedToken;
|
|
635
|
-
};
|
|
636
|
-
|
|
637
|
-
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
638
|
-
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/extraction-ner-function.ts";
|
|
639
|
-
var extractionNerFn = defineFunction2({
|
|
640
|
-
description: "Extracts named entities from a text",
|
|
641
|
-
inputSchema: ExtractionInput,
|
|
642
|
-
outputSchema: ExtractionOutput,
|
|
643
|
-
handler: async ({ data: { message, options }, context }) => {
|
|
644
|
-
log5.info("input", {
|
|
645
|
-
message,
|
|
646
|
-
options
|
|
647
|
-
}, {
|
|
648
|
-
F: __dxlog_file5,
|
|
649
|
-
L: 25,
|
|
650
|
-
S: void 0,
|
|
651
|
-
C: (f, a) => f(...a)
|
|
652
|
-
});
|
|
653
|
-
const startTime = performance.now();
|
|
654
|
-
const { db } = context.getService(DatabaseService3);
|
|
655
|
-
const entitiesPromise = Promise.all(message.blocks.map(async (block) => {
|
|
656
|
-
invariant(block._tag === "transcript" || block._tag === "text", "Block must have text", {
|
|
657
|
-
F: __dxlog_file5,
|
|
658
|
-
L: 31,
|
|
659
|
-
S: void 0,
|
|
660
|
-
A: [
|
|
661
|
-
"block._tag === 'transcript' || block._tag === 'text'",
|
|
662
|
-
"'Block must have text'"
|
|
663
|
-
]
|
|
664
|
-
});
|
|
665
|
-
return extractFullEntities(block.text);
|
|
666
|
-
})).then((entities2) => entities2.flat());
|
|
667
|
-
const entities = options?.timeout ? await asyncTimeout2(entitiesPromise, options.timeout) : await entitiesPromise;
|
|
668
|
-
log5.info("entities", {
|
|
669
|
-
entities
|
|
670
|
-
}, {
|
|
671
|
-
F: __dxlog_file5,
|
|
672
|
-
L: 36,
|
|
673
|
-
S: void 0,
|
|
674
|
-
C: (f, a) => f(...a)
|
|
675
|
-
});
|
|
676
|
-
const quoteReferences = await findQuotes(entities.map((entity) => entity.word), db);
|
|
677
|
-
const blocksWithReferences = message.blocks.map((block, i) => {
|
|
678
|
-
invariant(block._tag === "transcript" || block._tag === "text", "Block must have text", {
|
|
679
|
-
F: __dxlog_file5,
|
|
680
|
-
L: 42,
|
|
681
|
-
S: void 0,
|
|
682
|
-
A: [
|
|
683
|
-
"block._tag === 'transcript' || block._tag === 'text'",
|
|
684
|
-
"'Block must have text'"
|
|
685
|
-
]
|
|
686
|
-
});
|
|
687
|
-
return {
|
|
688
|
-
...block,
|
|
689
|
-
text: insertReferences(block._tag, quoteReferences)
|
|
690
|
-
};
|
|
691
|
-
});
|
|
692
|
-
const messageWithReferences = create2(DataType5.Message, {
|
|
693
|
-
...message,
|
|
694
|
-
blocks: blocksWithReferences
|
|
695
|
-
});
|
|
696
|
-
log5.info("output", {
|
|
697
|
-
messageWithReferences
|
|
698
|
-
}, {
|
|
699
|
-
F: __dxlog_file5,
|
|
700
|
-
L: 50,
|
|
701
|
-
S: void 0,
|
|
702
|
-
C: (f, a) => f(...a)
|
|
703
|
-
});
|
|
704
|
-
return {
|
|
705
|
-
message: messageWithReferences,
|
|
706
|
-
timeElapsed: performance.now() - startTime
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
|
|
711
143
|
// src/functions/services.ts
|
|
712
144
|
import { AiTool } from "@effect/ai";
|
|
713
|
-
import { Context
|
|
714
|
-
import { AiToolNotFoundError, ToolExecutionService
|
|
145
|
+
import { Context, Effect as Effect2, Layer, Match, Predicate, Record, Schema as Schema2 } from "effect";
|
|
146
|
+
import { AiToolNotFoundError, ToolExecutionService, ToolResolverService } from "@dxos/ai";
|
|
715
147
|
import { LocalFunctionExecutionService } from "@dxos/functions";
|
|
716
|
-
import { invariant
|
|
717
|
-
var
|
|
148
|
+
import { invariant } from "@dxos/invariant";
|
|
149
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant/src/functions/services.ts";
|
|
718
150
|
var makeToolResolverFromFunctions = (functions) => {
|
|
719
|
-
return Layer.succeed(
|
|
720
|
-
resolve:
|
|
151
|
+
return Layer.succeed(ToolResolverService, {
|
|
152
|
+
resolve: Effect2.fn("resolveTool")(function* (id) {
|
|
721
153
|
const fn = functions.find((f) => f.name === id);
|
|
722
154
|
if (!fn) {
|
|
723
|
-
return yield*
|
|
155
|
+
return yield* Effect2.fail(new AiToolNotFoundError(id));
|
|
724
156
|
}
|
|
725
157
|
return projectFunctionToTool(fn);
|
|
726
158
|
})
|
|
727
159
|
});
|
|
728
160
|
};
|
|
729
161
|
var makeToolExecutionServiceFromFunctions = (functions) => {
|
|
730
|
-
return Layer.effect(
|
|
162
|
+
return Layer.effect(ToolExecutionService, Effect2.gen(function* () {
|
|
731
163
|
const localFunctionExecutionService = yield* LocalFunctionExecutionService;
|
|
732
164
|
return {
|
|
733
165
|
handlersFor: (toolkit) => {
|
|
734
166
|
const makeHandler = (tool) => {
|
|
735
|
-
return
|
|
736
|
-
const { functionName } =
|
|
167
|
+
return Effect2.fn("toolFunctionHandler")(function* (input) {
|
|
168
|
+
const { functionName } = Context.get(FunctionToolAnnotation)(tool.annotations);
|
|
737
169
|
const fnDef = functions.find((f) => f.name === functionName);
|
|
738
170
|
if (!fnDef) {
|
|
739
|
-
return yield*
|
|
171
|
+
return yield* Effect2.fail(new AiToolNotFoundError(tool.name));
|
|
740
172
|
}
|
|
741
|
-
return yield* localFunctionExecutionService.invokeFunction(fnDef, input).pipe(
|
|
173
|
+
return yield* localFunctionExecutionService.invokeFunction(fnDef, input).pipe(Effect2.catchAllDefect((defect) => Effect2.fail(defect)));
|
|
742
174
|
});
|
|
743
175
|
};
|
|
744
176
|
return toolkit.of(Record.map(toolkit.tools, (tool, name) => makeHandler(tool)));
|
|
@@ -746,7 +178,7 @@ var makeToolExecutionServiceFromFunctions = (functions) => {
|
|
|
746
178
|
};
|
|
747
179
|
}));
|
|
748
180
|
};
|
|
749
|
-
var FunctionToolAnnotation = class extends
|
|
181
|
+
var FunctionToolAnnotation = class extends Context.Tag("@dxos/assisatnt/FunctionToolAnnotation")() {
|
|
750
182
|
};
|
|
751
183
|
var toolCache = /* @__PURE__ */ new WeakMap();
|
|
752
184
|
var projectFunctionToTool = (fn) => {
|
|
@@ -757,7 +189,7 @@ var projectFunctionToTool = (fn) => {
|
|
|
757
189
|
description: fn.description,
|
|
758
190
|
parameters: createStructFieldsFromSchema(fn.inputSchema),
|
|
759
191
|
// TODO(dmaretskyi): Include output schema.
|
|
760
|
-
failure:
|
|
192
|
+
failure: Schema2.Any
|
|
761
193
|
}).annotate(FunctionToolAnnotation, {
|
|
762
194
|
functionName: fn.name
|
|
763
195
|
});
|
|
@@ -766,8 +198,8 @@ var projectFunctionToTool = (fn) => {
|
|
|
766
198
|
};
|
|
767
199
|
var makeToolName = (name) => {
|
|
768
200
|
const toolName = name.replace(/[^a-zA-Z0-9]/g, "");
|
|
769
|
-
|
|
770
|
-
F:
|
|
201
|
+
invariant(toolName.match(/^[a-zA-Z_][a-zA-Z0-9-_]*$/), void 0, {
|
|
202
|
+
F: __dxlog_file,
|
|
771
203
|
L: 87,
|
|
772
204
|
S: void 0,
|
|
773
205
|
A: [
|
|
@@ -781,17 +213,17 @@ var createStructFieldsFromSchema = (schema) => {
|
|
|
781
213
|
return Match.value(schema.ast).pipe(Match.when(Predicate.isTagged("TypeLiteral"), (ast) => {
|
|
782
214
|
return Object.fromEntries(ast.propertySignatures.map((prop) => [
|
|
783
215
|
prop.name,
|
|
784
|
-
|
|
216
|
+
Schema2.make(prop.type)
|
|
785
217
|
]));
|
|
786
218
|
}), Match.orElseAbsurd);
|
|
787
219
|
};
|
|
788
220
|
|
|
789
221
|
// src/research/exa.ts
|
|
790
|
-
import { AiTool as AiTool2, AiToolkit
|
|
791
|
-
import { Effect as
|
|
222
|
+
import { AiTool as AiTool2, AiToolkit } from "@effect/ai";
|
|
223
|
+
import { Effect as Effect3, Schema as Schema3 } from "effect";
|
|
792
224
|
import Exa from "exa-js";
|
|
793
225
|
import { CredentialsService } from "@dxos/functions";
|
|
794
|
-
import { log
|
|
226
|
+
import { log } from "@dxos/log";
|
|
795
227
|
|
|
796
228
|
// src/testing/exa-search-1748337321991.ts
|
|
797
229
|
var exa_search_1748337321991_default = {
|
|
@@ -1303,36 +735,36 @@ var SEARCH_RESULTS = [
|
|
|
1303
735
|
];
|
|
1304
736
|
|
|
1305
737
|
// src/research/exa.ts
|
|
1306
|
-
var
|
|
1307
|
-
var ExaToolkit = class extends
|
|
738
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant/src/research/exa.ts";
|
|
739
|
+
var ExaToolkit = class extends AiToolkit.make(AiTool2.make("exa_search", {
|
|
1308
740
|
description: "Search the web for information",
|
|
1309
741
|
parameters: {
|
|
1310
|
-
query:
|
|
742
|
+
query: Schema3.String.annotations({
|
|
1311
743
|
description: "The query to search for"
|
|
1312
744
|
})
|
|
1313
745
|
},
|
|
1314
|
-
success:
|
|
1315
|
-
failure:
|
|
746
|
+
success: Schema3.Unknown,
|
|
747
|
+
failure: Schema3.Never
|
|
1316
748
|
}).addRequirement()) {
|
|
1317
749
|
};
|
|
1318
750
|
var LiveExaHandler = ExaToolkit.toLayer({
|
|
1319
|
-
exa_search:
|
|
751
|
+
exa_search: Effect3.fn(function* ({ query }) {
|
|
1320
752
|
const credential = yield* CredentialsService.getCredential({
|
|
1321
753
|
service: "exa.ai"
|
|
1322
754
|
});
|
|
1323
755
|
const exa = new Exa(credential.apiKey);
|
|
1324
|
-
const context = yield*
|
|
756
|
+
const context = yield* Effect3.promise(async () => exa.searchAndContents(query, {
|
|
1325
757
|
type: "auto",
|
|
1326
758
|
text: {
|
|
1327
759
|
maxCharacters: 3e3
|
|
1328
760
|
},
|
|
1329
761
|
livecrawl: "always"
|
|
1330
762
|
}));
|
|
1331
|
-
|
|
763
|
+
log.info("exa search", {
|
|
1332
764
|
query,
|
|
1333
765
|
costDollars: context.costDollars
|
|
1334
766
|
}, {
|
|
1335
|
-
F:
|
|
767
|
+
F: __dxlog_file2,
|
|
1336
768
|
L: 40,
|
|
1337
769
|
S: this,
|
|
1338
770
|
C: (f, a) => f(...a)
|
|
@@ -1341,7 +773,7 @@ var LiveExaHandler = ExaToolkit.toLayer({
|
|
|
1341
773
|
})
|
|
1342
774
|
});
|
|
1343
775
|
var MockExaHandler = ExaToolkit.toLayer({
|
|
1344
|
-
exa_search:
|
|
776
|
+
exa_search: Effect3.fn(function* ({ query }) {
|
|
1345
777
|
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1346
778
|
if (!current.autopromptString) {
|
|
1347
779
|
return closest;
|
|
@@ -1377,28 +809,28 @@ var levenshteinDistance = (str1, str2) => {
|
|
|
1377
809
|
};
|
|
1378
810
|
|
|
1379
811
|
// src/research/research.ts
|
|
1380
|
-
import { AiToolkit as
|
|
1381
|
-
import { Effect as
|
|
1382
|
-
import { AiService
|
|
1383
|
-
import { defineFunction
|
|
1384
|
-
import { log as
|
|
812
|
+
import { AiToolkit as AiToolkit3 } from "@effect/ai";
|
|
813
|
+
import { Effect as Effect5, Layer as Layer2, Schema as Schema5 } from "effect";
|
|
814
|
+
import { AiService, ConsolePrinter } from "@dxos/ai";
|
|
815
|
+
import { defineFunction, TracingService } from "@dxos/functions";
|
|
816
|
+
import { log as log3 } from "@dxos/log";
|
|
1385
817
|
import { DataTypes } from "@dxos/schema";
|
|
1386
818
|
|
|
1387
819
|
// src/research/graph.ts
|
|
1388
|
-
import { AiTool as AiTool3, AiToolkit as
|
|
1389
|
-
import { Context as
|
|
1390
|
-
import { Filter
|
|
820
|
+
import { AiTool as AiTool3, AiToolkit as AiToolkit2 } from "@effect/ai";
|
|
821
|
+
import { Context as Context2, Effect as Effect4, identity, Option, Schema as Schema4, SchemaAST } from "effect";
|
|
822
|
+
import { Filter, Query } from "@dxos/echo";
|
|
1391
823
|
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
1392
|
-
import { create
|
|
824
|
+
import { create, EntityKind, getEntityKind, getSchemaDXN, getSchemaTypename, getTypeAnnotation, getTypeIdentifierAnnotation, ObjectId, ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId } from "@dxos/echo-schema";
|
|
1393
825
|
import { mapAst } from "@dxos/effect";
|
|
1394
|
-
import { ContextQueueService, DatabaseService as
|
|
1395
|
-
import { DXN
|
|
1396
|
-
import { log as
|
|
826
|
+
import { ContextQueueService, DatabaseService as DatabaseService2 } from "@dxos/functions";
|
|
827
|
+
import { DXN } from "@dxos/keys";
|
|
828
|
+
import { log as log2 } from "@dxos/log";
|
|
1397
829
|
import { deepMapValues, isNonNullable } from "@dxos/util";
|
|
1398
|
-
var
|
|
1399
|
-
var Subgraph =
|
|
830
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant/src/research/graph.ts";
|
|
831
|
+
var Subgraph = Schema4.Struct({
|
|
1400
832
|
/** Objects and relations. */
|
|
1401
|
-
objects:
|
|
833
|
+
objects: Schema4.Array(Schema4.Any)
|
|
1402
834
|
});
|
|
1403
835
|
var findRelatedSchema = async (db, anchor) => {
|
|
1404
836
|
const allSchemas = [
|
|
@@ -1408,7 +840,7 @@ var findRelatedSchema = async (db, anchor) => {
|
|
|
1408
840
|
if (getTypeAnnotation(schema)?.kind !== EntityKind.Relation) {
|
|
1409
841
|
return false;
|
|
1410
842
|
}
|
|
1411
|
-
return isSchemaAddressableByDxn(anchor,
|
|
843
|
+
return isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).sourceSchema)) || isSchemaAddressableByDxn(anchor, DXN.parse(getTypeAnnotation(schema).targetSchema));
|
|
1412
844
|
}).map((schema) => ({
|
|
1413
845
|
schema,
|
|
1414
846
|
kind: "relation"
|
|
@@ -1424,28 +856,28 @@ var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
|
1424
856
|
}
|
|
1425
857
|
return false;
|
|
1426
858
|
};
|
|
1427
|
-
var LocalSearchToolkit = class extends
|
|
859
|
+
var LocalSearchToolkit = class extends AiToolkit2.make(AiTool3.make("search_local_search", {
|
|
1428
860
|
description: "Search the local database for information using a vector index",
|
|
1429
861
|
parameters: {
|
|
1430
|
-
query:
|
|
862
|
+
query: Schema4.String.annotations({
|
|
1431
863
|
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
1432
864
|
})
|
|
1433
865
|
},
|
|
1434
|
-
success:
|
|
1435
|
-
failure:
|
|
866
|
+
success: Schema4.Unknown,
|
|
867
|
+
failure: Schema4.Never
|
|
1436
868
|
}).addRequirement()) {
|
|
1437
869
|
};
|
|
1438
870
|
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
1439
|
-
search_local_search:
|
|
1440
|
-
const { objects } = yield*
|
|
871
|
+
search_local_search: Effect4.fn(function* ({ query }) {
|
|
872
|
+
const { objects } = yield* DatabaseService2.runQuery(Query.select(Filter.text(query, {
|
|
1441
873
|
type: "vector"
|
|
1442
874
|
})));
|
|
1443
875
|
const results = [
|
|
1444
876
|
...objects
|
|
1445
877
|
];
|
|
1446
|
-
const contextQueue = yield*
|
|
1447
|
-
if (
|
|
1448
|
-
const queueObjects = yield*
|
|
878
|
+
const contextQueue = yield* Effect4.serviceOption(ContextQueueService);
|
|
879
|
+
if (Option.isSome(contextQueue)) {
|
|
880
|
+
const queueObjects = yield* Effect4.promise(() => contextQueue.value.contextQueue.queryObjects());
|
|
1449
881
|
results.push(...queueObjects);
|
|
1450
882
|
}
|
|
1451
883
|
return `
|
|
@@ -1455,35 +887,35 @@ var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
|
1455
887
|
`;
|
|
1456
888
|
})
|
|
1457
889
|
});
|
|
1458
|
-
var GraphWriterSchema = class extends
|
|
890
|
+
var GraphWriterSchema = class extends Context2.Tag("@dxos/assistant/GraphWriterSchema")() {
|
|
1459
891
|
};
|
|
1460
892
|
var makeGraphWriterToolkit = ({ schema }) => {
|
|
1461
|
-
return
|
|
893
|
+
return AiToolkit2.make(AiTool3.make("graph_writer", {
|
|
1462
894
|
description: "Write to the local graph database",
|
|
1463
895
|
parameters: createExtractionSchema(schema).fields,
|
|
1464
|
-
success:
|
|
1465
|
-
failure:
|
|
1466
|
-
}).addRequirement().annotateContext(
|
|
896
|
+
success: Schema4.Unknown,
|
|
897
|
+
failure: Schema4.Never
|
|
898
|
+
}).addRequirement().annotateContext(Context2.make(GraphWriterSchema, {
|
|
1467
899
|
schema
|
|
1468
900
|
})));
|
|
1469
901
|
};
|
|
1470
902
|
var makeGraphWriterHandler = (toolkit) => {
|
|
1471
|
-
const { schema } =
|
|
903
|
+
const { schema } = Context2.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
1472
904
|
return toolkit.toLayer({
|
|
1473
|
-
graph_writer:
|
|
1474
|
-
const { db } = yield*
|
|
1475
|
-
const contextQueue = yield*
|
|
1476
|
-
const data = yield*
|
|
905
|
+
graph_writer: Effect4.fn(function* (input) {
|
|
906
|
+
const { db } = yield* DatabaseService2;
|
|
907
|
+
const contextQueue = yield* Effect4.serviceOption(ContextQueueService);
|
|
908
|
+
const data = yield* Effect4.promise(() => sanitizeObjects(schema, input, db, contextQueue.pipe(Option.getOrUndefined)?.contextQueue));
|
|
1477
909
|
return data;
|
|
1478
910
|
})
|
|
1479
911
|
});
|
|
1480
912
|
};
|
|
1481
913
|
var createExtractionSchema = (types) => {
|
|
1482
|
-
return
|
|
914
|
+
return Schema4.Struct({
|
|
1483
915
|
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
1484
916
|
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
1485
|
-
|
|
1486
|
-
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(
|
|
917
|
+
Schema4.optional(Schema4.Array(schema)).annotations({
|
|
918
|
+
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option.getOrElse(() => ""))}`
|
|
1487
919
|
})
|
|
1488
920
|
]))
|
|
1489
921
|
});
|
|
@@ -1500,21 +932,21 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1500
932
|
const existingIds = /* @__PURE__ */ new Set();
|
|
1501
933
|
const enitties = /* @__PURE__ */ new Map();
|
|
1502
934
|
const resolveId = (id) => {
|
|
1503
|
-
if (
|
|
935
|
+
if (ObjectId.isValid(id)) {
|
|
1504
936
|
existingIds.add(id);
|
|
1505
|
-
return
|
|
937
|
+
return DXN.fromLocalObjectId(id);
|
|
1506
938
|
}
|
|
1507
939
|
const mappedId = idMap.get(id);
|
|
1508
940
|
if (mappedId) {
|
|
1509
|
-
return
|
|
941
|
+
return DXN.fromLocalObjectId(mappedId);
|
|
1510
942
|
}
|
|
1511
943
|
return void 0;
|
|
1512
944
|
};
|
|
1513
945
|
const res = entries.map((entry) => {
|
|
1514
|
-
if (
|
|
946
|
+
if (ObjectId.isValid(entry.data.id)) {
|
|
1515
947
|
return entry;
|
|
1516
948
|
}
|
|
1517
|
-
idMap.set(entry.data.id,
|
|
949
|
+
idMap.set(entry.data.id, ObjectId.random());
|
|
1518
950
|
entry.data.id = idMap.get(entry.data.id);
|
|
1519
951
|
return entry;
|
|
1520
952
|
}).map((entry) => {
|
|
@@ -1537,10 +969,10 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1537
969
|
if (getEntityKind(entry.schema) === "relation") {
|
|
1538
970
|
const sourceDxn = resolveId(data2.source);
|
|
1539
971
|
if (!sourceDxn) {
|
|
1540
|
-
|
|
972
|
+
log2.warn("source not found", {
|
|
1541
973
|
source: data2.source
|
|
1542
974
|
}, {
|
|
1543
|
-
F:
|
|
975
|
+
F: __dxlog_file3,
|
|
1544
976
|
L: 262,
|
|
1545
977
|
S: void 0,
|
|
1546
978
|
C: (f, a) => f(...a)
|
|
@@ -1548,10 +980,10 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1548
980
|
}
|
|
1549
981
|
const targetDxn = resolveId(data2.target);
|
|
1550
982
|
if (!targetDxn) {
|
|
1551
|
-
|
|
983
|
+
log2.warn("target not found", {
|
|
1552
984
|
target: data2.target
|
|
1553
985
|
}, {
|
|
1554
|
-
F:
|
|
986
|
+
F: __dxlog_file3,
|
|
1555
987
|
L: 266,
|
|
1556
988
|
S: void 0,
|
|
1557
989
|
C: (f, a) => f(...a)
|
|
@@ -1567,7 +999,7 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1567
999
|
schema: entry.schema
|
|
1568
1000
|
};
|
|
1569
1001
|
}).filter((object) => !existingIds.has(object.data.id));
|
|
1570
|
-
const { objects: dbObjects } = await db.query(
|
|
1002
|
+
const { objects: dbObjects } = await db.query(Query.select(Filter.ids(...existingIds))).run();
|
|
1571
1003
|
const queueObjects = await queue?.getObjectsById([
|
|
1572
1004
|
...existingIds
|
|
1573
1005
|
]) ?? [];
|
|
@@ -1575,12 +1007,12 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1575
1007
|
...dbObjects,
|
|
1576
1008
|
...queueObjects
|
|
1577
1009
|
].filter(isNonNullable);
|
|
1578
|
-
|
|
1010
|
+
log2.info("objects", {
|
|
1579
1011
|
dbObjects,
|
|
1580
1012
|
queueObjects,
|
|
1581
1013
|
existingIds
|
|
1582
1014
|
}, {
|
|
1583
|
-
F:
|
|
1015
|
+
F: __dxlog_file3,
|
|
1584
1016
|
L: 287,
|
|
1585
1017
|
S: void 0,
|
|
1586
1018
|
C: (f, a) => f(...a)
|
|
@@ -1612,7 +1044,7 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1612
1044
|
}
|
|
1613
1045
|
}
|
|
1614
1046
|
if (!skip) {
|
|
1615
|
-
const obj =
|
|
1047
|
+
const obj = create(schema, data2);
|
|
1616
1048
|
enitties.set(obj.id, obj);
|
|
1617
1049
|
return [
|
|
1618
1050
|
obj
|
|
@@ -1621,8 +1053,8 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1621
1053
|
return [];
|
|
1622
1054
|
});
|
|
1623
1055
|
};
|
|
1624
|
-
var SoftRef =
|
|
1625
|
-
"/":
|
|
1056
|
+
var SoftRef = Schema4.Struct({
|
|
1057
|
+
"/": Schema4.String
|
|
1626
1058
|
}).annotations({
|
|
1627
1059
|
description: "Reference to another object."
|
|
1628
1060
|
});
|
|
@@ -1633,20 +1065,20 @@ var preprocessSchema = (schema) => {
|
|
|
1633
1065
|
return ast;
|
|
1634
1066
|
}
|
|
1635
1067
|
visited.add(ast);
|
|
1636
|
-
if (SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(
|
|
1068
|
+
if (SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(Option.isSome)) {
|
|
1637
1069
|
return SoftRef.ast;
|
|
1638
1070
|
}
|
|
1639
1071
|
return mapAst(ast, (child) => go(child, visited));
|
|
1640
1072
|
};
|
|
1641
|
-
return
|
|
1642
|
-
id:
|
|
1073
|
+
return Schema4.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema4.omit("id"), Schema4.extend(Schema4.Struct({
|
|
1074
|
+
id: Schema4.String.annotations({
|
|
1643
1075
|
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
1644
1076
|
})
|
|
1645
|
-
})), isRelationSchema ?
|
|
1646
|
-
source:
|
|
1077
|
+
})), isRelationSchema ? Schema4.extend(Schema4.Struct({
|
|
1078
|
+
source: Schema4.String.annotations({
|
|
1647
1079
|
description: "The id of the source object for this relation."
|
|
1648
1080
|
}),
|
|
1649
|
-
target:
|
|
1081
|
+
target: Schema4.String.annotations({
|
|
1650
1082
|
description: "The id of the target object for this relation."
|
|
1651
1083
|
})
|
|
1652
1084
|
})) : identity);
|
|
@@ -1656,39 +1088,39 @@ var preprocessSchema = (schema) => {
|
|
|
1656
1088
|
var instructions_research_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query (through a `web_search` tool)\n- Read the full content of retrieved pages\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n- Search the local database for information using a vector index (through a `local_search` tool)\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be delted, so only the data written to the graph will be preserved.\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent uses `web_search`(query) to retrieve information.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n\nIMPORTANT:\n\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>";
|
|
1657
1089
|
|
|
1658
1090
|
// src/research/research.ts
|
|
1659
|
-
var
|
|
1660
|
-
var researchFn =
|
|
1091
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant/src/research/research.ts";
|
|
1092
|
+
var researchFn = defineFunction({
|
|
1661
1093
|
description: "Research the web for information",
|
|
1662
|
-
inputSchema:
|
|
1663
|
-
query:
|
|
1094
|
+
inputSchema: Schema5.Struct({
|
|
1095
|
+
query: Schema5.String.annotations({
|
|
1664
1096
|
description: "The query to search for."
|
|
1665
1097
|
}),
|
|
1666
1098
|
// TOOD(burdon): Move to context.
|
|
1667
|
-
mockSearch:
|
|
1099
|
+
mockSearch: Schema5.optional(Schema5.Boolean).annotations({
|
|
1668
1100
|
description: "Whether to use the mock search tool.",
|
|
1669
1101
|
default: false
|
|
1670
1102
|
})
|
|
1671
1103
|
}),
|
|
1672
|
-
outputSchema:
|
|
1673
|
-
result:
|
|
1104
|
+
outputSchema: Schema5.Struct({
|
|
1105
|
+
result: Schema5.Unknown
|
|
1674
1106
|
}),
|
|
1675
|
-
handler:
|
|
1107
|
+
handler: Effect5.fnUntraced(function* ({ data: { query, mockSearch } }) {
|
|
1676
1108
|
yield* TracingService.emitStatus({
|
|
1677
1109
|
message: "Researching..."
|
|
1678
1110
|
});
|
|
1679
1111
|
const graphWriteToolkit = makeGraphWriterToolkit({
|
|
1680
1112
|
schema: DataTypes
|
|
1681
1113
|
});
|
|
1682
|
-
const toolkit = yield*
|
|
1114
|
+
const toolkit = yield* AiToolkit3.merge(ExaToolkit, LocalSearchToolkit, graphWriteToolkit).pipe(Effect5.provide(Layer2.mergeAll(mockSearch ? MockExaHandler : LiveExaHandler, LocalSearchHandler, makeGraphWriterHandler(graphWriteToolkit))));
|
|
1683
1115
|
const printer = new ConsolePrinter();
|
|
1684
1116
|
const session = new AiSession();
|
|
1685
1117
|
session.message.on((message) => printer.printMessage(message));
|
|
1686
1118
|
session.userMessage.on((message) => printer.printMessage(message));
|
|
1687
1119
|
session.block.on((block) => printer.printContentBlock(block));
|
|
1688
|
-
session.streamEvent.on((event) =>
|
|
1120
|
+
session.streamEvent.on((event) => log3("stream", {
|
|
1689
1121
|
event
|
|
1690
1122
|
}, {
|
|
1691
|
-
F:
|
|
1123
|
+
F: __dxlog_file4,
|
|
1692
1124
|
L: 62,
|
|
1693
1125
|
S: this,
|
|
1694
1126
|
C: (f, a) => f(...a)
|
|
@@ -1702,7 +1134,7 @@ var researchFn = defineFunction3({
|
|
|
1702
1134
|
return {
|
|
1703
1135
|
result
|
|
1704
1136
|
};
|
|
1705
|
-
},
|
|
1137
|
+
}, Effect5.provide(AiService.model("@anthropic/claude-3-5-sonnet-20241022")))
|
|
1706
1138
|
});
|
|
1707
1139
|
|
|
1708
1140
|
// src/templates/prompt.ts
|
|
@@ -1717,10 +1149,10 @@ var createSystemPrompt = (options) => {
|
|
|
1717
1149
|
};
|
|
1718
1150
|
|
|
1719
1151
|
// src/types.ts
|
|
1720
|
-
import { Schema as
|
|
1721
|
-
import { DXN as
|
|
1152
|
+
import { Schema as Schema6 } from "effect";
|
|
1153
|
+
import { DXN as DXN2, LOCAL_SPACE_TAG } from "@dxos/keys";
|
|
1722
1154
|
var createArtifactElement = (id) => `<artifact id=${id} />`;
|
|
1723
|
-
var ArtifactId = class extends
|
|
1155
|
+
var ArtifactId = class extends Schema6.String.annotations({
|
|
1724
1156
|
description: `
|
|
1725
1157
|
The ID of the referenced object. Formats accepted:
|
|
1726
1158
|
- DXN (dxn:echo:@:XXXXX). DXNs can be prepended with an @ symbol for compatibility with in-text references.
|
|
@@ -1736,17 +1168,17 @@ var ArtifactId = class extends Schema9.String.annotations({
|
|
|
1736
1168
|
}) {
|
|
1737
1169
|
static toDXN(reference, owningSpaceId) {
|
|
1738
1170
|
if (reference.startsWith("@dxn:")) {
|
|
1739
|
-
return
|
|
1171
|
+
return DXN2.parse(reference.slice(1));
|
|
1740
1172
|
} else if (reference.startsWith("dxn:")) {
|
|
1741
|
-
return
|
|
1173
|
+
return DXN2.parse(reference);
|
|
1742
1174
|
} else if (/^[A-Z0-9]+:[A-Z0-9]+$/.test(reference)) {
|
|
1743
1175
|
const [spaceId, objectId] = reference.split(":");
|
|
1744
|
-
return new
|
|
1176
|
+
return new DXN2(DXN2.kind.ECHO, [
|
|
1745
1177
|
spaceId === owningSpaceId ? LOCAL_SPACE_TAG : spaceId,
|
|
1746
1178
|
objectId
|
|
1747
1179
|
]);
|
|
1748
1180
|
} else if (/^[A-Z0-9]+$/.test(reference)) {
|
|
1749
|
-
return
|
|
1181
|
+
return DXN2.fromLocalObjectId(reference);
|
|
1750
1182
|
} else {
|
|
1751
1183
|
throw new Error(`Unable to parse object reference: ${reference}`);
|
|
1752
1184
|
}
|
|
@@ -1761,33 +1193,21 @@ export {
|
|
|
1761
1193
|
ContextBinding,
|
|
1762
1194
|
Conversation,
|
|
1763
1195
|
ExaToolkit,
|
|
1764
|
-
ExtractionInput,
|
|
1765
|
-
ExtractionOutput,
|
|
1766
1196
|
LiveExaHandler,
|
|
1767
1197
|
LocalSearchHandler,
|
|
1768
1198
|
LocalSearchToolkit,
|
|
1769
1199
|
MockExaHandler,
|
|
1770
|
-
ReferencedQuotes,
|
|
1771
1200
|
Subgraph,
|
|
1772
1201
|
VersionPin,
|
|
1773
|
-
combineNerTokens,
|
|
1774
1202
|
createArtifactElement,
|
|
1775
1203
|
createExtractionSchema,
|
|
1776
1204
|
createSystemPrompt,
|
|
1777
|
-
createTokenGroups,
|
|
1778
|
-
extractFullEntities,
|
|
1779
|
-
extractionAnthropicFn,
|
|
1780
|
-
extractionNerFn,
|
|
1781
|
-
findQuotes,
|
|
1782
1205
|
findRelatedSchema,
|
|
1783
|
-
getNer,
|
|
1784
1206
|
getSanitizedSchemaName,
|
|
1785
|
-
insertReferences,
|
|
1786
1207
|
makeGraphWriterHandler,
|
|
1787
1208
|
makeGraphWriterToolkit,
|
|
1788
1209
|
makeToolExecutionServiceFromFunctions,
|
|
1789
1210
|
makeToolResolverFromFunctions,
|
|
1790
|
-
processTranscriptMessage,
|
|
1791
1211
|
researchFn,
|
|
1792
1212
|
sanitizeObjects
|
|
1793
1213
|
};
|