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