@fevex/core 0.1.0-alpha.8 → 0.1.0-alpha.9
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/README.md +30 -1
- package/dist/agents/index.d.mts +2 -2
- package/dist/channels/index.d.mts +1 -1
- package/dist/evals/index.d.mts +3 -3
- package/dist/{fevex-DB0-k1fb.d.mts → fevex-WBvRWSpy.d.mts} +14 -8
- package/dist/http/index.d.mts +3 -3
- package/dist/{index-B8molngu.d.mts → index-3bFNzCiY.d.mts} +64 -3
- package/dist/{index-Bl0hR7EC.d.mts → index-BLgiXQK4.d.mts} +1 -1
- package/dist/{index-DtMxzCqj.d.mts → index-BbwT5XxQ.d.mts} +92 -2
- package/dist/{index-CuaetTLQ.d.mts → index-CmFBB4Px.d.mts} +2 -2
- package/dist/{index-CAyAoOW0.d.mts → index-D4mWV2zG.d.mts} +1 -1
- package/dist/{index-CecXoEbs.d.mts → index-D7FoZ7aQ.d.mts} +2 -2
- package/dist/{index-BfYzemR8.d.mts → index-D7r0puBi.d.mts} +14 -1
- package/dist/{index-CODYPevS.d.mts → index-D8lCFkc7.d.mts} +3 -3
- package/dist/{index-RKE3-CKs.d.mts → index-DgSxJZo4.d.mts} +2 -2
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +456 -77
- package/dist/knowledge/index.d.mts +1 -1
- package/dist/models/index.d.mts +2 -2
- package/dist/observability/index.d.mts +1 -1
- package/dist/policies/index.d.mts +1 -1
- package/dist/runtime/index.d.mts +2 -2
- package/dist/runtime/index.mjs +68 -1
- package/dist/teams/index.d.mts +1 -1
- package/dist/testing/index.d.mts +5 -5
- package/dist/tools/index.d.mts +2 -2
- package/dist/tools/index.mjs +221 -1
- package/dist/workflows/index.d.mts +1 -1
- package/package.json +1 -1
- package/dist/exact-definition-NHBBFlFR.d.mts +0 -4
package/dist/index.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import { n as RunPausedError, t as FevexRunError } from "./run-error-Cr17wPGH.mj
|
|
|
4
4
|
import { ChannelError, deliverChannelRun, handleChannelInput } from "./channels/index.mjs";
|
|
5
5
|
import { InMemoryMemoryStore, createAgentsMdContextProvider, createMemoryContextProvider, defineContextProvider, defineSkill, isProgressiveSkillProvider, loadSkillFile, loadSkillFiles } from "./knowledge/index.mjs";
|
|
6
6
|
import { n as teamAsWorkflow, t as defineTeam } from "./teams-Ctz676G4.mjs";
|
|
7
|
-
import { InMemoryRunStore, createDigestContextCompactor, estimateContextTokens, isDurableRunStore, isRetainableRunStore, resolveContextBudget, validateListEventsOptions, validatePurgeRunsOptions } from "./runtime/index.mjs";
|
|
8
|
-
import { FEVEX_JSON_SCHEMA_PROFILE_VERSION, IntegrationError, compileFevexJsonSchema, defineConnection, defineTool, toToolSpec, validateFevexJsonSchemaProfile } from "./tools/index.mjs";
|
|
7
|
+
import { InMemoryRunStore, createDigestContextCompactor, createModelContextCompactor, estimateContextTokens, isDurableRunStore, isRetainableRunStore, resolveContextBudget, validateListEventsOptions, validatePurgeRunsOptions } from "./runtime/index.mjs";
|
|
8
|
+
import { FEVEX_JSON_SCHEMA_PROFILE_VERSION, InMemoryToolEmbeddingCache, IntegrationError, buildToolEmbeddingIndex, compileFevexJsonSchema, cosineSimilarity, defineConnection, defineTool, schemaKeywords, searchToolEmbeddingIndex, toToolSpec, toolEmbeddingKey, toolEmbeddingText, validateFevexJsonSchemaProfile } from "./tools/index.mjs";
|
|
9
9
|
import { _ as serializeValue, a as assertTokenBudget, c as eventUsage, d as remainingDeadlineMs, f as remainingOutputTokens, g as serializeJsonValue, h as toErrorMessage, i as assertContinuationBudget, l as isTimeoutError, m as runSignal, n as abortable, o as cancellationReason, p as resumeDeadlineSignal, r as addUsage, s as deadlineAtFromMs, u as minDeadline, v as toJsonValue } from "./run-support-CmZ6Xo6H.mjs";
|
|
10
10
|
import { t as readModelStream } from "./model-stream-JQdHDDcj.mjs";
|
|
11
11
|
import "./models/index.mjs";
|
|
@@ -67,6 +67,139 @@ async function validateSchema(schema, value, errorMessage) {
|
|
|
67
67
|
return result.value;
|
|
68
68
|
}
|
|
69
69
|
//#endregion
|
|
70
|
+
//#region src/internal/tool-search.ts
|
|
71
|
+
function resolveToolSearchOptions(options, label, defaultCache) {
|
|
72
|
+
if (options !== void 0 && (typeof options !== "object" || options === null || Array.isArray(options))) throw new TypeError(`${label} must be an object`);
|
|
73
|
+
const mode = options?.mode ?? "auto";
|
|
74
|
+
if (mode !== "auto" && mode !== "on" && mode !== "off") throw new TypeError(`${label}.mode must be auto, on or off`);
|
|
75
|
+
const threshold = options?.threshold ?? 30;
|
|
76
|
+
if (!Number.isSafeInteger(threshold) || threshold < 1) throw new TypeError(`${label}.threshold must be a positive safe integer`);
|
|
77
|
+
const tokenThreshold = options?.tokenThreshold;
|
|
78
|
+
if (tokenThreshold !== void 0 && (!Number.isSafeInteger(tokenThreshold) || tokenThreshold < 1)) throw new TypeError(`${label}.tokenThreshold must be a positive safe integer`);
|
|
79
|
+
const limit = options?.limit ?? 5;
|
|
80
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 20) throw new TypeError(`${label}.limit must be a safe integer between 1 and 20`);
|
|
81
|
+
const pinned = options?.pinned ?? [];
|
|
82
|
+
if (!Array.isArray(pinned) || pinned.some((name) => typeof name !== "string" || !name.trim())) throw new TypeError(`${label}.pinned must contain non-empty tool names`);
|
|
83
|
+
const normalizedPinned = [...new Set(pinned.map((name) => name.trim()))];
|
|
84
|
+
if (normalizedPinned.length !== pinned.length) throw new TypeError(`${label}.pinned must contain unique tool names`);
|
|
85
|
+
const semantic = options?.semantic;
|
|
86
|
+
return {
|
|
87
|
+
mode,
|
|
88
|
+
threshold,
|
|
89
|
+
...tokenThreshold === void 0 ? {} : { tokenThreshold },
|
|
90
|
+
limit,
|
|
91
|
+
pinned: normalizedPinned,
|
|
92
|
+
...semantic === void 0 ? {} : { semantic: resolveSemanticOptions(semantic, `${label}.semantic`, defaultCache) }
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function serializeToolSearchOptions(options) {
|
|
96
|
+
return {
|
|
97
|
+
mode: options.mode,
|
|
98
|
+
threshold: options.threshold,
|
|
99
|
+
...options.tokenThreshold === void 0 ? {} : { tokenThreshold: options.tokenThreshold },
|
|
100
|
+
limit: options.limit,
|
|
101
|
+
pinned: [...options.pinned]
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function reciprocalRankFusionCandidates(lexical, semantic, limit, rankConstant = 60) {
|
|
105
|
+
if (!Number.isSafeInteger(limit) || limit < 1) throw new TypeError("Tool search fusion limit must be a positive safe integer");
|
|
106
|
+
if (!Number.isSafeInteger(rankConstant) || rankConstant < 1) throw new TypeError("Tool search fusion rankConstant must be a positive safe integer");
|
|
107
|
+
const scores = /* @__PURE__ */ new Map();
|
|
108
|
+
const add = (tools) => {
|
|
109
|
+
for (let index = 0; index < tools.length; index += 1) {
|
|
110
|
+
const tool = tools[index];
|
|
111
|
+
const entry = scores.get(tool.name) ?? {
|
|
112
|
+
tool,
|
|
113
|
+
score: 0
|
|
114
|
+
};
|
|
115
|
+
entry.score += 1 / (rankConstant + index + 1);
|
|
116
|
+
scores.set(tool.name, entry);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
add(lexical);
|
|
120
|
+
add(semantic);
|
|
121
|
+
return [...scores.values()].sort((left, right) => right.score - left.score || left.tool.name.localeCompare(right.tool.name)).slice(0, limit);
|
|
122
|
+
}
|
|
123
|
+
function resolveSemanticOptions(semantic, label, defaultCache) {
|
|
124
|
+
if (typeof semantic !== "object" || semantic === null || Array.isArray(semantic)) throw new TypeError(`${label} must be an object`);
|
|
125
|
+
const embeddings = semantic.embeddings;
|
|
126
|
+
if (typeof embeddings !== "object" || embeddings === null || typeof embeddings.id !== "string" || !embeddings.id.trim() || typeof embeddings.embed !== "function") throw new TypeError(`${label}.embeddings must implement EmbeddingModel`);
|
|
127
|
+
if (embeddings.dimensions !== void 0 && (!Number.isSafeInteger(embeddings.dimensions) || embeddings.dimensions < 1)) throw new TypeError(`${label}.embeddings.dimensions must be a positive safe integer`);
|
|
128
|
+
const cache = semantic.cache ?? defaultCache;
|
|
129
|
+
if (cache === void 0 || typeof cache.get !== "function" || typeof cache.set !== "function") throw new TypeError(`${label}.cache must implement get and set`);
|
|
130
|
+
const topK = semantic.topK ?? 20;
|
|
131
|
+
if (!Number.isSafeInteger(topK) || topK < 1) throw new TypeError(`${label}.topK must be a positive safe integer`);
|
|
132
|
+
const minScore = semantic.minScore ?? 0;
|
|
133
|
+
if (typeof minScore !== "number" || !Number.isFinite(minScore) || minScore < -1 || minScore > 1) throw new TypeError(`${label}.minScore must be a finite number between -1 and 1`);
|
|
134
|
+
const reranker = semantic.reranker;
|
|
135
|
+
if (reranker !== void 0 && (typeof reranker !== "object" || reranker === null || typeof reranker.rerank !== "function")) throw new TypeError(`${label}.reranker must implement rerank`);
|
|
136
|
+
return {
|
|
137
|
+
embeddings,
|
|
138
|
+
cache,
|
|
139
|
+
topK,
|
|
140
|
+
minScore,
|
|
141
|
+
...reranker === void 0 ? {} : { reranker }
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function shouldUseToolSearch(options, tools) {
|
|
145
|
+
if (options.mode === "off" || tools.length === 0) return false;
|
|
146
|
+
if (options.mode === "on") return true;
|
|
147
|
+
if (tools.length > options.threshold) return true;
|
|
148
|
+
if (options.tokenThreshold === void 0) return false;
|
|
149
|
+
return Math.ceil(JSON.stringify(tools).length / 4) > options.tokenThreshold;
|
|
150
|
+
}
|
|
151
|
+
const searchIndex = /* @__PURE__ */ new WeakMap();
|
|
152
|
+
function indexedTools(tools) {
|
|
153
|
+
const cached = searchIndex.get(tools);
|
|
154
|
+
if (cached !== void 0) return cached;
|
|
155
|
+
const index = tools.map((tool) => {
|
|
156
|
+
const name = tool.name.toLowerCase();
|
|
157
|
+
const description = (tool.description ?? "").toLowerCase();
|
|
158
|
+
return {
|
|
159
|
+
tool,
|
|
160
|
+
name,
|
|
161
|
+
nameTerms: new Set(name.split(/[^a-z0-9]+/).filter(Boolean)),
|
|
162
|
+
description,
|
|
163
|
+
descriptionTerms: new Set(description.split(/[^a-z0-9]+/).filter(Boolean)),
|
|
164
|
+
schema: JSON.stringify(tool.inputSchema ?? {}).toLowerCase()
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
searchIndex.set(tools, index);
|
|
168
|
+
return index;
|
|
169
|
+
}
|
|
170
|
+
function searchToolSpecs(tools, query, limit) {
|
|
171
|
+
const terms = [...new Set(query.toLowerCase().split(/[^a-z0-9]+/).filter((term) => term.length > 1))];
|
|
172
|
+
if (terms.length === 0) return [];
|
|
173
|
+
return indexedTools(tools).map(({ tool, name, nameTerms, description, descriptionTerms, schema }) => {
|
|
174
|
+
let score = 0;
|
|
175
|
+
for (const term of terms) {
|
|
176
|
+
if (name === term) score += 100;
|
|
177
|
+
else if (nameTerms.has(term)) score += 40;
|
|
178
|
+
else if (name.startsWith(term)) score += 30;
|
|
179
|
+
else if (name.includes(term)) score += 20;
|
|
180
|
+
if (descriptionTerms.has(term)) score += 8;
|
|
181
|
+
else if (description.includes(term)) score += 5;
|
|
182
|
+
if (schema.includes(term)) score += 1;
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
tool,
|
|
186
|
+
score
|
|
187
|
+
};
|
|
188
|
+
}).filter(({ score }) => score > 0).sort((left, right) => right.score - left.score || left.tool.name.localeCompare(right.tool.name)).slice(0, limit).map(({ tool }) => tool);
|
|
189
|
+
}
|
|
190
|
+
function readToolSearchInput(input) {
|
|
191
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new TypeError("Tool search input must be an object");
|
|
192
|
+
const record = input;
|
|
193
|
+
const query = record.query;
|
|
194
|
+
const limit = record.limit;
|
|
195
|
+
if (typeof query !== "string" || !query.trim()) throw new TypeError("Tool search query must be a non-empty string");
|
|
196
|
+
if (limit !== void 0 && (typeof limit !== "number" || !Number.isSafeInteger(limit) || limit < 1)) throw new TypeError("Tool search limit must be a positive safe integer");
|
|
197
|
+
return {
|
|
198
|
+
query: query.trim(),
|
|
199
|
+
...limit === void 0 ? {} : { limit }
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
70
203
|
//#region src/internal/configuration.ts
|
|
71
204
|
const REASONING_EFFORTS = /* @__PURE__ */ new Set([
|
|
72
205
|
"provider-default",
|
|
@@ -190,6 +323,7 @@ function expandConnection(connection) {
|
|
|
190
323
|
};
|
|
191
324
|
assertConfiguration(policy?.inputSchema === void 0 || isJsonObject(policy.inputSchema), "INVALID_TOOL", `Input schema for connection tool "${remoteName}" must be a JSON object`);
|
|
192
325
|
assertConfiguration(policy?.outputSchema === void 0 || isJsonObject(policy.outputSchema), "INVALID_TOOL", `Output schema for connection tool "${remoteName}" must be a JSON object`);
|
|
326
|
+
assertConfiguration(policy?.maxResultBytes === void 0 || policy.maxResultBytes === false || Number.isSafeInteger(policy.maxResultBytes) && policy.maxResultBytes > 0, "INVALID_TOOL", `maxResultBytes for connection tool "${remoteName}" must be a positive safe integer or false`);
|
|
193
327
|
return {
|
|
194
328
|
name: namespacedToolName(connection.name, remoteName),
|
|
195
329
|
...policy?.label === void 0 ? {} : { label: policy.label },
|
|
@@ -201,6 +335,7 @@ function expandConnection(connection) {
|
|
|
201
335
|
...policy?.idempotency === void 0 ? {} : { idempotency: policy.idempotency },
|
|
202
336
|
...policy?.retry === void 0 ? {} : { retry: policy.retry },
|
|
203
337
|
...policy?.credentials === void 0 ? {} : { credentials: policy.credentials },
|
|
338
|
+
...policy?.maxResultBytes === void 0 ? {} : { maxResultBytes: policy.maxResultBytes },
|
|
204
339
|
source,
|
|
205
340
|
async resolve(context) {
|
|
206
341
|
try {
|
|
@@ -305,10 +440,18 @@ function createComposition(config) {
|
|
|
305
440
|
} catch (error) {
|
|
306
441
|
throw configurationError("INVALID_CONFIG", error.message);
|
|
307
442
|
}
|
|
443
|
+
assertConfiguration(config.toolSearchCache === void 0 || isRecord(config.toolSearchCache) && typeof config.toolSearchCache.get === "function" && typeof config.toolSearchCache.set === "function", "INVALID_CONFIG", "Fevex config \"toolSearchCache\" must implement get and set");
|
|
444
|
+
const defaultToolSearchCache = config.toolSearchCache ?? new InMemoryToolEmbeddingCache();
|
|
445
|
+
if (config.toolSearch !== void 0) try {
|
|
446
|
+
resolveToolSearchOptions(config.toolSearch, "Fevex config \"toolSearch\"", defaultToolSearchCache);
|
|
447
|
+
} catch (error) {
|
|
448
|
+
throw configurationError("INVALID_CONFIG", error.message);
|
|
449
|
+
}
|
|
308
450
|
if (config.compaction !== void 0) {
|
|
309
451
|
assertConfiguration(typeof config.compaction === "object" && config.compaction !== null && !Array.isArray(config.compaction), "INVALID_CONFIG", "Fevex config \"compaction\" must be an object");
|
|
310
452
|
assertConfiguration(config.compaction.compactor === void 0 || isRecord(config.compaction.compactor) && typeof config.compaction.compactor.compact === "function", "INVALID_CONFIG", "Fevex config \"compaction.compactor\" must implement compact");
|
|
311
453
|
assertConfiguration(config.compaction.estimateTokens === void 0 || typeof config.compaction.estimateTokens === "function", "INVALID_CONFIG", "Fevex config \"compaction.estimateTokens\" must be a function");
|
|
454
|
+
assertConfiguration(config.compaction.redactSummary === void 0 || typeof config.compaction.redactSummary === "function", "INVALID_CONFIG", "Fevex config \"compaction.redactSummary\" must be a function");
|
|
312
455
|
}
|
|
313
456
|
assertConfiguration(config.memoryStore === void 0 || isMemoryStore(config.memoryStore), "INVALID_CONFIG", "Fevex config \"memoryStore\" must implement MemoryStore");
|
|
314
457
|
assertConfiguration(config.onEvent === void 0 || typeof config.onEvent === "function", "INVALID_CONFIG", "Fevex config \"onEvent\" must be a function");
|
|
@@ -395,6 +538,7 @@ function createComposition(config) {
|
|
|
395
538
|
assertConfiguration(definition.credentials === void 0 || Array.isArray(definition.credentials) && definition.credentials.every((value) => typeof value === "string" && value.trim()), "INVALID_TOOL", `Tool "${name}" credentials must be non-empty strings`);
|
|
396
539
|
assertSandboxCapabilities(definition.sandbox, name);
|
|
397
540
|
assertConfiguration(definition.sandbox === void 0 || config.sandbox !== void 0, "INVALID_TOOL", `Tool "${name}" requires Fevex config "sandbox"`);
|
|
541
|
+
assertConfiguration(definition.maxResultBytes === void 0 || definition.maxResultBytes === false || Number.isSafeInteger(definition.maxResultBytes) && definition.maxResultBytes > 0, "INVALID_TOOL", `Tool "${name}" maxResultBytes must be a positive safe integer or false`);
|
|
398
542
|
if (definition.retry !== void 0) assertConfiguration(isRecord(definition.retry) && Number.isInteger(definition.retry.maxAttempts) && definition.retry.maxAttempts >= 1 && Number.isInteger(definition.retry.backoffMs) && definition.retry.backoffMs >= 0 && (definition.retry.maxBackoffMs === void 0 || Number.isInteger(definition.retry.maxBackoffMs) && definition.retry.maxBackoffMs >= 0), "INVALID_TOOL", `Tool "${name}" retry is invalid`);
|
|
399
543
|
if (definition.inputSchema !== void 0) assertConfiguration(isStandardSchema(definition.inputSchema), "INVALID_TOOL", `Input schema for tool "${name}" must implement Standard Schema`);
|
|
400
544
|
if (definition.inputSchema !== void 0) assertConfiguration(isStandardSchema(definition.inputSchema), "INVALID_AGENT", `Input schema for agent "${name}" must implement Standard Schema`);
|
|
@@ -414,6 +558,7 @@ function createComposition(config) {
|
|
|
414
558
|
...definition.idempotency === void 0 ? {} : { idempotency: definition.idempotency },
|
|
415
559
|
...definition.retry === void 0 ? {} : { retry: { ...definition.retry } },
|
|
416
560
|
...definition.credentials === void 0 ? {} : { credentials: [...definition.credentials] },
|
|
561
|
+
...definition.maxResultBytes === void 0 ? {} : { maxResultBytes: definition.maxResultBytes },
|
|
417
562
|
...definition.sandbox === void 0 ? {} : { sandbox: copySandboxCapabilities(definition.sandbox) },
|
|
418
563
|
...definition.source === void 0 ? {} : { source: { ...definition.source } },
|
|
419
564
|
...definition.resolve === void 0 ? {} : { resolve: definition.resolve },
|
|
@@ -490,12 +635,18 @@ function createComposition(config) {
|
|
|
490
635
|
} catch (error) {
|
|
491
636
|
throw configurationError("INVALID_AGENT", error.message);
|
|
492
637
|
}
|
|
638
|
+
if (definition.toolSearch !== void 0) try {
|
|
639
|
+
resolveToolSearchOptions(definition.toolSearch, `Agent "${name}" toolSearch`, defaultToolSearchCache);
|
|
640
|
+
} catch (error) {
|
|
641
|
+
throw configurationError("INVALID_AGENT", error.message);
|
|
642
|
+
}
|
|
493
643
|
if (definition.outputSchema !== void 0) assertConfiguration(isStandardSchema(definition.outputSchema), "INVALID_AGENT", `Output schema for agent "${name}" must implement Standard Schema`);
|
|
494
644
|
const rawLimits = definition.limits;
|
|
495
645
|
assertLimit(rawLimits?.maxSteps, "maxSteps", 1, name);
|
|
496
646
|
assertLimit(rawLimits?.maxToolCalls, "maxToolCalls", 0, name);
|
|
497
647
|
assertLimit(rawLimits?.maxInputTokens, "maxInputTokens", 1, name, true);
|
|
498
648
|
assertLimit(rawLimits?.maxOutputTokens, "maxOutputTokens", 1, name, true);
|
|
649
|
+
assertLimit(rawLimits?.maxToolResultBytes, "maxToolResultBytes", 1, name, true);
|
|
499
650
|
agents.set(name, {
|
|
500
651
|
name,
|
|
501
652
|
instructions: definition.instructions,
|
|
@@ -514,13 +665,18 @@ function createComposition(config) {
|
|
|
514
665
|
...definition.elicitation === void 0 ? {} : { elicitation: definition.elicitation },
|
|
515
666
|
...definition.approvalMode === void 0 ? {} : { approvalMode: definition.approvalMode },
|
|
516
667
|
...definition.contextBudget === void 0 ? {} : { contextBudget: { ...definition.contextBudget } },
|
|
668
|
+
...definition.toolSearch === void 0 ? {} : { toolSearch: {
|
|
669
|
+
...definition.toolSearch,
|
|
670
|
+
...definition.toolSearch.pinned === void 0 ? {} : { pinned: [...definition.toolSearch.pinned] }
|
|
671
|
+
} },
|
|
517
672
|
...definition.inputSchema === void 0 ? {} : { inputSchema: definition.inputSchema },
|
|
518
673
|
...definition.outputSchema === void 0 ? {} : { outputSchema: definition.outputSchema },
|
|
519
674
|
...rawLimits === void 0 ? {} : { limits: {
|
|
520
675
|
...rawLimits.maxSteps === void 0 ? {} : { maxSteps: rawLimits.maxSteps },
|
|
521
676
|
...rawLimits.maxToolCalls === void 0 ? {} : { maxToolCalls: rawLimits.maxToolCalls },
|
|
522
677
|
...rawLimits.maxInputTokens === void 0 ? {} : { maxInputTokens: rawLimits.maxInputTokens },
|
|
523
|
-
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens }
|
|
678
|
+
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens },
|
|
679
|
+
...rawLimits.maxToolResultBytes === void 0 ? {} : { maxToolResultBytes: rawLimits.maxToolResultBytes }
|
|
524
680
|
} }
|
|
525
681
|
});
|
|
526
682
|
}
|
|
@@ -557,6 +713,7 @@ function createComposition(config) {
|
|
|
557
713
|
assertLimit(rawLimits?.maxToolCalls, "maxToolCalls", 0, name, false, "Workflow", "INVALID_WORKFLOW");
|
|
558
714
|
assertLimit(rawLimits?.maxInputTokens, "maxInputTokens", 1, name, true, "Workflow", "INVALID_WORKFLOW");
|
|
559
715
|
assertLimit(rawLimits?.maxOutputTokens, "maxOutputTokens", 1, name, true, "Workflow", "INVALID_WORKFLOW");
|
|
716
|
+
assertLimit(rawLimits?.maxToolResultBytes, "maxToolResultBytes", 1, name, false, "Workflow", "INVALID_WORKFLOW");
|
|
560
717
|
assertConfiguration(!workflows.has(name), "DUPLICATE_WORKFLOW", `Workflow "${name}" is duplicated`);
|
|
561
718
|
workflows.set(name, {
|
|
562
719
|
name,
|
|
@@ -568,7 +725,8 @@ function createComposition(config) {
|
|
|
568
725
|
...rawLimits.maxSteps === void 0 ? {} : { maxSteps: rawLimits.maxSteps },
|
|
569
726
|
...rawLimits.maxToolCalls === void 0 ? {} : { maxToolCalls: rawLimits.maxToolCalls },
|
|
570
727
|
...rawLimits.maxInputTokens === void 0 ? {} : { maxInputTokens: rawLimits.maxInputTokens },
|
|
571
|
-
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens }
|
|
728
|
+
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens },
|
|
729
|
+
...rawLimits.maxToolResultBytes === void 0 ? {} : { maxToolResultBytes: rawLimits.maxToolResultBytes }
|
|
572
730
|
} },
|
|
573
731
|
run: definition.run
|
|
574
732
|
});
|
|
@@ -607,6 +765,7 @@ function createComposition(config) {
|
|
|
607
765
|
assertLimit(rawLimits?.maxToolCalls, "maxToolCalls", 0, name, false, "Team", "INVALID_TEAM");
|
|
608
766
|
assertLimit(rawLimits?.maxInputTokens, "maxInputTokens", 1, name, true, "Team", "INVALID_TEAM");
|
|
609
767
|
assertLimit(rawLimits?.maxOutputTokens, "maxOutputTokens", 1, name, true, "Team", "INVALID_TEAM");
|
|
768
|
+
assertLimit(rawLimits?.maxToolResultBytes, "maxToolResultBytes", 1, name, false, "Team", "INVALID_TEAM");
|
|
610
769
|
assertConfiguration(!teams.has(name), "DUPLICATE_TEAM", `Team "${name}" is duplicated`);
|
|
611
770
|
assertConfiguration(!workflows.has(name), "INVALID_TEAM", `Team "${name}" conflicts with a workflow of the same name`);
|
|
612
771
|
const team = {
|
|
@@ -622,7 +781,8 @@ function createComposition(config) {
|
|
|
622
781
|
...rawLimits.maxSteps === void 0 ? {} : { maxSteps: rawLimits.maxSteps },
|
|
623
782
|
...rawLimits.maxToolCalls === void 0 ? {} : { maxToolCalls: rawLimits.maxToolCalls },
|
|
624
783
|
...rawLimits.maxInputTokens === void 0 ? {} : { maxInputTokens: rawLimits.maxInputTokens },
|
|
625
|
-
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens }
|
|
784
|
+
...rawLimits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: rawLimits.maxOutputTokens },
|
|
785
|
+
...rawLimits.maxToolResultBytes === void 0 ? {} : { maxToolResultBytes: rawLimits.maxToolResultBytes }
|
|
626
786
|
} },
|
|
627
787
|
run: definition.run
|
|
628
788
|
};
|
|
@@ -638,9 +798,15 @@ function createComposition(config) {
|
|
|
638
798
|
tools,
|
|
639
799
|
contextProviders,
|
|
640
800
|
contextBudget: config.contextBudget === void 0 ? void 0 : { ...config.contextBudget },
|
|
801
|
+
toolSearch: config.toolSearch === void 0 ? void 0 : {
|
|
802
|
+
...config.toolSearch,
|
|
803
|
+
...config.toolSearch.pinned === void 0 ? {} : { pinned: [...config.toolSearch.pinned] }
|
|
804
|
+
},
|
|
805
|
+
toolSearchCache: defaultToolSearchCache,
|
|
641
806
|
compaction: {
|
|
642
807
|
compactor: config.compaction?.compactor ?? createDigestContextCompactor(),
|
|
643
|
-
estimateTokens: config.compaction?.estimateTokens ?? estimateContextTokens
|
|
808
|
+
estimateTokens: config.compaction?.estimateTokens ?? estimateContextTokens,
|
|
809
|
+
...config.compaction?.redactSummary === void 0 ? {} : { redactSummary: config.compaction.redactSummary }
|
|
644
810
|
},
|
|
645
811
|
memoryStore: config.memoryStore ?? (usesMemory ? new InMemoryMemoryStore() : void 0),
|
|
646
812
|
runStore: config.runStore ?? new InMemoryRunStore(),
|
|
@@ -672,6 +838,10 @@ const LEASE_RENEW_MS = 1e4;
|
|
|
672
838
|
const ELICIT_TOOL_NAME = "fevex__elicit";
|
|
673
839
|
/** Reserved name of the internal progressive skill loader exposed to the model. */
|
|
674
840
|
const LOAD_SKILL_TOOL_NAME = "fevex__load_skill";
|
|
841
|
+
/** Reserved name of the internal on-demand tool search exposed to the model. */
|
|
842
|
+
const SEARCH_TOOLS_TOOL_NAME = "fevex__search_tools";
|
|
843
|
+
/** Default safety cap for one serialized tool result. */
|
|
844
|
+
const DEFAULT_MAX_TOOL_RESULT_BYTES = 1048576;
|
|
675
845
|
//#endregion
|
|
676
846
|
//#region src/internal/run-helpers.ts
|
|
677
847
|
function redact(message, secrets) {
|
|
@@ -799,9 +969,114 @@ const runErrorPayload = (error) => {
|
|
|
799
969
|
};
|
|
800
970
|
};
|
|
801
971
|
//#endregion
|
|
972
|
+
//#region src/internal/agent-internal-tools.ts
|
|
973
|
+
async function executeInternalTool(input) {
|
|
974
|
+
if (input.call.name === "fevex__search_tools") {
|
|
975
|
+
if (!input.searchEnabled) return void 0;
|
|
976
|
+
const search = readToolSearchInput(input.input);
|
|
977
|
+
const limit = Math.min(search.limit ?? input.toolSearch.limit, input.toolSearch.limit);
|
|
978
|
+
const semantic = input.toolSearch.semantic;
|
|
979
|
+
const candidateLimit = Math.max(limit, semantic?.topK ?? limit);
|
|
980
|
+
const lexical = searchToolSpecs(input.tools, search.query, candidateLimit);
|
|
981
|
+
let matches = lexical;
|
|
982
|
+
if (semantic !== void 0) try {
|
|
983
|
+
if (input.semanticState.index === void 0 && !input.semanticState.attempted) {
|
|
984
|
+
input.semanticState.attempted = true;
|
|
985
|
+
input.semanticState.index = await buildToolEmbeddingIndex({
|
|
986
|
+
tools: input.tools,
|
|
987
|
+
embeddings: semantic.embeddings,
|
|
988
|
+
cache: semantic.cache,
|
|
989
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
if (input.semanticState.index !== void 0) {
|
|
993
|
+
const queryVector = (await semantic.embeddings.embed({
|
|
994
|
+
texts: [search.query],
|
|
995
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
996
|
+
}))[0];
|
|
997
|
+
if (!queryVector) throw new Error("Embedding model returned no query vector");
|
|
998
|
+
const semanticMatches = searchToolEmbeddingIndex(input.semanticState.index, queryVector, semantic.topK, semantic.minScore);
|
|
999
|
+
if (semanticMatches.length > 0) {
|
|
1000
|
+
const fusionLimit = semantic.reranker === void 0 ? limit : Math.max(limit, semantic.topK);
|
|
1001
|
+
const fused = reciprocalRankFusionCandidates(lexical, semanticMatches.map((match) => match.tool), fusionLimit);
|
|
1002
|
+
if (semantic.reranker !== void 0 && fused.length > 1) matches = (await rerankToolCandidates(semantic.reranker, search.query, fused, limit, input.signal) ?? fused).map((candidate) => candidate.tool);
|
|
1003
|
+
else matches = fused.map((candidate) => candidate.tool);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
if (input.signal?.aborted) throw error;
|
|
1008
|
+
matches = lexical;
|
|
1009
|
+
}
|
|
1010
|
+
const selected = matches.slice(0, limit);
|
|
1011
|
+
for (const match of selected) input.loadedTools.add(match.name);
|
|
1012
|
+
return { content: serializeValue({
|
|
1013
|
+
tools: selected.map((tool) => ({
|
|
1014
|
+
name: tool.name,
|
|
1015
|
+
...tool.description === void 0 ? {} : { description: tool.description }
|
|
1016
|
+
})),
|
|
1017
|
+
...selected.length === 0 ? { message: "No tools matched; try a different query." } : {}
|
|
1018
|
+
}, "Tool search result must be serializable") };
|
|
1019
|
+
}
|
|
1020
|
+
if (input.call.name === "fevex__load_skill") {
|
|
1021
|
+
if (input.progressiveSkills.length === 0) return void 0;
|
|
1022
|
+
const skillInput = readSkillInput(input.input);
|
|
1023
|
+
const skill = input.progressiveSkills.find((item) => item.name === skillInput.name);
|
|
1024
|
+
if (!skill) throw new Error(`Skill "${skillInput.name}" is not available`);
|
|
1025
|
+
try {
|
|
1026
|
+
return { content: (await abortable(() => skill.load(input.knowledgeContext, skillInput.resource), input.signal)).filter((block) => block.content.trim()).map((block) => `[Skill: ${skill.name}/${block.id}]\n${block.content}`).join("\n\n") };
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
throw new Error(`Skill provider "${skill.name}" failed: ${toErrorMessage(error)}`, { cause: error });
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
async function rerankToolCandidates(reranker, query, candidates, limit, signal) {
|
|
1033
|
+
try {
|
|
1034
|
+
const result = await reranker.rerank({
|
|
1035
|
+
query,
|
|
1036
|
+
tools: candidates,
|
|
1037
|
+
limit,
|
|
1038
|
+
...signal === void 0 ? {} : { signal }
|
|
1039
|
+
});
|
|
1040
|
+
if (!Array.isArray(result)) return void 0;
|
|
1041
|
+
const byName = new Map(candidates.map((candidate) => [candidate.tool.name, candidate]));
|
|
1042
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1043
|
+
const ordered = [];
|
|
1044
|
+
for (const candidate of result) {
|
|
1045
|
+
const name = candidate?.tool?.name;
|
|
1046
|
+
const original = typeof name === "string" ? byName.get(name) : void 0;
|
|
1047
|
+
if (!original || seen.has(name)) return void 0;
|
|
1048
|
+
seen.add(name);
|
|
1049
|
+
ordered.push(original);
|
|
1050
|
+
}
|
|
1051
|
+
return ordered.slice(0, limit);
|
|
1052
|
+
} catch (error) {
|
|
1053
|
+
if (signal?.aborted) throw error;
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function readSkillInput(input) {
|
|
1058
|
+
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} input must be an object`);
|
|
1059
|
+
const record = input;
|
|
1060
|
+
const name = record.name;
|
|
1061
|
+
const resource = record.resource;
|
|
1062
|
+
if (typeof name !== "string" || !name.trim()) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} name must be a non-empty string`);
|
|
1063
|
+
if (resource !== void 0 && (typeof resource !== "string" || !resource.trim())) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} resource must be a non-empty string`);
|
|
1064
|
+
return {
|
|
1065
|
+
name: name.trim(),
|
|
1066
|
+
...resource === void 0 ? {} : { resource: resource.trim() }
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
//#endregion
|
|
802
1070
|
//#region src/internal/context-compaction.ts
|
|
803
1071
|
/** Maximum summary characters copied into the context.compacted event. */
|
|
804
1072
|
const MAX_COMPACTION_EVENT_SUMMARY_CHARS = 4e3;
|
|
1073
|
+
/** Keeps the newest summary segments instead of cutting mid-sentence. */
|
|
1074
|
+
function capSummary(summary, maxChars) {
|
|
1075
|
+
if (summary.length <= maxChars) return summary;
|
|
1076
|
+
const tail = summary.slice(summary.length - maxChars + 1);
|
|
1077
|
+
const boundary = tail.indexOf("\n\n");
|
|
1078
|
+
return `…${boundary === -1 ? tail : tail.slice(boundary + 2)}`;
|
|
1079
|
+
}
|
|
805
1080
|
async function compactContext(input) {
|
|
806
1081
|
const estimateWith = (messages, includeTools) => {
|
|
807
1082
|
const value = input.estimateTokens({
|
|
@@ -914,6 +1189,7 @@ async function transportableTool(tool) {
|
|
|
914
1189
|
retry: tool.retry,
|
|
915
1190
|
credentials: tool.credentials ?? [],
|
|
916
1191
|
sandbox: tool.sandbox,
|
|
1192
|
+
maxResultBytes: tool.maxResultBytes,
|
|
917
1193
|
source: tool.source
|
|
918
1194
|
};
|
|
919
1195
|
}
|
|
@@ -983,7 +1259,8 @@ function combineLimits(first, second) {
|
|
|
983
1259
|
...minLimit(first.maxSteps, second.maxSteps) === void 0 ? {} : { maxSteps: minLimit(first.maxSteps, second.maxSteps) },
|
|
984
1260
|
...minLimit(first.maxToolCalls, second.maxToolCalls) === void 0 ? {} : { maxToolCalls: minLimit(first.maxToolCalls, second.maxToolCalls) },
|
|
985
1261
|
...minLimit(first.maxInputTokens, second.maxInputTokens) === void 0 ? {} : { maxInputTokens: minLimit(first.maxInputTokens, second.maxInputTokens) },
|
|
986
|
-
...minLimit(first.maxOutputTokens, second.maxOutputTokens) === void 0 ? {} : { maxOutputTokens: minLimit(first.maxOutputTokens, second.maxOutputTokens) }
|
|
1262
|
+
...minLimit(first.maxOutputTokens, second.maxOutputTokens) === void 0 ? {} : { maxOutputTokens: minLimit(first.maxOutputTokens, second.maxOutputTokens) },
|
|
1263
|
+
...minLimit(first.maxToolResultBytes, second.maxToolResultBytes) === void 0 ? {} : { maxToolResultBytes: minLimit(first.maxToolResultBytes, second.maxToolResultBytes) }
|
|
987
1264
|
};
|
|
988
1265
|
}
|
|
989
1266
|
function subtractLimit(limit, used) {
|
|
@@ -996,7 +1273,8 @@ function remainingWorkflowLimits(limits, budget) {
|
|
|
996
1273
|
...limits.maxSteps === void 0 ? {} : { maxSteps: subtractLimit(limits.maxSteps, budget?.steps) },
|
|
997
1274
|
...limits.maxToolCalls === void 0 ? {} : { maxToolCalls: subtractLimit(limits.maxToolCalls, budget?.toolCalls) },
|
|
998
1275
|
...limits.maxInputTokens === void 0 ? {} : { maxInputTokens: subtractLimit(limits.maxInputTokens, budget?.usage?.inputTokens) },
|
|
999
|
-
...limits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: subtractLimit(limits.maxOutputTokens, budget?.usage?.outputTokens) }
|
|
1276
|
+
...limits.maxOutputTokens === void 0 ? {} : { maxOutputTokens: subtractLimit(limits.maxOutputTokens, budget?.usage?.outputTokens) },
|
|
1277
|
+
...limits.maxToolResultBytes === void 0 ? {} : { maxToolResultBytes: limits.maxToolResultBytes }
|
|
1000
1278
|
};
|
|
1001
1279
|
}
|
|
1002
1280
|
function assertWorkflowBudget(workflowName, limits, budget) {
|
|
@@ -1023,13 +1301,24 @@ function addWorkflowBudget(first, second) {
|
|
|
1023
1301
|
* engine — that direction is what keeps the two separable.
|
|
1024
1302
|
*/
|
|
1025
1303
|
function createAgentEngine(composition, core) {
|
|
1026
|
-
const { models, agents, tools, contextProviders, contextBudget: defaultContextBudget, compaction, memoryStore, runStore, credentialStore, sandbox, artifacts, policies } = composition;
|
|
1304
|
+
const { models, agents, tools, contextProviders, contextBudget: defaultContextBudget, compaction, toolSearch: defaultToolSearch, toolSearchCache: defaultToolSearchCache, memoryStore, runStore, credentialStore, sandbox, artifacts, policies } = composition;
|
|
1305
|
+
const compactionStats = {
|
|
1306
|
+
compactions: 0,
|
|
1307
|
+
removedMessages: 0,
|
|
1308
|
+
estimatedTokens: 0,
|
|
1309
|
+
compactedTokens: 0,
|
|
1310
|
+
savedTokens: 0
|
|
1311
|
+
};
|
|
1027
1312
|
const { activeRuns, activeSessions, runtimeOwner, isClosed, admitStart, markInternalRun, resolveModel, resolveCheckpointModel, notifyObserver, createEvent, emitEvent, releaseExecution, commit, startLease, cancelExecution, authorize } = core;
|
|
1028
1313
|
const prepareExecutionBody = async (name, request, internal = false, correlation = {}) => {
|
|
1029
1314
|
if (!internal && isClosed()) throw new FevexRunError("RUNTIME_CLOSED", "Runtime is not accepting new runs");
|
|
1030
1315
|
const agent = agents.get(name);
|
|
1031
1316
|
if (!agent) throw new FevexRunError("AGENT_NOT_FOUND", `Agent "${name}" is not registered`);
|
|
1032
1317
|
const contextBudget = resolveContextBudget(request.contextBudget ?? agent.contextBudget ?? defaultContextBudget, `Agent "${name}" contextBudget`);
|
|
1318
|
+
const toolSearch = resolveToolSearchOptions(request.toolSearch ?? agent.toolSearch ?? defaultToolSearch, `Agent "${name}" toolSearch`, defaultToolSearchCache);
|
|
1319
|
+
const toolChoice = effectiveToolChoice(agent, request);
|
|
1320
|
+
const initialLoadedTools = new Set(toolSearch.pinned.filter((toolName) => agent.tools?.includes(toolName)));
|
|
1321
|
+
if (typeof toolChoice === "object" && agent.tools?.includes(toolChoice.name)) initialLoadedTools.add(toolChoice.name);
|
|
1033
1322
|
const { modelName, model } = resolveModel(agent, request.model);
|
|
1034
1323
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1035
1324
|
let session;
|
|
@@ -1103,6 +1392,8 @@ function createAgentEngine(composition, core) {
|
|
|
1103
1392
|
definitionHash: await definitionHash(name, modelName, agent, tools, contextBudget),
|
|
1104
1393
|
limits: combineLimits(agent.limits, request.limits),
|
|
1105
1394
|
...contextBudget === void 0 ? {} : { contextBudget },
|
|
1395
|
+
toolSearch: serializeToolSearchOptions(toolSearch),
|
|
1396
|
+
loadedTools: [...initialLoadedTools],
|
|
1106
1397
|
messages,
|
|
1107
1398
|
inputContent,
|
|
1108
1399
|
context: request.context,
|
|
@@ -1113,7 +1404,7 @@ function createAgentEngine(composition, core) {
|
|
|
1113
1404
|
pendingIndex: 0,
|
|
1114
1405
|
effectiveElicitationMode: effectiveElicitationMode(agent, request),
|
|
1115
1406
|
effectiveApprovalMode: effectiveApprovalMode(agent, request),
|
|
1116
|
-
effectiveToolChoice:
|
|
1407
|
+
effectiveToolChoice: toolChoice
|
|
1117
1408
|
};
|
|
1118
1409
|
const ownerId = `${runtimeOwner}:${crypto.randomUUID()}`;
|
|
1119
1410
|
const lease = {
|
|
@@ -1161,6 +1452,7 @@ function createAgentEngine(composition, core) {
|
|
|
1161
1452
|
const agent = agents.get(state.run.agentName);
|
|
1162
1453
|
if (agent.model !== void 0 && typeof agent.model !== "string") throw new FevexRunError("RUN_NOT_RESUMABLE", "Durable continuation requires a named model", state.run.id);
|
|
1163
1454
|
const contextBudget = resolveContextBudget(state.checkpoint?.contextBudget ?? state.request.contextBudget ?? agent.contextBudget ?? defaultContextBudget, `Agent "${state.run.agentName}" contextBudget`);
|
|
1455
|
+
const toolSearch = state.toolSearch ?? resolveToolSearchOptions(state.checkpoint?.toolSearch ?? state.request.toolSearch ?? agent.toolSearch ?? defaultToolSearch, `Agent "${state.run.agentName}" toolSearch`, defaultToolSearchCache);
|
|
1164
1456
|
let serializedState;
|
|
1165
1457
|
if (providerState !== void 0) {
|
|
1166
1458
|
if (!model.stateCodec) throw new FevexRunError("RUN_NOT_RESUMABLE", "ModelGateway must provide stateCodec for durable continuation", state.run.id);
|
|
@@ -1174,6 +1466,8 @@ function createAgentEngine(composition, core) {
|
|
|
1174
1466
|
definitionHash: await definitionHash(state.run.agentName, modelName, agent, tools, contextBudget),
|
|
1175
1467
|
limits: state.checkpoint?.limits ?? combineLimits(agent.limits, state.request.limits),
|
|
1176
1468
|
...contextBudget === void 0 ? {} : { contextBudget },
|
|
1469
|
+
toolSearch: serializeToolSearchOptions(toolSearch),
|
|
1470
|
+
loadedTools: [...state.loadedTools ?? []],
|
|
1177
1471
|
messages: structuredClone(messages),
|
|
1178
1472
|
inputContent,
|
|
1179
1473
|
context: state.request.context,
|
|
@@ -1233,6 +1527,14 @@ function createAgentEngine(composition, core) {
|
|
|
1233
1527
|
const agent = agents.get(name);
|
|
1234
1528
|
const { modelName, model } = resolveModel(agent, state.checkpoint?.modelName ?? request.model);
|
|
1235
1529
|
const contextBudget = resolveContextBudget(state.checkpoint?.contextBudget ?? request.contextBudget ?? agent.contextBudget ?? defaultContextBudget, `Agent "${name}" contextBudget`);
|
|
1530
|
+
const semantic = request.toolSearch?.semantic ?? agent.toolSearch?.semantic ?? defaultToolSearch?.semantic;
|
|
1531
|
+
const toolSearch = resolveToolSearchOptions(state.checkpoint === void 0 ? request.toolSearch ?? agent.toolSearch ?? defaultToolSearch : state.checkpoint.toolSearch === void 0 ? {
|
|
1532
|
+
mode: "off",
|
|
1533
|
+
...semantic === void 0 ? {} : { semantic }
|
|
1534
|
+
} : {
|
|
1535
|
+
...state.checkpoint.toolSearch,
|
|
1536
|
+
...semantic === void 0 ? {} : { semantic }
|
|
1537
|
+
}, `Agent "${name}" toolSearch`, defaultToolSearchCache);
|
|
1236
1538
|
const events = [...state.initialEvents ?? []];
|
|
1237
1539
|
const firstEvents = state.initialEvents ?? [];
|
|
1238
1540
|
state.initialEvents = void 0;
|
|
@@ -1251,6 +1553,7 @@ function createAgentEngine(composition, core) {
|
|
|
1251
1553
|
let pendingTools;
|
|
1252
1554
|
let pendingIndex;
|
|
1253
1555
|
let compactionApplied = false;
|
|
1556
|
+
const semanticState = { attempted: false };
|
|
1254
1557
|
try {
|
|
1255
1558
|
for (const event of firstEvents) yield event;
|
|
1256
1559
|
if (state.checkpoint) {
|
|
@@ -1326,30 +1629,86 @@ function createAgentEngine(composition, core) {
|
|
|
1326
1629
|
additionalProperties: false
|
|
1327
1630
|
}
|
|
1328
1631
|
};
|
|
1632
|
+
const searchEnabled = shouldUseToolSearch(toolSearch, agentTools);
|
|
1633
|
+
const searchTool = searchEnabled ? {
|
|
1634
|
+
name: SEARCH_TOOLS_TOOL_NAME,
|
|
1635
|
+
description: `Search ${agentTools.length} tools available to this agent by capability. Use it when you need a tool that is not currently exposed. Returns matching tools and makes their schemas available on the next turn.`,
|
|
1636
|
+
inputSchema: {
|
|
1637
|
+
type: "object",
|
|
1638
|
+
properties: {
|
|
1639
|
+
query: {
|
|
1640
|
+
type: "string",
|
|
1641
|
+
description: "Capability to search for, such as \"send email\" or \"query database\"."
|
|
1642
|
+
},
|
|
1643
|
+
limit: {
|
|
1644
|
+
type: "integer",
|
|
1645
|
+
minimum: 1,
|
|
1646
|
+
maximum: toolSearch.limit
|
|
1647
|
+
}
|
|
1648
|
+
},
|
|
1649
|
+
required: ["query"],
|
|
1650
|
+
additionalProperties: false
|
|
1651
|
+
}
|
|
1652
|
+
} : void 0;
|
|
1653
|
+
const elicitationTool = currentElicitationMode === "pause" ? {
|
|
1654
|
+
name: ELICIT_TOOL_NAME,
|
|
1655
|
+
description: "Request external information required to continue this run. Use prompt for explanatory text shown outside the form. Put short field labels in responseSchema property titles and optional field help in property descriptions.",
|
|
1656
|
+
inputSchema: {
|
|
1657
|
+
type: "object",
|
|
1658
|
+
properties: {
|
|
1659
|
+
prompt: {
|
|
1660
|
+
type: "string",
|
|
1661
|
+
description: "Explanatory text for the user; do not duplicate field labels here."
|
|
1662
|
+
},
|
|
1663
|
+
responseSchema: {
|
|
1664
|
+
type: "object",
|
|
1665
|
+
description: "JSON Schema for the expected response. Each property should include a short title for the form label and may include a description for field help."
|
|
1666
|
+
},
|
|
1667
|
+
expiresAt: { type: "string" }
|
|
1668
|
+
},
|
|
1669
|
+
required: ["prompt", "responseSchema"],
|
|
1670
|
+
additionalProperties: false
|
|
1671
|
+
}
|
|
1672
|
+
} : void 0;
|
|
1329
1673
|
const allTools = [
|
|
1330
1674
|
...agentTools,
|
|
1331
1675
|
...skillTool === void 0 ? [] : [skillTool],
|
|
1332
|
-
...
|
|
1333
|
-
|
|
1334
|
-
description: "Request external information required to continue this run. Use prompt for explanatory text shown outside the form. Put short field labels in responseSchema property titles and optional field help in property descriptions.",
|
|
1335
|
-
inputSchema: {
|
|
1336
|
-
type: "object",
|
|
1337
|
-
properties: {
|
|
1338
|
-
prompt: {
|
|
1339
|
-
type: "string",
|
|
1340
|
-
description: "Explanatory text for the user; do not duplicate field labels here."
|
|
1341
|
-
},
|
|
1342
|
-
responseSchema: {
|
|
1343
|
-
type: "object",
|
|
1344
|
-
description: "JSON Schema for the expected response. Each property should include a short title for the form label and may include a description for field help."
|
|
1345
|
-
},
|
|
1346
|
-
expiresAt: { type: "string" }
|
|
1347
|
-
},
|
|
1348
|
-
required: ["prompt", "responseSchema"],
|
|
1349
|
-
additionalProperties: false
|
|
1350
|
-
}
|
|
1351
|
-
}] : []
|
|
1676
|
+
...searchTool === void 0 ? [] : [searchTool],
|
|
1677
|
+
...elicitationTool === void 0 ? [] : [elicitationTool]
|
|
1352
1678
|
];
|
|
1679
|
+
const loadedTools = new Set(state.loadedTools ?? state.checkpoint?.loadedTools ?? []);
|
|
1680
|
+
for (const toolName of toolSearch.pinned) if (agent.tools?.includes(toolName)) loadedTools.add(toolName);
|
|
1681
|
+
if (typeof currentToolChoice === "object" && agent.tools?.includes(currentToolChoice.name)) loadedTools.add(currentToolChoice.name);
|
|
1682
|
+
state.loadedTools = loadedTools;
|
|
1683
|
+
state.toolSearch = toolSearch;
|
|
1684
|
+
let loadedToolsVersion = 0;
|
|
1685
|
+
let cachedModelTools;
|
|
1686
|
+
let cachedModelToolsVersion = -1;
|
|
1687
|
+
const modelTools = () => {
|
|
1688
|
+
if (!searchEnabled) return allTools;
|
|
1689
|
+
if (cachedModelTools !== void 0 && cachedModelToolsVersion === loadedToolsVersion) return cachedModelTools;
|
|
1690
|
+
cachedModelTools = [
|
|
1691
|
+
...agentTools.filter((tool) => loadedTools.has(tool.name)),
|
|
1692
|
+
...skillTool === void 0 ? [] : [skillTool],
|
|
1693
|
+
...searchTool === void 0 ? [] : [searchTool],
|
|
1694
|
+
...elicitationTool === void 0 ? [] : [elicitationTool]
|
|
1695
|
+
];
|
|
1696
|
+
cachedModelToolsVersion = loadedToolsVersion;
|
|
1697
|
+
return cachedModelTools;
|
|
1698
|
+
};
|
|
1699
|
+
const toolsTokenCache = /* @__PURE__ */ new WeakMap();
|
|
1700
|
+
const estimateContext = (input) => {
|
|
1701
|
+
if (!input.tools?.length) return compaction.estimateTokens(input);
|
|
1702
|
+
let toolTokens = toolsTokenCache.get(input.tools);
|
|
1703
|
+
if (toolTokens === void 0) {
|
|
1704
|
+
toolTokens = compaction.estimateTokens({
|
|
1705
|
+
messages: [],
|
|
1706
|
+
tools: input.tools
|
|
1707
|
+
});
|
|
1708
|
+
toolsTokenCache.set(input.tools, toolTokens);
|
|
1709
|
+
}
|
|
1710
|
+
return compaction.estimateTokens({ messages: input.messages }) + toolTokens;
|
|
1711
|
+
};
|
|
1353
1712
|
const effectiveLimits = state.checkpoint?.limits ?? combineLimits(agent.limits, request.limits);
|
|
1354
1713
|
const maxSteps = effectiveLimits?.maxSteps ?? 8;
|
|
1355
1714
|
const maxToolCalls = effectiveLimits?.maxToolCalls ?? 16;
|
|
@@ -1357,16 +1716,17 @@ function createAgentEngine(composition, core) {
|
|
|
1357
1716
|
while (step <= maxSteps) {
|
|
1358
1717
|
request.signal.throwIfAborted();
|
|
1359
1718
|
if (pendingTools.length === 0) {
|
|
1719
|
+
const currentTools = modelTools();
|
|
1360
1720
|
if (contextBudget !== void 0) {
|
|
1361
1721
|
const compacted = await compactContext({
|
|
1362
1722
|
runId: state.run.id,
|
|
1363
1723
|
agentName: name,
|
|
1364
1724
|
sessionId: state.session.id,
|
|
1365
1725
|
messages,
|
|
1366
|
-
tools:
|
|
1726
|
+
tools: currentTools,
|
|
1367
1727
|
contextBudget,
|
|
1368
1728
|
compactor: compaction.compactor,
|
|
1369
|
-
estimateTokens:
|
|
1729
|
+
estimateTokens: estimateContext,
|
|
1370
1730
|
step,
|
|
1371
1731
|
...request.context === void 0 ? {} : { context: request.context },
|
|
1372
1732
|
signal: request.signal,
|
|
@@ -1375,15 +1735,22 @@ function createAgentEngine(composition, core) {
|
|
|
1375
1735
|
if (compacted !== void 0) {
|
|
1376
1736
|
messages = compacted.messages;
|
|
1377
1737
|
compactionApplied = true;
|
|
1738
|
+
compactionStats.compactions += 1;
|
|
1739
|
+
compactionStats.removedMessages += compacted.removedMessages;
|
|
1740
|
+
compactionStats.estimatedTokens += compacted.estimatedTokens;
|
|
1741
|
+
compactionStats.compactedTokens += compacted.compactedTokens;
|
|
1742
|
+
compactionStats.savedTokens += Math.max(0, compacted.estimatedTokens - compacted.compactedTokens);
|
|
1378
1743
|
const previous = state.session.compaction;
|
|
1379
1744
|
const combined = previous === void 0 ? compacted.summary : `${previous.summary}\n\n${compacted.summary}`;
|
|
1380
1745
|
const maxSummaryChars = Math.max(200, contextBudget.targetTokens * 4);
|
|
1381
1746
|
state.session.compaction = {
|
|
1382
|
-
summary:
|
|
1747
|
+
summary: capSummary(combined, maxSummaryChars),
|
|
1383
1748
|
coveredMessages: state.session.history.length,
|
|
1384
1749
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1385
1750
|
};
|
|
1386
|
-
const
|
|
1751
|
+
const redactedSummary = compaction.redactSummary?.(compacted.summary) ?? compacted.summary;
|
|
1752
|
+
if (typeof redactedSummary !== "string") throw new TypeError("compaction.redactSummary must return a string");
|
|
1753
|
+
const summaryTruncated = redactedSummary.length > MAX_COMPACTION_EVENT_SUMMARY_CHARS;
|
|
1387
1754
|
const event = createEvent(state, "context.compacted", {
|
|
1388
1755
|
step,
|
|
1389
1756
|
removedMessages: compacted.removedMessages,
|
|
@@ -1391,7 +1758,7 @@ function createAgentEngine(composition, core) {
|
|
|
1391
1758
|
compactedTokens: compacted.compactedTokens,
|
|
1392
1759
|
targetTokens: contextBudget.targetTokens,
|
|
1393
1760
|
contextWindow: contextBudget.contextWindow,
|
|
1394
|
-
summary: summaryTruncated ?
|
|
1761
|
+
summary: summaryTruncated ? capSummary(redactedSummary, MAX_COMPACTION_EVENT_SUMMARY_CHARS) : redactedSummary,
|
|
1395
1762
|
...summaryTruncated ? { summaryTruncated: true } : {}
|
|
1396
1763
|
});
|
|
1397
1764
|
if (isDurableRunStore(runStore)) {
|
|
@@ -1411,11 +1778,11 @@ function createAgentEngine(composition, core) {
|
|
|
1411
1778
|
}
|
|
1412
1779
|
}
|
|
1413
1780
|
const hasToolBudget = step < maxSteps && toolCallCount < maxToolCalls;
|
|
1414
|
-
const modelToolChoice = hasToolBudget &&
|
|
1781
|
+
const modelToolChoice = hasToolBudget && currentTools.length ? currentToolChoice === "auto" ? void 0 : currentToolChoice : void 0;
|
|
1415
1782
|
yield await emit("model.started", { step });
|
|
1416
1783
|
const modelStream = readModelStream(model, {
|
|
1417
1784
|
messages: [...messages],
|
|
1418
|
-
tools: hasToolBudget &&
|
|
1785
|
+
tools: hasToolBudget && currentTools.length ? currentTools : void 0,
|
|
1419
1786
|
...modelToolChoice === void 0 ? {} : { toolChoice: modelToolChoice },
|
|
1420
1787
|
reasoning: state.request.reasoning ?? agent.reasoning,
|
|
1421
1788
|
modelOptions: agent.modelOptions,
|
|
@@ -1491,52 +1858,63 @@ function createAgentEngine(composition, core) {
|
|
|
1491
1858
|
assertContinuationBudget(name, "maxInputTokens", "inputTokens", effectiveLimits?.maxInputTokens, usage);
|
|
1492
1859
|
assertContinuationBudget(name, "maxOutputTokens", "outputTokens", effectiveLimits?.maxOutputTokens, usage);
|
|
1493
1860
|
if (result.toolCalls.length > maxToolCalls - toolCallCount) throw new Error(`Agent "${name}" exceeded maxToolCalls limit of ${maxToolCalls}`);
|
|
1494
|
-
const
|
|
1495
|
-
if (
|
|
1496
|
-
if (result.toolCalls.length !== 1) throw new Error(`${
|
|
1497
|
-
if (!
|
|
1498
|
-
if (seenToolCallIds.has(
|
|
1861
|
+
const internalCall = result.toolCalls.find((call) => searchEnabled && call.name === "fevex__search_tools" || progressiveSkills.length > 0 && call.name === "fevex__load_skill");
|
|
1862
|
+
if (internalCall) {
|
|
1863
|
+
if (result.toolCalls.length !== 1) throw new Error(`${internalCall.name} must be the only tool call in a model turn`);
|
|
1864
|
+
if (!internalCall.id?.trim()) throw new Error("Tool call id cannot be empty");
|
|
1865
|
+
if (seenToolCallIds.has(internalCall.id)) throw new Error(`Tool call id "${internalCall.id}" is duplicated in run "${state.run.id}"`);
|
|
1499
1866
|
if (toolCallCount + 1 > maxToolCalls) throw new Error(`Agent "${name}" exceeded maxToolCalls limit of ${maxToolCalls}`);
|
|
1500
|
-
const rawInput = toJsonValue(
|
|
1501
|
-
const
|
|
1502
|
-
|
|
1503
|
-
if (!skill) throw new Error(`Skill "${skillInput.name}" is not available to agent "${name}"`);
|
|
1504
|
-
seenToolCallIds.add(loadSkillCall.id);
|
|
1867
|
+
const rawInput = toJsonValue(internalCall.input, `Input for tool "${internalCall.name}" must be JSON-serializable`);
|
|
1868
|
+
const loadedBefore = loadedTools.size;
|
|
1869
|
+
seenToolCallIds.add(internalCall.id);
|
|
1505
1870
|
messages.push({
|
|
1506
1871
|
role: "assistant",
|
|
1507
1872
|
content: result.output === void 0 ? "" : serializeValue(result.output, `Model output for agent "${name}" must be serializable`),
|
|
1508
1873
|
toolCalls: [{
|
|
1509
|
-
...
|
|
1874
|
+
...internalCall,
|
|
1510
1875
|
input: rawInput
|
|
1511
1876
|
}]
|
|
1512
1877
|
});
|
|
1513
1878
|
yield await emit("tool.started", {
|
|
1514
1879
|
step,
|
|
1515
|
-
toolCallId:
|
|
1516
|
-
toolName:
|
|
1880
|
+
toolCallId: internalCall.id,
|
|
1881
|
+
toolName: internalCall.name
|
|
1517
1882
|
});
|
|
1518
|
-
let
|
|
1883
|
+
let execution;
|
|
1519
1884
|
try {
|
|
1520
|
-
|
|
1885
|
+
execution = await executeInternalTool({
|
|
1886
|
+
call: internalCall,
|
|
1887
|
+
input: rawInput,
|
|
1888
|
+
tools: agentTools,
|
|
1889
|
+
searchEnabled,
|
|
1890
|
+
toolSearch,
|
|
1891
|
+
loadedTools,
|
|
1892
|
+
progressiveSkills,
|
|
1893
|
+
knowledgeContext: knowledgeContext(state, inputContent),
|
|
1894
|
+
semanticState,
|
|
1895
|
+
signal: request.signal
|
|
1896
|
+
});
|
|
1521
1897
|
} catch (error) {
|
|
1522
1898
|
yield await emit("tool.failed", {
|
|
1523
1899
|
step,
|
|
1524
|
-
toolCallId:
|
|
1525
|
-
toolName:
|
|
1900
|
+
toolCallId: internalCall.id,
|
|
1901
|
+
toolName: internalCall.name,
|
|
1526
1902
|
error: toErrorMessage(error)
|
|
1527
1903
|
});
|
|
1528
|
-
throw
|
|
1904
|
+
throw error;
|
|
1529
1905
|
}
|
|
1906
|
+
if (!execution) throw new Error(`Tool "${internalCall.name}" is not available to agent "${name}"`);
|
|
1907
|
+
if (loadedTools.size > loadedBefore) loadedToolsVersion += 1;
|
|
1530
1908
|
messages.push({
|
|
1531
1909
|
role: "tool",
|
|
1532
|
-
name:
|
|
1533
|
-
toolCallId:
|
|
1534
|
-
content:
|
|
1910
|
+
name: internalCall.name,
|
|
1911
|
+
toolCallId: internalCall.id,
|
|
1912
|
+
content: execution.content
|
|
1535
1913
|
});
|
|
1536
1914
|
yield await emit("tool.completed", {
|
|
1537
1915
|
step,
|
|
1538
|
-
toolCallId:
|
|
1539
|
-
toolName:
|
|
1916
|
+
toolCallId: internalCall.id,
|
|
1917
|
+
toolName: internalCall.name
|
|
1540
1918
|
});
|
|
1541
1919
|
toolCallCount += 1;
|
|
1542
1920
|
step += 1;
|
|
@@ -1598,6 +1976,7 @@ function createAgentEngine(composition, core) {
|
|
|
1598
1976
|
batch.add(call.id);
|
|
1599
1977
|
const tool = agent.tools?.includes(call.name) ? tools.get(call.name) : void 0;
|
|
1600
1978
|
if (!tool) throw new Error(`Tool "${call.name}" is not available to agent "${name}"`);
|
|
1979
|
+
if (searchEnabled && !loadedTools.has(call.name)) throw new Error(`Tool "${call.name}" is not loaded; use ${SEARCH_TOOLS_TOOL_NAME} first`);
|
|
1601
1980
|
const rawInput = toJsonValue(call.input, `Input for tool "${call.name}" must be JSON-serializable`);
|
|
1602
1981
|
let validated;
|
|
1603
1982
|
try {
|
|
@@ -1854,7 +2233,13 @@ function createAgentEngine(composition, core) {
|
|
|
1854
2233
|
signal: request.signal
|
|
1855
2234
|
}), request.signal);
|
|
1856
2235
|
for (const event of createdArtifacts.splice(0)) yield event;
|
|
1857
|
-
|
|
2236
|
+
const validated = tool.outputSchema === void 0 ? raw : await validateSchema(tool.outputSchema, raw, `Output from tool "${tool.name}" does not match outputSchema`);
|
|
2237
|
+
const serialized = serializeValue(validated, `Output from tool "${tool.name}" must be JSON-serializable`);
|
|
2238
|
+
const configuredMaxResultBytes = tool.maxResultBytes !== void 0 ? tool.maxResultBytes : effectiveLimits?.maxToolResultBytes;
|
|
2239
|
+
const maxResultBytes = configuredMaxResultBytes === void 0 ? DEFAULT_MAX_TOOL_RESULT_BYTES : configuredMaxResultBytes;
|
|
2240
|
+
const resultBytes = new TextEncoder().encode(serialized).byteLength;
|
|
2241
|
+
if (maxResultBytes !== false && resultBytes > maxResultBytes) throw new FevexRunError("TOOL_RESULT_TOO_LARGE", `Tool "${tool.name}" returned ${resultBytes} bytes; limit is ${maxResultBytes}. Store large outputs as artifacts and return an artifact descriptor.`, state.run.id);
|
|
2242
|
+
output = toJsonValue(validated, `Output from tool "${tool.name}" must be JSON-serializable`);
|
|
1858
2243
|
if (containsSecret(output, secrets)) throw new Error(`Output from tool "${tool.name}" contains a credential`);
|
|
1859
2244
|
record = {
|
|
1860
2245
|
...record,
|
|
@@ -1891,7 +2276,7 @@ function createAgentEngine(composition, core) {
|
|
|
1891
2276
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1892
2277
|
};
|
|
1893
2278
|
if (durable) await commit(state, { toolExecution: record });
|
|
1894
|
-
if (attempt >= maxAttempts || tool.idempotency !== "keyed") {
|
|
2279
|
+
if (attempt >= maxAttempts || tool.idempotency !== "keyed" || error instanceof FevexRunError && error.code === "TOOL_RESULT_TOO_LARGE") {
|
|
1895
2280
|
yield await emit("tool.failed", {
|
|
1896
2281
|
step,
|
|
1897
2282
|
toolCallId: pending.call.id,
|
|
@@ -2288,7 +2673,10 @@ function createAgentEngine(composition, core) {
|
|
|
2288
2673
|
nextEvent,
|
|
2289
2674
|
drainExecution,
|
|
2290
2675
|
resumeAgent,
|
|
2291
|
-
cancelStoredAgent
|
|
2676
|
+
cancelStoredAgent,
|
|
2677
|
+
getCompactionStats() {
|
|
2678
|
+
return { ...compactionStats };
|
|
2679
|
+
}
|
|
2292
2680
|
};
|
|
2293
2681
|
}
|
|
2294
2682
|
function sessionHistoryMessages(session) {
|
|
@@ -2299,18 +2687,6 @@ function sessionHistoryMessages(session) {
|
|
|
2299
2687
|
content: `[Compacted conversation]\n${compaction.summary}`
|
|
2300
2688
|
}, ...session.history.slice(compaction.coveredMessages)];
|
|
2301
2689
|
}
|
|
2302
|
-
function readSkillInput(input) {
|
|
2303
|
-
if (typeof input !== "object" || input === null || Array.isArray(input)) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} input must be an object`);
|
|
2304
|
-
const record = input;
|
|
2305
|
-
const name = record.name;
|
|
2306
|
-
const resource = record.resource;
|
|
2307
|
-
if (typeof name !== "string" || !name.trim()) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} name must be a non-empty string`);
|
|
2308
|
-
if (resource !== void 0 && (typeof resource !== "string" || !resource.trim())) throw new TypeError(`${LOAD_SKILL_TOOL_NAME} resource must be a non-empty string`);
|
|
2309
|
-
return {
|
|
2310
|
-
name: name.trim(),
|
|
2311
|
-
...resource === void 0 ? {} : { resource: resource.trim() }
|
|
2312
|
-
};
|
|
2313
|
-
}
|
|
2314
2690
|
function scopedArtifacts(store, options) {
|
|
2315
2691
|
const scopedContext = (value) => {
|
|
2316
2692
|
const contextTenant = options.request.context?.attributes?.tenantId;
|
|
@@ -4415,7 +4791,7 @@ function createRuntime(composition) {
|
|
|
4415
4791
|
const core = createRunCore(composition);
|
|
4416
4792
|
const { activeRuns, activeWorkflowRuns, activeSessions, isIdle, waitForIdle, closeAdmission, isClosed, traceExports, runtimeOwner, createEvent, createCoordinatorEvent, notifyObserver, commit, startLease, cancelExecution, releaseWorkflowExecution, commitWorkflow } = core;
|
|
4417
4793
|
const agentEngine = createAgentEngine(composition, core);
|
|
4418
|
-
const { prepareExecution, executeAgent, nextEvent, drainExecution, resumeAgent, cancelStoredAgent } = agentEngine;
|
|
4794
|
+
const { prepareExecution, executeAgent, nextEvent, drainExecution, resumeAgent, cancelStoredAgent, getCompactionStats } = agentEngine;
|
|
4419
4795
|
const { prepareWorkflowExecution, executeWorkflow, nextWorkflowEvent, drainWorkflowExecution, resumeWorkflow, cancelWorkflowExecution, cancelStoredWorkflow } = createWorkflowEngine(composition, core, agentEngine);
|
|
4420
4796
|
const resumeRun = async (runId, resolution) => {
|
|
4421
4797
|
if (isClosed()) throw new FevexRunError("RUNTIME_CLOSED", "Runtime is not accepting new runs", runId);
|
|
@@ -4616,6 +4992,9 @@ function createRuntime(composition) {
|
|
|
4616
4992
|
getObservabilityStats() {
|
|
4617
4993
|
return traceExports.stats();
|
|
4618
4994
|
},
|
|
4995
|
+
getCompactionStats() {
|
|
4996
|
+
return getCompactionStats();
|
|
4997
|
+
},
|
|
4619
4998
|
shutdown
|
|
4620
4999
|
};
|
|
4621
5000
|
}
|
|
@@ -4631,4 +5010,4 @@ function createFevex(config) {
|
|
|
4631
5010
|
return createRuntime(createComposition(config));
|
|
4632
5011
|
}
|
|
4633
5012
|
//#endregion
|
|
4634
|
-
export { ArtifactError, CatalogedArtifactStore, ChannelError, FEVEX_JSON_SCHEMA_PROFILE_VERSION, FevexConfigurationError, FevexRunError, FileSystemArtifactStore, InMemoryArtifactCatalog, InMemoryArtifactStore, InMemoryMemoryStore, InMemoryRunStore, IntegrationError, PROVIDER_REASONING_UNSUPPORTED, PROVIDER_SCHEMA_UNSUPPORTED, RunPausedError, S3ArtifactStore, SCHEMA_NOT_TRANSPORTABLE, SandboxError, artifactTenantId, assertArtifactId, compileFevexJsonSchema, createAgentsMdContextProvider, createDigestContextCompactor, createFevex, createLocalSandbox, createMemoryContextProvider, defineAgent, defineConnection, defineContextProvider, definePolicy, defineSkill, defineTeam, defineTool, defineWorkflow, deliverChannelRun, estimateContextTokens, handleChannelInput, isDurableRunStore, isProgressiveSkillProvider, isRetainableRunStore, loadSkillFile, loadSkillFiles, resolveContextBudget, sandboxResultToJson, toToolSpec, validateFevexJsonSchemaProfile, validateListEventsOptions, validatePurgeRunsOptions };
|
|
5013
|
+
export { ArtifactError, CatalogedArtifactStore, ChannelError, FEVEX_JSON_SCHEMA_PROFILE_VERSION, FevexConfigurationError, FevexRunError, FileSystemArtifactStore, InMemoryArtifactCatalog, InMemoryArtifactStore, InMemoryMemoryStore, InMemoryRunStore, InMemoryToolEmbeddingCache, IntegrationError, PROVIDER_REASONING_UNSUPPORTED, PROVIDER_SCHEMA_UNSUPPORTED, RunPausedError, S3ArtifactStore, SCHEMA_NOT_TRANSPORTABLE, SandboxError, artifactTenantId, assertArtifactId, buildToolEmbeddingIndex, compileFevexJsonSchema, cosineSimilarity, createAgentsMdContextProvider, createDigestContextCompactor, createFevex, createLocalSandbox, createMemoryContextProvider, createModelContextCompactor, defineAgent, defineConnection, defineContextProvider, definePolicy, defineSkill, defineTeam, defineTool, defineWorkflow, deliverChannelRun, estimateContextTokens, handleChannelInput, isDurableRunStore, isProgressiveSkillProvider, isRetainableRunStore, loadSkillFile, loadSkillFiles, resolveContextBudget, sandboxResultToJson, schemaKeywords, searchToolEmbeddingIndex, toToolSpec, toolEmbeddingKey, toolEmbeddingText, validateFevexJsonSchemaProfile, validateListEventsOptions, validatePurgeRunsOptions };
|