@n8n/agents 0.5.2 → 0.7.0
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/build.tsbuildinfo +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/integrations/langsmith.d.ts +2 -0
- package/dist/integrations/langsmith.js +117 -2
- package/dist/integrations/langsmith.js.map +1 -1
- package/dist/runtime/agent-runtime.d.ts +6 -0
- package/dist/runtime/agent-runtime.js +291 -80
- package/dist/runtime/agent-runtime.js.map +1 -1
- package/dist/runtime/event-bus.d.ts +2 -0
- package/dist/runtime/event-bus.js +7 -0
- package/dist/runtime/event-bus.js.map +1 -1
- package/dist/runtime/json-value.d.ts +2 -0
- package/dist/runtime/json-value.js +43 -0
- package/dist/runtime/json-value.js.map +1 -0
- package/dist/runtime/memory-store.d.ts +40 -2
- package/dist/runtime/memory-store.js +138 -3
- package/dist/runtime/memory-store.js.map +1 -1
- package/dist/runtime/message-list.d.ts +5 -0
- package/dist/runtime/message-list.js +47 -0
- package/dist/runtime/message-list.js.map +1 -1
- package/dist/runtime/messages.d.ts +0 -2
- package/dist/runtime/messages.js +127 -101
- package/dist/runtime/messages.js.map +1 -1
- package/dist/runtime/model-factory.js +117 -34
- package/dist/runtime/model-factory.js.map +1 -1
- package/dist/runtime/provider-credentials.d.ts +167 -0
- package/dist/runtime/provider-credentials.js +34 -0
- package/dist/runtime/provider-credentials.js.map +1 -0
- package/dist/runtime/run-state.js.map +1 -1
- package/dist/runtime/runtime-helpers.d.ts +3 -4
- package/dist/runtime/runtime-helpers.js +6 -32
- package/dist/runtime/runtime-helpers.js.map +1 -1
- package/dist/runtime/stream.js +25 -43
- package/dist/runtime/stream.js.map +1 -1
- package/dist/runtime/strip-orphaned-tool-messages.js +1 -25
- package/dist/runtime/strip-orphaned-tool-messages.js.map +1 -1
- package/dist/runtime/title-generation.d.ts +12 -3
- package/dist/runtime/title-generation.js +72 -3
- package/dist/runtime/title-generation.js.map +1 -1
- package/dist/runtime/tool-adapter.d.ts +1 -1
- package/dist/runtime/tool-adapter.js +3 -2
- package/dist/runtime/tool-adapter.js.map +1 -1
- package/dist/runtime/working-memory.d.ts +1 -1
- package/dist/runtime/working-memory.js +1 -1
- package/dist/runtime/working-memory.js.map +1 -1
- package/dist/sdk/agent.d.ts +19 -15
- package/dist/sdk/agent.js +22 -201
- package/dist/sdk/agent.js.map +1 -1
- package/dist/sdk/eval.d.ts +0 -3
- package/dist/sdk/eval.js +4 -9
- package/dist/sdk/eval.js.map +1 -1
- package/dist/sdk/provider-capabilities.js +4 -2
- package/dist/sdk/provider-capabilities.js.map +1 -1
- package/dist/sdk/provider-tools.d.ts +17 -2
- package/dist/sdk/provider-tools.js +19 -0
- package/dist/sdk/provider-tools.js.map +1 -1
- package/dist/sdk/telemetry.d.ts +2 -0
- package/dist/sdk/telemetry.js +6 -0
- package/dist/sdk/telemetry.js.map +1 -1
- package/dist/sdk/tool.d.ts +17 -10
- package/dist/sdk/tool.js +34 -0
- package/dist/sdk/tool.js.map +1 -1
- package/dist/sdk/verify.js +1 -4
- package/dist/sdk/verify.js.map +1 -1
- package/dist/storage/base-memory.d.ts +64 -0
- package/dist/storage/base-memory.js +54 -0
- package/dist/storage/base-memory.js.map +1 -0
- package/dist/storage/postgres-memory.d.ts +33 -16
- package/dist/storage/postgres-memory.js +46 -25
- package/dist/storage/postgres-memory.js.map +1 -1
- package/dist/storage/sqlite-memory.d.ts +16 -6
- package/dist/storage/sqlite-memory.js +16 -10
- package/dist/storage/sqlite-memory.js.map +1 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +3 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/runtime/event.d.ts +2 -2
- package/dist/types/sdk/agent-builder.d.ts +0 -3
- package/dist/types/sdk/agent.d.ts +63 -25
- package/dist/types/sdk/credential-provider.d.ts +2 -3
- package/dist/types/sdk/memory.d.ts +23 -2
- package/dist/types/sdk/message.d.ts +11 -10
- package/dist/types/sdk/observation.d.ts +100 -0
- package/dist/types/sdk/observation.js +5 -0
- package/dist/types/sdk/observation.js.map +1 -0
- package/dist/types/sdk/tool-descriptor.d.ts +13 -0
- package/dist/types/sdk/{schema.js → tool-descriptor.js} +1 -1
- package/dist/types/sdk/tool-descriptor.js.map +1 -0
- package/dist/types/sdk/tool.d.ts +8 -3
- package/dist/types/telemetry.d.ts +1 -0
- package/dist/utils/parse.d.ts +10 -0
- package/dist/utils/parse.js +26 -0
- package/dist/utils/parse.js.map +1 -0
- package/dist/utils/zod.d.ts +1 -1
- package/dist/utils/zod.js.map +1 -1
- package/dist/workspace/tools/batch-str-replace-file.d.ts +3 -0
- package/dist/workspace/tools/batch-str-replace-file.js +67 -0
- package/dist/workspace/tools/batch-str-replace-file.js.map +1 -0
- package/dist/workspace/tools/str-replace-file.d.ts +3 -0
- package/dist/workspace/tools/str-replace-file.js +51 -0
- package/dist/workspace/tools/str-replace-file.js.map +1 -0
- package/dist/workspace/tools/workspace-tools.js +4 -0
- package/dist/workspace/tools/workspace-tools.js.map +1 -1
- package/package.json +17 -8
- package/dist/codegen/generate-agent-code.d.ts +0 -2
- package/dist/codegen/generate-agent-code.js +0 -197
- package/dist/codegen/generate-agent-code.js.map +0 -1
- package/dist/sdk/from-schema.d.ts +0 -15
- package/dist/sdk/from-schema.js +0 -218
- package/dist/sdk/from-schema.js.map +0 -1
- package/dist/types/sdk/schema.d.ts +0 -99
- package/dist/types/sdk/schema.js.map +0 -1
|
@@ -32,17 +32,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.AgentRuntime = void 0;
|
|
40
37
|
const ai_1 = require("ai");
|
|
41
|
-
const ajv_1 = __importDefault(require("ajv"));
|
|
42
38
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
43
39
|
const catalog_1 = require("../sdk/catalog");
|
|
44
40
|
const message_1 = require("../sdk/message");
|
|
45
41
|
const event_bus_1 = require("./event-bus");
|
|
42
|
+
const json_value_1 = require("./json-value");
|
|
46
43
|
const memory_store_1 = require("./memory-store");
|
|
47
44
|
const message_list_1 = require("./message-list");
|
|
48
45
|
const messages_1 = require("./messages");
|
|
@@ -54,9 +51,67 @@ const strip_orphaned_tool_messages_1 = require("./strip-orphaned-tool-messages")
|
|
|
54
51
|
const title_generation_1 = require("./title-generation");
|
|
55
52
|
const tool_adapter_1 = require("./tool-adapter");
|
|
56
53
|
const working_memory_1 = require("./working-memory");
|
|
54
|
+
const parse_1 = require("../utils/parse");
|
|
57
55
|
const zod_1 = require("../utils/zod");
|
|
56
|
+
function isActiveSpanTracer(value) {
|
|
57
|
+
return (value !== null &&
|
|
58
|
+
typeof value === 'object' &&
|
|
59
|
+
typeof Reflect.get(value, 'startActiveSpan') === 'function');
|
|
60
|
+
}
|
|
61
|
+
function stringifyTelemetryValue(value) {
|
|
62
|
+
try {
|
|
63
|
+
return JSON.stringify(value);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function getToolInputSchema(tool) {
|
|
70
|
+
if (!tool.inputSchema) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return (0, zod_1.isZodSchema)(tool.inputSchema) ? (0, zod_to_json_schema_1.zodToJsonSchema)(tool.inputSchema) : tool.inputSchema;
|
|
74
|
+
}
|
|
75
|
+
function summarizeToolForTelemetry(tool) {
|
|
76
|
+
return {
|
|
77
|
+
name: tool.name,
|
|
78
|
+
description: tool.description,
|
|
79
|
+
type: tool.mcpTool ? 'mcp' : 'local',
|
|
80
|
+
...(tool.mcpServerName ? { mcp_server: tool.mcpServerName } : {}),
|
|
81
|
+
...(tool.suspendSchema || tool.resumeSchema || tool.withDefaultApproval
|
|
82
|
+
? { approval: true }
|
|
83
|
+
: {}),
|
|
84
|
+
...(tool.inputSchema ? { input_schema: getToolInputSchema(tool) } : {}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function summarizeProviderToolForTelemetry(tool) {
|
|
88
|
+
const [provider] = tool.name.split('.');
|
|
89
|
+
return {
|
|
90
|
+
name: tool.name,
|
|
91
|
+
provider,
|
|
92
|
+
type: 'provider',
|
|
93
|
+
args: tool.args,
|
|
94
|
+
...(tool.inputSchema ? { input_schema: getToolInputSchema(tool) } : {}),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function buildAgentRootInputAttributes(config) {
|
|
98
|
+
const localTools = (config.tools ?? []).map(summarizeToolForTelemetry);
|
|
99
|
+
const providerTools = (config.providerTools ?? []).map(summarizeProviderToolForTelemetry);
|
|
100
|
+
const tools = [...localTools, ...providerTools];
|
|
101
|
+
const toolNames = tools
|
|
102
|
+
.map((tool) => (typeof tool.name === 'string' ? tool.name : undefined))
|
|
103
|
+
.filter((name) => name !== undefined);
|
|
104
|
+
const serialized = stringifyTelemetryValue({
|
|
105
|
+
agent: config.name,
|
|
106
|
+
tool_count: tools.length,
|
|
107
|
+
tools,
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
...(toolNames.length > 0 ? { 'langsmith.metadata.available_tools': toolNames } : {}),
|
|
111
|
+
...(serialized ? { 'gen_ai.prompt': serialized } : {}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
58
114
|
const MAX_LOOP_ITERATIONS = 20;
|
|
59
|
-
const ajv = new ajv_1.default({ strict: false });
|
|
60
115
|
const EMPTY_MESSAGE_LIST = {
|
|
61
116
|
messages: [],
|
|
62
117
|
historyIds: [],
|
|
@@ -85,8 +140,9 @@ class AgentRuntime {
|
|
|
85
140
|
const runId = (0, run_state_1.generateRunId)();
|
|
86
141
|
let list = undefined;
|
|
87
142
|
try {
|
|
88
|
-
|
|
89
|
-
|
|
143
|
+
const initializedList = await this.initRun(input, options);
|
|
144
|
+
list = initializedList;
|
|
145
|
+
const rawResult = await this.withTelemetryRootSpan('generate', options, runId, async () => await this.runGenerateLoop({ list: initializedList, options, runId }));
|
|
90
146
|
return this.finalizeGenerate(rawResult, list, runId);
|
|
91
147
|
}
|
|
92
148
|
catch (error) {
|
|
@@ -113,7 +169,7 @@ class AgentRuntime {
|
|
|
113
169
|
}
|
|
114
170
|
return { runId, stream: (0, runtime_helpers_1.makeErrorStream)(error) };
|
|
115
171
|
}
|
|
116
|
-
return { runId, stream: this.startStreamLoop(list, options,
|
|
172
|
+
return { runId, stream: this.startStreamLoop({ list, options, runId }) };
|
|
117
173
|
}
|
|
118
174
|
async resume(method, data, options) {
|
|
119
175
|
const state = await this.runState.resume(options.runId);
|
|
@@ -127,9 +183,9 @@ class AgentRuntime {
|
|
|
127
183
|
throw new Error(`Tool ${toolCall.toolName} not found`);
|
|
128
184
|
let resumeData = data;
|
|
129
185
|
if (tool.resumeSchema) {
|
|
130
|
-
const parseResult = await tool.resumeSchema
|
|
186
|
+
const parseResult = await (0, parse_1.parseWithSchema)(tool.resumeSchema, data);
|
|
131
187
|
if (!parseResult.success) {
|
|
132
|
-
throw new Error(`Invalid resume payload: ${parseResult.error
|
|
188
|
+
throw new Error(`Invalid resume payload: ${parseResult.error}`);
|
|
133
189
|
}
|
|
134
190
|
resumeData = parseResult.data;
|
|
135
191
|
}
|
|
@@ -155,7 +211,12 @@ class AgentRuntime {
|
|
|
155
211
|
await this.ensureModelCost();
|
|
156
212
|
await this.setListWorkingMemoryConfig(list, state.persistence);
|
|
157
213
|
if (method === 'generate') {
|
|
158
|
-
const rawResult = await this.
|
|
214
|
+
const rawResult = await this.withTelemetryRootSpan('generate', resumeOptions, options.runId, async () => await this.runGenerateLoop({
|
|
215
|
+
list,
|
|
216
|
+
options: resumeOptions,
|
|
217
|
+
runId: options.runId,
|
|
218
|
+
pendingResume,
|
|
219
|
+
}));
|
|
159
220
|
if (!rawResult.pendingSuspend) {
|
|
160
221
|
await this.cleanupRun(options.runId);
|
|
161
222
|
}
|
|
@@ -163,7 +224,12 @@ class AgentRuntime {
|
|
|
163
224
|
}
|
|
164
225
|
return {
|
|
165
226
|
runId: options.runId,
|
|
166
|
-
stream: this.startStreamLoop(
|
|
227
|
+
stream: this.startStreamLoop({
|
|
228
|
+
list,
|
|
229
|
+
options: resumeOptions,
|
|
230
|
+
runId: options.runId,
|
|
231
|
+
pendingResume,
|
|
232
|
+
}),
|
|
167
233
|
};
|
|
168
234
|
}
|
|
169
235
|
catch (error) {
|
|
@@ -332,16 +398,96 @@ class AgentRuntime {
|
|
|
332
398
|
},
|
|
333
399
|
};
|
|
334
400
|
}
|
|
335
|
-
|
|
336
|
-
const
|
|
401
|
+
buildTelemetryRootAttributes(t, spanName, runId) {
|
|
402
|
+
const metadataAttributes = this.buildTelemetryMetadataAttributes(t, 'langsmith.metadata');
|
|
403
|
+
return {
|
|
404
|
+
'langsmith.traceable': 'true',
|
|
405
|
+
'langsmith.trace.name': spanName,
|
|
406
|
+
'langsmith.span.kind': 'chain',
|
|
407
|
+
'langsmith.metadata.agent_name': this.config.name,
|
|
408
|
+
'langsmith.metadata.agent_run_id': runId,
|
|
409
|
+
...metadataAttributes,
|
|
410
|
+
...buildAgentRootInputAttributes(this.config),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
buildTelemetryMetadataAttributes(t, prefix) {
|
|
414
|
+
return Object.fromEntries(Object.entries(t.metadata ?? {}).map(([key, value]) => [`${prefix}.${key}`, value]));
|
|
415
|
+
}
|
|
416
|
+
buildAiSdkOperationAttributes(operationId, t) {
|
|
417
|
+
const functionId = t.functionId ?? this.config.name;
|
|
418
|
+
return {
|
|
419
|
+
'operation.name': `${operationId} ${functionId}`,
|
|
420
|
+
'resource.name': functionId,
|
|
421
|
+
'ai.operationId': operationId,
|
|
422
|
+
'ai.telemetry.functionId': functionId,
|
|
423
|
+
...this.buildTelemetryMetadataAttributes(t, 'ai.telemetry.metadata'),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
async withTelemetryRootSpan(operation, options, runId, fn) {
|
|
427
|
+
const t = this.resolveTelemetry(options);
|
|
428
|
+
if (!t?.enabled || t.runtimeRootSpanEnabled === false || !isActiveSpanTracer(t.tracer)) {
|
|
429
|
+
return await fn();
|
|
430
|
+
}
|
|
431
|
+
const spanName = `${t.functionId ?? this.config.name}.${operation}`;
|
|
432
|
+
return await t.tracer.startActiveSpan(spanName, { attributes: this.buildTelemetryRootAttributes(t, spanName, runId) }, async (span) => {
|
|
433
|
+
try {
|
|
434
|
+
return await fn();
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
span.recordException?.(error);
|
|
438
|
+
span.setStatus?.({ code: 2, message: String(error) });
|
|
439
|
+
throw error;
|
|
440
|
+
}
|
|
441
|
+
finally {
|
|
442
|
+
span.end();
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
async withTelemetryToolSpan(toolCallId, toolName, input, t, fn) {
|
|
447
|
+
if (!t?.enabled || !isActiveSpanTracer(t.tracer)) {
|
|
448
|
+
return await fn();
|
|
449
|
+
}
|
|
450
|
+
const shouldRecordInputs = t.recordInputs ?? true;
|
|
451
|
+
const inputValue = shouldRecordInputs ? stringifyTelemetryValue(input) : undefined;
|
|
452
|
+
return await t.tracer.startActiveSpan('ai.toolCall', {
|
|
453
|
+
attributes: {
|
|
454
|
+
...this.buildAiSdkOperationAttributes('ai.toolCall', t),
|
|
455
|
+
'ai.toolCall.name': toolName,
|
|
456
|
+
'ai.toolCall.id': toolCallId,
|
|
457
|
+
...(inputValue !== undefined ? { 'ai.toolCall.args': inputValue } : {}),
|
|
458
|
+
},
|
|
459
|
+
}, async (span) => {
|
|
460
|
+
try {
|
|
461
|
+
const result = await fn();
|
|
462
|
+
const shouldRecordOutputs = t.recordOutputs ?? true;
|
|
463
|
+
const outputValue = shouldRecordOutputs ? stringifyTelemetryValue(result) : undefined;
|
|
464
|
+
if (outputValue !== undefined) {
|
|
465
|
+
span.setAttributes?.({ 'ai.toolCall.result': outputValue });
|
|
466
|
+
}
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
span.recordException?.(error);
|
|
471
|
+
span.setStatus?.({ code: 2, message: String(error) });
|
|
472
|
+
throw error;
|
|
473
|
+
}
|
|
474
|
+
finally {
|
|
475
|
+
span.end();
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
async runGenerateLoop(ctx) {
|
|
480
|
+
const { list, options, runId, pendingResume } = ctx;
|
|
481
|
+
const { model, toolMap, aiTools, providerOptions, hasTools, outputSpec, effectiveInstructions, } = this.buildLoopContext({ ...options, persistence: options?.persistence });
|
|
337
482
|
let totalUsage;
|
|
338
483
|
let lastFinishReason = 'stop';
|
|
339
484
|
let structuredOutput;
|
|
340
485
|
const toolCallSummary = [];
|
|
341
486
|
const collectedSubAgentUsage = [];
|
|
342
487
|
const runTelemetry = this.resolveTelemetry(options);
|
|
488
|
+
const toolCtx = { toolMap, list, runId, telemetry: runTelemetry };
|
|
343
489
|
if (pendingResume) {
|
|
344
|
-
const batch = await this.iteratePendingToolCallsConcurrent(
|
|
490
|
+
const batch = await this.iteratePendingToolCallsConcurrent({ ...toolCtx, pendingResume });
|
|
345
491
|
for (const r of batch.results) {
|
|
346
492
|
toolCallSummary.push(r.toolEntry);
|
|
347
493
|
if (r.subAgentUsage)
|
|
@@ -374,7 +520,7 @@ class AgentRuntime {
|
|
|
374
520
|
this.eventBus.emit({ type: "turn_start" });
|
|
375
521
|
const result = await (0, ai_1.generateText)({
|
|
376
522
|
model,
|
|
377
|
-
messages: list.forLlm(
|
|
523
|
+
messages: list.forLlm(effectiveInstructions, this.config.instructionProviderOptions),
|
|
378
524
|
abortSignal: this.eventBus.signal,
|
|
379
525
|
...(hasTools ? { tools: aiTools } : {}),
|
|
380
526
|
...(providerOptions
|
|
@@ -393,10 +539,13 @@ class AgentRuntime {
|
|
|
393
539
|
if (outputSpec) {
|
|
394
540
|
structuredOutput = result.output;
|
|
395
541
|
}
|
|
396
|
-
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.
|
|
542
|
+
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.extractSettledToolCalls)(newMessages));
|
|
397
543
|
break;
|
|
398
544
|
}
|
|
399
|
-
const batch = await this.iterateToolCallsConcurrent(
|
|
545
|
+
const batch = await this.iterateToolCallsConcurrent({
|
|
546
|
+
...toolCtx,
|
|
547
|
+
toolCalls: result.toolCalls,
|
|
548
|
+
});
|
|
400
549
|
for (const r of batch.results) {
|
|
401
550
|
toolCallSummary.push(r.toolEntry);
|
|
402
551
|
if (r.subAgentUsage)
|
|
@@ -419,7 +568,7 @@ class AgentRuntime {
|
|
|
419
568
|
})),
|
|
420
569
|
};
|
|
421
570
|
}
|
|
422
|
-
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.
|
|
571
|
+
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.extractSettledToolCalls)(list.responseDelta()));
|
|
423
572
|
}
|
|
424
573
|
if (lastFinishReason === 'tool-calls') {
|
|
425
574
|
throw new Error(`Agent loop exceeded ${maxIterations} iterations without reaching a stop condition`);
|
|
@@ -427,7 +576,7 @@ class AgentRuntime {
|
|
|
427
576
|
await this.saveToMemory(list, options);
|
|
428
577
|
await this.flushTelemetry(options);
|
|
429
578
|
if (this.config.titleGeneration && options?.persistence?.threadId && this.config.memory) {
|
|
430
|
-
|
|
579
|
+
const titlePromise = (0, title_generation_1.generateThreadTitle)({
|
|
431
580
|
memory: this.config.memory,
|
|
432
581
|
threadId: options.persistence.threadId,
|
|
433
582
|
resourceId: options.persistence.resourceId,
|
|
@@ -435,6 +584,9 @@ class AgentRuntime {
|
|
|
435
584
|
agentModel: this.config.model,
|
|
436
585
|
turnDelta: list.turnDelta(),
|
|
437
586
|
});
|
|
587
|
+
if (this.config.titleGeneration.sync) {
|
|
588
|
+
await titlePromise;
|
|
589
|
+
}
|
|
438
590
|
}
|
|
439
591
|
return {
|
|
440
592
|
runId: runId ?? '',
|
|
@@ -446,10 +598,24 @@ class AgentRuntime {
|
|
|
446
598
|
...(collectedSubAgentUsage.length > 0 && { subAgentUsage: collectedSubAgentUsage }),
|
|
447
599
|
};
|
|
448
600
|
}
|
|
449
|
-
startStreamLoop(
|
|
601
|
+
startStreamLoop(ctx) {
|
|
602
|
+
const { options, runId } = ctx;
|
|
450
603
|
const { readable, writable } = new TransformStream();
|
|
451
604
|
const writer = writable.getWriter();
|
|
452
|
-
|
|
605
|
+
const onToolExecutionStart = (data) => {
|
|
606
|
+
if (data.type !== "tool_execution_start")
|
|
607
|
+
return;
|
|
608
|
+
writer
|
|
609
|
+
.write({
|
|
610
|
+
type: 'tool-execution-start',
|
|
611
|
+
toolCallId: data.toolCallId,
|
|
612
|
+
toolName: data.toolName,
|
|
613
|
+
})
|
|
614
|
+
.catch(() => { });
|
|
615
|
+
};
|
|
616
|
+
this.eventBus.on("tool_execution_start", onToolExecutionStart);
|
|
617
|
+
this.withTelemetryRootSpan('stream', options, runId, async () => await this.runStreamLoop({ ...ctx, writer }))
|
|
618
|
+
.catch(async (error) => {
|
|
453
619
|
await this.flushTelemetry(options);
|
|
454
620
|
await this.cleanupRun(runId);
|
|
455
621
|
try {
|
|
@@ -460,11 +626,15 @@ class AgentRuntime {
|
|
|
460
626
|
catch {
|
|
461
627
|
writer.abort(error).catch(() => { });
|
|
462
628
|
}
|
|
629
|
+
})
|
|
630
|
+
.finally(() => {
|
|
631
|
+
this.eventBus.off("tool_execution_start", onToolExecutionStart);
|
|
463
632
|
});
|
|
464
633
|
return readable;
|
|
465
634
|
}
|
|
466
|
-
async runStreamLoop(
|
|
467
|
-
const {
|
|
635
|
+
async runStreamLoop(ctx) {
|
|
636
|
+
const { list, options, runId, pendingResume, writer } = ctx;
|
|
637
|
+
const { model, toolMap, aiTools, providerOptions, hasTools, outputSpec, effectiveInstructions, } = this.buildLoopContext({ ...options, persistence: options?.persistence });
|
|
468
638
|
const writeChunk = async (chunk) => {
|
|
469
639
|
await writer.write(chunk);
|
|
470
640
|
};
|
|
@@ -487,15 +657,21 @@ class AgentRuntime {
|
|
|
487
657
|
return true;
|
|
488
658
|
};
|
|
489
659
|
const runTelemetry = this.resolveTelemetry(options);
|
|
660
|
+
const toolCtx = { toolMap, list, runId, telemetry: runTelemetry };
|
|
490
661
|
if (pendingResume) {
|
|
491
662
|
try {
|
|
492
|
-
const batch = await this.iteratePendingToolCallsConcurrent(
|
|
663
|
+
const batch = await this.iteratePendingToolCallsConcurrent({
|
|
664
|
+
...toolCtx,
|
|
665
|
+
pendingResume,
|
|
666
|
+
});
|
|
493
667
|
for (const r of batch.results) {
|
|
494
668
|
if (r.subAgentUsage)
|
|
495
669
|
collectedSubAgentUsage.push(...r.subAgentUsage);
|
|
496
670
|
await writer.write({
|
|
497
|
-
type: '
|
|
498
|
-
|
|
671
|
+
type: 'tool-result',
|
|
672
|
+
toolCallId: r.toolCallId,
|
|
673
|
+
toolName: r.toolName,
|
|
674
|
+
output: r.modelOutput,
|
|
499
675
|
});
|
|
500
676
|
if (r.customMessage) {
|
|
501
677
|
await writer.write({ type: 'message', message: r.customMessage });
|
|
@@ -503,8 +679,11 @@ class AgentRuntime {
|
|
|
503
679
|
}
|
|
504
680
|
for (const e of batch.errors) {
|
|
505
681
|
await writer.write({
|
|
506
|
-
type: '
|
|
507
|
-
|
|
682
|
+
type: 'tool-result',
|
|
683
|
+
toolCallId: e.toolCallId,
|
|
684
|
+
toolName: e.toolName,
|
|
685
|
+
output: e.error,
|
|
686
|
+
isError: true,
|
|
508
687
|
});
|
|
509
688
|
}
|
|
510
689
|
if (Object.keys(batch.pending).length > 0) {
|
|
@@ -535,9 +714,10 @@ class AgentRuntime {
|
|
|
535
714
|
if (await handleAbort())
|
|
536
715
|
return;
|
|
537
716
|
this.eventBus.emit({ type: "turn_start" });
|
|
717
|
+
const messages = list.forLlm(effectiveInstructions, this.config.instructionProviderOptions);
|
|
538
718
|
const result = (0, ai_1.streamText)({
|
|
539
719
|
model,
|
|
540
|
-
messages
|
|
720
|
+
messages,
|
|
541
721
|
abortSignal: this.eventBus.signal,
|
|
542
722
|
...(hasTools ? { tools: aiTools } : {}),
|
|
543
723
|
...(providerOptions
|
|
@@ -548,7 +728,7 @@ class AgentRuntime {
|
|
|
548
728
|
});
|
|
549
729
|
try {
|
|
550
730
|
for await (const chunk of result.fullStream) {
|
|
551
|
-
if (chunk.type === 'finish'
|
|
731
|
+
if (chunk.type === 'finish')
|
|
552
732
|
continue;
|
|
553
733
|
const converted = (0, stream_1.convertChunk)(chunk);
|
|
554
734
|
if (converted)
|
|
@@ -580,20 +760,22 @@ class AgentRuntime {
|
|
|
580
760
|
if (outputSpec) {
|
|
581
761
|
structuredOutput = await result.output;
|
|
582
762
|
}
|
|
583
|
-
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.
|
|
763
|
+
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.extractSettledToolCalls)(newMessages));
|
|
584
764
|
break;
|
|
585
765
|
}
|
|
586
766
|
const toolCalls = await result.toolCalls;
|
|
587
767
|
try {
|
|
588
|
-
const batch = await this.iterateToolCallsConcurrent(
|
|
768
|
+
const batch = await this.iterateToolCallsConcurrent({ ...toolCtx, toolCalls });
|
|
589
769
|
if (await handleAbort())
|
|
590
770
|
return;
|
|
591
771
|
for (const r of batch.results) {
|
|
592
772
|
if (r.subAgentUsage)
|
|
593
773
|
collectedSubAgentUsage.push(...r.subAgentUsage);
|
|
594
774
|
await writer.write({
|
|
595
|
-
type: '
|
|
596
|
-
|
|
775
|
+
type: 'tool-result',
|
|
776
|
+
toolCallId: r.toolCallId,
|
|
777
|
+
toolName: r.toolName,
|
|
778
|
+
output: r.modelOutput,
|
|
597
779
|
});
|
|
598
780
|
if (r.customMessage) {
|
|
599
781
|
await writer.write({ type: 'message', message: r.customMessage });
|
|
@@ -601,8 +783,11 @@ class AgentRuntime {
|
|
|
601
783
|
}
|
|
602
784
|
for (const e of batch.errors) {
|
|
603
785
|
await writer.write({
|
|
604
|
-
type: '
|
|
605
|
-
|
|
786
|
+
type: 'tool-result',
|
|
787
|
+
toolCallId: e.toolCallId,
|
|
788
|
+
toolName: e.toolName,
|
|
789
|
+
output: e.error,
|
|
790
|
+
isError: true,
|
|
606
791
|
});
|
|
607
792
|
}
|
|
608
793
|
if (Object.keys(batch.pending).length > 0) {
|
|
@@ -628,7 +813,7 @@ class AgentRuntime {
|
|
|
628
813
|
await closeStreamWithError(error, 'failed');
|
|
629
814
|
return;
|
|
630
815
|
}
|
|
631
|
-
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.
|
|
816
|
+
this.emitTurnEnd(newMessages, (0, runtime_helpers_1.extractSettledToolCalls)(list.responseDelta()));
|
|
632
817
|
}
|
|
633
818
|
const costUsage = this.applyCost(totalUsage);
|
|
634
819
|
const parentCost = costUsage?.cost ?? 0;
|
|
@@ -647,7 +832,7 @@ class AgentRuntime {
|
|
|
647
832
|
try {
|
|
648
833
|
await this.saveToMemory(list, options);
|
|
649
834
|
if (this.config.titleGeneration && options?.persistence && this.config.memory) {
|
|
650
|
-
|
|
835
|
+
const titlePromise = (0, title_generation_1.generateThreadTitle)({
|
|
651
836
|
memory: this.config.memory,
|
|
652
837
|
threadId: options.persistence.threadId,
|
|
653
838
|
resourceId: options.persistence.resourceId,
|
|
@@ -655,6 +840,9 @@ class AgentRuntime {
|
|
|
655
840
|
agentModel: this.config.model,
|
|
656
841
|
turnDelta: list.turnDelta(),
|
|
657
842
|
});
|
|
843
|
+
if (this.config.titleGeneration.sync) {
|
|
844
|
+
await titlePromise;
|
|
845
|
+
}
|
|
658
846
|
}
|
|
659
847
|
await this.cleanupRun(runId);
|
|
660
848
|
await this.flushTelemetry(options);
|
|
@@ -771,7 +959,8 @@ class AgentRuntime {
|
|
|
771
959
|
}
|
|
772
960
|
return merged;
|
|
773
961
|
}
|
|
774
|
-
async iterateToolCallsConcurrent(
|
|
962
|
+
async iterateToolCallsConcurrent(ctx) {
|
|
963
|
+
const { toolCalls, toolMap, list, runId, telemetry: resolvedTelemetry } = ctx;
|
|
775
964
|
const executableCalls = toolCalls.filter((tc) => !tc.providerExecuted);
|
|
776
965
|
const executableCallsById = new Map(executableCalls.map((tc) => [tc.toolCallId, tc]));
|
|
777
966
|
const unexecutedIds = new Set(executableCalls.map((tc) => tc.toolCallId));
|
|
@@ -796,12 +985,12 @@ class AgentRuntime {
|
|
|
796
985
|
const tc = batch[i];
|
|
797
986
|
const toolInput = tc.input;
|
|
798
987
|
if (result.status === 'rejected') {
|
|
988
|
+
list.setToolCallError(tc.toolCallId, result.reason);
|
|
799
989
|
errors.push({
|
|
800
990
|
toolCallId: tc.toolCallId,
|
|
801
991
|
toolName: tc.toolName,
|
|
802
992
|
input: toolInput,
|
|
803
993
|
error: result.reason,
|
|
804
|
-
message: (0, runtime_helpers_1.makeErrorToolResultMessage)(tc.toolCallId, tc.toolName, result.reason),
|
|
805
994
|
});
|
|
806
995
|
}
|
|
807
996
|
else if (result.value.outcome === 'suspended') {
|
|
@@ -820,6 +1009,7 @@ class AgentRuntime {
|
|
|
820
1009
|
input: toolInput,
|
|
821
1010
|
suspendPayload: result.value.payload,
|
|
822
1011
|
resumeSchema: result.value.resumeSchema,
|
|
1012
|
+
runId,
|
|
823
1013
|
};
|
|
824
1014
|
}
|
|
825
1015
|
else if (result.value.outcome === 'success') {
|
|
@@ -828,9 +1018,9 @@ class AgentRuntime {
|
|
|
828
1018
|
toolName: tc.toolName,
|
|
829
1019
|
input: toolInput,
|
|
830
1020
|
toolEntry: result.value.toolEntry,
|
|
1021
|
+
modelOutput: result.value.modelOutput,
|
|
831
1022
|
subAgentUsage: result.value.subAgentUsage,
|
|
832
1023
|
customMessage: result.value.customMessage,
|
|
833
|
-
message: result.value.message,
|
|
834
1024
|
});
|
|
835
1025
|
}
|
|
836
1026
|
else if (result.value.outcome === 'error') {
|
|
@@ -839,7 +1029,6 @@ class AgentRuntime {
|
|
|
839
1029
|
toolName: tc.toolName,
|
|
840
1030
|
input: toolInput,
|
|
841
1031
|
error: result.value.error,
|
|
842
|
-
message: result.value.message,
|
|
843
1032
|
});
|
|
844
1033
|
}
|
|
845
1034
|
else if (result.value.outcome === 'noop') {
|
|
@@ -860,7 +1049,8 @@ class AgentRuntime {
|
|
|
860
1049
|
}
|
|
861
1050
|
return { results, suspensions, errors, pending };
|
|
862
1051
|
}
|
|
863
|
-
async iteratePendingToolCallsConcurrent(
|
|
1052
|
+
async iteratePendingToolCallsConcurrent(ctx) {
|
|
1053
|
+
const { pendingResume, toolMap, list, runId, telemetry: resolvedTelemetry } = ctx;
|
|
864
1054
|
const resumedId = pendingResume.resumeToolCallId;
|
|
865
1055
|
const resumedEntry = pendingResume.pendingToolCalls[resumedId];
|
|
866
1056
|
if (!resumedEntry) {
|
|
@@ -878,6 +1068,7 @@ class AgentRuntime {
|
|
|
878
1068
|
suspended: true,
|
|
879
1069
|
suspendPayload: processResult.payload,
|
|
880
1070
|
resumeSchema: processResult.resumeSchema,
|
|
1071
|
+
runId,
|
|
881
1072
|
};
|
|
882
1073
|
suspensions.push({
|
|
883
1074
|
toolCallId: resumedId,
|
|
@@ -893,9 +1084,9 @@ class AgentRuntime {
|
|
|
893
1084
|
toolName: resumedToolName,
|
|
894
1085
|
input: resumedEntry.input,
|
|
895
1086
|
toolEntry: processResult.toolEntry,
|
|
1087
|
+
modelOutput: processResult.modelOutput,
|
|
896
1088
|
subAgentUsage: processResult.subAgentUsage,
|
|
897
1089
|
customMessage: processResult.customMessage,
|
|
898
|
-
message: processResult.message,
|
|
899
1090
|
});
|
|
900
1091
|
}
|
|
901
1092
|
else if (processResult.outcome === 'error') {
|
|
@@ -904,7 +1095,6 @@ class AgentRuntime {
|
|
|
904
1095
|
toolName: resumedToolName,
|
|
905
1096
|
input: resumedEntry.input,
|
|
906
1097
|
error: processResult.error,
|
|
907
|
-
message: processResult.message,
|
|
908
1098
|
});
|
|
909
1099
|
}
|
|
910
1100
|
else if (processResult.outcome === 'noop') {
|
|
@@ -933,7 +1123,13 @@ class AgentRuntime {
|
|
|
933
1123
|
}
|
|
934
1124
|
}
|
|
935
1125
|
if (unexecuted.length > 0) {
|
|
936
|
-
const batch = await this.iterateToolCallsConcurrent(
|
|
1126
|
+
const batch = await this.iterateToolCallsConcurrent({
|
|
1127
|
+
toolCalls: unexecuted,
|
|
1128
|
+
toolMap,
|
|
1129
|
+
list,
|
|
1130
|
+
runId,
|
|
1131
|
+
telemetry: resolvedTelemetry,
|
|
1132
|
+
});
|
|
937
1133
|
results.push(...batch.results);
|
|
938
1134
|
suspensions.push(...batch.suspensions);
|
|
939
1135
|
errors.push(...batch.errors);
|
|
@@ -957,57 +1153,52 @@ class AgentRuntime {
|
|
|
957
1153
|
result: error,
|
|
958
1154
|
isError: true,
|
|
959
1155
|
});
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
return { outcome: 'error', error, message: errorMsg };
|
|
1156
|
+
list.setToolCallError(toolCallId, error);
|
|
1157
|
+
return { outcome: 'error', error };
|
|
963
1158
|
};
|
|
964
1159
|
if (!builtTool) {
|
|
965
1160
|
return makeToolError(new Error(`Tool ${toolName} not found`));
|
|
966
1161
|
}
|
|
967
|
-
const
|
|
1162
|
+
const settledBlock = list
|
|
968
1163
|
.responseDelta()
|
|
969
|
-
.
|
|
970
|
-
.
|
|
971
|
-
|
|
972
|
-
|
|
1164
|
+
.flatMap((m) => ((0, message_1.isLlmMessage)(m) && 'content' in m ? m.content : []))
|
|
1165
|
+
.find((c) => c.type === 'tool-call' && c.toolCallId === toolCallId && c.state !== 'pending');
|
|
1166
|
+
if (settledBlock) {
|
|
1167
|
+
let settledResult;
|
|
1168
|
+
if (settledBlock.state === 'resolved') {
|
|
1169
|
+
settledResult = settledBlock.output;
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
settledResult = settledBlock.error;
|
|
1173
|
+
}
|
|
973
1174
|
this.eventBus.emit({
|
|
974
1175
|
type: "tool_execution_end",
|
|
975
1176
|
toolCallId,
|
|
976
1177
|
toolName,
|
|
977
|
-
result:
|
|
978
|
-
isError:
|
|
1178
|
+
result: settledResult,
|
|
1179
|
+
isError: settledBlock.state === 'rejected',
|
|
979
1180
|
});
|
|
980
1181
|
return { outcome: 'noop' };
|
|
981
1182
|
}
|
|
982
1183
|
if (builtTool.inputSchema) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
return makeToolError(new Error(`Invalid tool input: ${result.error.message}`));
|
|
987
|
-
}
|
|
988
|
-
toolInput = result.data;
|
|
989
|
-
}
|
|
990
|
-
else {
|
|
991
|
-
const validate = ajv.compile(builtTool.inputSchema);
|
|
992
|
-
const valid = validate(toolInput);
|
|
993
|
-
if (!valid) {
|
|
994
|
-
const message = ajv.errorsText(validate.errors);
|
|
995
|
-
return makeToolError(new Error(`Invalid tool input: ${message}`));
|
|
996
|
-
}
|
|
1184
|
+
const result = await (0, parse_1.parseWithSchema)(builtTool.inputSchema, toolInput);
|
|
1185
|
+
if (!result.success) {
|
|
1186
|
+
return makeToolError(new Error(`Invalid tool input: ${result.error}`));
|
|
997
1187
|
}
|
|
1188
|
+
toolInput = result.data;
|
|
998
1189
|
}
|
|
999
1190
|
let toolResult;
|
|
1000
1191
|
try {
|
|
1001
|
-
toolResult = await (0, tool_adapter_1.executeTool)(toolInput, builtTool, resumeData, resolvedTelemetry);
|
|
1192
|
+
toolResult = await this.withTelemetryToolSpan(toolCallId, toolName, toolInput, resolvedTelemetry, async () => await (0, tool_adapter_1.executeTool)(toolInput, builtTool, resumeData, resolvedTelemetry, toolCallId));
|
|
1002
1193
|
}
|
|
1003
1194
|
catch (error) {
|
|
1004
1195
|
return makeToolError(error);
|
|
1005
1196
|
}
|
|
1006
1197
|
if ((0, tool_adapter_1.isSuspendedToolResult)(toolResult)) {
|
|
1007
1198
|
if (builtTool?.suspendSchema) {
|
|
1008
|
-
const parseResult = await builtTool.suspendSchema
|
|
1199
|
+
const parseResult = await (0, parse_1.parseWithSchema)(builtTool.suspendSchema, toolResult.payload);
|
|
1009
1200
|
if (!parseResult.success) {
|
|
1010
|
-
return makeToolError(new Error(`Invalid suspend payload: ${parseResult.error
|
|
1201
|
+
return makeToolError(new Error(`Invalid suspend payload: ${parseResult.error}`));
|
|
1011
1202
|
}
|
|
1012
1203
|
toolResult.payload = parseResult.data;
|
|
1013
1204
|
}
|
|
@@ -1015,8 +1206,17 @@ class AgentRuntime {
|
|
|
1015
1206
|
const error = new Error(`Tool ${toolName} has no resume schema`);
|
|
1016
1207
|
return makeToolError(error);
|
|
1017
1208
|
}
|
|
1018
|
-
const resumeSchema = (0,
|
|
1019
|
-
|
|
1209
|
+
const resumeSchema = (0, zod_1.isZodSchema)(builtTool.resumeSchema)
|
|
1210
|
+
? (0, zod_to_json_schema_1.zodToJsonSchema)(builtTool.resumeSchema)
|
|
1211
|
+
: builtTool.resumeSchema;
|
|
1212
|
+
if (!resumeSchema) {
|
|
1213
|
+
return makeToolError(new Error('Invalid resume schema'));
|
|
1214
|
+
}
|
|
1215
|
+
return {
|
|
1216
|
+
outcome: 'suspended',
|
|
1217
|
+
payload: toolResult.payload,
|
|
1218
|
+
resumeSchema,
|
|
1219
|
+
};
|
|
1020
1220
|
}
|
|
1021
1221
|
let actualResult = toolResult;
|
|
1022
1222
|
let extractedSubAgentUsage;
|
|
@@ -1034,8 +1234,7 @@ class AgentRuntime {
|
|
|
1034
1234
|
const modelResult = builtTool.toModelOutput
|
|
1035
1235
|
? builtTool.toModelOutput(actualResult)
|
|
1036
1236
|
: actualResult;
|
|
1037
|
-
|
|
1038
|
-
list.addResponse([toolResultMsg]);
|
|
1237
|
+
list.setToolCallResult(toolCallId, (0, json_value_1.toJsonValue)(modelResult));
|
|
1039
1238
|
const customMessage = builtTool?.toMessage?.(actualResult);
|
|
1040
1239
|
if (customMessage) {
|
|
1041
1240
|
list.addResponse([customMessage]);
|
|
@@ -1048,9 +1247,9 @@ class AgentRuntime {
|
|
|
1048
1247
|
output: actualResult,
|
|
1049
1248
|
transformed: !!builtTool.toModelOutput,
|
|
1050
1249
|
},
|
|
1250
|
+
modelOutput: modelResult,
|
|
1051
1251
|
subAgentUsage: extractedSubAgentUsage,
|
|
1052
1252
|
customMessage,
|
|
1053
|
-
message: toolResultMsg,
|
|
1054
1253
|
};
|
|
1055
1254
|
}
|
|
1056
1255
|
buildLoopContext(execOptions) {
|
|
@@ -1061,8 +1260,9 @@ class AgentRuntime {
|
|
|
1061
1260
|
const aiTools = (0, tool_adapter_1.toAiSdkTools)(allUserTools);
|
|
1062
1261
|
const aiProviderTools = (0, tool_adapter_1.toAiSdkProviderTools)(this.config.providerTools);
|
|
1063
1262
|
const allTools = { ...aiTools, ...aiProviderTools };
|
|
1263
|
+
const model = (0, model_factory_1.createModel)(this.config.model);
|
|
1064
1264
|
return {
|
|
1065
|
-
model
|
|
1265
|
+
model,
|
|
1066
1266
|
toolMap: (0, tool_adapter_1.buildToolMap)(allUserTools),
|
|
1067
1267
|
aiTools: allTools,
|
|
1068
1268
|
providerOptions: this.buildCallProviderOptions(execOptions?.providerOptions),
|
|
@@ -1070,8 +1270,19 @@ class AgentRuntime {
|
|
|
1070
1270
|
outputSpec: this.config.structuredOutput
|
|
1071
1271
|
? ai_1.Output.object({ schema: this.config.structuredOutput })
|
|
1072
1272
|
: undefined,
|
|
1273
|
+
effectiveInstructions: this.composeEffectiveInstructions(allUserTools),
|
|
1073
1274
|
};
|
|
1074
1275
|
}
|
|
1276
|
+
composeEffectiveInstructions(tools) {
|
|
1277
|
+
const fragments = tools
|
|
1278
|
+
.map((t) => t.systemInstruction)
|
|
1279
|
+
.filter((s) => typeof s === 'string' && s.trim().length > 0);
|
|
1280
|
+
const userInstructions = this.config.instructions;
|
|
1281
|
+
if (fragments.length === 0)
|
|
1282
|
+
return userInstructions;
|
|
1283
|
+
const block = `<built_in_rules>\n${fragments.map((f) => `- ${f}`).join('\n')}\n</built_in_rules>`;
|
|
1284
|
+
return userInstructions ? `${block}\n\n${userInstructions}` : block;
|
|
1285
|
+
}
|
|
1075
1286
|
buildWorkingMemoryToolForRun(persistence) {
|
|
1076
1287
|
const wmParams = this.resolveWorkingMemoryParams(persistence);
|
|
1077
1288
|
if (!wmParams)
|