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