@dxos/assistant 0.8.3 → 0.8.4-main.3a94e84
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 +760 -1087
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +760 -1087
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- 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 +56 -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 +38 -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/errors.d.ts +38 -0
- package/dist/types/src/errors.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 +135 -41
- package/dist/types/src/extraction/extraction-ner-function/extraction-ner-function.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts +1 -1
- package/dist/types/src/extraction/extraction-ner-function/named-entity-recognition.d.ts.map +1 -1
- package/dist/types/src/extraction/extraction.d.ts +100 -42
- package/dist/types/src/extraction/extraction.d.ts.map +1 -1
- package/dist/types/src/functions/index.d.ts +2 -0
- package/dist/types/src/functions/index.d.ts.map +1 -0
- package/dist/types/src/functions/services.d.ts +6 -0
- package/dist/types/src/functions/services.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/research/exa.d.ts +10 -5
- package/dist/types/src/research/exa.d.ts.map +1 -1
- package/dist/types/src/research/graph.d.ts +18 -8
- package/dist/types/src/research/graph.d.ts.map +1 -1
- package/dist/types/src/research/research.d.ts +1 -1
- package/dist/types/src/research/research.d.ts.map +1 -1
- package/dist/types/src/session/session.d.ts +183 -184
- package/dist/types/src/session/session.d.ts.map +1 -1
- package/dist/types/src/session/version-pin.d.ts +2 -2
- package/dist/types/src/session/version-pin.d.ts.map +1 -1
- package/dist/types/src/templates/index.d.ts +2 -0
- package/dist/types/src/templates/index.d.ts.map +1 -0
- package/dist/types/src/templates/prompt.d.ts +30 -0
- package/dist/types/src/templates/prompt.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +10 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -30
- package/src/context/binder.ts +103 -0
- package/src/context/binding.ts +32 -0
- package/src/context/index.ts +6 -0
- package/src/conversation/conversation.ts +96 -0
- package/src/conversation/index.ts +5 -0
- package/src/errors.ts +10 -0
- package/src/extraction/extraction-llm-function/extraction-llm-function.test.ts +6 -18
- package/src/extraction/extraction-llm-function/extraction-llm-function.ts +19 -14
- package/src/extraction/extraction-ner-function/extraction-ner-function.ts +6 -3
- package/src/extraction/extraction-ner-function/named-entity-recognition.test.ts +2 -2
- package/src/extraction/extraction-ner-function/named-entity-recognition.ts +1 -1
- package/src/functions/index.ts +5 -0
- package/src/functions/services.ts +139 -0
- package/src/index.ts +4 -1
- package/src/research/exa.ts +56 -59
- package/src/research/graph.test.ts +50 -1
- package/src/research/graph.ts +85 -53
- package/src/research/instructions-research.tpl +1 -0
- package/src/research/research.test.ts +27 -27
- package/src/research/research.ts +50 -52
- package/src/session/__snapshots__/session.test.ts.snap +32 -0
- package/src/session/session.test.ts +99 -18
- package/src/session/session.ts +230 -443
- package/src/session/version-pin.test.ts +2 -21
- package/src/session/version-pin.ts +5 -5
- package/src/summarization/summarization.test.ts +75 -88
- package/src/templates/assistant.tpl +111 -0
- package/src/templates/index.ts +5 -0
- package/src/templates/prompt.ts +45 -0
- package/src/types.ts +40 -1
- 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.d.ts +0 -55
- package/dist/types/src/blueprint/blueprint.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/index.d.ts +0 -4
- package/dist/types/src/blueprint/index.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/blueprint.ts +0 -75
- package/src/blueprint/index.ts +0 -7
- package/src/blueprint/logger.ts +0 -155
- package/src/blueprint/machine.ts +0 -251
- package/src/blueprint/test-data.ts +0 -55
|
@@ -1,512 +1,294 @@
|
|
|
1
|
-
//
|
|
1
|
+
// src/context/binder.ts
|
|
2
|
+
import { computed } from "@preact/signals-core";
|
|
3
|
+
import { Array as Array2, pipe } from "effect";
|
|
4
|
+
import { Obj } from "@dxos/echo";
|
|
5
|
+
import { ComplexSet } from "@dxos/util";
|
|
6
|
+
|
|
7
|
+
// src/context/binding.ts
|
|
2
8
|
import { Schema } from "effect";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
import { Blueprint } from "@dxos/blueprints";
|
|
10
|
+
import { Type } from "@dxos/echo";
|
|
11
|
+
var ContextBinding = Schema.Struct({
|
|
12
|
+
blueprints: Schema.Struct({
|
|
13
|
+
added: Schema.Array(Type.Ref(Blueprint.Blueprint)),
|
|
14
|
+
removed: Schema.Array(Type.Ref(Blueprint.Blueprint))
|
|
15
|
+
}),
|
|
16
|
+
// TODO(burdon): Type.Expando => Type.Obj (or Obj.Any?)
|
|
17
|
+
objects: Schema.Struct({
|
|
18
|
+
added: Schema.Array(Type.Ref(Type.Expando)),
|
|
19
|
+
removed: Schema.Array(Type.Ref(Type.Expando))
|
|
20
|
+
})
|
|
21
|
+
}).pipe(Type.Obj({
|
|
22
|
+
typename: "dxos.org/type/ContextBinding",
|
|
23
|
+
version: "0.1.0"
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
// src/context/binder.ts
|
|
27
|
+
var ContextBinder = class {
|
|
28
|
+
constructor(_queue) {
|
|
29
|
+
this._queue = _queue;
|
|
30
|
+
this.bindings = computed(() => this._reduce(this._queue.objects));
|
|
31
|
+
this.blueprints = computed(() => [
|
|
32
|
+
...this.bindings.value.blueprints
|
|
33
|
+
]);
|
|
34
|
+
this.objects = computed(() => [
|
|
35
|
+
...this.bindings.value.objects
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Asynchronous query of all bindings.
|
|
40
|
+
*/
|
|
41
|
+
async query() {
|
|
42
|
+
const queueItems = await this._queue.queryObjects();
|
|
43
|
+
return this._reduce(queueItems);
|
|
44
|
+
}
|
|
45
|
+
// TODO(burdon): Pass in Blueprint obj (from registry?) and create reference.
|
|
46
|
+
async bind(props) {
|
|
47
|
+
if (!props.blueprints?.length && !props.objects?.length) {
|
|
48
|
+
return;
|
|
26
49
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
await this._queue.append([
|
|
51
|
+
Obj.make(ContextBinding, {
|
|
52
|
+
blueprints: {
|
|
53
|
+
added: props.blueprints ?? [],
|
|
54
|
+
removed: []
|
|
55
|
+
},
|
|
56
|
+
objects: {
|
|
57
|
+
added: props.objects ?? [],
|
|
58
|
+
removed: []
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
async unbind(props) {
|
|
64
|
+
if (!props.blueprints?.length && !props.objects?.length) {
|
|
65
|
+
return;
|
|
43
66
|
}
|
|
67
|
+
await this._queue.append([
|
|
68
|
+
Obj.make(ContextBinding, {
|
|
69
|
+
blueprints: {
|
|
70
|
+
added: [],
|
|
71
|
+
removed: props.blueprints ?? []
|
|
72
|
+
},
|
|
73
|
+
objects: {
|
|
74
|
+
added: [],
|
|
75
|
+
removed: props.objects ?? []
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
_reduce(items) {
|
|
81
|
+
return pipe(items, Array2.filter(Obj.instanceOf(ContextBinding)), Array2.reduce(new Bindings(), (context, item) => {
|
|
82
|
+
item.blueprints.removed.forEach((item2) => context.blueprints.delete(item2));
|
|
83
|
+
item.blueprints.added.forEach((item2) => context.blueprints.add(item2));
|
|
84
|
+
item.objects.removed.forEach((item2) => context.objects.delete(item2));
|
|
85
|
+
item.objects.added.forEach((item2) => context.objects.add(item2));
|
|
86
|
+
return context;
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var Bindings = class {
|
|
91
|
+
constructor() {
|
|
92
|
+
this.blueprints = new ComplexSet((ref) => ref.dxn.toString());
|
|
93
|
+
this.objects = new ComplexSet((ref) => ref.dxn.toString());
|
|
44
94
|
}
|
|
45
95
|
};
|
|
46
96
|
|
|
47
|
-
//
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
97
|
+
// src/conversation/conversation.ts
|
|
98
|
+
import { Effect as Effect2 } from "effect";
|
|
99
|
+
import { Event as Event2 } from "@dxos/async";
|
|
100
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
101
|
+
import { DatabaseService as DatabaseService2 } from "@dxos/functions";
|
|
52
102
|
import { DataType as DataType2 } from "@dxos/schema";
|
|
53
103
|
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import { Obj } from "@dxos/echo";
|
|
104
|
+
// src/session/session.ts
|
|
105
|
+
import { AiLanguageModel, AiToolkit } from "@effect/ai";
|
|
106
|
+
import { Chunk, Context, Effect, Option, pipe as pipe2, Stream } from "effect";
|
|
107
|
+
import { Array as Array3, String } from "effect";
|
|
108
|
+
import { AiParser, AiPreprocessor, getToolCalls, runTool, ToolExecutionService, ToolResolverService } from "@dxos/ai";
|
|
109
|
+
import { Event } from "@dxos/async";
|
|
110
|
+
import { todo } from "@dxos/debug";
|
|
111
|
+
import { Obj as Obj2 } from "@dxos/echo";
|
|
62
112
|
import { ObjectVersion } from "@dxos/echo-db";
|
|
63
|
-
import {
|
|
64
|
-
import {
|
|
65
|
-
import {
|
|
113
|
+
import { DatabaseService } from "@dxos/functions";
|
|
114
|
+
import { log } from "@dxos/log";
|
|
115
|
+
import { DataType } from "@dxos/schema";
|
|
66
116
|
|
|
67
|
-
//
|
|
68
|
-
import {
|
|
69
|
-
|
|
70
|
-
import { ObjectId } from "@dxos/echo-schema";
|
|
71
|
-
var ObjectVersionSchema = Schema2.Unknown;
|
|
72
|
-
var VersionPinSchema = Schema2.Struct({
|
|
73
|
-
// TODO(dmaretskyi): Use Ref when those support encoding.
|
|
74
|
-
objectId: ObjectId,
|
|
75
|
-
// TODO(dmaretskyi): Could be opaque
|
|
76
|
-
version: ObjectVersionSchema
|
|
77
|
-
});
|
|
78
|
-
var VersionPin = class extends VersionPinSchema {
|
|
79
|
-
static {
|
|
80
|
-
this.DISPOSITION = "version-pin";
|
|
81
|
-
}
|
|
82
|
-
static fromObject(object) {
|
|
83
|
-
return VersionPin.make({
|
|
84
|
-
objectId: object.id,
|
|
85
|
-
version: getVersion(object)
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
static createBlock(pin) {
|
|
89
|
-
return {
|
|
90
|
-
type: "json",
|
|
91
|
-
disposition: VersionPin.DISPOSITION,
|
|
92
|
-
json: JSON.stringify(pin)
|
|
93
|
-
};
|
|
94
|
-
}
|
|
117
|
+
// src/errors.ts
|
|
118
|
+
import { BaseError } from "@dxos/errors";
|
|
119
|
+
var AiAssistantError = class extends BaseError.extend("AI_ASSISTANT_ERROR") {
|
|
95
120
|
};
|
|
96
121
|
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
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
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
103
|
-
}
|
|
104
|
-
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/assistant/src/session/session.ts";
|
|
105
|
-
var AISession = class _AISession {
|
|
106
|
-
constructor(_options) {
|
|
122
|
+
// src/session/session.ts
|
|
123
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/core/assistant/src/session/session.ts";
|
|
124
|
+
var AiSession = class {
|
|
125
|
+
constructor(_options = {}) {
|
|
107
126
|
this._options = _options;
|
|
108
|
-
this.
|
|
127
|
+
this._semaphore = Effect.runSync(Effect.makeSemaphore(1));
|
|
109
128
|
this._pending = [];
|
|
110
129
|
this._history = [];
|
|
111
|
-
this.message =
|
|
112
|
-
this.block =
|
|
113
|
-
this.update =
|
|
114
|
-
this.streamEvent =
|
|
130
|
+
this.message = new Event();
|
|
131
|
+
this.block = new Event();
|
|
132
|
+
this.update = new Event();
|
|
133
|
+
this.streamEvent = new Event();
|
|
115
134
|
this.userMessage = new Event();
|
|
116
135
|
this.statusReport = new Event();
|
|
117
|
-
this.
|
|
118
|
-
this.
|
|
119
|
-
this.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
async run(options) {
|
|
130
|
-
const systemTools = [];
|
|
131
|
-
switch (this._options.operationModel) {
|
|
132
|
-
case "planning":
|
|
133
|
-
systemTools.push(this._createQueryArtifactsTool(options.artifacts), this._createPlanningTool(options));
|
|
134
|
-
break;
|
|
135
|
-
case "importing":
|
|
136
|
-
systemTools.push(this._createQueryArtifactsTool(options.artifacts), this._createRequireTool(options.artifacts, (artifactDefinitionIds) => {
|
|
137
|
-
for (const artifactDefinitionId of artifactDefinitionIds) {
|
|
138
|
-
requiredArtifactIds.add(artifactDefinitionId);
|
|
139
|
-
}
|
|
140
|
-
}));
|
|
141
|
-
break;
|
|
142
|
-
case "configured":
|
|
143
|
-
break;
|
|
144
|
-
default:
|
|
145
|
-
throw new TypeError(`Invalid operation model: ${this._options.operationModel}`);
|
|
146
|
-
}
|
|
147
|
-
this._history = [
|
|
148
|
-
...options.history
|
|
149
|
-
];
|
|
150
|
-
this._pending = [
|
|
151
|
-
await this._formatUserPrompt(options.artifactDiffResolver, options.prompt, options.history)
|
|
152
|
-
];
|
|
153
|
-
this.userMessage.emit(this._pending.at(-1));
|
|
154
|
-
this._stream = void 0;
|
|
155
|
-
let error;
|
|
156
|
-
const requiredArtifactIds = new Set(options.requiredArtifactIds ?? []);
|
|
157
|
-
try {
|
|
158
|
-
let more = false;
|
|
136
|
+
this.done = new Event();
|
|
137
|
+
this.run = (options) => Effect.gen(this, function* () {
|
|
138
|
+
this._history = [
|
|
139
|
+
...options.history
|
|
140
|
+
];
|
|
141
|
+
const promptMessages = yield* this._formatUserPrompt(options.prompt, options.history);
|
|
142
|
+
this._pending = [
|
|
143
|
+
promptMessages
|
|
144
|
+
];
|
|
145
|
+
this.userMessage.emit(promptMessages);
|
|
159
146
|
do {
|
|
160
|
-
|
|
161
|
-
...systemTools,
|
|
162
|
-
...options.tools,
|
|
163
|
-
...options.artifacts.filter((artifact) => requiredArtifactIds.has(artifact.id)).flatMap((artifact) => artifact.tools)
|
|
164
|
-
];
|
|
165
|
-
log2("request", {
|
|
147
|
+
log("request", {
|
|
166
148
|
pending: this._pending.length,
|
|
167
149
|
history: this._history.length,
|
|
168
|
-
tools: tools.map((tool) => tool.name)
|
|
150
|
+
tools: Object.values(options.toolkit?.tools ?? {}).map((tool) => tool.name)
|
|
169
151
|
}, {
|
|
170
|
-
F:
|
|
171
|
-
L:
|
|
152
|
+
F: __dxlog_file,
|
|
153
|
+
L: 126,
|
|
172
154
|
S: this,
|
|
173
155
|
C: (f, a) => f(...a)
|
|
174
156
|
});
|
|
175
|
-
|
|
176
|
-
...
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
157
|
+
const prompt = yield* AiPreprocessor.preprocessAiInput([
|
|
158
|
+
...this._history,
|
|
159
|
+
...this._pending
|
|
160
|
+
]);
|
|
161
|
+
const blueprints = options.blueprints ?? [];
|
|
162
|
+
const systemPrompt = yield* pipe2(blueprints, Effect.forEach((blueprint) => DatabaseService.loadRef(blueprint.instructions)), Effect.flatMap(Effect.forEach((template) => DatabaseService.loadRef(template.source))), Effect.map(Array3.map((template) => `
|
|
163
|
+
|
|
164
|
+
<blueprint>${template.content}</blueprint>`)), Effect.map(Array3.reduce(options.systemPrompt ?? "", String.concat)));
|
|
165
|
+
const blueprintToolkit = yield* ToolResolverService.resolveToolkit(blueprints.flatMap((bp) => bp.tools));
|
|
166
|
+
const blueprintToolkitHandler = yield* blueprintToolkit.toContext(yield* ToolExecutionService.handlersFor(blueprintToolkit));
|
|
167
|
+
const toolkit = options.toolkit != null ? AiToolkit.merge(options.toolkit, blueprintToolkit) : blueprintToolkit;
|
|
168
|
+
const toolkitWithBlueprintHandlers = yield* toolkit.pipe(Effect.provide(blueprintToolkitHandler));
|
|
169
|
+
log.info("run", {
|
|
170
|
+
systemPrompt: [
|
|
171
|
+
systemPrompt.slice(0, 32),
|
|
172
|
+
"...",
|
|
173
|
+
systemPrompt.slice(-32),
|
|
174
|
+
systemPrompt.length
|
|
175
|
+
].join(" "),
|
|
176
|
+
tools: Object.keys(blueprintToolkit.tools)
|
|
192
177
|
}, {
|
|
193
|
-
F:
|
|
194
|
-
L:
|
|
178
|
+
F: __dxlog_file,
|
|
179
|
+
L: 155,
|
|
195
180
|
S: this,
|
|
196
181
|
C: (f, a) => f(...a)
|
|
197
182
|
});
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (isToolUse(message)) {
|
|
210
|
-
log2("tool request...", void 0, {
|
|
211
|
-
F: __dxlog_file2,
|
|
212
|
-
L: 233,
|
|
213
|
-
S: this,
|
|
214
|
-
C: (f, a) => f(...a)
|
|
215
|
-
});
|
|
216
|
-
const response = await runTools({
|
|
217
|
-
message: this._pending.at(-1),
|
|
218
|
-
tools,
|
|
219
|
-
extensions: options.extensions ?? {},
|
|
220
|
-
reportStatus: (status) => this._onToolStatusReport(message, status)
|
|
221
|
-
});
|
|
222
|
-
log2("tool response", {
|
|
223
|
-
response
|
|
224
|
-
}, {
|
|
225
|
-
F: __dxlog_file2,
|
|
226
|
-
L: 241,
|
|
227
|
-
S: this,
|
|
228
|
-
C: (f, a) => f(...a)
|
|
229
|
-
});
|
|
230
|
-
switch (response.type) {
|
|
231
|
-
case "continue": {
|
|
232
|
-
this._pending = [
|
|
233
|
-
...this._pending,
|
|
234
|
-
response.message
|
|
235
|
-
];
|
|
236
|
-
this.userMessage.emit(response.message);
|
|
237
|
-
more = true;
|
|
238
|
-
break;
|
|
183
|
+
const blocks = yield* AiLanguageModel.streamText({
|
|
184
|
+
prompt,
|
|
185
|
+
system: systemPrompt,
|
|
186
|
+
toolkit: toolkitWithBlueprintHandlers,
|
|
187
|
+
disableToolCallResolution: true
|
|
188
|
+
}).pipe(AiParser.parseGptStream({
|
|
189
|
+
onBlock: (block) => Effect.gen(this, function* () {
|
|
190
|
+
if (block.pending) {
|
|
191
|
+
this.update.emit(block);
|
|
192
|
+
} else {
|
|
193
|
+
this.block.emit(block);
|
|
239
194
|
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
} while (more);
|
|
243
|
-
} catch (err) {
|
|
244
|
-
log2.catch(err, void 0, {
|
|
245
|
-
F: __dxlog_file2,
|
|
246
|
-
L: 253,
|
|
247
|
-
S: this,
|
|
248
|
-
C: (f, a) => f(...a)
|
|
249
|
-
});
|
|
250
|
-
if (err instanceof Error && err.message.includes("Overloaded")) {
|
|
251
|
-
error = new AIServiecOverloadedError("AI service overloaded", {
|
|
252
|
-
cause: err
|
|
253
|
-
});
|
|
254
|
-
} else {
|
|
255
|
-
error = new Error("AI service error", {
|
|
256
|
-
cause: err
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
} finally {
|
|
260
|
-
this._stream = void 0;
|
|
261
|
-
}
|
|
262
|
-
if (error) {
|
|
263
|
-
throw error;
|
|
264
|
-
}
|
|
265
|
-
return this._pending;
|
|
266
|
-
}
|
|
267
|
-
async runStructured(schema, options) {
|
|
268
|
-
const parser = structuredOutputParser(schema);
|
|
269
|
-
const result = await this.run({
|
|
270
|
-
...options,
|
|
271
|
-
tools: [
|
|
272
|
-
...options.tools,
|
|
273
|
-
parser.tool
|
|
274
|
-
]
|
|
275
|
-
});
|
|
276
|
-
return parser.getResult(result);
|
|
277
|
-
}
|
|
278
|
-
async _formatUserPrompt(artifactDiffResolver, prompt, history) {
|
|
279
|
-
const prelude = [];
|
|
280
|
-
if (artifactDiffResolver) {
|
|
281
|
-
const versions = gatherObjectVersions(history);
|
|
282
|
-
const artifactDiff = await artifactDiffResolver(Array.from(versions.entries()).map(([id, version]) => ({
|
|
283
|
-
id,
|
|
284
|
-
lastVersion: version
|
|
285
|
-
})));
|
|
286
|
-
log2.info("vision", {
|
|
287
|
-
artifactDiff,
|
|
288
|
-
versions
|
|
289
|
-
}, {
|
|
290
|
-
F: __dxlog_file2,
|
|
291
|
-
L: 296,
|
|
292
|
-
S: this,
|
|
293
|
-
C: (f, a) => f(...a)
|
|
294
|
-
});
|
|
295
|
-
for (const [id, { version }] of [
|
|
296
|
-
...artifactDiff.entries()
|
|
297
|
-
]) {
|
|
298
|
-
if (ObjectVersion.equals(version, versions.get(id))) {
|
|
299
|
-
artifactDiff.delete(id);
|
|
300
|
-
continue;
|
|
301
|
-
}
|
|
302
|
-
prelude.push(VersionPin.createBlock(VersionPin.make({
|
|
303
|
-
objectId: id,
|
|
304
|
-
version
|
|
305
|
-
})));
|
|
306
|
-
}
|
|
307
|
-
if (artifactDiff.size > 0) {
|
|
308
|
-
prelude.push(createArtifactUpdateBlock(artifactDiff));
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
return Obj.make(Message, {
|
|
312
|
-
role: "user",
|
|
313
|
-
content: [
|
|
314
|
-
...prelude,
|
|
315
|
-
{
|
|
316
|
-
type: "text",
|
|
317
|
-
text: prompt
|
|
318
|
-
}
|
|
319
|
-
]
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
_createQueryArtifactsTool(artifacts) {
|
|
323
|
-
return createTool("system", {
|
|
324
|
-
name: "query_artifact_definitions",
|
|
325
|
-
description: "Query the available artifact definitions",
|
|
326
|
-
schema: Schema3.Struct({}),
|
|
327
|
-
execute: async () => {
|
|
328
|
-
return ToolResult.Success({
|
|
329
|
-
artifactDefinitions: artifacts.map((artifact) => ({
|
|
330
|
-
id: artifact.id,
|
|
331
|
-
name: artifact.name,
|
|
332
|
-
description: artifact.description
|
|
333
|
-
}))
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
_createRequireTool(artifacts, onRequire) {
|
|
339
|
-
return createTool("system", {
|
|
340
|
-
name: "require_artifact_definitions",
|
|
341
|
-
description: "Require the use of specific artifact definitions. This will allow the model to interact with artifact definitions and use their tools.",
|
|
342
|
-
schema: Schema3.Struct({
|
|
343
|
-
artifactDefinitionIds: Schema3.Array(Schema3.String).annotations({
|
|
344
|
-
description: "The ids of the artifact definitions to require",
|
|
345
|
-
examples: [
|
|
346
|
-
[
|
|
347
|
-
"artifact:dxos.org/example/Test"
|
|
348
|
-
]
|
|
349
|
-
]
|
|
350
|
-
})
|
|
351
|
-
}),
|
|
352
|
-
execute: async ({ artifactDefinitionIds }) => {
|
|
353
|
-
const missingArtifactDefinitionIds = artifactDefinitionIds.filter((artifactId) => !artifacts.some((artifact) => artifact.id === artifactId));
|
|
354
|
-
if (missingArtifactDefinitionIds.length > 0) {
|
|
355
|
-
return ToolResult.Error(`One or more artifact definition ids are invalid: ${missingArtifactDefinitionIds.join(", ")}`);
|
|
356
|
-
}
|
|
357
|
-
onRequire(artifactDefinitionIds);
|
|
358
|
-
return ToolResult.Success({});
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
_createPlanningTool(options) {
|
|
363
|
-
return createTool("system", {
|
|
364
|
-
name: "create_plan",
|
|
365
|
-
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: Schema3.Struct({
|
|
367
|
-
goal: Schema3.String.annotations({
|
|
368
|
-
description: "The goal that the plan will achieve."
|
|
369
|
-
}),
|
|
370
|
-
steps: Schema3.Array(Schema3.Struct({
|
|
371
|
-
action: Schema3.String.annotations({
|
|
372
|
-
description: "Complete, detailed action to perform."
|
|
373
|
-
}),
|
|
374
|
-
input: Schema3.String.annotations({
|
|
375
|
-
description: "The required input data for this step. First step must not require any data."
|
|
376
195
|
}),
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}),
|
|
380
|
-
requiredArtifactIds: Schema3.Array(Schema3.String).annotations({
|
|
381
|
-
description: "The ids of the artifacts required to perform this step.",
|
|
382
|
-
examples: [
|
|
383
|
-
[
|
|
384
|
-
"artifact:dxos.org/example/Test"
|
|
385
|
-
]
|
|
386
|
-
]
|
|
196
|
+
onPart: (part) => Effect.gen(this, function* () {
|
|
197
|
+
this.streamEvent.emit(part);
|
|
387
198
|
})
|
|
388
|
-
})
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
199
|
+
}), Stream.runCollect, Effect.map(Chunk.toArray));
|
|
200
|
+
const response = Obj2.make(DataType.Message, {
|
|
201
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
202
|
+
sender: {
|
|
203
|
+
role: "assistant"
|
|
204
|
+
},
|
|
205
|
+
blocks
|
|
206
|
+
});
|
|
207
|
+
this._pending.push(response);
|
|
208
|
+
this.message.emit(response);
|
|
209
|
+
const toolCalls = getToolCalls(response);
|
|
210
|
+
if (toolCalls.length === 0) {
|
|
211
|
+
break;
|
|
396
212
|
}
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
213
|
+
const toolResults = yield* runTools(toolCalls, toolkitWithBlueprintHandlers);
|
|
214
|
+
this._pending.push(Obj2.make(DataType.Message, {
|
|
215
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
216
|
+
sender: {
|
|
217
|
+
role: "user"
|
|
218
|
+
},
|
|
219
|
+
blocks: toolResults
|
|
220
|
+
}));
|
|
221
|
+
} while (true);
|
|
222
|
+
return this._pending;
|
|
223
|
+
}).pipe(this._semaphore.withPermits(1), Effect.withSpan("AiSession.run"));
|
|
224
|
+
this._formatUserPrompt = (prompt, history) => Effect.gen(function* () {
|
|
225
|
+
const prelude = [];
|
|
226
|
+
const artifactDiffResolver = yield* Effect.serviceOption(ArtifactDiffResolver);
|
|
227
|
+
if (Option.isSome(artifactDiffResolver)) {
|
|
228
|
+
const versions = gatherObjectVersions(history);
|
|
229
|
+
const artifactDiff = yield* Effect.tryPromise({
|
|
230
|
+
try: () => artifactDiffResolver.value.resolve([
|
|
231
|
+
...versions.entries()
|
|
232
|
+
].map(([id, version]) => ({
|
|
233
|
+
id,
|
|
234
|
+
lastVersion: version
|
|
235
|
+
}))),
|
|
236
|
+
catch: AiAssistantError.wrap("Artifact diff resolution error")
|
|
237
|
+
});
|
|
238
|
+
log.info("vision", {
|
|
239
|
+
artifactDiff,
|
|
240
|
+
versions
|
|
241
|
+
}, {
|
|
242
|
+
F: __dxlog_file,
|
|
243
|
+
L: 240,
|
|
244
|
+
S: this,
|
|
245
|
+
C: (f, a) => f(...a)
|
|
246
|
+
});
|
|
247
|
+
for (const [id, { version }] of [
|
|
248
|
+
...artifactDiff.entries()
|
|
249
|
+
]) {
|
|
250
|
+
if (ObjectVersion.equals(version, versions.get(id))) {
|
|
251
|
+
artifactDiff.delete(id);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
prelude.push({
|
|
255
|
+
_tag: "anchor",
|
|
256
|
+
objectId: id,
|
|
257
|
+
version
|
|
442
258
|
});
|
|
443
|
-
const result = messages.at(-1);
|
|
444
|
-
stepResults.push(result);
|
|
445
259
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
260
|
+
if (artifactDiff.size > 0) {
|
|
261
|
+
prelude.push(createArtifactUpdateBlock(artifactDiff));
|
|
262
|
+
}
|
|
449
263
|
}
|
|
264
|
+
return Obj2.make(DataType.Message, {
|
|
265
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
266
|
+
sender: {
|
|
267
|
+
role: "user"
|
|
268
|
+
},
|
|
269
|
+
blocks: [
|
|
270
|
+
...prelude,
|
|
271
|
+
{
|
|
272
|
+
_tag: "text",
|
|
273
|
+
text: prompt
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
});
|
|
450
277
|
});
|
|
451
278
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
message,
|
|
455
|
-
status
|
|
456
|
-
});
|
|
279
|
+
async runStructured(schema, options) {
|
|
280
|
+
return todo();
|
|
457
281
|
}
|
|
458
282
|
abort() {
|
|
459
283
|
this._stream?.abort();
|
|
460
284
|
}
|
|
461
285
|
};
|
|
462
|
-
_ts_decorate([
|
|
463
|
-
synchronized
|
|
464
|
-
], AISession.prototype, "run", null);
|
|
465
|
-
var createBaseInstructions = ({ availableArtifacts, operationModel }) => `
|
|
466
|
-
You are a friendly, advanced AI assistant capable of creating and managing artifacts from available data and tools.
|
|
467
|
-
Your task is to process user commands and questions and decide how best to respond.
|
|
468
|
-
In some cases, you will need to create or reference data objects called artifacts.
|
|
469
|
-
|
|
470
|
-
Follow these guidelines carefully:
|
|
471
|
-
|
|
472
|
-
Decision-making:
|
|
473
|
-
|
|
474
|
-
- Analyze the structure and type of the content in the user's message.
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
${operationModel === "planning" ? `
|
|
478
|
-
- Can you complete the task using the available artifacts?
|
|
479
|
-
- If you can't complete the task using the available artifacts, query the list of available artifacts using the appropriate tool.
|
|
480
|
-
- Identify which artifacts are relevant to the user's request.
|
|
481
|
-
- Break down the user's request into a step-by-step plan that you will use to execute the user's request, the plan items should include artifacts which will be used to perform the actions.
|
|
482
|
-
` : ""}
|
|
483
|
-
${operationModel === "importing" ? `
|
|
484
|
-
- Can you complete the task using the available artifacts?
|
|
485
|
-
- If you can't complete the task using the available artifacts, query the list of available artifacts using the appropriate tool.
|
|
486
|
-
- Identify which artifacts are relevant to the user's request.
|
|
487
|
-
- Are the required artifacts already available?
|
|
488
|
-
- If not, select which artifact(s) will be the most relevant and require them using the require_artifacts tool.
|
|
489
|
-
- The require'd artifact tools will be available for use after require.
|
|
490
|
-
` : ""}
|
|
491
|
-
${operationModel === "configured" ? `
|
|
492
|
-
- Select the most relevant artifact(s) to complete the task.
|
|
493
|
-
- Call the appropriate tool to use the artifact(s).
|
|
494
|
-
` : ""}
|
|
495
|
-
|
|
496
|
-
${availableArtifacts.length > 0 ? `Artifacts already in context: ${availableArtifacts.join("\n")}` : ""}
|
|
497
|
-
`;
|
|
498
|
-
var AIServiecOverloadedError = class extends Schema3.TaggedError()("AIServiecOverloadedError", {}) {
|
|
499
|
-
};
|
|
500
286
|
var gatherObjectVersions = (messages) => {
|
|
501
287
|
const artifactIds = /* @__PURE__ */ new Map();
|
|
502
288
|
for (const message of messages) {
|
|
503
|
-
for (const block of message.
|
|
504
|
-
if (block.
|
|
505
|
-
|
|
506
|
-
if (!pin) {
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
artifactIds.set(pin.objectId, pin.version);
|
|
289
|
+
for (const block of message.blocks) {
|
|
290
|
+
if (block._tag === "anchor") {
|
|
291
|
+
artifactIds.set(block.objectId, block.version);
|
|
510
292
|
}
|
|
511
293
|
}
|
|
512
294
|
}
|
|
@@ -514,23 +296,153 @@ var gatherObjectVersions = (messages) => {
|
|
|
514
296
|
};
|
|
515
297
|
var createArtifactUpdateBlock = (artifactDiff) => {
|
|
516
298
|
return {
|
|
517
|
-
|
|
299
|
+
_tag: "text",
|
|
300
|
+
// TODO(dmaretskyi): Does this need to be a special content-block?
|
|
518
301
|
disposition: "artifact-update",
|
|
519
302
|
text: `
|
|
520
303
|
The following artifacts have been updated since the last message:
|
|
521
|
-
${
|
|
304
|
+
${[
|
|
305
|
+
...artifactDiff.entries()
|
|
306
|
+
].map(([id, { diff }]) => `<changed-artifact id="${id}">${diff ? `
|
|
522
307
|
${diff}` : ""}</changed-artifact>`).join("\n")}
|
|
523
308
|
`
|
|
524
309
|
};
|
|
525
310
|
};
|
|
311
|
+
var ArtifactDiffResolver = class extends Context.Tag("ArtifactDiffResolver")() {
|
|
312
|
+
};
|
|
313
|
+
var runTools = Effect.fn("runTools")(function* (toolCalls, toolkit) {
|
|
314
|
+
const toolkitWithHandlers = Effect.isEffect(toolkit) ? yield* toolkit : toolkit;
|
|
315
|
+
return yield* Effect.forEach(toolCalls, (toolCall) => runTool(toolkitWithHandlers, toolCall));
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// src/session/version-pin.ts
|
|
319
|
+
import { Schema as Schema2 } from "effect";
|
|
320
|
+
import { getVersion } from "@dxos/echo-db";
|
|
321
|
+
import { ObjectId } from "@dxos/echo-schema";
|
|
322
|
+
var ObjectVersionSchema = Schema2.Unknown;
|
|
323
|
+
var VersionPinSchema = Schema2.Struct({
|
|
324
|
+
// TODO(dmaretskyi): Use Ref when those support encoding.
|
|
325
|
+
objectId: ObjectId,
|
|
326
|
+
// TODO(dmaretskyi): Could be opaque
|
|
327
|
+
version: ObjectVersionSchema
|
|
328
|
+
});
|
|
329
|
+
var VersionPin = class extends VersionPinSchema {
|
|
330
|
+
static {
|
|
331
|
+
this.DISPOSITION = "version-pin";
|
|
332
|
+
}
|
|
333
|
+
static fromObject(object) {
|
|
334
|
+
return VersionPin.make({
|
|
335
|
+
objectId: object.id,
|
|
336
|
+
version: getVersion(object)
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
static createBlock(pin) {
|
|
340
|
+
return {
|
|
341
|
+
_tag: "json",
|
|
342
|
+
disposition: VersionPin.DISPOSITION,
|
|
343
|
+
data: JSON.stringify(pin)
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
// src/conversation/conversation.ts
|
|
349
|
+
var Conversation = class {
|
|
350
|
+
constructor(options) {
|
|
351
|
+
/**
|
|
352
|
+
* Fired when the execution loop begins.
|
|
353
|
+
* This is called before the first message is sent.
|
|
354
|
+
*/
|
|
355
|
+
this.onBegin = new Event2();
|
|
356
|
+
this.run = (options) => Effect2.gen(this, function* () {
|
|
357
|
+
const session = new AiSession();
|
|
358
|
+
this.onBegin.emit(session);
|
|
359
|
+
const history = yield* Effect2.promise(() => this.getHistory());
|
|
360
|
+
const context = yield* Effect2.promise(() => this.context.query());
|
|
361
|
+
const blueprints = yield* Effect2.forEach(context.blueprints.values(), DatabaseService2.loadRef);
|
|
362
|
+
const contextObjects = yield* Effect2.forEach(context.objects.values(), DatabaseService2.loadRef);
|
|
363
|
+
const systemPrompt = (options.systemPrompt ?? "") + "\n\n" + contextObjects.map((obj) => `<object>${Obj3.getDXN(obj)}</object>`).join("\n");
|
|
364
|
+
const messages = yield* session.run({
|
|
365
|
+
prompt: options.prompt,
|
|
366
|
+
history,
|
|
367
|
+
systemPrompt,
|
|
368
|
+
toolkit: options.toolkit,
|
|
369
|
+
blueprints
|
|
370
|
+
});
|
|
371
|
+
yield* Effect2.promise(() => this._queue.append(messages));
|
|
372
|
+
return messages;
|
|
373
|
+
}).pipe(Effect2.withSpan("Conversation.run"));
|
|
374
|
+
this._queue = options.queue;
|
|
375
|
+
this.context = new ContextBinder(this._queue);
|
|
376
|
+
}
|
|
377
|
+
async getHistory() {
|
|
378
|
+
const queueItems = await this._queue.queryObjects();
|
|
379
|
+
return queueItems.filter(Obj3.instanceOf(DataType2.Message));
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
// src/extraction/extraction.ts
|
|
384
|
+
import { Schema as Schema3 } from "effect";
|
|
385
|
+
import { asyncTimeout } from "@dxos/async";
|
|
386
|
+
import { Expando } from "@dxos/echo-schema";
|
|
387
|
+
import { log as log2 } from "@dxos/log";
|
|
388
|
+
import { DataType as DataType3 } from "@dxos/schema";
|
|
389
|
+
var __dxlog_file2 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction.ts";
|
|
390
|
+
var ExtractionInput = Schema3.Struct({
|
|
391
|
+
message: DataType3.Message,
|
|
392
|
+
objects: Schema3.optional(Schema3.Array(Expando)),
|
|
393
|
+
options: Schema3.optional(Schema3.Struct({
|
|
394
|
+
timeout: Schema3.optional(Schema3.Number),
|
|
395
|
+
fallbackToRaw: Schema3.optional(Schema3.Boolean)
|
|
396
|
+
}))
|
|
397
|
+
});
|
|
398
|
+
var ExtractionOutput = Schema3.Struct({
|
|
399
|
+
message: DataType3.Message,
|
|
400
|
+
timeElapsed: Schema3.Number
|
|
401
|
+
});
|
|
402
|
+
var processTranscriptMessage = async (params) => {
|
|
403
|
+
try {
|
|
404
|
+
if (params.options?.timeout && params.options.timeout > 0) {
|
|
405
|
+
return await asyncTimeout(params.executor.invoke(params.function, params.input), params.options.timeout);
|
|
406
|
+
} else {
|
|
407
|
+
return await params.executor.invoke(params.function, params.input);
|
|
408
|
+
}
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (params.options?.fallbackToRaw) {
|
|
411
|
+
log2.warn("failed to process message, falling back to raw text", {
|
|
412
|
+
error
|
|
413
|
+
}, {
|
|
414
|
+
F: __dxlog_file2,
|
|
415
|
+
L: 66,
|
|
416
|
+
S: void 0,
|
|
417
|
+
C: (f, a) => f(...a)
|
|
418
|
+
});
|
|
419
|
+
return {
|
|
420
|
+
message: params.input.message,
|
|
421
|
+
timeElapsed: 0
|
|
422
|
+
};
|
|
423
|
+
} else {
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
};
|
|
526
428
|
|
|
527
|
-
//
|
|
429
|
+
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
430
|
+
import { ToolRegistry, AiService } from "@dxos/ai";
|
|
431
|
+
import { Obj as Obj4 } from "@dxos/echo";
|
|
432
|
+
import { create } from "@dxos/echo-schema";
|
|
433
|
+
import { defineFunction } from "@dxos/functions";
|
|
434
|
+
import { DataType as DataType4 } from "@dxos/schema";
|
|
435
|
+
|
|
436
|
+
// raw-loader:./instructions.tpl?raw
|
|
437
|
+
var instructions_default = 'You are an AI assistant specialized in processing and enhancing transcripts with contextual information.\nYour task is to analyze a given transcript and extract references to the context objects.\n\nThe context and transcript are provided in the user message in `context` and `transcript` XML tags.\n\nHere are your instructions:\n\n1. Read the transcript and context information provided above.\n\n2. Process each segment of the transcript separately.\n\n3. For each segment:\n a. Analyze the content and identify relevant information from the context.\n b. Extract a number of references to the context objects that are mentioned in the segment.\n c. Output the references in the format `{ "quote": "earnings report", "id": "01JT0JP9AX0XKGZX4MV4B69VT6" }`.\n d. If there are no references, just output an empty array.\n\n4. Maintain the exact order and structure of the original transcript segments.\n\nOutput Format:\nYou have been provided with a tool that specifies output format\n\nRemember:\n- Only quote the text that is in the transcript.\n- Analyze each segment carefully before processing it.\n- Only reference objects that appear in the context and exactly by their id, If the object is not in the context, do not insert a reference. \n\nNow, process the transcript and context provided below according to these instructions.';
|
|
438
|
+
|
|
439
|
+
// src/extraction/quotes.ts
|
|
528
440
|
import { Schema as Schema4 } from "effect";
|
|
529
441
|
import { Query, Filter } from "@dxos/echo";
|
|
530
442
|
import { ObjectId as ObjectId2 } from "@dxos/echo-schema";
|
|
531
443
|
import { DXN } from "@dxos/keys";
|
|
532
444
|
import { log as log3 } from "@dxos/log";
|
|
533
|
-
var __dxlog_file3 = "/
|
|
445
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/quotes.ts";
|
|
534
446
|
var ReferencedQuotes = Schema4.Struct({
|
|
535
447
|
references: Schema4.Array(Schema4.Struct({
|
|
536
448
|
id: Schema4.String,
|
|
@@ -579,7 +491,7 @@ var insertReferences = (text, quotes) => {
|
|
|
579
491
|
return text;
|
|
580
492
|
};
|
|
581
493
|
|
|
582
|
-
//
|
|
494
|
+
// src/extraction/extraction-llm-function/extraction-llm-function.ts
|
|
583
495
|
var extractionAnthropicFn = defineFunction({
|
|
584
496
|
description: "Extract entities from the transcript message and add them to the message.",
|
|
585
497
|
inputSchema: ExtractionInput,
|
|
@@ -587,7 +499,7 @@ var extractionAnthropicFn = defineFunction({
|
|
|
587
499
|
handler: async ({ data: { message, objects }, context }) => {
|
|
588
500
|
const startTime = performance.now();
|
|
589
501
|
const ai = context.getService(AiService);
|
|
590
|
-
const session = new
|
|
502
|
+
const session = new AiSession({
|
|
591
503
|
operationModel: "configured"
|
|
592
504
|
});
|
|
593
505
|
const result = await session.runStructured(ReferencedQuotes, {
|
|
@@ -597,15 +509,18 @@ var extractionAnthropicFn = defineFunction({
|
|
|
597
509
|
client: ai.client,
|
|
598
510
|
systemPrompt: instructions_default,
|
|
599
511
|
history: [
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
512
|
+
Obj4.make(DataType4.Message, {
|
|
513
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
514
|
+
sender: {
|
|
515
|
+
role: "user"
|
|
516
|
+
},
|
|
517
|
+
blocks: [
|
|
603
518
|
{
|
|
604
|
-
|
|
519
|
+
_tag: "text",
|
|
605
520
|
text: `<context>${JSON.stringify(objects)}</context>`
|
|
606
521
|
},
|
|
607
522
|
{
|
|
608
|
-
|
|
523
|
+
_tag: "text",
|
|
609
524
|
text: `<transcript>${JSON.stringify(message.blocks)}</transcript>`
|
|
610
525
|
}
|
|
611
526
|
]
|
|
@@ -613,12 +528,13 @@ var extractionAnthropicFn = defineFunction({
|
|
|
613
528
|
],
|
|
614
529
|
artifacts: [],
|
|
615
530
|
prompt: "",
|
|
616
|
-
tools: []
|
|
531
|
+
tools: [],
|
|
532
|
+
toolResolver: new ToolRegistry([])
|
|
617
533
|
});
|
|
618
534
|
return {
|
|
619
|
-
message:
|
|
535
|
+
message: create(DataType4.Message, {
|
|
620
536
|
...message,
|
|
621
|
-
blocks: message.blocks.map((block, i) => block.
|
|
537
|
+
blocks: message.blocks.map((block, i) => block._tag !== "transcript" ? block : {
|
|
622
538
|
...block,
|
|
623
539
|
text: insertReferences(block.text, result)
|
|
624
540
|
})
|
|
@@ -628,18 +544,18 @@ var extractionAnthropicFn = defineFunction({
|
|
|
628
544
|
}
|
|
629
545
|
});
|
|
630
546
|
|
|
631
|
-
//
|
|
547
|
+
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
632
548
|
import { asyncTimeout as asyncTimeout2 } from "@dxos/async";
|
|
633
|
-
import { create as
|
|
634
|
-
import { DatabaseService, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
635
|
-
import { invariant
|
|
549
|
+
import { create as create2 } from "@dxos/echo-schema";
|
|
550
|
+
import { DatabaseService as DatabaseService3, defineFunction as defineFunction2 } from "@dxos/functions";
|
|
551
|
+
import { invariant } from "@dxos/invariant";
|
|
636
552
|
import { log as log5 } from "@dxos/log";
|
|
637
|
-
import { DataType as
|
|
553
|
+
import { DataType as DataType5 } from "@dxos/schema";
|
|
638
554
|
|
|
639
|
-
//
|
|
555
|
+
// src/extraction/extraction-ner-function/named-entity-recognition.ts
|
|
640
556
|
import { pipeline } from "@xenova/transformers";
|
|
641
557
|
import { log as log4 } from "@dxos/log";
|
|
642
|
-
var __dxlog_file4 = "/
|
|
558
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/named-entity-recognition.ts";
|
|
643
559
|
var _ner;
|
|
644
560
|
var getNer = () => {
|
|
645
561
|
if (!_ner) {
|
|
@@ -718,8 +634,8 @@ var combineNerTokens = (group) => {
|
|
|
718
634
|
return combinedToken;
|
|
719
635
|
};
|
|
720
636
|
|
|
721
|
-
//
|
|
722
|
-
var __dxlog_file5 = "/
|
|
637
|
+
// src/extraction/extraction-ner-function/extraction-ner-function.ts
|
|
638
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/core/assistant/src/extraction/extraction-ner-function/extraction-ner-function.ts";
|
|
723
639
|
var extractionNerFn = defineFunction2({
|
|
724
640
|
description: "Extracts named entities from a text",
|
|
725
641
|
inputSchema: ExtractionInput,
|
|
@@ -730,19 +646,19 @@ var extractionNerFn = defineFunction2({
|
|
|
730
646
|
options
|
|
731
647
|
}, {
|
|
732
648
|
F: __dxlog_file5,
|
|
733
|
-
L:
|
|
649
|
+
L: 25,
|
|
734
650
|
S: void 0,
|
|
735
651
|
C: (f, a) => f(...a)
|
|
736
652
|
});
|
|
737
653
|
const startTime = performance.now();
|
|
738
|
-
const { db } = context.getService(
|
|
654
|
+
const { db } = context.getService(DatabaseService3);
|
|
739
655
|
const entitiesPromise = Promise.all(message.blocks.map(async (block) => {
|
|
740
|
-
|
|
656
|
+
invariant(block._tag === "transcript" || block._tag === "text", "Block must have text", {
|
|
741
657
|
F: __dxlog_file5,
|
|
742
|
-
L:
|
|
658
|
+
L: 31,
|
|
743
659
|
S: void 0,
|
|
744
660
|
A: [
|
|
745
|
-
"block.
|
|
661
|
+
"block._tag === 'transcript' || block._tag === 'text'",
|
|
746
662
|
"'Block must have text'"
|
|
747
663
|
]
|
|
748
664
|
});
|
|
@@ -753,27 +669,27 @@ var extractionNerFn = defineFunction2({
|
|
|
753
669
|
entities
|
|
754
670
|
}, {
|
|
755
671
|
F: __dxlog_file5,
|
|
756
|
-
L:
|
|
672
|
+
L: 36,
|
|
757
673
|
S: void 0,
|
|
758
674
|
C: (f, a) => f(...a)
|
|
759
675
|
});
|
|
760
676
|
const quoteReferences = await findQuotes(entities.map((entity) => entity.word), db);
|
|
761
677
|
const blocksWithReferences = message.blocks.map((block, i) => {
|
|
762
|
-
|
|
678
|
+
invariant(block._tag === "transcript" || block._tag === "text", "Block must have text", {
|
|
763
679
|
F: __dxlog_file5,
|
|
764
|
-
L:
|
|
680
|
+
L: 42,
|
|
765
681
|
S: void 0,
|
|
766
682
|
A: [
|
|
767
|
-
"block.
|
|
683
|
+
"block._tag === 'transcript' || block._tag === 'text'",
|
|
768
684
|
"'Block must have text'"
|
|
769
685
|
]
|
|
770
686
|
});
|
|
771
687
|
return {
|
|
772
688
|
...block,
|
|
773
|
-
text: insertReferences(block.
|
|
689
|
+
text: insertReferences(block._tag, quoteReferences)
|
|
774
690
|
};
|
|
775
691
|
});
|
|
776
|
-
const messageWithReferences =
|
|
692
|
+
const messageWithReferences = create2(DataType5.Message, {
|
|
777
693
|
...message,
|
|
778
694
|
blocks: blocksWithReferences
|
|
779
695
|
});
|
|
@@ -781,7 +697,7 @@ var extractionNerFn = defineFunction2({
|
|
|
781
697
|
messageWithReferences
|
|
782
698
|
}, {
|
|
783
699
|
F: __dxlog_file5,
|
|
784
|
-
L:
|
|
700
|
+
L: 50,
|
|
785
701
|
S: void 0,
|
|
786
702
|
C: (f, a) => f(...a)
|
|
787
703
|
});
|
|
@@ -792,13 +708,129 @@ var extractionNerFn = defineFunction2({
|
|
|
792
708
|
}
|
|
793
709
|
});
|
|
794
710
|
|
|
795
|
-
//
|
|
796
|
-
import {
|
|
711
|
+
// src/functions/services.ts
|
|
712
|
+
import { AiTool } from "@effect/ai";
|
|
713
|
+
import { Context as Context2, Effect as Effect3, Layer, Match, Predicate, Record, Schema as Schema5 } from "effect";
|
|
714
|
+
import { AiToolNotFoundError, ToolExecutionService as ToolExecutionService2, ToolResolverService as ToolResolverService2 } from "@dxos/ai";
|
|
715
|
+
import { todo as todo2 } from "@dxos/debug";
|
|
716
|
+
import { FunctionError } from "@dxos/functions";
|
|
717
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
718
|
+
var __dxlog_file6 = "/__w/dxos/dxos/packages/core/assistant/src/functions/services.ts";
|
|
719
|
+
var makeToolResolverFromFunctions = (functions) => {
|
|
720
|
+
return Layer.succeed(ToolResolverService2, {
|
|
721
|
+
resolve: Effect3.fn("resolveTool")(function* (id) {
|
|
722
|
+
const fn = functions.find((f) => f.name === id);
|
|
723
|
+
if (!fn) {
|
|
724
|
+
return yield* Effect3.fail(new AiToolNotFoundError(id));
|
|
725
|
+
}
|
|
726
|
+
return projectFunctionToTool(fn);
|
|
727
|
+
})
|
|
728
|
+
});
|
|
729
|
+
};
|
|
730
|
+
var makeToolExecutionServiceFromFunctions = (functions) => {
|
|
731
|
+
return Layer.succeed(ToolExecutionService2, {
|
|
732
|
+
handlersFor: (toolkit) => {
|
|
733
|
+
const makeHandler = (tool) => {
|
|
734
|
+
return Effect3.fn("toolFunctionHandler")(function* (input) {
|
|
735
|
+
const { functionName } = Context2.get(FunctionToolAnnotation)(tool.annotations);
|
|
736
|
+
const fnDef = functions.find((f) => f.name === functionName);
|
|
737
|
+
if (!fnDef) {
|
|
738
|
+
return yield* Effect3.fail(new AiToolNotFoundError(tool.name));
|
|
739
|
+
}
|
|
740
|
+
return yield* invokeFunction(fnDef, input).pipe(Effect3.catchAllDefect((defect) => Effect3.fail(defect)));
|
|
741
|
+
});
|
|
742
|
+
};
|
|
743
|
+
return toolkit.of(Record.map(toolkit.tools, (tool, name) => makeHandler(tool)));
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
var FunctionToolAnnotation = class extends Context2.Tag("@dxos/assisatnt/FunctionToolAnnotation")() {
|
|
748
|
+
};
|
|
749
|
+
var toolCache = /* @__PURE__ */ new WeakMap();
|
|
750
|
+
var projectFunctionToTool = (fn) => {
|
|
751
|
+
if (toolCache.has(fn)) {
|
|
752
|
+
return toolCache.get(fn);
|
|
753
|
+
}
|
|
754
|
+
const tool = AiTool.make(makeToolName(fn.name), {
|
|
755
|
+
description: fn.description,
|
|
756
|
+
parameters: createStructFieldsFromSchema(fn.inputSchema),
|
|
757
|
+
// TODO(dmaretskyi): Include output schema.
|
|
758
|
+
failure: Schema5.Any
|
|
759
|
+
}).annotate(FunctionToolAnnotation, {
|
|
760
|
+
functionName: fn.name
|
|
761
|
+
});
|
|
762
|
+
toolCache.set(fn, tool);
|
|
763
|
+
return tool;
|
|
764
|
+
};
|
|
765
|
+
var makeToolName = (name) => {
|
|
766
|
+
const toolName = name.replace(/[^a-zA-Z0-9]/g, "");
|
|
767
|
+
invariant2(toolName.match(/^[a-zA-Z_][a-zA-Z0-9-_]*$/), void 0, {
|
|
768
|
+
F: __dxlog_file6,
|
|
769
|
+
L: 80,
|
|
770
|
+
S: void 0,
|
|
771
|
+
A: [
|
|
772
|
+
"toolName.match(/^[a-zA-Z_][a-zA-Z0-9-_]*$/)",
|
|
773
|
+
""
|
|
774
|
+
]
|
|
775
|
+
});
|
|
776
|
+
return toolName;
|
|
777
|
+
};
|
|
778
|
+
var createStructFieldsFromSchema = (schema) => {
|
|
779
|
+
return Match.value(schema.ast).pipe(Match.when(Predicate.isTagged("TypeLiteral"), (ast) => {
|
|
780
|
+
return Object.fromEntries(ast.propertySignatures.map((prop) => [
|
|
781
|
+
prop.name,
|
|
782
|
+
Schema5.make(prop.type)
|
|
783
|
+
]));
|
|
784
|
+
}), Match.orElseAbsurd);
|
|
785
|
+
};
|
|
786
|
+
var invokeFunction = (fnDef, input) => Effect3.gen(function* () {
|
|
787
|
+
const assertInput = fnDef.inputSchema.pipe(Schema5.asserts);
|
|
788
|
+
assertInput(input);
|
|
789
|
+
const context = {
|
|
790
|
+
getService: () => todo2(),
|
|
791
|
+
getSpace: async (_spaceId) => {
|
|
792
|
+
throw new Error("Not available. Use the database service instead.");
|
|
793
|
+
},
|
|
794
|
+
space: void 0,
|
|
795
|
+
get ai() {
|
|
796
|
+
throw new Error("Not available. Use the ai service instead.");
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
const data = yield* Effect3.gen(function* () {
|
|
800
|
+
const result = fnDef.handler({
|
|
801
|
+
context,
|
|
802
|
+
data: input
|
|
803
|
+
});
|
|
804
|
+
if (Effect3.isEffect(result)) {
|
|
805
|
+
return yield* result.pipe(Effect3.orDie);
|
|
806
|
+
} else if (typeof result === "object" && result !== null && "then" in result && typeof result.then === "function") {
|
|
807
|
+
return yield* Effect3.promise(() => result);
|
|
808
|
+
} else {
|
|
809
|
+
return result;
|
|
810
|
+
}
|
|
811
|
+
}).pipe(Effect3.orDie, Effect3.catchAllDefect((defect) => Effect3.die(new FunctionError("Error running function", {
|
|
812
|
+
context: {
|
|
813
|
+
name: fnDef.name
|
|
814
|
+
},
|
|
815
|
+
cause: defect
|
|
816
|
+
}))));
|
|
817
|
+
const assertOutput = fnDef.outputSchema?.pipe(Schema5.asserts);
|
|
818
|
+
assertOutput(data);
|
|
819
|
+
return data;
|
|
820
|
+
}).pipe(Effect3.withSpan("invokeFunction", {
|
|
821
|
+
attributes: {
|
|
822
|
+
name: fnDef.name
|
|
823
|
+
}
|
|
824
|
+
}));
|
|
825
|
+
|
|
826
|
+
// src/research/exa.ts
|
|
827
|
+
import { AiTool as AiTool2, AiToolkit as AiToolkit2 } from "@effect/ai";
|
|
828
|
+
import { Effect as Effect4, Schema as Schema6 } from "effect";
|
|
797
829
|
import Exa from "exa-js";
|
|
798
|
-
import {
|
|
830
|
+
import { CredentialsService } from "@dxos/functions";
|
|
799
831
|
import { log as log6 } from "@dxos/log";
|
|
800
832
|
|
|
801
|
-
//
|
|
833
|
+
// src/testing/exa-search-1748337321991.ts
|
|
802
834
|
var exa_search_1748337321991_default = {
|
|
803
835
|
requestId: "324936368a74f4db978982172bc18a6c",
|
|
804
836
|
autopromptString: "AI personal knowledge management tools projects 2024",
|
|
@@ -954,7 +986,7 @@ var exa_search_1748337321991_default = {
|
|
|
954
986
|
}
|
|
955
987
|
};
|
|
956
988
|
|
|
957
|
-
//
|
|
989
|
+
// src/testing/exa-search-1748337331526.ts
|
|
958
990
|
var exa_search_1748337331526_default = {
|
|
959
991
|
requestId: "0dc12e344fa649884456960ca1a54954",
|
|
960
992
|
autopromptString: "PKM software artificial intelligence integration open source projects",
|
|
@@ -1177,7 +1209,7 @@ npm run tauri dev
|
|
|
1177
1209
|
}
|
|
1178
1210
|
};
|
|
1179
1211
|
|
|
1180
|
-
//
|
|
1212
|
+
// src/testing/exa-search-1748337344119.ts
|
|
1181
1213
|
var exa_search_1748337344119_default = {
|
|
1182
1214
|
requestId: "32df0c541f9883180b35e04caece4374",
|
|
1183
1215
|
autopromptString: "open source AI knowledge management projects features comparison 2024",
|
|
@@ -1300,73 +1332,69 @@ var exa_search_1748337344119_default = {
|
|
|
1300
1332
|
}
|
|
1301
1333
|
};
|
|
1302
1334
|
|
|
1303
|
-
//
|
|
1335
|
+
// src/testing/index.ts
|
|
1304
1336
|
var SEARCH_RESULTS = [
|
|
1305
1337
|
exa_search_1748337321991_default,
|
|
1306
1338
|
exa_search_1748337331526_default,
|
|
1307
1339
|
exa_search_1748337344119_default
|
|
1308
1340
|
];
|
|
1309
1341
|
|
|
1310
|
-
//
|
|
1311
|
-
var
|
|
1312
|
-
var
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
execute: async ({ query }) => {
|
|
1323
|
-
const context = await exa.searchAndContents(query, {
|
|
1324
|
-
type: "auto",
|
|
1325
|
-
text: {
|
|
1326
|
-
maxCharacters: 3e3
|
|
1327
|
-
},
|
|
1328
|
-
livecrawl: "always"
|
|
1329
|
-
});
|
|
1330
|
-
log6.info("exa search", {
|
|
1331
|
-
query,
|
|
1332
|
-
costDollars: context.costDollars
|
|
1333
|
-
}, {
|
|
1334
|
-
F: __dxlog_file6,
|
|
1335
|
-
L: 35,
|
|
1336
|
-
S: void 0,
|
|
1337
|
-
C: (f, a) => f(...a)
|
|
1338
|
-
});
|
|
1339
|
-
return ToolResult2.Success(context);
|
|
1340
|
-
}
|
|
1341
|
-
});
|
|
1342
|
-
};
|
|
1343
|
-
var createMockExaTool = () => {
|
|
1344
|
-
return createTool2("search", {
|
|
1345
|
-
name: "web_search",
|
|
1346
|
-
description: "Search the web for information",
|
|
1347
|
-
schema: Schema5.Struct({
|
|
1348
|
-
query: Schema5.String.annotations({
|
|
1349
|
-
description: "The query to search for"
|
|
1350
|
-
})
|
|
1351
|
-
}),
|
|
1352
|
-
execute: async ({ query }) => {
|
|
1353
|
-
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1354
|
-
if (!current.autopromptString) {
|
|
1355
|
-
return closest;
|
|
1356
|
-
}
|
|
1357
|
-
if (!closest) {
|
|
1358
|
-
return current;
|
|
1359
|
-
}
|
|
1360
|
-
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1361
|
-
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1362
|
-
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1363
|
-
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1364
|
-
return weight1 < weight2 ? current : closest;
|
|
1365
|
-
}, null);
|
|
1366
|
-
return ToolResult2.Success(result);
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1342
|
+
// src/research/exa.ts
|
|
1343
|
+
var __dxlog_file7 = "/__w/dxos/dxos/packages/core/assistant/src/research/exa.ts";
|
|
1344
|
+
var ExaToolkit = class extends AiToolkit2.make(AiTool2.make("exa_search", {
|
|
1345
|
+
description: "Search the web for information",
|
|
1346
|
+
parameters: {
|
|
1347
|
+
query: Schema6.String.annotations({
|
|
1348
|
+
description: "The query to search for"
|
|
1349
|
+
})
|
|
1350
|
+
},
|
|
1351
|
+
success: Schema6.Unknown,
|
|
1352
|
+
failure: Schema6.Never
|
|
1353
|
+
}).addRequirement()) {
|
|
1369
1354
|
};
|
|
1355
|
+
var LiveExaHandler = ExaToolkit.toLayer({
|
|
1356
|
+
exa_search: Effect4.fn(function* ({ query }) {
|
|
1357
|
+
const credential = yield* CredentialsService.getCredential({
|
|
1358
|
+
service: "exa.ai"
|
|
1359
|
+
});
|
|
1360
|
+
const exa = new Exa(credential.apiKey);
|
|
1361
|
+
const context = yield* Effect4.promise(async () => exa.searchAndContents(query, {
|
|
1362
|
+
type: "auto",
|
|
1363
|
+
text: {
|
|
1364
|
+
maxCharacters: 3e3
|
|
1365
|
+
},
|
|
1366
|
+
livecrawl: "always"
|
|
1367
|
+
}));
|
|
1368
|
+
log6.info("exa search", {
|
|
1369
|
+
query,
|
|
1370
|
+
costDollars: context.costDollars
|
|
1371
|
+
}, {
|
|
1372
|
+
F: __dxlog_file7,
|
|
1373
|
+
L: 40,
|
|
1374
|
+
S: this,
|
|
1375
|
+
C: (f, a) => f(...a)
|
|
1376
|
+
});
|
|
1377
|
+
return context;
|
|
1378
|
+
})
|
|
1379
|
+
});
|
|
1380
|
+
var MockExaHandler = ExaToolkit.toLayer({
|
|
1381
|
+
exa_search: Effect4.fn(function* ({ query }) {
|
|
1382
|
+
const result = SEARCH_RESULTS.reduce((closest, current) => {
|
|
1383
|
+
if (!current.autopromptString) {
|
|
1384
|
+
return closest;
|
|
1385
|
+
}
|
|
1386
|
+
if (!closest) {
|
|
1387
|
+
return current;
|
|
1388
|
+
}
|
|
1389
|
+
const dist1 = levenshteinDistance(query, current.autopromptString);
|
|
1390
|
+
const dist2 = levenshteinDistance(query, closest.autopromptString || "");
|
|
1391
|
+
const weight1 = dist1 / Math.max(query.length, current.autopromptString.length);
|
|
1392
|
+
const weight2 = dist2 / Math.max(query.length, closest.autopromptString?.length || 0);
|
|
1393
|
+
return weight1 < weight2 ? current : closest;
|
|
1394
|
+
}, null);
|
|
1395
|
+
return result;
|
|
1396
|
+
})
|
|
1397
|
+
});
|
|
1370
1398
|
var levenshteinDistance = (str1, str2) => {
|
|
1371
1399
|
const m = str1.length;
|
|
1372
1400
|
const n = str2.length;
|
|
@@ -1385,28 +1413,29 @@ var levenshteinDistance = (str1, str2) => {
|
|
|
1385
1413
|
return dp[m][n];
|
|
1386
1414
|
};
|
|
1387
1415
|
|
|
1388
|
-
//
|
|
1389
|
-
import {
|
|
1390
|
-
import {
|
|
1391
|
-
import {
|
|
1392
|
-
import {
|
|
1416
|
+
// src/research/research.ts
|
|
1417
|
+
import { AiToolkit as AiToolkit4 } from "@effect/ai";
|
|
1418
|
+
import { Effect as Effect6, Layer as Layer2, Schema as Schema8 } from "effect";
|
|
1419
|
+
import { AiService as AiService2, ConsolePrinter } from "@dxos/ai";
|
|
1420
|
+
import { defineFunction as defineFunction3, TracingService } from "@dxos/functions";
|
|
1393
1421
|
import { log as log8 } from "@dxos/log";
|
|
1394
1422
|
import { DataTypes } from "@dxos/schema";
|
|
1395
1423
|
|
|
1396
|
-
//
|
|
1397
|
-
import {
|
|
1398
|
-
import {
|
|
1399
|
-
import {
|
|
1424
|
+
// src/research/graph.ts
|
|
1425
|
+
import { AiTool as AiTool3, AiToolkit as AiToolkit3 } from "@effect/ai";
|
|
1426
|
+
import { Context as Context3, Effect as Effect5, identity, Option as Option2, Schema as Schema7, SchemaAST } from "effect";
|
|
1427
|
+
import { Filter as Filter2, Query as Query2 } from "@dxos/echo";
|
|
1400
1428
|
import { isEncodedReference } from "@dxos/echo-protocol";
|
|
1401
|
-
import {
|
|
1429
|
+
import { create as create3, EntityKind, getEntityKind, getSchemaDXN, getSchemaTypename, getTypeAnnotation, getTypeIdentifierAnnotation, ObjectId as ObjectId3, ReferenceAnnotationId, RelationSourceDXNId, RelationSourceId, RelationTargetDXNId, RelationTargetId } from "@dxos/echo-schema";
|
|
1402
1430
|
import { mapAst } from "@dxos/effect";
|
|
1431
|
+
import { ContextQueueService, DatabaseService as DatabaseService4 } from "@dxos/functions";
|
|
1403
1432
|
import { DXN as DXN2 } from "@dxos/keys";
|
|
1404
1433
|
import { log as log7 } from "@dxos/log";
|
|
1405
1434
|
import { deepMapValues, isNonNullable } from "@dxos/util";
|
|
1406
|
-
var
|
|
1407
|
-
var Subgraph =
|
|
1435
|
+
var __dxlog_file8 = "/__w/dxos/dxos/packages/core/assistant/src/research/graph.ts";
|
|
1436
|
+
var Subgraph = Schema7.Struct({
|
|
1408
1437
|
/** Objects and relations. */
|
|
1409
|
-
objects:
|
|
1438
|
+
objects: Schema7.Array(Schema7.Any)
|
|
1410
1439
|
});
|
|
1411
1440
|
var findRelatedSchema = async (db, anchor) => {
|
|
1412
1441
|
const allSchemas = [
|
|
@@ -1432,39 +1461,65 @@ var isSchemaAddressableByDxn = (schema, dxn) => {
|
|
|
1432
1461
|
}
|
|
1433
1462
|
return false;
|
|
1434
1463
|
};
|
|
1435
|
-
var
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
</local_context>
|
|
1459
|
-
`);
|
|
1464
|
+
var LocalSearchToolkit = class extends AiToolkit3.make(AiTool3.make("search_local_search", {
|
|
1465
|
+
description: "Search the local database for information using a vector index",
|
|
1466
|
+
parameters: {
|
|
1467
|
+
query: Schema7.String.annotations({
|
|
1468
|
+
description: "The query to search for. Could be a question or a topic or a set of keywords."
|
|
1469
|
+
})
|
|
1470
|
+
},
|
|
1471
|
+
success: Schema7.Unknown,
|
|
1472
|
+
failure: Schema7.Never
|
|
1473
|
+
}).addRequirement()) {
|
|
1474
|
+
};
|
|
1475
|
+
var LocalSearchHandler = LocalSearchToolkit.toLayer({
|
|
1476
|
+
search_local_search: Effect5.fn(function* ({ query }) {
|
|
1477
|
+
const { objects } = yield* DatabaseService4.runQuery(Query2.select(Filter2.text(query, {
|
|
1478
|
+
type: "vector"
|
|
1479
|
+
})));
|
|
1480
|
+
const results = [
|
|
1481
|
+
...objects
|
|
1482
|
+
];
|
|
1483
|
+
const contextQueue = yield* Effect5.serviceOption(ContextQueueService);
|
|
1484
|
+
if (Option2.isSome(contextQueue)) {
|
|
1485
|
+
const queueObjects = yield* Effect5.promise(() => contextQueue.value.contextQueue.queryObjects());
|
|
1486
|
+
results.push(...queueObjects);
|
|
1460
1487
|
}
|
|
1488
|
+
return `
|
|
1489
|
+
<local_context>
|
|
1490
|
+
${JSON.stringify(results, null, 2)}
|
|
1491
|
+
</local_context>
|
|
1492
|
+
`;
|
|
1493
|
+
})
|
|
1494
|
+
});
|
|
1495
|
+
var GraphWriterSchema = class extends Context3.Tag("GraphWriterSchema")() {
|
|
1496
|
+
};
|
|
1497
|
+
var makeGraphWriterToolkit = ({ schema }) => {
|
|
1498
|
+
return AiToolkit3.make(AiTool3.make("graph_writer", {
|
|
1499
|
+
description: "Write to the local graph database",
|
|
1500
|
+
parameters: createExtractionSchema(schema).fields,
|
|
1501
|
+
success: Schema7.Unknown,
|
|
1502
|
+
failure: Schema7.Never
|
|
1503
|
+
}).addRequirement().annotateContext(Context3.make(GraphWriterSchema, {
|
|
1504
|
+
schema
|
|
1505
|
+
})));
|
|
1506
|
+
};
|
|
1507
|
+
var makeGraphWriterHandler = (toolkit) => {
|
|
1508
|
+
const { schema } = Context3.get(toolkit.tools.graph_writer.annotations, GraphWriterSchema);
|
|
1509
|
+
return toolkit.toLayer({
|
|
1510
|
+
graph_writer: Effect5.fn(function* (input) {
|
|
1511
|
+
const { db } = yield* DatabaseService4;
|
|
1512
|
+
const contextQueue = yield* Effect5.serviceOption(ContextQueueService);
|
|
1513
|
+
const data = yield* Effect5.promise(() => sanitizeObjects(schema, input, db, contextQueue.pipe(Option2.getOrUndefined)?.contextQueue));
|
|
1514
|
+
return data;
|
|
1515
|
+
})
|
|
1461
1516
|
});
|
|
1462
1517
|
};
|
|
1463
1518
|
var createExtractionSchema = (types) => {
|
|
1464
|
-
return
|
|
1519
|
+
return Schema7.Struct({
|
|
1465
1520
|
...Object.fromEntries(types.map(preprocessSchema).map((schema, index) => [
|
|
1466
1521
|
`objects_${getSanitizedSchemaName(types[index])}`,
|
|
1467
|
-
|
|
1522
|
+
Schema7.optional(Schema7.Array(schema)).annotations({
|
|
1468
1523
|
description: `The objects of type: ${getSchemaDXN(types[index])?.asTypeDXN().type}. ${SchemaAST.getDescriptionAnnotation(types[index].ast).pipe(Option2.getOrElse(() => ""))}`
|
|
1469
1524
|
})
|
|
1470
1525
|
]))
|
|
@@ -1522,8 +1577,8 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1522
1577
|
log7.warn("source not found", {
|
|
1523
1578
|
source: data2.source
|
|
1524
1579
|
}, {
|
|
1525
|
-
F:
|
|
1526
|
-
L:
|
|
1580
|
+
F: __dxlog_file8,
|
|
1581
|
+
L: 262,
|
|
1527
1582
|
S: void 0,
|
|
1528
1583
|
C: (f, a) => f(...a)
|
|
1529
1584
|
});
|
|
@@ -1533,8 +1588,8 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1533
1588
|
log7.warn("target not found", {
|
|
1534
1589
|
target: data2.target
|
|
1535
1590
|
}, {
|
|
1536
|
-
F:
|
|
1537
|
-
L:
|
|
1591
|
+
F: __dxlog_file8,
|
|
1592
|
+
L: 266,
|
|
1538
1593
|
S: void 0,
|
|
1539
1594
|
C: (f, a) => f(...a)
|
|
1540
1595
|
});
|
|
@@ -1562,8 +1617,8 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1562
1617
|
queueObjects,
|
|
1563
1618
|
existingIds
|
|
1564
1619
|
}, {
|
|
1565
|
-
F:
|
|
1566
|
-
L:
|
|
1620
|
+
F: __dxlog_file8,
|
|
1621
|
+
L: 287,
|
|
1567
1622
|
S: void 0,
|
|
1568
1623
|
C: (f, a) => f(...a)
|
|
1569
1624
|
});
|
|
@@ -1594,7 +1649,7 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1594
1649
|
}
|
|
1595
1650
|
}
|
|
1596
1651
|
if (!skip) {
|
|
1597
|
-
const obj =
|
|
1652
|
+
const obj = create3(schema, data2);
|
|
1598
1653
|
enitties.set(obj.id, obj);
|
|
1599
1654
|
return [
|
|
1600
1655
|
obj
|
|
@@ -1603,543 +1658,159 @@ var sanitizeObjects = async (types, data, db, queue) => {
|
|
|
1603
1658
|
return [];
|
|
1604
1659
|
});
|
|
1605
1660
|
};
|
|
1606
|
-
var SoftRef =
|
|
1607
|
-
"/":
|
|
1661
|
+
var SoftRef = Schema7.Struct({
|
|
1662
|
+
"/": Schema7.String
|
|
1608
1663
|
}).annotations({
|
|
1609
1664
|
description: "Reference to another object."
|
|
1610
1665
|
});
|
|
1611
1666
|
var preprocessSchema = (schema) => {
|
|
1612
1667
|
const isRelationSchema = getEntityKind(schema) === "relation";
|
|
1613
|
-
const go = (ast) => {
|
|
1668
|
+
const go = (ast, visited = /* @__PURE__ */ new Set()) => {
|
|
1669
|
+
if (visited.has(ast)) {
|
|
1670
|
+
return ast;
|
|
1671
|
+
}
|
|
1672
|
+
visited.add(ast);
|
|
1614
1673
|
if (SchemaAST.getAnnotation(ast, ReferenceAnnotationId).pipe(Option2.isSome)) {
|
|
1615
1674
|
return SoftRef.ast;
|
|
1616
1675
|
}
|
|
1617
|
-
return mapAst(ast, go);
|
|
1676
|
+
return mapAst(ast, (child) => go(child, visited));
|
|
1618
1677
|
};
|
|
1619
|
-
return
|
|
1620
|
-
id:
|
|
1678
|
+
return Schema7.make(mapAst(schema.ast, (ast) => go(ast))).pipe(Schema7.omit("id"), Schema7.extend(Schema7.Struct({
|
|
1679
|
+
id: Schema7.String.annotations({
|
|
1621
1680
|
description: "The id of this object. Come up with a unique id based on your judgement."
|
|
1622
1681
|
})
|
|
1623
|
-
})), isRelationSchema ?
|
|
1624
|
-
source:
|
|
1682
|
+
})), isRelationSchema ? Schema7.extend(Schema7.Struct({
|
|
1683
|
+
source: Schema7.String.annotations({
|
|
1625
1684
|
description: "The id of the source object for this relation."
|
|
1626
1685
|
}),
|
|
1627
|
-
target:
|
|
1686
|
+
target: Schema7.String.annotations({
|
|
1628
1687
|
description: "The id of the target object for this relation."
|
|
1629
1688
|
})
|
|
1630
1689
|
})) : identity);
|
|
1631
1690
|
};
|
|
1632
|
-
var createGraphWriterTool = ({ db, queue, schema, onDone = async (x) => x }) => {
|
|
1633
|
-
return createTool3("graph", {
|
|
1634
|
-
name: "writer",
|
|
1635
|
-
description: "Write to the local graph database",
|
|
1636
|
-
schema: createExtractionSchema(schema),
|
|
1637
|
-
execute: async (input) => {
|
|
1638
|
-
const data = await sanitizeObjects(schema, input, db, queue);
|
|
1639
|
-
return ToolResult3.Success(await onDone(data));
|
|
1640
|
-
}
|
|
1641
|
-
});
|
|
1642
|
-
};
|
|
1643
1691
|
|
|
1644
1692
|
// raw-loader:./instructions-research.tpl?raw
|
|
1645
|
-
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>";
|
|
1693
|
+
var instructions_research_default = "You are the Research Agent.\n\nThe Research Agent is an expert assistant that conducts in-depth research using real-time web search.\nThe Research Agent outputs results in a structured format matching the schema provided.\n\nThe Research Agent is equipped with the ability to:\n\n- Generate precise and effective search queries \n- Request web pages by query (through a `web_search` tool)\n- Read the full content of retrieved pages\n- Synthesize accurate, clear, and structured answers using reliable information from the retrieved content\n- Search the local database for information using a vector index (through a `local_search` tool)\n\nThe Research Agent always follows these principles:\n\n- Relevance First: The Research Agent only returns facts supported by content in retrieved web pages. The Research Agent never fabricates or guesses information.\n- Summarize, Don't Copy: The Research Agent synthesizes and rephrases content in its own words. The Research Agent quotes only when necessary.\n- Multiple Sources: The Research Agent cross-references at least 2 sources before drawing conclusions, unless the information is directly stated and non-controversial.\n- Transparency: The Research Agent mentions which sources were used and explains how it arrived at conclusions.\n- Accuracy Over Brevity: The Research Agent prefers detailed, technically accurate explanations over shallow summaries.\n- The Research Agent admits uncertainty rather than misleading.\n- The Research Agent picks the most concrete schema types for extracted information.\n- The Research Agent fills schema fields completely with information it is confident about, and omits fields it is not confident about.\n- When outputting results, the Research Agent adds extra data that fits the schema even if not directly related to the user's question.\n- The Research Agent creates relations and references between new objects found and what's already in the database.\n- The Research Agent does not create objects that are already in the database.\n- The Research Agent re-uses existing object IDs as references when enriching existing objects.\n- The Research Agent ALWAYS calls the `graph_writer` at the end to save the data. This conversation will be delted, so only the data written to the graph will be preserved.\n\nThe Research Agent may be asked for:\n\n- Technical explanations\n- Literature reviews \n- Comparisons\n- Emerging trends\n- Implementation strategies\n\nThe Research Agent begins by interpreting the user's request, then:\n\nThe Research Agent breaks it into sub-questions (if applicable).\n\nFor each sub-question, the Research Agent generates a clear, concise web search query.\n\nThe Research Agent uses `web_search`(query) to retrieve information.\n\nThe Research Agent extracts and synthesizes relevant answers.\n\nThe Research Agent's output includes:\n\n- A clear, structured answer to the user's question\n- A citation list or link list of sources used\n\nOptionally, the Research Agent provides follow-up suggestions or questions for deeper inquiry.\n\nHere's how the Research Agent operates:\n\n1. The Research Agent analyzes the user's request and identifies key topics to search for (3 or more), printing them out.\n2. The Research Agent performs a web search for each topic.\n3. The Research Agent reads and analyzes results, cross references information from multiple sources, and represents conflicting information as ranges of possible values.\n\n4. The Research Agent searches the local database for information using a vector index that might link to the user's question.\n6. The Research Agent creates relations and references between new objects and existing database objects when related, using existing object IDs as references.\n7. The Research Agent selects the most concrete schema types for extracted information, using multiple types as needed, and prints its decision and reasoning.\n5. The Research Agent creates a clear, structured answer to the user's question.\n8. The Research Agent submits results using the specific schema.\n\nIMPORTANT:\n\n- The Research Agent always runs the `local_search` tool to search the local database at least once before submitting results.\n- The Research Agent does not create objects that already exist in the database.\n- Ids that are not in the database are human-readable strings like `ivan_zhao_1`.\n\nStatus reporting:\n\nThe Research Agent reports its status frequently using the `<status>` tags: <status>Searching for Google Founders</status>\nThe Research Agent reports its status in-between each tool call and before submitting results.\n\n<example>\n\nBased on my research, I can now provide information about Google and it's founders.\n\nThe following objects are already in the database, I will not submit them again, but I'll re-use their IDs as references:\n\n- 01JWRDEHPB5TT2JQQQC15038BT Google\n- 01JWRDEHPA14CYW2NW9FAH6DJJ Larry Page\n- 01JWRDEHPBN0BBJP57B9S108W6 Sergey Brin\n\nI will use the following schema to construct new objects:\n\n- type:dxos.org/type/Organization for Alphabet Inc.\n- type:dxos.org/type/Person for Ivan Zhao\n- type:dxos.org/type/Person for Simon Last\n- dxn:type:dxos.org/relation/Employer for Ivan's employer\n- dxn:type:dxos.org/relation/Employer for Simon's employer\n\n<status>Formatting results</status>\n\n</example>";
|
|
1646
1694
|
|
|
1647
|
-
//
|
|
1648
|
-
var
|
|
1695
|
+
// src/research/research.ts
|
|
1696
|
+
var __dxlog_file9 = "/__w/dxos/dxos/packages/core/assistant/src/research/research.ts";
|
|
1649
1697
|
var researchFn = defineFunction3({
|
|
1650
1698
|
description: "Research the web for information",
|
|
1651
|
-
inputSchema:
|
|
1652
|
-
query:
|
|
1699
|
+
inputSchema: Schema8.Struct({
|
|
1700
|
+
query: Schema8.String.annotations({
|
|
1653
1701
|
description: "The query to search for."
|
|
1654
1702
|
}),
|
|
1655
1703
|
// TOOD(burdon): Move to context.
|
|
1656
|
-
mockSearch:
|
|
1704
|
+
mockSearch: Schema8.optional(Schema8.Boolean).annotations({
|
|
1657
1705
|
description: "Whether to use the mock search tool.",
|
|
1658
1706
|
default: false
|
|
1659
1707
|
})
|
|
1660
1708
|
}),
|
|
1661
|
-
outputSchema:
|
|
1662
|
-
|
|
1663
|
-
result: Schema7.Any
|
|
1709
|
+
outputSchema: Schema8.Struct({
|
|
1710
|
+
result: Schema8.Unknown
|
|
1664
1711
|
}),
|
|
1665
|
-
handler:
|
|
1666
|
-
|
|
1667
|
-
const credentials = context.getService(CredentialsService);
|
|
1668
|
-
const { db } = context.getService(DatabaseService2);
|
|
1669
|
-
const tracing = context.getService(TracingService);
|
|
1670
|
-
tracing.write(create5(AgentStatusReport2, {
|
|
1712
|
+
handler: Effect6.fnUntraced(function* ({ data: { query, mockSearch } }) {
|
|
1713
|
+
yield* TracingService.emitStatus({
|
|
1671
1714
|
message: "Researching..."
|
|
1672
|
-
}));
|
|
1673
|
-
const exaCredential = await credentials.getCredential({
|
|
1674
|
-
service: "exa.ai"
|
|
1675
1715
|
});
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1716
|
+
const graphWriteToolkit = makeGraphWriterToolkit({
|
|
1717
|
+
schema: DataTypes
|
|
1678
1718
|
});
|
|
1719
|
+
const toolkit = yield* AiToolkit4.merge(ExaToolkit, LocalSearchToolkit, graphWriteToolkit).pipe(Effect6.provide(Layer2.mergeAll(mockSearch ? MockExaHandler : LiveExaHandler, LocalSearchHandler, makeGraphWriterHandler(graphWriteToolkit))));
|
|
1679
1720
|
const printer = new ConsolePrinter();
|
|
1680
|
-
const session = new
|
|
1681
|
-
operationModel: "configured"
|
|
1682
|
-
});
|
|
1721
|
+
const session = new AiSession();
|
|
1683
1722
|
session.message.on((message) => printer.printMessage(message));
|
|
1684
1723
|
session.userMessage.on((message) => printer.printMessage(message));
|
|
1685
1724
|
session.block.on((block) => printer.printContentBlock(block));
|
|
1686
|
-
session.statusReport.on((status) => {
|
|
1687
|
-
log8.info("[agent] status", {
|
|
1688
|
-
status
|
|
1689
|
-
}, {
|
|
1690
|
-
F: __dxlog_file8,
|
|
1691
|
-
L: 58,
|
|
1692
|
-
S: void 0,
|
|
1693
|
-
C: (f, a) => f(...a)
|
|
1694
|
-
});
|
|
1695
|
-
tracing.write(status);
|
|
1696
|
-
});
|
|
1697
1725
|
session.streamEvent.on((event) => log8("stream", {
|
|
1698
1726
|
event
|
|
1699
1727
|
}, {
|
|
1700
|
-
F:
|
|
1701
|
-
L:
|
|
1702
|
-
S:
|
|
1728
|
+
F: __dxlog_file9,
|
|
1729
|
+
L: 62,
|
|
1730
|
+
S: this,
|
|
1703
1731
|
C: (f, a) => f(...a)
|
|
1704
1732
|
}));
|
|
1705
|
-
const
|
|
1706
|
-
|
|
1707
|
-
schema: DataTypes
|
|
1708
|
-
});
|
|
1709
|
-
log8.info("graphWriteTool", {
|
|
1710
|
-
schema: graphWriteTool.parameters
|
|
1711
|
-
}, {
|
|
1712
|
-
F: __dxlog_file8,
|
|
1713
|
-
L: 64,
|
|
1714
|
-
S: void 0,
|
|
1715
|
-
C: (f, a) => f(...a)
|
|
1716
|
-
});
|
|
1717
|
-
const result = await session.run({
|
|
1718
|
-
client: ai.client,
|
|
1719
|
-
systemPrompt: instructions_research_default,
|
|
1720
|
-
artifacts: [],
|
|
1721
|
-
tools: [
|
|
1722
|
-
searchTool,
|
|
1723
|
-
graphWriteTool
|
|
1724
|
-
],
|
|
1733
|
+
const result = yield* session.run({
|
|
1734
|
+
prompt: query,
|
|
1725
1735
|
history: [],
|
|
1726
|
-
|
|
1736
|
+
systemPrompt: instructions_research_default,
|
|
1737
|
+
toolkit
|
|
1727
1738
|
});
|
|
1728
1739
|
return {
|
|
1729
1740
|
result
|
|
1730
1741
|
};
|
|
1731
|
-
}
|
|
1742
|
+
}, Effect6.provide(AiService2.model("@anthropic/claude-3-5-sonnet-20241022")))
|
|
1732
1743
|
});
|
|
1733
1744
|
|
|
1734
|
-
//
|
|
1735
|
-
|
|
1745
|
+
// src/templates/prompt.ts
|
|
1746
|
+
import { Template } from "@dxos/blueprints";
|
|
1736
1747
|
|
|
1737
|
-
//
|
|
1738
|
-
|
|
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;
|
|
1748
|
+
// raw-loader:./assistant.tpl?raw
|
|
1749
|
+
var assistant_default = "{{! System Prompt }}\n\nYou are a friendly, advanced AI assistant capable of creating and managing artifacts from available data and tools.\nYour task is to process user commands and questions and decide how best to respond.\nIn some cases, you will need to create or reference data objects called artifacts.\n\nFollow these guidelines carefully:\n\n{{section}}. Decision-making:\n\n{{#if cot}}\nBefore responding, explain your reasoning and include your detailed chain-of-thought in a <cot> tag.\n{{/if}}\n\nInclude the following steps:\n\n- Analyze the structure and type of the content in the user's message.\n- Can you complete the task using the available artifact definitions?\n- If you can't complete the task using the available artifact definitions, query the list of available artifact definitions using the appropriate tool.\n- Identify which artifact definitions are relevant to the user's request.\n- Evaluate the potential benefits of creating an artifact vs. normal processing for each identified element.\n- Make a final decision on whether to create an artifact and explain your reasoning.\n- Are the required artifact definitions already available?\n- If not, select which artifact definition(s) will be the most relevant and require them using the require_artifact_definitions tool.\n- The require'd artifact tools will be available for use after require.\n- If creating an artifact, outline how you will structure it within the response.\n- Decide if the artifact needs to be shown to the user.\n- Call the show tool to show the artifact to the user.\n- If you ask the user a multiple choice question, then present each of the possible answers as concise text inside <option> tags inside a well formed <select> tag.\n- If you have suggestions for follow-up actions then present each action as text within a <suggest> tag.\n- Your reasoning must include: whether to use artifacts or not, to create one or query, whether to show the artifact to the user, and how to structure the response.\n\nIf the user asks for a list of tools, then just emit a single self-closing <tool-list/> tag instead of listing the tools.The tag will be replaced with the list of tools when the response is rendered.\nDo not list the tools or artifacts in your response, only emit the tag.\nDo not mention the tag anywhere else in your response unless you are rendering a tool list.\n\n{{section}}. Artifacts:\n\n- Determine if the interaction involves an artifact. Prefer artifacts for tables, lists, spreadsheets, kanbans, games, images, and other structured data.\n- Determine if the user is explicitly talking about creating a new artifact, or wants to use an existing artifact.\n- If it is ambiguous, query for existing artifacts first and then decide.\n- If you decide to create an artifact, call the associated tool to create the artifact.\n- Artifacts are stored in the database. Tools are used to create and query artifacts.\n- If you are unsure about creating an artifact ask the user for clarification.\n\n{{#if artifacts}}\n{{section}}. Artifact Rules:\n\n- Artifacts are mutable objects that can change over the course of the conversation.\n- Always re-query the artifact using the tool (like query or inspect) to get the latest state of the artifact before answering the user.\n- You must never generate the id of the artifact; only recall the ids that are already in the history.\n- Artifacts are created by requiring the specific artifact using the require_artifact tool and creating it by calling the associated tool.\n\n{{section}}. Artifact Providers:\n\n{{#each artifacts}}\n- {{this}}\n{{/each}}\n{{/if}}\n\n{{#if associatedArtifact}}\n{{section}}. Associated artifact:\n\nThe following ID and typename identify the artifact associated with this conversation.\nThis conversation appears alongside the associated artifact as a peer, and the user is likely to make reference to and requests about it.\nYou can interact with this artifact using tools.\n\nID: {{associatedArtifact.id}}\nTypename: {{associatedArtifact.typename}}\n{{/if}}\n\n{{#if suggestions}}\n{{section}}. Suggested actions:\n\n- You can add suggested actions at the end of your response.\n- Suggested actions should be very concise and start with a verb and be phrased as a command to an agent -- not a question to the user.\n- Suggested actions must be in the form of a user instruction that you can follow.\n- Suggested actions could include actions that create artifacts.\n- Suggested actions must be enclosed in a <suggest> tag and on a separate line.\n Examples:\n <suggest>Show the data on a map.</suggest>\n <suggest>Create a kanban from the table.</suggest>\n\n- If you have asked a multiple choice question, then present each of the possible answers as concise text inside <option> tags inside a well formed <select> tag.\n Example:\n <select><option>Yes</option><option>No</option></select>\n{{/if}}\n\n{{section}}. Content proposals:\n\nYou can propose content to add to associated artifacts. Enclose the content you are proposing to add in a <proposal> tag on a separate line.\nFor example:\n<proposal>Apples add a delightful crunch and natural sweetness to salads</proposal>\n\n{{section}}. Output Formats:\n\nIt is very important to respond in the correct format.\n\n{{#if cot}}\n- Your detailed chain-of-thought must be in the form of a markdown list enclosed in <cot> tags.\n- The <cot> tag should be the first thing in your response.\n{{/if}}\n- Suggested actions must be enclosed in a <suggest> tag and on a separate line.\n- Content proposals must be enclosed in a <proposal> tag and on a separate line.\n\nReferences:\n\n- Both user and you can reference external data in the markdown format: [label][URI].\n- If you get references back from a tool call, you can render them as is by preserving the ID literally.\n\n{{instructions}}";
|
|
1792
1750
|
|
|
1793
|
-
//
|
|
1794
|
-
|
|
1795
|
-
|
|
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
|
-
};
|
|
1751
|
+
// src/templates/prompt.ts
|
|
1752
|
+
var createSystemPrompt = (options) => {
|
|
1753
|
+
return Template.createPrompt(assistant_default, options);
|
|
1991
1754
|
};
|
|
1992
1755
|
|
|
1993
|
-
//
|
|
1994
|
-
import {
|
|
1995
|
-
import
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
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;
|
|
1756
|
+
// src/types.ts
|
|
1757
|
+
import { Schema as Schema9 } from "effect";
|
|
1758
|
+
import { DXN as DXN3, LOCAL_SPACE_TAG } from "@dxos/keys";
|
|
1759
|
+
var createArtifactElement = (id) => `<artifact id=${id} />`;
|
|
1760
|
+
var ArtifactId = class extends Schema9.String.annotations({
|
|
1761
|
+
description: `
|
|
1762
|
+
The ID of the referenced object. Formats accepted:
|
|
1763
|
+
- DXN (dxn:echo:@:XXXXX). DXNs can be prepended with an @ symbol for compatibility with in-text references.
|
|
1764
|
+
- space ID, object ID tuple (spaceID:objectID)
|
|
1765
|
+
- Only object ID that is assumed to be in the current space (XXXXX)
|
|
1766
|
+
`,
|
|
1767
|
+
examples: [
|
|
1768
|
+
"dxn:echo:@:XXXXX",
|
|
1769
|
+
"@dxn:echo:@:XXXXX",
|
|
1770
|
+
"spaceID:objectID",
|
|
1771
|
+
"XXXXX"
|
|
1772
|
+
]
|
|
1773
|
+
}) {
|
|
1774
|
+
static toDXN(reference, owningSpaceId) {
|
|
1775
|
+
if (reference.startsWith("@dxn:")) {
|
|
1776
|
+
return DXN3.parse(reference.slice(1));
|
|
1777
|
+
} else if (reference.startsWith("dxn:")) {
|
|
1778
|
+
return DXN3.parse(reference);
|
|
1779
|
+
} else if (/^[A-Z0-9]+:[A-Z0-9]+$/.test(reference)) {
|
|
1780
|
+
const [spaceId, objectId] = reference.split(":");
|
|
1781
|
+
return new DXN3(DXN3.kind.ECHO, [
|
|
1782
|
+
spaceId === owningSpaceId ? LOCAL_SPACE_TAG : spaceId,
|
|
1783
|
+
objectId
|
|
1784
|
+
]);
|
|
1785
|
+
} else if (/^[A-Z0-9]+$/.test(reference)) {
|
|
1786
|
+
return DXN3.fromLocalObjectId(reference);
|
|
1787
|
+
} else {
|
|
1788
|
+
throw new Error(`Unable to parse object reference: ${reference}`);
|
|
2060
1789
|
}
|
|
2061
1790
|
}
|
|
2062
1791
|
};
|
|
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
1792
|
export {
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
BlueprintStep,
|
|
2130
|
-
BufferedLogger,
|
|
1793
|
+
AiSession,
|
|
1794
|
+
ArtifactDiffResolver,
|
|
1795
|
+
ArtifactId,
|
|
1796
|
+
Bindings,
|
|
1797
|
+
ContextBinder,
|
|
1798
|
+
ContextBinding,
|
|
1799
|
+
Conversation,
|
|
1800
|
+
ExaToolkit,
|
|
2131
1801
|
ExtractionInput,
|
|
2132
1802
|
ExtractionOutput,
|
|
1803
|
+
LiveExaHandler,
|
|
1804
|
+
LocalSearchHandler,
|
|
1805
|
+
LocalSearchToolkit,
|
|
1806
|
+
MockExaHandler,
|
|
2133
1807
|
ReferencedQuotes,
|
|
2134
1808
|
Subgraph,
|
|
2135
1809
|
VersionPin,
|
|
2136
1810
|
combineNerTokens,
|
|
2137
1811
|
createArtifactElement,
|
|
2138
|
-
createExaTool,
|
|
2139
1812
|
createExtractionSchema,
|
|
2140
|
-
|
|
2141
|
-
createLocalSearchTool,
|
|
2142
|
-
createMockExaTool,
|
|
1813
|
+
createSystemPrompt,
|
|
2143
1814
|
createTokenGroups,
|
|
2144
1815
|
extractFullEntities,
|
|
2145
1816
|
extractionAnthropicFn,
|
|
@@ -2149,10 +1820,12 @@ export {
|
|
|
2149
1820
|
getNer,
|
|
2150
1821
|
getSanitizedSchemaName,
|
|
2151
1822
|
insertReferences,
|
|
1823
|
+
makeGraphWriterHandler,
|
|
1824
|
+
makeGraphWriterToolkit,
|
|
1825
|
+
makeToolExecutionServiceFromFunctions,
|
|
1826
|
+
makeToolResolverFromFunctions,
|
|
2152
1827
|
processTranscriptMessage,
|
|
2153
1828
|
researchFn,
|
|
2154
|
-
sanitizeObjects
|
|
2155
|
-
setConsolePrinter,
|
|
2156
|
-
setLogger
|
|
1829
|
+
sanitizeObjects
|
|
2157
1830
|
};
|
|
2158
1831
|
//# sourceMappingURL=index.mjs.map
|