@dxos/assistant 0.8.3 → 0.8.4-main.f9ba587
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/index.mjs +456 -595
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +456 -595
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/blueprint/blueprint.d.ts +33 -47
- package/dist/types/src/blueprint/blueprint.d.ts.map +1 -1
- package/dist/types/src/blueprint/index.d.ts +1 -2
- package/dist/types/src/blueprint/index.d.ts.map +1 -1
- package/dist/types/src/blueprint/registry.d.ts +7 -0
- package/dist/types/src/blueprint/registry.d.ts.map +1 -0
- package/dist/types/src/context/binder.d.ts +34 -0
- package/dist/types/src/context/binder.d.ts.map +1 -0
- package/dist/types/src/context/binding.d.ts +38 -0
- package/dist/types/src/context/binding.d.ts.map +1 -0
- package/dist/types/src/context/index.d.ts +3 -0
- package/dist/types/src/context/index.d.ts.map +1 -0
- package/dist/types/src/conversation/conversation.d.ts +44 -0
- package/dist/types/src/conversation/conversation.d.ts.map +1 -0
- package/dist/types/src/conversation/index.d.ts +2 -0
- package/dist/types/src/conversation/index.d.ts.map +1 -0
- package/dist/types/src/extraction/extraction-llm-function/extraction-llm-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts +10 -10
- package/dist/types/src/index.d.ts +4 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/research/research.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +25 -3
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +21 -30
- package/src/blueprint/blueprint.ts +57 -57
- package/src/blueprint/index.ts +1 -2
- package/src/blueprint/registry.ts +15 -0
- package/src/context/binder.ts +101 -0
- package/src/context/binding.ts +31 -0
- package/src/context/index.ts +6 -0
- package/src/conversation/conversation.ts +103 -0
- package/src/conversation/index.ts +5 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +2 -1
- package/src/index.ts +4 -1
- package/src/research/research.ts +3 -2
- package/src/session/session.test.ts +48 -2
- package/src/session/session.ts +51 -18
- package/dist/lib/node/index.cjs +0 -2178
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
- package/dist/types/src/blueprint/ai.test.d.ts +0 -2
- package/dist/types/src/blueprint/ai.test.d.ts.map +0 -1
- package/dist/types/src/blueprint/blueprint.test.d.ts +0 -2
- package/dist/types/src/blueprint/blueprint.test.d.ts.map +0 -1
- package/dist/types/src/blueprint/logger.d.ts +0 -25
- package/dist/types/src/blueprint/logger.d.ts.map +0 -1
- package/dist/types/src/blueprint/machine.d.ts +0 -143
- package/dist/types/src/blueprint/machine.d.ts.map +0 -1
- package/dist/types/src/blueprint/test-data.d.ts +0 -3
- package/dist/types/src/blueprint/test-data.d.ts.map +0 -1
- package/src/blueprint/ai.test.ts +0 -156
- package/src/blueprint/blueprint.test.ts +0 -151
- package/src/blueprint/logger.ts +0 -155
- package/src/blueprint/machine.ts +0 -251
- package/src/blueprint/test-data.ts +0 -55
|
@@ -1,77 +1,193 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// src/blueprint/blueprint.ts
|
|
4
4
|
import { Schema } from "effect";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
import { ToolId } from "@dxos/ai";
|
|
6
|
+
import { Type } from "@dxos/echo";
|
|
7
|
+
import { LabelAnnotation } from "@dxos/echo-schema";
|
|
8
|
+
var Blueprint = Schema.Struct({
|
|
9
|
+
/**
|
|
10
|
+
* Global registry ID.
|
|
11
|
+
* NOTE: Once a blueprint has been cloned from the registry, its stored definition may converge,
|
|
12
|
+
* but the `key` property refers to the original registry entry.
|
|
13
|
+
*/
|
|
14
|
+
// TODO(burdon): Create Format type.
|
|
15
|
+
key: Schema.String.annotations({
|
|
16
|
+
description: "Unique registration key for the blueprint"
|
|
17
|
+
}),
|
|
18
|
+
/**
|
|
19
|
+
* Human-readable name of the blueprint.
|
|
20
|
+
*/
|
|
21
|
+
name: Schema.String.annotations({
|
|
22
|
+
description: "Human-readable name of the blueprint"
|
|
23
|
+
}),
|
|
24
|
+
/**
|
|
25
|
+
* Description of the blueprint's purpose and functionality.
|
|
26
|
+
*/
|
|
27
|
+
description: Schema.optional(Schema.String).annotations({
|
|
28
|
+
description: "Description of the blueprint's purpose and functionality"
|
|
29
|
+
}),
|
|
30
|
+
/**
|
|
31
|
+
* Instructions that guide the AI assistant's behavior and responses.
|
|
32
|
+
* These are system prompts or guidelines that the AI should follow.
|
|
33
|
+
*/
|
|
34
|
+
instructions: Schema.String.annotations({
|
|
35
|
+
description: "Instructions that guide the AI assistant's behavior and responses"
|
|
36
|
+
}),
|
|
37
|
+
/**
|
|
38
|
+
* Array of tools that the AI assistant can use when this blueprint is active.
|
|
39
|
+
*/
|
|
40
|
+
tools: Schema.Array(ToolId).annotations({
|
|
41
|
+
description: "Array of tools that the AI assistant can use when this blueprint is active"
|
|
42
|
+
}),
|
|
43
|
+
/**
|
|
44
|
+
* Array of artifacts that the AI assistant can create or modify.
|
|
45
|
+
*/
|
|
46
|
+
artifacts: Schema.Array(Schema.String).annotations({
|
|
47
|
+
description: "Ids of artifact definitions that should be pulled into the blueprint"
|
|
48
|
+
})
|
|
49
|
+
}).pipe(
|
|
50
|
+
Type.Obj({
|
|
51
|
+
// TODO(burdon): Is this a DXN? Need to create a Format type for these IDs.
|
|
52
|
+
typename: "dxos.org/type/Blueprint",
|
|
53
|
+
version: "0.1.0"
|
|
54
|
+
}),
|
|
55
|
+
// TODO(burdon): Move to main API.
|
|
56
|
+
LabelAnnotation.set([
|
|
57
|
+
"name"
|
|
58
|
+
])
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// src/blueprint/registry.ts
|
|
62
|
+
var BlueprintRegistry = class {
|
|
63
|
+
constructor(_blueprints) {
|
|
64
|
+
this._blueprints = _blueprints;
|
|
65
|
+
this._blueprints.sort(({ name: a }, { name: b }) => a.localeCompare(b));
|
|
66
|
+
}
|
|
67
|
+
query() {
|
|
68
|
+
return this._blueprints;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/context/binder.ts
|
|
73
|
+
import { computed } from "@preact/signals-core";
|
|
74
|
+
import { Array as Array2, pipe } from "effect";
|
|
75
|
+
import { Obj } from "@dxos/echo";
|
|
76
|
+
import { ComplexSet } from "@dxos/util";
|
|
77
|
+
|
|
78
|
+
// src/context/binding.ts
|
|
79
|
+
import { Schema as Schema2 } from "effect";
|
|
80
|
+
import { Type as Type2 } from "@dxos/echo";
|
|
81
|
+
var ContextBinding = Schema2.Struct({
|
|
82
|
+
blueprints: Schema2.Struct({
|
|
83
|
+
added: Schema2.Array(Type2.Ref(Blueprint)),
|
|
84
|
+
removed: Schema2.Array(Type2.Ref(Blueprint))
|
|
85
|
+
}),
|
|
86
|
+
// TODO(burdon): Type.Expando => Type.Obj (or Obj.Any?)
|
|
87
|
+
objects: Schema2.Struct({
|
|
88
|
+
added: Schema2.Array(Type2.Ref(Type2.Expando)),
|
|
89
|
+
removed: Schema2.Array(Type2.Ref(Type2.Expando))
|
|
90
|
+
})
|
|
91
|
+
}).pipe(Type2.Obj({
|
|
92
|
+
typename: "dxos.org/type/ContextBinding",
|
|
93
|
+
version: "0.1.0"
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
// src/context/binder.ts
|
|
97
|
+
var ContextBinder = class {
|
|
98
|
+
constructor(_queue) {
|
|
99
|
+
this._queue = _queue;
|
|
100
|
+
this.bindings = computed(() => this._reduce(this._queue.objects));
|
|
101
|
+
this.blueprints = computed(() => [
|
|
102
|
+
...this.bindings.value.blueprints
|
|
103
|
+
]);
|
|
104
|
+
this.objects = computed(() => [
|
|
105
|
+
...this.bindings.value.objects
|
|
106
|
+
]);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Asynchronous query of all bindings.
|
|
110
|
+
*/
|
|
111
|
+
async query() {
|
|
112
|
+
const queueItems = await this._queue.queryObjects();
|
|
113
|
+
return this._reduce(queueItems);
|
|
114
|
+
}
|
|
115
|
+
// TODO(burdon): Pass in Blueprint obj (from registry?) and create reference.
|
|
116
|
+
async bind(props) {
|
|
117
|
+
if (!props.blueprints?.length && !props.objects?.length) {
|
|
118
|
+
return;
|
|
28
119
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
120
|
+
await this._queue.append([
|
|
121
|
+
Obj.make(ContextBinding, {
|
|
122
|
+
blueprints: {
|
|
123
|
+
added: props.blueprints ?? [],
|
|
124
|
+
removed: []
|
|
125
|
+
},
|
|
126
|
+
objects: {
|
|
127
|
+
added: props.objects ?? [],
|
|
128
|
+
removed: []
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
]);
|
|
132
|
+
}
|
|
133
|
+
async unbind(props) {
|
|
134
|
+
if (!props.blueprints?.length && !props.objects?.length) {
|
|
135
|
+
return;
|
|
45
136
|
}
|
|
137
|
+
await this._queue.append([
|
|
138
|
+
Obj.make(ContextBinding, {
|
|
139
|
+
blueprints: {
|
|
140
|
+
added: [],
|
|
141
|
+
removed: props.blueprints ?? []
|
|
142
|
+
},
|
|
143
|
+
objects: {
|
|
144
|
+
added: [],
|
|
145
|
+
removed: props.objects ?? []
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
]);
|
|
149
|
+
}
|
|
150
|
+
_reduce(items) {
|
|
151
|
+
return pipe(items, Array2.filter(Obj.instanceOf(ContextBinding)), Array2.reduce(new Bindings(), (context, item) => {
|
|
152
|
+
item.blueprints.removed.forEach((item2) => context.blueprints.delete(item2));
|
|
153
|
+
item.blueprints.added.forEach((item2) => context.blueprints.add(item2));
|
|
154
|
+
item.objects.removed.forEach((item2) => context.objects.delete(item2));
|
|
155
|
+
item.objects.added.forEach((item2) => context.objects.add(item2));
|
|
156
|
+
return context;
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var Bindings = class {
|
|
161
|
+
constructor() {
|
|
162
|
+
this.blueprints = new ComplexSet((ref) => ref.dxn.toString());
|
|
163
|
+
this.objects = new ComplexSet((ref) => ref.dxn.toString());
|
|
46
164
|
}
|
|
47
165
|
};
|
|
48
166
|
|
|
49
|
-
//
|
|
167
|
+
// src/conversation/conversation.ts
|
|
50
168
|
import { Message as Message2 } from "@dxos/ai";
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import { AiService,
|
|
54
|
-
import {
|
|
55
|
-
|
|
56
|
-
// raw-loader:./instructions.tpl?raw
|
|
57
|
-
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.';
|
|
169
|
+
import { Event as Event2 } from "@dxos/async";
|
|
170
|
+
import { Obj as Obj3, Ref } from "@dxos/echo";
|
|
171
|
+
import { AiService, ToolResolverService } from "@dxos/functions";
|
|
172
|
+
import { log as log2 } from "@dxos/log";
|
|
173
|
+
import { isNonNullable } from "@dxos/util";
|
|
58
174
|
|
|
59
|
-
//
|
|
60
|
-
import { Option, Schema as
|
|
175
|
+
// src/session/session.ts
|
|
176
|
+
import { Array as Array3, Option, pipe as pipe2, Schema as Schema4 } from "effect";
|
|
61
177
|
import { AgentStatusReport, isToolUse, runTools, structuredOutputParser, Message, MixedStreamParser, ToolResult, createTool } from "@dxos/ai";
|
|
62
178
|
import { Event, synchronized } from "@dxos/async";
|
|
63
|
-
import { Obj } from "@dxos/echo";
|
|
179
|
+
import { Obj as Obj2 } from "@dxos/echo";
|
|
64
180
|
import { ObjectVersion } from "@dxos/echo-db";
|
|
65
181
|
import { create } from "@dxos/echo-schema";
|
|
66
182
|
import { invariant } from "@dxos/invariant";
|
|
67
|
-
import { log
|
|
183
|
+
import { log } from "@dxos/log";
|
|
68
184
|
|
|
69
|
-
//
|
|
70
|
-
import { Schema as
|
|
185
|
+
// src/session/version-pin.ts
|
|
186
|
+
import { Schema as Schema3 } from "effect";
|
|
71
187
|
import { getVersion } from "@dxos/echo-db";
|
|
72
188
|
import { ObjectId } from "@dxos/echo-schema";
|
|
73
|
-
var ObjectVersionSchema =
|
|
74
|
-
var VersionPinSchema =
|
|
189
|
+
var ObjectVersionSchema = Schema3.Unknown;
|
|
190
|
+
var VersionPinSchema = Schema3.Struct({
|
|
75
191
|
// TODO(dmaretskyi): Use Ref when those support encoding.
|
|
76
192
|
objectId: ObjectId,
|
|
77
193
|
// TODO(dmaretskyi): Could be opaque
|
|
@@ -96,14 +212,14 @@ var VersionPin = class extends VersionPinSchema {
|
|
|
96
212
|
}
|
|
97
213
|
};
|
|
98
214
|
|
|
99
|
-
//
|
|
215
|
+
// src/session/session.ts
|
|
100
216
|
function _ts_decorate(decorators, target, key, desc) {
|
|
101
217
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
102
218
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
103
219
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
104
220
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
105
221
|
}
|
|
106
|
-
var
|
|
222
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant/src/session/session.ts";
|
|
107
223
|
var AISession = class _AISession {
|
|
108
224
|
constructor(_options) {
|
|
109
225
|
this._options = _options;
|
|
@@ -116,6 +232,7 @@ var AISession = class _AISession {
|
|
|
116
232
|
this.streamEvent = this._parser.streamEvent;
|
|
117
233
|
this.userMessage = new Event();
|
|
118
234
|
this.statusReport = new Event();
|
|
235
|
+
this.done = new Event();
|
|
119
236
|
this.toolStatusReport = new Event();
|
|
120
237
|
this._parser.message.on((message) => {
|
|
121
238
|
this._pending.push(message);
|
|
@@ -128,6 +245,11 @@ var AISession = class _AISession {
|
|
|
128
245
|
}
|
|
129
246
|
});
|
|
130
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Runs the AI model loop interacting with tools and artifacts.
|
|
250
|
+
* @param options - The session options.
|
|
251
|
+
* @returns The messages generated by the session, including the user's prompt.
|
|
252
|
+
*/
|
|
131
253
|
async run(options) {
|
|
132
254
|
const systemTools = [];
|
|
133
255
|
switch (this._options.operationModel) {
|
|
@@ -159,18 +281,19 @@ var AISession = class _AISession {
|
|
|
159
281
|
try {
|
|
160
282
|
let more = false;
|
|
161
283
|
do {
|
|
162
|
-
const tools = [
|
|
284
|
+
const tools = pipe2([
|
|
163
285
|
...systemTools,
|
|
164
|
-
...options.tools,
|
|
286
|
+
...await Promise.all(options.tools.map((toolId) => options.toolResolver.resolve(toolId))),
|
|
287
|
+
...options.executableTools ?? [],
|
|
165
288
|
...options.artifacts.filter((artifact) => requiredArtifactIds.has(artifact.id)).flatMap((artifact) => artifact.tools)
|
|
166
|
-
];
|
|
167
|
-
|
|
289
|
+
], Array3.dedupeWith((a, b) => a.id === b.id));
|
|
290
|
+
log("request", {
|
|
168
291
|
pending: this._pending.length,
|
|
169
292
|
history: this._history.length,
|
|
170
293
|
tools: tools.map((tool) => tool.name)
|
|
171
294
|
}, {
|
|
172
|
-
F:
|
|
173
|
-
L:
|
|
295
|
+
F: __dxlog_file,
|
|
296
|
+
L: 231,
|
|
174
297
|
S: this,
|
|
175
298
|
C: (f, a) => f(...a)
|
|
176
299
|
});
|
|
@@ -183,25 +306,27 @@ var AISession = class _AISession {
|
|
|
183
306
|
],
|
|
184
307
|
tools,
|
|
185
308
|
systemPrompt: options.systemPrompt ?? createBaseInstructions({
|
|
186
|
-
availableArtifacts:
|
|
309
|
+
availableArtifacts: [
|
|
310
|
+
...requiredArtifactIds
|
|
311
|
+
],
|
|
187
312
|
operationModel: this._options.operationModel
|
|
188
313
|
})
|
|
189
314
|
});
|
|
190
315
|
await this._parser.parse(this._stream);
|
|
191
316
|
await this._stream.complete();
|
|
192
|
-
|
|
317
|
+
log("response", {
|
|
193
318
|
pending: this._pending
|
|
194
319
|
}, {
|
|
195
|
-
F:
|
|
196
|
-
L:
|
|
320
|
+
F: __dxlog_file,
|
|
321
|
+
L: 256,
|
|
197
322
|
S: this,
|
|
198
323
|
C: (f, a) => f(...a)
|
|
199
324
|
});
|
|
200
325
|
more = false;
|
|
201
326
|
const message = this._pending.at(-1);
|
|
202
327
|
invariant(message, void 0, {
|
|
203
|
-
F:
|
|
204
|
-
L:
|
|
328
|
+
F: __dxlog_file,
|
|
329
|
+
L: 261,
|
|
205
330
|
S: this,
|
|
206
331
|
A: [
|
|
207
332
|
"message",
|
|
@@ -209,9 +334,9 @@ var AISession = class _AISession {
|
|
|
209
334
|
]
|
|
210
335
|
});
|
|
211
336
|
if (isToolUse(message)) {
|
|
212
|
-
|
|
213
|
-
F:
|
|
214
|
-
L:
|
|
337
|
+
log("tool request...", void 0, {
|
|
338
|
+
F: __dxlog_file,
|
|
339
|
+
L: 263,
|
|
215
340
|
S: this,
|
|
216
341
|
C: (f, a) => f(...a)
|
|
217
342
|
});
|
|
@@ -221,11 +346,11 @@ var AISession = class _AISession {
|
|
|
221
346
|
extensions: options.extensions ?? {},
|
|
222
347
|
reportStatus: (status) => this._onToolStatusReport(message, status)
|
|
223
348
|
});
|
|
224
|
-
|
|
349
|
+
log("tool response", {
|
|
225
350
|
response
|
|
226
351
|
}, {
|
|
227
|
-
F:
|
|
228
|
-
L:
|
|
352
|
+
F: __dxlog_file,
|
|
353
|
+
L: 271,
|
|
229
354
|
S: this,
|
|
230
355
|
C: (f, a) => f(...a)
|
|
231
356
|
});
|
|
@@ -243,9 +368,9 @@ var AISession = class _AISession {
|
|
|
243
368
|
}
|
|
244
369
|
} while (more);
|
|
245
370
|
} catch (err) {
|
|
246
|
-
|
|
247
|
-
F:
|
|
248
|
-
L:
|
|
371
|
+
log.catch(err, void 0, {
|
|
372
|
+
F: __dxlog_file,
|
|
373
|
+
L: 283,
|
|
249
374
|
S: this,
|
|
250
375
|
C: (f, a) => f(...a)
|
|
251
376
|
});
|
|
@@ -260,6 +385,7 @@ var AISession = class _AISession {
|
|
|
260
385
|
}
|
|
261
386
|
} finally {
|
|
262
387
|
this._stream = void 0;
|
|
388
|
+
this.done.emit();
|
|
263
389
|
}
|
|
264
390
|
if (error) {
|
|
265
391
|
throw error;
|
|
@@ -270,8 +396,8 @@ var AISession = class _AISession {
|
|
|
270
396
|
const parser = structuredOutputParser(schema);
|
|
271
397
|
const result = await this.run({
|
|
272
398
|
...options,
|
|
273
|
-
|
|
274
|
-
...options.
|
|
399
|
+
executableTools: [
|
|
400
|
+
...options.executableTools ?? [],
|
|
275
401
|
parser.tool
|
|
276
402
|
]
|
|
277
403
|
});
|
|
@@ -281,16 +407,18 @@ var AISession = class _AISession {
|
|
|
281
407
|
const prelude = [];
|
|
282
408
|
if (artifactDiffResolver) {
|
|
283
409
|
const versions = gatherObjectVersions(history);
|
|
284
|
-
const artifactDiff = await artifactDiffResolver(
|
|
410
|
+
const artifactDiff = await artifactDiffResolver([
|
|
411
|
+
...versions.entries()
|
|
412
|
+
].map(([id, version]) => ({
|
|
285
413
|
id,
|
|
286
414
|
lastVersion: version
|
|
287
415
|
})));
|
|
288
|
-
|
|
416
|
+
log.info("vision", {
|
|
289
417
|
artifactDiff,
|
|
290
418
|
versions
|
|
291
419
|
}, {
|
|
292
|
-
F:
|
|
293
|
-
L:
|
|
420
|
+
F: __dxlog_file,
|
|
421
|
+
L: 327,
|
|
294
422
|
S: this,
|
|
295
423
|
C: (f, a) => f(...a)
|
|
296
424
|
});
|
|
@@ -310,7 +438,7 @@ var AISession = class _AISession {
|
|
|
310
438
|
prelude.push(createArtifactUpdateBlock(artifactDiff));
|
|
311
439
|
}
|
|
312
440
|
}
|
|
313
|
-
return
|
|
441
|
+
return Obj2.make(Message, {
|
|
314
442
|
role: "user",
|
|
315
443
|
content: [
|
|
316
444
|
...prelude,
|
|
@@ -325,7 +453,7 @@ var AISession = class _AISession {
|
|
|
325
453
|
return createTool("system", {
|
|
326
454
|
name: "query_artifact_definitions",
|
|
327
455
|
description: "Query the available artifact definitions",
|
|
328
|
-
schema:
|
|
456
|
+
schema: Schema4.Struct({}),
|
|
329
457
|
execute: async () => {
|
|
330
458
|
return ToolResult.Success({
|
|
331
459
|
artifactDefinitions: artifacts.map((artifact) => ({
|
|
@@ -341,8 +469,8 @@ var AISession = class _AISession {
|
|
|
341
469
|
return createTool("system", {
|
|
342
470
|
name: "require_artifact_definitions",
|
|
343
471
|
description: "Require the use of specific artifact definitions. This will allow the model to interact with artifact definitions and use their tools.",
|
|
344
|
-
schema:
|
|
345
|
-
artifactDefinitionIds:
|
|
472
|
+
schema: Schema4.Struct({
|
|
473
|
+
artifactDefinitionIds: Schema4.Array(Schema4.String).annotations({
|
|
346
474
|
description: "The ids of the artifact definitions to require",
|
|
347
475
|
examples: [
|
|
348
476
|
[
|
|
@@ -365,21 +493,21 @@ var AISession = class _AISession {
|
|
|
365
493
|
return createTool("system", {
|
|
366
494
|
name: "create_plan",
|
|
367
495
|
description: "Create a plan. Make sure that each step is independent and can be executed solely on the data returned by the previous step. The steps only share the data that is specified in the plan.",
|
|
368
|
-
schema:
|
|
369
|
-
goal:
|
|
496
|
+
schema: Schema4.Struct({
|
|
497
|
+
goal: Schema4.String.annotations({
|
|
370
498
|
description: "The goal that the plan will achieve."
|
|
371
499
|
}),
|
|
372
|
-
steps:
|
|
373
|
-
action:
|
|
500
|
+
steps: Schema4.Array(Schema4.Struct({
|
|
501
|
+
action: Schema4.String.annotations({
|
|
374
502
|
description: "Complete, detailed action to perform."
|
|
375
503
|
}),
|
|
376
|
-
input:
|
|
504
|
+
input: Schema4.String.annotations({
|
|
377
505
|
description: "The required input data for this step. First step must not require any data."
|
|
378
506
|
}),
|
|
379
|
-
output:
|
|
507
|
+
output: Schema4.String.annotations({
|
|
380
508
|
description: "The output data from this step. This is passed to the next step as input."
|
|
381
509
|
}),
|
|
382
|
-
requiredArtifactIds:
|
|
510
|
+
requiredArtifactIds: Schema4.Array(Schema4.String).annotations({
|
|
383
511
|
description: "The ids of the artifacts required to perform this step.",
|
|
384
512
|
examples: [
|
|
385
513
|
[
|
|
@@ -398,11 +526,11 @@ var AISession = class _AISession {
|
|
|
398
526
|
}
|
|
399
527
|
const stepResults = [];
|
|
400
528
|
for (const step of steps) {
|
|
401
|
-
|
|
529
|
+
log("executing step", {
|
|
402
530
|
action: step.action
|
|
403
531
|
}, {
|
|
404
|
-
F:
|
|
405
|
-
L:
|
|
532
|
+
F: __dxlog_file,
|
|
533
|
+
L: 434,
|
|
406
534
|
S: this,
|
|
407
535
|
C: (f, a) => f(...a)
|
|
408
536
|
});
|
|
@@ -415,14 +543,11 @@ var AISession = class _AISession {
|
|
|
415
543
|
session.streamEvent.on((ev) => this.streamEvent.emit(ev));
|
|
416
544
|
session.userMessage.on((ev) => this.userMessage.emit(ev));
|
|
417
545
|
const messages = await session.run({
|
|
418
|
-
client: options.client,
|
|
419
546
|
artifacts: options.artifacts,
|
|
420
547
|
tools: options.tools,
|
|
421
548
|
history: options.history,
|
|
422
549
|
extensions: options.extensions,
|
|
423
|
-
generationOptions: options.generationOptions,
|
|
424
550
|
requiredArtifactIds: step.requiredArtifactIds.slice(),
|
|
425
|
-
artifactDiffResolver: options.artifactDiffResolver,
|
|
426
551
|
prompt: `
|
|
427
552
|
You are an agent that executes the subtask in a plan.
|
|
428
553
|
|
|
@@ -440,7 +565,11 @@ var AISession = class _AISession {
|
|
|
440
565
|
|
|
441
566
|
Previous step results:
|
|
442
567
|
${JSON.stringify(stepResults.at(-1))}.
|
|
443
|
-
|
|
568
|
+
`,
|
|
569
|
+
generationOptions: options.generationOptions,
|
|
570
|
+
client: options.client,
|
|
571
|
+
toolResolver: options.toolResolver,
|
|
572
|
+
artifactDiffResolver: options.artifactDiffResolver
|
|
444
573
|
});
|
|
445
574
|
const result = messages.at(-1);
|
|
446
575
|
stepResults.push(result);
|
|
@@ -497,14 +626,14 @@ var createBaseInstructions = ({ availableArtifacts, operationModel }) => `
|
|
|
497
626
|
|
|
498
627
|
${availableArtifacts.length > 0 ? `Artifacts already in context: ${availableArtifacts.join("\n")}` : ""}
|
|
499
628
|
`;
|
|
500
|
-
var AIServiecOverloadedError = class extends
|
|
629
|
+
var AIServiecOverloadedError = class extends Schema4.TaggedError()("AIServiecOverloadedError", {}) {
|
|
501
630
|
};
|
|
502
631
|
var gatherObjectVersions = (messages) => {
|
|
503
632
|
const artifactIds = /* @__PURE__ */ new Map();
|
|
504
633
|
for (const message of messages) {
|
|
505
634
|
for (const block of message.content) {
|
|
506
635
|
if (block.type === "json" && block.disposition === VersionPin.DISPOSITION) {
|
|
507
|
-
const pin = VersionPin.pipe(
|
|
636
|
+
const pin = VersionPin.pipe(Schema4.decodeOption)(JSON.parse(block.json)).pipe(Option.getOrUndefined);
|
|
508
637
|
if (!pin) {
|
|
509
638
|
continue;
|
|
510
639
|
}
|
|
@@ -520,24 +649,139 @@ var createArtifactUpdateBlock = (artifactDiff) => {
|
|
|
520
649
|
disposition: "artifact-update",
|
|
521
650
|
text: `
|
|
522
651
|
The following artifacts have been updated since the last message:
|
|
523
|
-
${
|
|
652
|
+
${[
|
|
653
|
+
...artifactDiff.entries()
|
|
654
|
+
].map(([id, { diff }]) => `<changed-artifact id="${id}">${diff ? `
|
|
524
655
|
${diff}` : ""}</changed-artifact>`).join("\n")}
|
|
525
656
|
`
|
|
526
657
|
};
|
|
527
658
|
};
|
|
528
659
|
|
|
529
|
-
//
|
|
530
|
-
|
|
660
|
+
// src/conversation/conversation.ts
|
|
661
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant/src/conversation/conversation.ts";
|
|
662
|
+
var Conversation = class {
|
|
663
|
+
constructor(options) {
|
|
664
|
+
/**
|
|
665
|
+
* Fired when the execution loop begins.
|
|
666
|
+
* This is called before the first message is sent.
|
|
667
|
+
*/
|
|
668
|
+
this.onBegin = new Event2();
|
|
669
|
+
this._serviceContainer = options.serviceContainer;
|
|
670
|
+
this._queue = options.queue;
|
|
671
|
+
this.context = new ContextBinder(this._queue);
|
|
672
|
+
}
|
|
673
|
+
async run(options) {
|
|
674
|
+
const session = new AISession({
|
|
675
|
+
operationModel: "configured"
|
|
676
|
+
});
|
|
677
|
+
this.onBegin.emit(session);
|
|
678
|
+
const history = await this.getHistory();
|
|
679
|
+
const context = await this.context.query();
|
|
680
|
+
const blueprints = (await Ref.Array.loadAll([
|
|
681
|
+
...context.blueprints
|
|
682
|
+
])).filter(isNonNullable);
|
|
683
|
+
if (blueprints.length > 1) {
|
|
684
|
+
log2.warn("multiple blueprints are not yet supported", void 0, {
|
|
685
|
+
F: __dxlog_file2,
|
|
686
|
+
L: 72,
|
|
687
|
+
S: this,
|
|
688
|
+
C: (f, a) => f(...a)
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
const messages = await session.run({
|
|
692
|
+
history,
|
|
693
|
+
prompt: options.prompt,
|
|
694
|
+
systemPrompt: (options.systemPrompt ?? "") + (blueprints.at(0)?.instructions ?? ""),
|
|
695
|
+
// TODO(dmaretskyi): Artifacts come from the blueprint?
|
|
696
|
+
artifacts: options.artifacts ?? [],
|
|
697
|
+
tools: blueprints.at(0)?.tools ?? [],
|
|
698
|
+
executableTools: options.tools,
|
|
699
|
+
requiredArtifactIds: options.requiredArtifactIds,
|
|
700
|
+
client: this._serviceContainer.getService(AiService).client,
|
|
701
|
+
toolResolver: this._serviceContainer.getService(ToolResolverService).toolResolver,
|
|
702
|
+
extensions: {
|
|
703
|
+
serviceContainer: this._serviceContainer,
|
|
704
|
+
...options.extensions
|
|
705
|
+
},
|
|
706
|
+
generationOptions: options.generationOptions
|
|
707
|
+
});
|
|
708
|
+
await this._queue.append(messages);
|
|
709
|
+
return messages;
|
|
710
|
+
}
|
|
711
|
+
async getHistory() {
|
|
712
|
+
const queueItems = await this._queue.queryObjects();
|
|
713
|
+
return queueItems.filter(Obj3.instanceOf(Message2));
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
// src/extraction/extraction.ts
|
|
718
|
+
import { Schema as Schema5 } from "effect";
|
|
719
|
+
import { asyncTimeout } from "@dxos/async";
|
|
720
|
+
import { Expando } from "@dxos/echo-schema";
|
|
721
|
+
import { log as log3 } from "@dxos/log";
|
|
722
|
+
import { DataType } from "@dxos/schema";
|
|
723
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction.ts";
|
|
724
|
+
var ExtractionInput = Schema5.Struct({
|
|
725
|
+
message: DataType.Message,
|
|
726
|
+
objects: Schema5.optional(Schema5.Array(Expando)),
|
|
727
|
+
options: Schema5.optional(Schema5.Struct({
|
|
728
|
+
timeout: Schema5.optional(Schema5.Number),
|
|
729
|
+
fallbackToRaw: Schema5.optional(Schema5.Boolean)
|
|
730
|
+
}))
|
|
731
|
+
});
|
|
732
|
+
var ExtractionOutput = Schema5.Struct({
|
|
733
|
+
message: DataType.Message,
|
|
734
|
+
timeElapsed: Schema5.Number
|
|
735
|
+
});
|
|
736
|
+
var processTranscriptMessage = async (params) => {
|
|
737
|
+
try {
|
|
738
|
+
if (params.options?.timeout && params.options.timeout > 0) {
|
|
739
|
+
return await asyncTimeout(params.executor.invoke(params.function, params.input), params.options.timeout);
|
|
740
|
+
} else {
|
|
741
|
+
return await params.executor.invoke(params.function, params.input);
|
|
742
|
+
}
|
|
743
|
+
} catch (error) {
|
|
744
|
+
if (params.options?.fallbackToRaw) {
|
|
745
|
+
log3.warn("failed to process message, falling back to raw text", {
|
|
746
|
+
error
|
|
747
|
+
}, {
|
|
748
|
+
F: __dxlog_file3,
|
|
749
|
+
L: 66,
|
|
750
|
+
S: void 0,
|
|
751
|
+
C: (f, a) => f(...a)
|
|
752
|
+
});
|
|
753
|
+
return {
|
|
754
|
+
message: params.input.message,
|
|
755
|
+
timeElapsed: 0
|
|
756
|
+
};
|
|
757
|
+
} else {
|
|
758
|
+
throw error;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
764
|
+
import { Message as Message3, ToolRegistry } from "@dxos/ai";
|
|
765
|
+
import { Obj as Obj4 } from "@dxos/echo";
|
|
766
|
+
import { create as create2 } from "@dxos/echo-schema";
|
|
767
|
+
import { AiService as AiService2, defineFunction } from "@dxos/functions";
|
|
768
|
+
import { DataType as DataType2 } from "@dxos/schema";
|
|
769
|
+
|
|
770
|
+
// raw-loader:./instructions.tpl?raw
|
|
771
|
+
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.';
|
|
772
|
+
|
|
773
|
+
// src/extraction/quotes.ts
|
|
774
|
+
import { Schema as Schema6 } from "effect";
|
|
531
775
|
import { Query, Filter } from "@dxos/echo";
|
|
532
776
|
import { ObjectId as ObjectId2 } from "@dxos/echo-schema";
|
|
533
777
|
import { DXN } from "@dxos/keys";
|
|
534
|
-
import { log as
|
|
535
|
-
var
|
|
536
|
-
var ReferencedQuotes =
|
|
537
|
-
references:
|
|
538
|
-
id:
|
|
539
|
-
quote:
|
|
540
|
-
})).pipe(
|
|
778
|
+
import { log as log4 } from "@dxos/log";
|
|
779
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/quotes.ts";
|
|
780
|
+
var ReferencedQuotes = Schema6.Struct({
|
|
781
|
+
references: Schema6.Array(Schema6.Struct({
|
|
782
|
+
id: Schema6.String,
|
|
783
|
+
quote: Schema6.String
|
|
784
|
+
})).pipe(Schema6.mutable).annotations({
|
|
541
785
|
// TODO(burdon): Does this description make sense?
|
|
542
786
|
description: `
|
|
543
787
|
The references to the context objects that are mentioned in the transcript.
|
|
@@ -550,11 +794,11 @@ var findQuotes = async (quotes, db) => {
|
|
|
550
794
|
const { objects } = await db.query(Query.select(Filter.text(quote, {
|
|
551
795
|
type: "vector"
|
|
552
796
|
}))).run();
|
|
553
|
-
|
|
797
|
+
log4.info("found quotes in vector index", {
|
|
554
798
|
objects,
|
|
555
799
|
quote
|
|
556
800
|
}, {
|
|
557
|
-
F:
|
|
801
|
+
F: __dxlog_file4,
|
|
558
802
|
L: 35,
|
|
559
803
|
S: void 0,
|
|
560
804
|
C: (f, a) => f(...a)
|
|
@@ -581,14 +825,14 @@ var insertReferences = (text, quotes) => {
|
|
|
581
825
|
return text;
|
|
582
826
|
};
|
|
583
827
|
|
|
584
|
-
//
|
|
828
|
+
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
585
829
|
var extractionAnthropicFn = defineFunction({
|
|
586
830
|
description: "Extract entities from the transcript message and add them to the message.",
|
|
587
831
|
inputSchema: ExtractionInput,
|
|
588
832
|
outputSchema: ExtractionOutput,
|
|
589
833
|
handler: async ({ data: { message, objects }, context }) => {
|
|
590
834
|
const startTime = performance.now();
|
|
591
|
-
const ai = context.getService(
|
|
835
|
+
const ai = context.getService(AiService2);
|
|
592
836
|
const session = new AISession({
|
|
593
837
|
operationModel: "configured"
|
|
594
838
|
});
|
|
@@ -599,7 +843,7 @@ var extractionAnthropicFn = defineFunction({
|
|
|
599
843
|
client: ai.client,
|
|
600
844
|
systemPrompt: instructions_default,
|
|
601
845
|
history: [
|
|
602
|
-
|
|
846
|
+
Obj4.make(Message3, {
|
|
603
847
|
role: "user",
|
|
604
848
|
content: [
|
|
605
849
|
{
|
|
@@ -615,7 +859,8 @@ var extractionAnthropicFn = defineFunction({
|
|
|
615
859
|
],
|
|
616
860
|
artifacts: [],
|
|
617
861
|
prompt: "",
|
|
618
|
-
tools: []
|
|
862
|
+
tools: [],
|
|
863
|
+
toolResolver: new ToolRegistry([])
|
|
619
864
|
});
|
|
620
865
|
return {
|
|
621
866
|
message: create2(DataType2.Message, {
|
|
@@ -630,24 +875,24 @@ var extractionAnthropicFn = defineFunction({
|
|
|
630
875
|
}
|
|
631
876
|
});
|
|
632
877
|
|
|
633
|
-
//
|
|
878
|
+
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
634
879
|
import { asyncTimeout as asyncTimeout2 } from "@dxos/async";
|
|
635
880
|
import { create as create3 } from "@dxos/echo-schema";
|
|
636
881
|
import { DatabaseService, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
637
882
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
638
|
-
import { log as
|
|
883
|
+
import { log as log6 } from "@dxos/log";
|
|
639
884
|
import { DataType as DataType3 } from "@dxos/schema";
|
|
640
885
|
|
|
641
|
-
//
|
|
886
|
+
// src/extraction/extraction-ner-function/named-entity-recognition.ts
|
|
642
887
|
import { pipeline } from "@xenova/transformers";
|
|
643
|
-
import { log as
|
|
644
|
-
var
|
|
888
|
+
import { log as log5 } from "@dxos/log";
|
|
889
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/named-entity-recognition.ts";
|
|
645
890
|
var _ner;
|
|
646
891
|
var getNer = () => {
|
|
647
892
|
if (!_ner) {
|
|
648
893
|
_ner = pipeline("ner", "Xenova/bert-base-NER").then((ner) => {
|
|
649
|
-
|
|
650
|
-
F:
|
|
894
|
+
log5.info("NER model is ready", void 0, {
|
|
895
|
+
F: __dxlog_file5,
|
|
651
896
|
L: 23,
|
|
652
897
|
S: void 0,
|
|
653
898
|
C: (f, a) => f(...a)
|
|
@@ -720,18 +965,18 @@ var combineNerTokens = (group) => {
|
|
|
720
965
|
return combinedToken;
|
|
721
966
|
};
|
|
722
967
|
|
|
723
|
-
//
|
|
724
|
-
var
|
|
968
|
+
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
969
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/extraction-ner-function.ts";
|
|
725
970
|
var extractionNerFn = defineFunction2({
|
|
726
971
|
description: "Extracts named entities from a text",
|
|
727
972
|
inputSchema: ExtractionInput,
|
|
728
973
|
outputSchema: ExtractionOutput,
|
|
729
974
|
handler: async ({ data: { message, options }, context }) => {
|
|
730
|
-
|
|
975
|
+
log6.info("input", {
|
|
731
976
|
message,
|
|
732
977
|
options
|
|
733
978
|
}, {
|
|
734
|
-
F:
|
|
979
|
+
F: __dxlog_file6,
|
|
735
980
|
L: 22,
|
|
736
981
|
S: void 0,
|
|
737
982
|
C: (f, a) => f(...a)
|
|
@@ -740,7 +985,7 @@ var extractionNerFn = defineFunction2({
|
|
|
740
985
|
const { db } = context.getService(DatabaseService);
|
|
741
986
|
const entitiesPromise = Promise.all(message.blocks.map(async (block) => {
|
|
742
987
|
invariant2(block.type === "transcription" || block.type === "text", "Block must have text", {
|
|
743
|
-
F:
|
|
988
|
+
F: __dxlog_file6,
|
|
744
989
|
L: 28,
|
|
745
990
|
S: void 0,
|
|
746
991
|
A: [
|
|
@@ -751,10 +996,10 @@ var extractionNerFn = defineFunction2({
|
|
|
751
996
|
return extractFullEntities(block.text);
|
|
752
997
|
})).then((entities2) => entities2.flat());
|
|
753
998
|
const entities = options?.timeout ? await asyncTimeout2(entitiesPromise, options.timeout) : await entitiesPromise;
|
|
754
|
-
|
|
999
|
+
log6.info("entities", {
|
|
755
1000
|
entities
|
|
756
1001
|
}, {
|
|
757
|
-
F:
|
|
1002
|
+
F: __dxlog_file6,
|
|
758
1003
|
L: 33,
|
|
759
1004
|
S: void 0,
|
|
760
1005
|
C: (f, a) => f(...a)
|
|
@@ -762,7 +1007,7 @@ var extractionNerFn = defineFunction2({
|
|
|
762
1007
|
const quoteReferences = await findQuotes(entities.map((entity) => entity.word), db);
|
|
763
1008
|
const blocksWithReferences = message.blocks.map((block, i) => {
|
|
764
1009
|
invariant2(block.type === "transcription" || block.type === "text", "Block must have text", {
|
|
765
|
-
F:
|
|
1010
|
+
F: __dxlog_file6,
|
|
766
1011
|
L: 39,
|
|
767
1012
|
S: void 0,
|
|
768
1013
|
A: [
|
|
@@ -779,10 +1024,10 @@ var extractionNerFn = defineFunction2({
|
|
|
779
1024
|
...message,
|
|
780
1025
|
blocks: blocksWithReferences
|
|
781
1026
|
});
|
|
782
|
-
|
|
1027
|
+
log6.info("output", {
|
|
783
1028
|
messageWithReferences
|
|
784
1029
|
}, {
|
|
785
|
-
F:
|
|
1030
|
+
F: __dxlog_file6,
|
|
786
1031
|
L: 47,
|
|
787
1032
|
S: void 0,
|
|
788
1033
|
C: (f, a) => f(...a)
|
|
@@ -794,13 +1039,13 @@ var extractionNerFn = defineFunction2({
|
|
|
794
1039
|
}
|
|
795
1040
|
});
|
|
796
1041
|
|
|
797
|
-
//
|
|
798
|
-
import { Schema as
|
|
1042
|
+
// src/research/exa.ts
|
|
1043
|
+
import { Schema as Schema7 } from "effect";
|
|
799
1044
|
import Exa from "exa-js";
|
|
800
1045
|
import { createTool as createTool2, ToolResult as ToolResult2 } from "@dxos/ai";
|
|
801
|
-
import { log as
|
|
1046
|
+
import { log as log7 } from "@dxos/log";
|
|
802
1047
|
|
|
803
|
-
//
|
|
1048
|
+
// src/testing/exa-search-1748337321991.ts
|
|
804
1049
|
var exa_search_1748337321991_default = {
|
|
805
1050
|
requestId: "324936368a74f4db978982172bc18a6c",
|
|
806
1051
|
autopromptString: "AI personal knowledge management tools projects 2024",
|
|
@@ -956,7 +1201,7 @@ var exa_search_1748337321991_default = {
|
|
|
956
1201
|
}
|
|
957
1202
|
};
|
|
958
1203
|
|
|
959
|
-
//
|
|
1204
|
+
// src/testing/exa-search-1748337331526.ts
|
|
960
1205
|
var exa_search_1748337331526_default = {
|
|
961
1206
|
requestId: "0dc12e344fa649884456960ca1a54954",
|
|
962
1207
|
autopromptString: "PKM software artificial intelligence integration open source projects",
|
|
@@ -1179,7 +1424,7 @@ npm run tauri dev
|
|
|
1179
1424
|
}
|
|
1180
1425
|
};
|
|
1181
1426
|
|
|
1182
|
-
//
|
|
1427
|
+
// src/testing/exa-search-1748337344119.ts
|
|
1183
1428
|
var exa_search_1748337344119_default = {
|
|
1184
1429
|
requestId: "32df0c541f9883180b35e04caece4374",
|
|
1185
1430
|
autopromptString: "open source AI knowledge management projects features comparison 2024",
|
|
@@ -1302,22 +1547,22 @@ var exa_search_1748337344119_default = {
|
|
|
1302
1547
|
}
|
|
1303
1548
|
};
|
|
1304
1549
|
|
|
1305
|
-
//
|
|
1550
|
+
// src/testing/index.ts
|
|
1306
1551
|
var SEARCH_RESULTS = [
|
|
1307
1552
|
exa_search_1748337321991_default,
|
|
1308
1553
|
exa_search_1748337331526_default,
|
|
1309
1554
|
exa_search_1748337344119_default
|
|
1310
1555
|
];
|
|
1311
1556
|
|
|
1312
|
-
//
|
|
1313
|
-
var
|
|
1557
|
+
// src/research/exa.ts
|
|
1558
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/assistant/src/research/exa.ts";
|
|
1314
1559
|
var createExaTool = ({ apiKey }) => {
|
|
1315
1560
|
const exa = new Exa(apiKey);
|
|
1316
1561
|
return createTool2("search", {
|
|
1317
1562
|
name: "web_search",
|
|
1318
1563
|
description: "Search the web for information",
|
|
1319
|
-
schema:
|
|
1320
|
-
query:
|
|
1564
|
+
schema: Schema7.Struct({
|
|
1565
|
+
query: Schema7.String.annotations({
|
|
1321
1566
|
description: "The query to search for"
|
|
1322
1567
|
})
|
|
1323
1568
|
}),
|
|
@@ -1329,11 +1574,11 @@ var createExaTool = ({ apiKey }) => {
|
|
|
1329
1574
|
},
|
|
1330
1575
|
livecrawl: "always"
|
|
1331
1576
|
});
|
|
1332
|
-
|
|
1577
|
+
log7.info("exa search", {
|
|
1333
1578
|
query,
|
|
1334
1579
|
costDollars: context.costDollars
|
|
1335
1580
|
}, {
|
|
1336
|
-
F:
|
|
1581
|
+
F: __dxlog_file7,
|
|
1337
1582
|
L: 35,
|
|
1338
1583
|
S: void 0,
|
|
1339
1584
|
C: (f, a) => f(...a)
|
|
@@ -1346,8 +1591,8 @@ var createMockExaTool = () => {
|
|
|
1346
1591
|
return createTool2("search", {
|
|
1347
1592
|
name: "web_search",
|
|
1348
1593
|
description: "Search the web for information",
|
|
1349
|
-
schema:
|
|
1350
|
-
query:
|
|
1594
|
+
schema: Schema7.Struct({
|
|
1595
|
+
query: Schema7.String.annotations({
|
|
1351
1596
|
description: "The query to search for"
|
|
1352
1597
|
})
|
|
1353
1598
|
}),
|
|
@@ -1387,28 +1632,28 @@ var levenshteinDistance = (str1, str2) => {
|
|
|
1387
1632
|
return dp[m][n];
|
|
1388
1633
|
};
|
|
1389
1634
|
|
|
1390
|
-
//
|
|
1391
|
-
import { Schema as
|
|
1392
|
-
import { AgentStatusReport as AgentStatusReport2, ConsolePrinter } from "@dxos/ai";
|
|
1635
|
+
// src/research/research.ts
|
|
1636
|
+
import { Schema as Schema9 } from "effect";
|
|
1637
|
+
import { AgentStatusReport as AgentStatusReport2, ConsolePrinter, ToolRegistry as ToolRegistry2 } from "@dxos/ai";
|
|
1393
1638
|
import { create as create5 } from "@dxos/echo-schema";
|
|
1394
|
-
import { AiService as
|
|
1395
|
-
import { log as
|
|
1639
|
+
import { AiService as AiService3, CredentialsService, DatabaseService as DatabaseService2, defineFunction as defineFunction3, TracingService } from "@dxos/functions";
|
|
1640
|
+
import { log as log9 } from "@dxos/log";
|
|
1396
1641
|
import { DataTypes } from "@dxos/schema";
|
|
1397
1642
|
|
|
1398
|
-
//
|
|
1399
|
-
import { Schema as
|
|
1643
|
+
// src/research/graph.ts
|
|
1644
|
+
import { Schema as Schema8, identity, Option as Option2, SchemaAST } from "effect";
|
|
1400
1645
|
import { createTool as createTool3, ToolResult as ToolResult3 } from "@dxos/ai";
|
|
1401
1646
|
import { Query as Query2, Filter as Filter2 } from "@dxos/echo";
|
|
1402
1647
|
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
1403
1648
|
import { EntityKind, getSchemaTypename, getTypeAnnotation, getTypeIdentifierAnnotation, create as create4, getEntityKind, getSchemaDXN, ObjectId as ObjectId3, ReferenceAnnotationId, RelationSourceDXNId, RelationTargetDXNId, RelationSourceId, RelationTargetId } from "@dxos/echo-schema";
|
|
1404
1649
|
import { mapAst } from "@dxos/effect";
|
|
1405
1650
|
import { DXN as DXN2 } from "@dxos/keys";
|
|
1406
|
-
import { log as
|
|
1407
|
-
import { deepMapValues, isNonNullable } from "@dxos/util";
|
|
1408
|
-
var
|
|
1409
|
-
var Subgraph =
|
|
1651
|
+
import { log as log8 } from "@dxos/log";
|
|
1652
|
+
import { deepMapValues, isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
1653
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/assistant/src/research/graph.ts";
|
|
1654
|
+
var Subgraph = Schema8.Struct({
|
|
1410
1655
|
/** Objects and relations. */
|
|
1411
|
-
objects:
|
|
1656
|
+
objects: Schema8.Array(Schema8.Any)
|
|
1412
1657
|
});
|
|
1413
1658
|
var findRelatedSchema = async (db, anchor) => {
|
|
1414
1659
|
const allSchemas = [
|
|
@@ -1438,8 +1683,8 @@ var createLocalSearchTool = (db, queue) => {
|
|
|
1438
1683
|
return createTool3("search", {
|
|
1439
1684
|
name: "local_search",
|
|
1440
1685
|
description: "Search the local database for information using a vector index",
|
|
1441
|
-
schema:
|
|
1442
|
-
query:
|
|
1686
|
+
schema: Schema8.Struct({
|
|
1687
|
+
query: Schema8.String.annotations({
|
|
1443
1688
|
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
1444
1689
|
})
|
|
1445
1690
|
}),
|
|
@@ -1463,10 +1708,10 @@ var createLocalSearchTool = (db, queue) => {
|
|
|
1463
1708
|
});
|
|
1464
1709
|
};
|
|
1465
1710
|
var createExtractionSchema = (types) => {
|
|
1466
|
-
return
|
|
1711
|
+
return Schema8.Struct({
|
|
1467
1712
|
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
1468
1713
|
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
1469
|
-
|
|
1714
|
+
Schema8.optional(Schema8.Array(schema)).annotations({
|
|
1470
1715
|
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option2.getOrElse(() => ""))}`
|
|
1471
1716
|
})
|
|
1472
1717
|
]))
|
|
@@ -1521,10 +1766,10 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1521
1766
|
if (getEntityKind(entry.schema) === "relation") {
|
|
1522
1767
|
const sourceDxn = resolveId(data2.source);
|
|
1523
1768
|
if (!sourceDxn) {
|
|
1524
|
-
|
|
1769
|
+
log8.warn("source not found", {
|
|
1525
1770
|
source: data2.source
|
|
1526
1771
|
}, {
|
|
1527
|
-
F:
|
|
1772
|
+
F: __dxlog_file8,
|
|
1528
1773
|
L: 214,
|
|
1529
1774
|
S: void 0,
|
|
1530
1775
|
C: (f, a) => f(...a)
|
|
@@ -1532,10 +1777,10 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1532
1777
|
}
|
|
1533
1778
|
const targetDxn = resolveId(data2.target);
|
|
1534
1779
|
if (!targetDxn) {
|
|
1535
|
-
|
|
1780
|
+
log8.warn("target not found", {
|
|
1536
1781
|
target: data2.target
|
|
1537
1782
|
}, {
|
|
1538
|
-
F:
|
|
1783
|
+
F: __dxlog_file8,
|
|
1539
1784
|
L: 218,
|
|
1540
1785
|
S: void 0,
|
|
1541
1786
|
C: (f, a) => f(...a)
|
|
@@ -1558,13 +1803,13 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1558
1803
|
const objects = [
|
|
1559
1804
|
...dbObjects,
|
|
1560
1805
|
...queueObjects
|
|
1561
|
-
].filter(
|
|
1562
|
-
|
|
1806
|
+
].filter(isNonNullable2);
|
|
1807
|
+
log8.info("objects", {
|
|
1563
1808
|
dbObjects,
|
|
1564
1809
|
queueObjects,
|
|
1565
1810
|
existingIds
|
|
1566
1811
|
}, {
|
|
1567
|
-
F:
|
|
1812
|
+
F: __dxlog_file8,
|
|
1568
1813
|
L: 239,
|
|
1569
1814
|
S: void 0,
|
|
1570
1815
|
C: (f, a) => f(...a)
|
|
@@ -1605,8 +1850,8 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1605
1850
|
return [];
|
|
1606
1851
|
});
|
|
1607
1852
|
};
|
|
1608
|
-
var SoftRef =
|
|
1609
|
-
"/":
|
|
1853
|
+
var SoftRef = Schema8.Struct({
|
|
1854
|
+
"/": Schema8.String
|
|
1610
1855
|
}).annotations({
|
|
1611
1856
|
description: "Reference to another object."
|
|
1612
1857
|
});
|
|
@@ -1618,15 +1863,15 @@ var preprocessSchema = (schema) => {
|
|
|
1618
1863
|
}
|
|
1619
1864
|
return mapAst(ast, go);
|
|
1620
1865
|
};
|
|
1621
|
-
return
|
|
1622
|
-
id:
|
|
1866
|
+
return Schema8.make(mapAst(schema.ast, go)).pipe(Schema8.omit("id"), Schema8.extend(Schema8.Struct({
|
|
1867
|
+
id: Schema8.String.annotations({
|
|
1623
1868
|
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
1624
1869
|
})
|
|
1625
|
-
})), isRelationSchema ?
|
|
1626
|
-
source:
|
|
1870
|
+
})), isRelationSchema ? Schema8.extend(Schema8.Struct({
|
|
1871
|
+
source: Schema8.String.annotations({
|
|
1627
1872
|
description: "The id of the source object for this relation."
|
|
1628
1873
|
}),
|
|
1629
|
-
target:
|
|
1874
|
+
target: Schema8.String.annotations({
|
|
1630
1875
|
description: "The id of the target object for this relation."
|
|
1631
1876
|
})
|
|
1632
1877
|
})) : identity);
|
|
@@ -1646,26 +1891,26 @@ var createGraphWriterTool = ({ db, queue, schema, onDone = async (x) => x }) =>
|
|
|
1646
1891
|
// raw-loader:./instructions-research.tpl?raw
|
|
1647
1892
|
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\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>";
|
|
1648
1893
|
|
|
1649
|
-
//
|
|
1650
|
-
var
|
|
1894
|
+
// src/research/research.ts
|
|
1895
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/core/assistant/src/research/research.ts";
|
|
1651
1896
|
var researchFn = defineFunction3({
|
|
1652
1897
|
description: "Research the web for information",
|
|
1653
|
-
inputSchema:
|
|
1654
|
-
query:
|
|
1898
|
+
inputSchema: Schema9.Struct({
|
|
1899
|
+
query: Schema9.String.annotations({
|
|
1655
1900
|
description: "The query to search for."
|
|
1656
1901
|
}),
|
|
1657
1902
|
// TOOD(burdon): Move to context.
|
|
1658
|
-
mockSearch:
|
|
1903
|
+
mockSearch: Schema9.optional(Schema9.Boolean).annotations({
|
|
1659
1904
|
description: "Whether to use the mock search tool.",
|
|
1660
1905
|
default: false
|
|
1661
1906
|
})
|
|
1662
1907
|
}),
|
|
1663
|
-
outputSchema:
|
|
1908
|
+
outputSchema: Schema9.Struct({
|
|
1664
1909
|
// result: Schema.String,
|
|
1665
|
-
result:
|
|
1910
|
+
result: Schema9.Any
|
|
1666
1911
|
}),
|
|
1667
1912
|
handler: async ({ data: { query, mockSearch }, context }) => {
|
|
1668
|
-
const ai = context.getService(
|
|
1913
|
+
const ai = context.getService(AiService3);
|
|
1669
1914
|
const credentials = context.getService(CredentialsService);
|
|
1670
1915
|
const { db } = context.getService(DatabaseService2);
|
|
1671
1916
|
const tracing = context.getService(TracingService);
|
|
@@ -1686,20 +1931,20 @@ var researchFn = defineFunction3({
|
|
|
1686
1931
|
session.userMessage.on((message) => printer.printMessage(message));
|
|
1687
1932
|
session.block.on((block) => printer.printContentBlock(block));
|
|
1688
1933
|
session.statusReport.on((status) => {
|
|
1689
|
-
|
|
1934
|
+
log9.info("[agent] status", {
|
|
1690
1935
|
status
|
|
1691
1936
|
}, {
|
|
1692
|
-
F:
|
|
1937
|
+
F: __dxlog_file9,
|
|
1693
1938
|
L: 58,
|
|
1694
1939
|
S: void 0,
|
|
1695
1940
|
C: (f, a) => f(...a)
|
|
1696
1941
|
});
|
|
1697
1942
|
tracing.write(status);
|
|
1698
1943
|
});
|
|
1699
|
-
session.streamEvent.on((event) =>
|
|
1944
|
+
session.streamEvent.on((event) => log9("stream", {
|
|
1700
1945
|
event
|
|
1701
1946
|
}, {
|
|
1702
|
-
F:
|
|
1947
|
+
F: __dxlog_file9,
|
|
1703
1948
|
L: 61,
|
|
1704
1949
|
S: void 0,
|
|
1705
1950
|
C: (f, a) => f(...a)
|
|
@@ -1708,10 +1953,10 @@ var researchFn = defineFunction3({
|
|
|
1708
1953
|
db,
|
|
1709
1954
|
schema: DataTypes
|
|
1710
1955
|
});
|
|
1711
|
-
|
|
1956
|
+
log9.info("graphWriteTool", {
|
|
1712
1957
|
schema: graphWriteTool.parameters
|
|
1713
1958
|
}, {
|
|
1714
|
-
F:
|
|
1959
|
+
F: __dxlog_file9,
|
|
1715
1960
|
L: 64,
|
|
1716
1961
|
S: void 0,
|
|
1717
1962
|
C: (f, a) => f(...a)
|
|
@@ -1721,11 +1966,15 @@ var researchFn = defineFunction3({
|
|
|
1721
1966
|
systemPrompt: instructions_research_default,
|
|
1722
1967
|
artifacts: [],
|
|
1723
1968
|
tools: [
|
|
1724
|
-
searchTool,
|
|
1725
|
-
graphWriteTool
|
|
1969
|
+
searchTool.id,
|
|
1970
|
+
graphWriteTool.id
|
|
1726
1971
|
],
|
|
1727
1972
|
history: [],
|
|
1728
|
-
prompt: query
|
|
1973
|
+
prompt: query,
|
|
1974
|
+
toolResolver: new ToolRegistry2([
|
|
1975
|
+
searchTool,
|
|
1976
|
+
graphWriteTool
|
|
1977
|
+
])
|
|
1729
1978
|
});
|
|
1730
1979
|
return {
|
|
1731
1980
|
result
|
|
@@ -1733,403 +1982,17 @@ var researchFn = defineFunction3({
|
|
|
1733
1982
|
}
|
|
1734
1983
|
});
|
|
1735
1984
|
|
|
1736
|
-
//
|
|
1985
|
+
// src/types.ts
|
|
1737
1986
|
var createArtifactElement = (id) => `<artifact id=${id} />`;
|
|
1738
|
-
|
|
1739
|
-
// packages/core/assistant/src/blueprint/blueprint.ts
|
|
1740
|
-
import { Schema as Schema8 } from "effect";
|
|
1741
|
-
import { Key, Obj as Obj3, Type } from "@dxos/echo";
|
|
1742
|
-
var BlueprintStep = Schema8.Struct({
|
|
1743
|
-
id: Key.ObjectId,
|
|
1744
|
-
instructions: Schema8.String,
|
|
1745
|
-
tools: Schema8.optional(Schema8.Array(Schema8.String))
|
|
1746
|
-
});
|
|
1747
|
-
var BlueprintDefinition = Schema8.Struct({
|
|
1748
|
-
steps: Schema8.Array(BlueprintStep.pipe(Schema8.omit("id")))
|
|
1749
|
-
});
|
|
1750
|
-
var Blueprint = Schema8.Struct({
|
|
1751
|
-
name: Schema8.optional(Schema8.String),
|
|
1752
|
-
steps: Schema8.Array(BlueprintStep)
|
|
1753
|
-
}).pipe(Type.Obj({
|
|
1754
|
-
typename: "dxos.org/type/Blueprint",
|
|
1755
|
-
version: "0.1.0"
|
|
1756
|
-
}));
|
|
1757
|
-
(function(BlueprintBuilder2) {
|
|
1758
|
-
BlueprintBuilder2.create = () => new Builder();
|
|
1759
|
-
class Builder {
|
|
1760
|
-
constructor() {
|
|
1761
|
-
this._steps = [];
|
|
1762
|
-
}
|
|
1763
|
-
step(instructions, options) {
|
|
1764
|
-
this._steps.push({
|
|
1765
|
-
id: Key.ObjectId.random(),
|
|
1766
|
-
instructions,
|
|
1767
|
-
tools: options?.tools ?? []
|
|
1768
|
-
});
|
|
1769
|
-
return this;
|
|
1770
|
-
}
|
|
1771
|
-
build() {
|
|
1772
|
-
return Obj3.make(Blueprint, {
|
|
1773
|
-
steps: this._steps
|
|
1774
|
-
});
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
})(BlueprintBuilder || (BlueprintBuilder = {}));
|
|
1778
|
-
(function(BlueprintParser2) {
|
|
1779
|
-
BlueprintParser2.create = () => new Parser();
|
|
1780
|
-
class Parser {
|
|
1781
|
-
parse({ steps }) {
|
|
1782
|
-
const builder = BlueprintBuilder.create();
|
|
1783
|
-
for (const step of steps) {
|
|
1784
|
-
builder.step(step.instructions, {
|
|
1785
|
-
tools: step.tools ?? []
|
|
1786
|
-
});
|
|
1787
|
-
}
|
|
1788
|
-
return builder.build();
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
})(BlueprintParser || (BlueprintParser = {}));
|
|
1792
|
-
var BlueprintBuilder;
|
|
1793
|
-
var BlueprintParser;
|
|
1794
|
-
|
|
1795
|
-
// packages/core/assistant/src/blueprint/machine.ts
|
|
1796
|
-
import { Match, Schema as Schema9 } from "effect";
|
|
1797
|
-
import { createTool as createTool4, Message as Message3, ToolResult as ToolResult4 } from "@dxos/ai";
|
|
1798
|
-
import { Event as Event2 } from "@dxos/async";
|
|
1799
|
-
import { Key as Key2, Obj as Obj4 } from "@dxos/echo";
|
|
1800
|
-
import { log as log9 } from "@dxos/log";
|
|
1801
|
-
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
1802
|
-
var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/assistant/src/blueprint/machine.ts";
|
|
1803
|
-
var SYSTEM_PROMPT = `
|
|
1804
|
-
You are a smart Rule-Following Agent.
|
|
1805
|
-
Rule-Following Agent executes the command that the user sent in the last message.
|
|
1806
|
-
After doing the work, the Rule-Following Agent calls report tool.
|
|
1807
|
-
If the Rule-Following agent believes that no action is needed, it calls the report tool with "skipped" status.
|
|
1808
|
-
If the Rule-Following Agent is unable to perform the task, it calls the report tool with "bail" status.
|
|
1809
|
-
Rule-Following Agent explains the reason it is unable to perform the task before bailing.
|
|
1810
|
-
The Rule-Following Agent can express creativity and imagination in the way it performs the task.
|
|
1811
|
-
The Rule-Following Agent precisely follows the instructions.
|
|
1812
|
-
`;
|
|
1813
|
-
var INITIAL_STATE = {
|
|
1814
|
-
state: "working",
|
|
1815
|
-
history: [],
|
|
1816
|
-
trace: []
|
|
1817
|
-
};
|
|
1818
|
-
var BlueprintMachine = class {
|
|
1819
|
-
constructor(registry, blueprint) {
|
|
1820
|
-
this.registry = registry;
|
|
1821
|
-
this.blueprint = blueprint;
|
|
1822
|
-
this.begin = new Event2();
|
|
1823
|
-
this.end = new Event2();
|
|
1824
|
-
this.stepStart = new Event2();
|
|
1825
|
-
this.stepComplete = new Event2();
|
|
1826
|
-
this.message = new Event2();
|
|
1827
|
-
this.block = new Event2();
|
|
1828
|
-
this._state = structuredClone(INITIAL_STATE);
|
|
1829
|
-
}
|
|
1830
|
-
get state() {
|
|
1831
|
-
return this._state;
|
|
1832
|
-
}
|
|
1833
|
-
setLogger(logger) {
|
|
1834
|
-
this.logger = logger;
|
|
1835
|
-
return this;
|
|
1836
|
-
}
|
|
1837
|
-
async runToCompletion(options) {
|
|
1838
|
-
const invocationId = Key2.ObjectId.random();
|
|
1839
|
-
log9.info("runToCompletion", {
|
|
1840
|
-
invocationId,
|
|
1841
|
-
options
|
|
1842
|
-
}, {
|
|
1843
|
-
F: __dxlog_file9,
|
|
1844
|
-
L: 107,
|
|
1845
|
-
S: this,
|
|
1846
|
-
C: (f, a) => f(...a)
|
|
1847
|
-
});
|
|
1848
|
-
this.begin.emit();
|
|
1849
|
-
this.logger?.log({
|
|
1850
|
-
type: "begin",
|
|
1851
|
-
invocationId
|
|
1852
|
-
});
|
|
1853
|
-
let firstStep = true;
|
|
1854
|
-
while (this._state.state !== "done") {
|
|
1855
|
-
const input = firstStep ? options.input : void 0;
|
|
1856
|
-
firstStep = false;
|
|
1857
|
-
this._state = await this._execStep(invocationId, this._state, {
|
|
1858
|
-
input,
|
|
1859
|
-
aiClient: options.aiClient
|
|
1860
|
-
});
|
|
1861
|
-
const step = this.blueprint.steps.find((step2) => step2.id === this._state.trace.at(-1)?.stepId);
|
|
1862
|
-
this.stepComplete.emit(step);
|
|
1863
|
-
this.logger?.log({
|
|
1864
|
-
type: "step-complete",
|
|
1865
|
-
invocationId,
|
|
1866
|
-
step
|
|
1867
|
-
});
|
|
1868
|
-
if (this._state.state === "bail") {
|
|
1869
|
-
throw new Error("Agent unable to follow the blueprint");
|
|
1870
|
-
}
|
|
1871
|
-
}
|
|
1872
|
-
this.end.emit();
|
|
1873
|
-
this.logger?.log({
|
|
1874
|
-
type: "end",
|
|
1875
|
-
invocationId
|
|
1876
|
-
});
|
|
1877
|
-
}
|
|
1878
|
-
async _execStep(invocationId, state, options) {
|
|
1879
|
-
const prevStep = this.blueprint.steps.findIndex((step) => step.id === this._state.trace.at(-1)?.stepId);
|
|
1880
|
-
if (prevStep === this.blueprint.steps.length - 1) {
|
|
1881
|
-
throw new Error("Done execution blueprint");
|
|
1882
|
-
}
|
|
1883
|
-
const nextStep = this.blueprint.steps[prevStep + 1];
|
|
1884
|
-
const onLastStep = prevStep === this.blueprint.steps.length - 2;
|
|
1885
|
-
this.stepStart.emit(nextStep);
|
|
1886
|
-
this.logger?.log({
|
|
1887
|
-
type: "step-start",
|
|
1888
|
-
invocationId,
|
|
1889
|
-
step: nextStep
|
|
1890
|
-
});
|
|
1891
|
-
const ReportSchema = Schema9.Struct({
|
|
1892
|
-
status: Schema9.Literal("done", "bailed", "skipped").annotations({
|
|
1893
|
-
description: "The status of the task completion"
|
|
1894
|
-
}),
|
|
1895
|
-
comment: Schema9.String.annotations({
|
|
1896
|
-
description: "A comment about the task completion. If you bailed, you must explain why in detail (min couple of sentences)."
|
|
1897
|
-
})
|
|
1898
|
-
});
|
|
1899
|
-
const report = createTool4("system", {
|
|
1900
|
-
name: "report",
|
|
1901
|
-
description: "This tool reports that the agent has completed the task or is unable to do so.",
|
|
1902
|
-
schema: ReportSchema,
|
|
1903
|
-
execute: async (input) => ToolResult4.Break(input)
|
|
1904
|
-
});
|
|
1905
|
-
const session = new AISession({
|
|
1906
|
-
operationModel: "configured"
|
|
1907
|
-
});
|
|
1908
|
-
session.userMessage.pipeInto(this.message);
|
|
1909
|
-
session.message.pipeInto(this.message);
|
|
1910
|
-
session.block.pipeInto(this.block);
|
|
1911
|
-
const inputMessages = options.input ? [
|
|
1912
|
-
Obj4.make(Message3, {
|
|
1913
|
-
role: "user",
|
|
1914
|
-
content: [
|
|
1915
|
-
taggedDataBlock("input", options.input)
|
|
1916
|
-
]
|
|
1917
|
-
})
|
|
1918
|
-
] : [];
|
|
1919
|
-
inputMessages.forEach((message) => {
|
|
1920
|
-
this.message.emit(message);
|
|
1921
|
-
this.logger?.log({
|
|
1922
|
-
type: "message",
|
|
1923
|
-
invocationId,
|
|
1924
|
-
message
|
|
1925
|
-
});
|
|
1926
|
-
});
|
|
1927
|
-
const tools = nextStep.tools?.map((tool) => this.registry.get(tool)).filter(isNonNullable2) ?? [];
|
|
1928
|
-
const messages = await session.run({
|
|
1929
|
-
systemPrompt: SYSTEM_PROMPT,
|
|
1930
|
-
history: [
|
|
1931
|
-
...state.history,
|
|
1932
|
-
...inputMessages
|
|
1933
|
-
],
|
|
1934
|
-
tools: [
|
|
1935
|
-
...tools,
|
|
1936
|
-
report
|
|
1937
|
-
],
|
|
1938
|
-
artifacts: [],
|
|
1939
|
-
client: options.aiClient,
|
|
1940
|
-
prompt: nextStep.instructions
|
|
1941
|
-
});
|
|
1942
|
-
const { messages: trimmedHistory, call: lastBlock } = popLastToolCall(messages);
|
|
1943
|
-
if (!lastBlock) {
|
|
1944
|
-
throw new Error("Agent did not call the report tool");
|
|
1945
|
-
}
|
|
1946
|
-
const { status, comment } = ReportSchema.pipe(Schema9.decodeUnknownSync)(lastBlock.input);
|
|
1947
|
-
return {
|
|
1948
|
-
history: [
|
|
1949
|
-
...state.history,
|
|
1950
|
-
...inputMessages,
|
|
1951
|
-
...trimmedHistory
|
|
1952
|
-
],
|
|
1953
|
-
trace: [
|
|
1954
|
-
...state.trace,
|
|
1955
|
-
{
|
|
1956
|
-
stepId: nextStep.id,
|
|
1957
|
-
status,
|
|
1958
|
-
comment
|
|
1959
|
-
}
|
|
1960
|
-
],
|
|
1961
|
-
state: Match.value(status).pipe(Match.withReturnType(), Match.when("done", () => onLastStep ? "done" : "working"), Match.when("skipped", () => onLastStep ? "done" : "working"), Match.when("bailed", () => "bail"), Match.exhaustive)
|
|
1962
|
-
};
|
|
1963
|
-
}
|
|
1964
|
-
};
|
|
1965
|
-
var taggedDataBlock = (tag, data) => {
|
|
1966
|
-
return {
|
|
1967
|
-
type: "text",
|
|
1968
|
-
text: `<${tag}>
|
|
1969
|
-
${JSON.stringify(data, null, 2)}
|
|
1970
|
-
</${tag}>`
|
|
1971
|
-
};
|
|
1972
|
-
};
|
|
1973
|
-
var popLastToolCall = (messages) => {
|
|
1974
|
-
const lastBlock = messages.at(-1)?.content.at(-1);
|
|
1975
|
-
if (lastBlock?.type !== "tool_use") {
|
|
1976
|
-
return {
|
|
1977
|
-
messages
|
|
1978
|
-
};
|
|
1979
|
-
}
|
|
1980
|
-
const trimmedHistory = [
|
|
1981
|
-
...messages.slice(0, -1),
|
|
1982
|
-
{
|
|
1983
|
-
...messages.at(-1),
|
|
1984
|
-
content: [
|
|
1985
|
-
...messages.at(-1).content.slice(0, -1)
|
|
1986
|
-
]
|
|
1987
|
-
}
|
|
1988
|
-
];
|
|
1989
|
-
return {
|
|
1990
|
-
messages: trimmedHistory,
|
|
1991
|
-
call: lastBlock
|
|
1992
|
-
};
|
|
1993
|
-
};
|
|
1994
|
-
|
|
1995
|
-
// packages/core/assistant/src/blueprint/logger.ts
|
|
1996
|
-
import { signal } from "@preact/signals-core";
|
|
1997
|
-
import chalk from "chalk";
|
|
1998
|
-
import { ConsolePrinter as ConsolePrinter2 } from "@dxos/ai";
|
|
1999
|
-
import { combine } from "@dxos/async";
|
|
2000
|
-
import { log as log10 } from "@dxos/log";
|
|
2001
|
-
chalk.level = 2;
|
|
2002
|
-
var DEFAULT_LOGGER = {
|
|
2003
|
-
log: log10.info
|
|
2004
|
-
};
|
|
2005
|
-
var BufferedLogger = class {
|
|
2006
|
-
constructor() {
|
|
2007
|
-
this._messages = signal([]);
|
|
2008
|
-
}
|
|
2009
|
-
get messages() {
|
|
2010
|
-
return this._messages;
|
|
2011
|
-
}
|
|
2012
|
-
clear() {
|
|
2013
|
-
this._messages.value = [];
|
|
2014
|
-
}
|
|
2015
|
-
log(message) {
|
|
2016
|
-
this._messages.value = [
|
|
2017
|
-
...this._messages.value,
|
|
2018
|
-
message
|
|
2019
|
-
];
|
|
2020
|
-
}
|
|
2021
|
-
};
|
|
2022
|
-
var BlueprintLoggerAdapter = class {
|
|
2023
|
-
constructor(logger = DEFAULT_LOGGER) {
|
|
2024
|
-
this.logger = logger;
|
|
2025
|
-
}
|
|
2026
|
-
log(event) {
|
|
2027
|
-
switch (event.type) {
|
|
2028
|
-
case "begin":
|
|
2029
|
-
this.logger.log("begin", {
|
|
2030
|
-
invocationId: event.invocationId
|
|
2031
|
-
});
|
|
2032
|
-
break;
|
|
2033
|
-
case "end":
|
|
2034
|
-
this.logger.log("end", {
|
|
2035
|
-
invocationId: event.invocationId
|
|
2036
|
-
});
|
|
2037
|
-
break;
|
|
2038
|
-
case "step-start":
|
|
2039
|
-
this.logger.log("step-start", {
|
|
2040
|
-
invocationId: event.invocationId,
|
|
2041
|
-
step: event.step
|
|
2042
|
-
});
|
|
2043
|
-
break;
|
|
2044
|
-
case "step-complete":
|
|
2045
|
-
this.logger.log("step-complete", {
|
|
2046
|
-
invocationId: event.invocationId,
|
|
2047
|
-
step: event.step
|
|
2048
|
-
});
|
|
2049
|
-
break;
|
|
2050
|
-
case "message":
|
|
2051
|
-
this.logger.log("message", {
|
|
2052
|
-
invocationId: event.invocationId,
|
|
2053
|
-
message: event.message
|
|
2054
|
-
});
|
|
2055
|
-
break;
|
|
2056
|
-
case "block":
|
|
2057
|
-
this.logger.log("block", {
|
|
2058
|
-
invocationId: event.invocationId,
|
|
2059
|
-
block: event.block
|
|
2060
|
-
});
|
|
2061
|
-
break;
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
|
-
};
|
|
2065
|
-
var setLogger = (machine, logger) => {
|
|
2066
|
-
return combine(machine.begin.on(() => {
|
|
2067
|
-
logger.log("Starting...");
|
|
2068
|
-
}), machine.stepStart.on((step) => {
|
|
2069
|
-
const index = machine.blueprint.steps.indexOf(step);
|
|
2070
|
-
logger.log(`Step ${index + 1} of ${machine.blueprint.steps.length}`);
|
|
2071
|
-
logger.log(`Instructions: ${step.instructions}`);
|
|
2072
|
-
}), machine.stepComplete.on((step) => {
|
|
2073
|
-
const trace = machine.state.trace.find((t) => t.stepId === step.id);
|
|
2074
|
-
logger.log(`Complete: ${trace?.comment}`);
|
|
2075
|
-
}), machine.end.on(() => {
|
|
2076
|
-
logger.log("OK");
|
|
2077
|
-
}));
|
|
2078
|
-
};
|
|
2079
|
-
var setConsolePrinter = (machine, verbose = false) => {
|
|
2080
|
-
const printer = new ConsolePrinter2();
|
|
2081
|
-
return combine(machine.begin.on(() => printTrace(machine.blueprint, machine.state)), machine.stepStart.on((step) => console.log(`
|
|
2082
|
-
${chalk.magenta(`${chalk.bold(`STEP ${machine.blueprint.steps.indexOf(step) + 1} of ${machine.blueprint.steps.length}:`)} ${step.instructions}`)}
|
|
2083
|
-
`)), machine.stepComplete.on(() => printTrace(machine.blueprint, machine.state)), machine.end.on(() => console.log("DONE")), verbose ? [
|
|
2084
|
-
machine.message.on((msg) => printer.printMessage(msg)),
|
|
2085
|
-
machine.block.on((block) => printer.printContentBlock(block))
|
|
2086
|
-
] : []);
|
|
2087
|
-
};
|
|
2088
|
-
var BREAK_LINE = `
|
|
2089
|
-
${"_".repeat(80)}
|
|
2090
|
-
`;
|
|
2091
|
-
var printTrace = (blueprint, state) => {
|
|
2092
|
-
console.group(chalk.bold("\nBlueprint"));
|
|
2093
|
-
blueprint.steps.forEach((step) => {
|
|
2094
|
-
const traceStep = state.trace.find((t) => t.stepId === step.id);
|
|
2095
|
-
let color = chalk.gray;
|
|
2096
|
-
let bullet = "\u25CB";
|
|
2097
|
-
if (traceStep) {
|
|
2098
|
-
switch (traceStep.status) {
|
|
2099
|
-
case "done":
|
|
2100
|
-
color = chalk.green;
|
|
2101
|
-
bullet = "\u2713";
|
|
2102
|
-
break;
|
|
2103
|
-
case "skipped":
|
|
2104
|
-
color = chalk.blue;
|
|
2105
|
-
bullet = "\u2193";
|
|
2106
|
-
break;
|
|
2107
|
-
case "bailed":
|
|
2108
|
-
color = chalk.red;
|
|
2109
|
-
bullet = "\u2717";
|
|
2110
|
-
break;
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
console.log(color(`
|
|
2114
|
-
${bullet} ${step.instructions}`));
|
|
2115
|
-
if (traceStep?.comment) {
|
|
2116
|
-
console.log(chalk.white(` \u21B3 ${traceStep.comment}`));
|
|
2117
|
-
}
|
|
2118
|
-
});
|
|
2119
|
-
console.groupEnd();
|
|
2120
|
-
console.log(BREAK_LINE);
|
|
2121
|
-
};
|
|
2122
1987
|
export {
|
|
2123
1988
|
AIServiecOverloadedError,
|
|
2124
1989
|
AISession,
|
|
1990
|
+
Bindings,
|
|
2125
1991
|
Blueprint,
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
BlueprintParser,
|
|
2131
|
-
BlueprintStep,
|
|
2132
|
-
BufferedLogger,
|
|
1992
|
+
BlueprintRegistry,
|
|
1993
|
+
ContextBinder,
|
|
1994
|
+
ContextBinding,
|
|
1995
|
+
Conversation,
|
|
2133
1996
|
ExtractionInput,
|
|
2134
1997
|
ExtractionOutput,
|
|
2135
1998
|
ReferencedQuotes,
|
|
@@ -2153,8 +2016,6 @@ export {
|
|
|
2153
2016
|
insertReferences,
|
|
2154
2017
|
processTranscriptMessage,
|
|
2155
2018
|
researchFn,
|
|
2156
|
-
sanitizeObjects
|
|
2157
|
-
setConsolePrinter,
|
|
2158
|
-
setLogger
|
|
2019
|
+
sanitizeObjects
|
|
2159
2020
|
};
|
|
2160
2021
|
//# sourceMappingURL=index.mjs.map
|