norn-cli 3.3.0 → 4.0.1
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/cli.js +1396 -276
- package/dist/knowledgeIndexWorker.js +71 -35
- package/package.json +3 -3
- package/schemas/norn.config.schema.json +13 -0
- package/CLAUDE.md +0 -69
- package/NOW.md +0 -223
- package/demos/agent-workbench/README.md +0 -156
- package/demos/agent-workbench/agents.nornagent +0 -87
- package/demos/agent-workbench/contracts/domain-answer.schema.json +0 -28
- package/demos/agent-workbench/contracts/domain-question.schema.json +0 -34
- package/demos/agent-workbench/contracts/router-verdict.schema.json +0 -43
- package/demos/agent-workbench/contracts/ticket.schema.json +0 -29
- package/demos/agent-workbench/contracts/verdict.schema.json +0 -48
- package/demos/agent-workbench/fake-openai-server.js +0 -128
- package/demos/agent-workbench/fixtures/aligned-ticket.json +0 -10
- package/demos/agent-workbench/fixtures/cross-domain-ticket.json +0 -10
- package/demos/agent-workbench/fixtures/invalid-output-ticket.json +0 -8
- package/demos/agent-workbench/norn.config.json +0 -15
- package/demos/agent-workbench/prompts/ticket-router.md +0 -11
- package/demos/agent-workbench/workbench.norn +0 -32
- package/demos/knowledge-editor/README.md +0 -74
- package/demos/knowledge-editor/agents.nornagent +0 -16
- package/demos/knowledge-editor/api.nornapi +0 -10
- package/demos/knowledge-editor/handbook/ops/flow.svg +0 -1
- package/demos/knowledge-editor/handbook/ops/retired.md +0 -9
- package/demos/knowledge-editor/handbook/ops/runbook.md +0 -14
- package/demos/knowledge-editor/handbook/payments/charges.md +0 -25
- package/demos/knowledge-editor/handbook/payments/pricing-tiers.draft.md +0 -7
- package/demos/knowledge-editor/handbook/payments/refunds/policy.md +0 -12
- package/demos/knowledge-editor/support.norn +0 -10
- package/demos/mcp-ticket-testing/README.md +0 -114
- package/demos/mcp-ticket-testing/agents.nornagent +0 -77
- package/demos/mcp-ticket-testing/contracts/test-run.schema.json +0 -31
- package/demos/mcp-ticket-testing/expectations/proj-142.md +0 -12
- package/demos/mcp-ticket-testing/fixtures/proj-142.json +0 -13
- package/demos/mcp-ticket-testing/prompts/backend-tester.md +0 -12
- package/demos/mcp-ticket-testing/prompts/frontend-tester.md +0 -14
- package/demos/mcp-ticket-testing/prompts/reporter.md +0 -10
- package/demos/mcp-ticket-testing/servers/browser-server.js +0 -133
- package/demos/mcp-ticket-testing/servers/house-server.js +0 -125
- package/demos/mcp-ticket-testing/tickets.norn +0 -32
- package/demos/nornenv-region-refactor/README.md +0 -64
- package/demos/nornenv-showcase/README.md +0 -62
- package/demos/nornenv-showcase/norn.config.json +0 -16
- package/demos/nornenv-showcase/showcase.norn +0 -70
- package/demos/nornenv-showcase/showcase.nornapi +0 -26
- package/demos/nornenv-showcase/showcase.nornsql +0 -20
- package/demos/tests-showcase/01-single-requests.norn +0 -31
- package/demos/tests-showcase/02-sequences.norn +0 -54
- package/demos/tests-showcase/03-sidecars.norn +0 -42
- package/demos/tests-showcase/04-api-plus-sql.norn +0 -27
- package/demos/tests-showcase/db/testDb.nornsql +0 -12
- package/demos/tests-showcase/demo-api.nornapi +0 -17
- package/demos/tests-showcase/norn.config.json +0 -16
- package/playground/ai.norn +0 -15
- package/playground/ai_orchastration.nornagent +0 -34
- package/playground/knowedge_base/ACDC/testing_notes_new_clients.md +0 -11
- package/playground/knowedge_base/nexus_system_prompt.md +0 -1
package/dist/cli.js
CHANGED
|
@@ -101513,10 +101513,10 @@ var init_values = __esm({
|
|
|
101513
101513
|
});
|
|
101514
101514
|
|
|
101515
101515
|
// node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs
|
|
101516
|
-
var
|
|
101516
|
+
var sleep;
|
|
101517
101517
|
var init_sleep = __esm({
|
|
101518
101518
|
"node_modules/@anthropic-ai/sdk/internal/utils/sleep.mjs"() {
|
|
101519
|
-
|
|
101519
|
+
sleep = (ms, signal) => new Promise((resolve28) => {
|
|
101520
101520
|
if (signal?.aborted)
|
|
101521
101521
|
return resolve28();
|
|
101522
101522
|
const onAbort = () => {
|
|
@@ -106070,14 +106070,14 @@ var init_poller = __esm({
|
|
|
106070
106070
|
const wait = applyJitter(backoff2(attempt));
|
|
106071
106071
|
log.warn("poll failed, backing off", { error: String(e2), backoff_ms: wait });
|
|
106072
106072
|
attempt++;
|
|
106073
|
-
await
|
|
106073
|
+
await sleep(wait, __classPrivateFieldGet2(this, _WorkPoller_controller, "f").signal);
|
|
106074
106074
|
continue;
|
|
106075
106075
|
}
|
|
106076
106076
|
attempt = 0;
|
|
106077
106077
|
if (work == null) {
|
|
106078
106078
|
if (__classPrivateFieldGet2(this, _WorkPoller_drain, "f"))
|
|
106079
106079
|
return;
|
|
106080
|
-
await
|
|
106080
|
+
await sleep(jitter(1e3, 3e3), __classPrivateFieldGet2(this, _WorkPoller_controller, "f").signal);
|
|
106081
106081
|
continue;
|
|
106082
106082
|
}
|
|
106083
106083
|
log.info("claimed work", {
|
|
@@ -106470,7 +106470,7 @@ var init_SessionToolRunner = __esm({
|
|
|
106470
106470
|
});
|
|
106471
106471
|
}
|
|
106472
106472
|
ctrl.signal.throwIfAborted();
|
|
106473
|
-
await
|
|
106473
|
+
await sleep(backoff3, ctrl.signal);
|
|
106474
106474
|
backoff3 = Math.min(backoff3 * 2, STREAM_BACKOFF_CAP_MS);
|
|
106475
106475
|
}
|
|
106476
106476
|
}, _SessionToolRunner_reconcile = /**
|
|
@@ -106710,7 +106710,7 @@ var init_SessionToolRunner = __esm({
|
|
|
106710
106710
|
if (isFatal4xx(e2))
|
|
106711
106711
|
break;
|
|
106712
106712
|
if (i2 < SEND_RETRIES - 1)
|
|
106713
|
-
await
|
|
106713
|
+
await sleep((i2 + 1) * 1e3, ctrl.signal);
|
|
106714
106714
|
}
|
|
106715
106715
|
}
|
|
106716
106716
|
__classPrivateFieldGet2(this, _SessionToolRunner_logger, "f").error("failed to send tool result", {
|
|
@@ -106722,7 +106722,7 @@ var init_SessionToolRunner = __esm({
|
|
|
106722
106722
|
async function _SessionToolRunner_drain2() {
|
|
106723
106723
|
if (__classPrivateFieldGet2(this, _SessionToolRunner_inFlightCount, "f") === 0)
|
|
106724
106724
|
return;
|
|
106725
|
-
await Promise.race([new Promise((r2) => __classPrivateFieldSet2(this, _SessionToolRunner_onIdle, r2, "f")),
|
|
106725
|
+
await Promise.race([new Promise((r2) => __classPrivateFieldSet2(this, _SessionToolRunner_onIdle, r2, "f")), sleep(DRAIN_TIMEOUT_MS)]);
|
|
106726
106726
|
__classPrivateFieldSet2(this, _SessionToolRunner_onIdle, null, "f");
|
|
106727
106727
|
if (__classPrivateFieldGet2(this, _SessionToolRunner_inFlightCount, "f") > 0) {
|
|
106728
106728
|
__classPrivateFieldGet2(this, _SessionToolRunner_logger, "f").warn("drain timeout exceeded");
|
|
@@ -107698,7 +107698,7 @@ async function heartbeatLoop(client, work, ctrl, logger, requestOptions) {
|
|
|
107698
107698
|
};
|
|
107699
107699
|
await beat();
|
|
107700
107700
|
while (!ctrl.signal.aborted) {
|
|
107701
|
-
await
|
|
107701
|
+
await sleep(intervalMs, ctrl.signal);
|
|
107702
107702
|
ctrl.signal.throwIfAborted();
|
|
107703
107703
|
await beat();
|
|
107704
107704
|
}
|
|
@@ -113627,7 +113627,7 @@ var init_client = __esm({
|
|
|
113627
113627
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
113628
113628
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
113629
113629
|
}
|
|
113630
|
-
await
|
|
113630
|
+
await sleep(timeoutMillis);
|
|
113631
113631
|
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
113632
113632
|
}
|
|
113633
113633
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -149218,7 +149218,7 @@ async function uploadBlobInternal(file2, uploadUrl, apiClient, httpOptions) {
|
|
|
149218
149218
|
break;
|
|
149219
149219
|
}
|
|
149220
149220
|
retryCount++;
|
|
149221
|
-
await
|
|
149221
|
+
await sleep2(currentDelayMs);
|
|
149222
149222
|
currentDelayMs = currentDelayMs * DELAY_MULTIPLIER;
|
|
149223
149223
|
}
|
|
149224
149224
|
offset += chunkSize;
|
|
@@ -149235,7 +149235,7 @@ async function getBlobStat(file2) {
|
|
|
149235
149235
|
const fileStat = { size: file2.size, type: file2.type };
|
|
149236
149236
|
return fileStat;
|
|
149237
149237
|
}
|
|
149238
|
-
function
|
|
149238
|
+
function sleep2(ms) {
|
|
149239
149239
|
return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
|
|
149240
149240
|
}
|
|
149241
149241
|
function resolveCloudFlag(options) {
|
|
@@ -156759,7 +156759,7 @@ var init_node2 = __esm({
|
|
|
156759
156759
|
break;
|
|
156760
156760
|
}
|
|
156761
156761
|
retryCount++;
|
|
156762
|
-
await
|
|
156762
|
+
await sleep2(currentDelayMs);
|
|
156763
156763
|
currentDelayMs = currentDelayMs * DELAY_MULTIPLIER;
|
|
156764
156764
|
}
|
|
156765
156765
|
offset += bytesRead;
|
|
@@ -158648,11 +158648,20 @@ function readAgentPromptBlock(lines, openingLineNumber, opening, stripTrailingCo
|
|
|
158648
158648
|
};
|
|
158649
158649
|
}
|
|
158650
158650
|
|
|
158651
|
+
// src/agents/agentTypes.ts
|
|
158652
|
+
var AGENT_REASONING_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
|
|
158653
|
+
var DEFAULT_AGENT_MAX_TOKENS = 16e3;
|
|
158654
|
+
var DEFAULT_LOCAL_AGENT_MAX_TOKENS = 4096;
|
|
158655
|
+
var DEFAULT_AGENT_MAX_DEPTH = 5;
|
|
158656
|
+
var DEFAULT_AGENT_MAX_INVOCATIONS = 25;
|
|
158657
|
+
var DEFAULT_AGENT_MAX_TURNS = 100;
|
|
158658
|
+
var DEFAULT_AGENT_CONTRACT_RETRIES = 2;
|
|
158659
|
+
|
|
158651
158660
|
// src/agents/nornAgentParser.ts
|
|
158652
158661
|
var IDENTIFIER = "[a-zA-Z_][a-zA-Z0-9_]*";
|
|
158653
|
-
var MODEL_PROVIDERS = ["anthropic", "google", "local", "openai"];
|
|
158662
|
+
var MODEL_PROVIDERS = ["anthropic", "google", "local", "openai", "openai_compatible"];
|
|
158654
158663
|
var MODEL_PROVIDER = new RegExp(`^(${MODEL_PROVIDERS.join("|")})$`, "i");
|
|
158655
|
-
var MODEL_DIRECTIVES = ["provider", "name", "apiKey", "baseUrl"];
|
|
158664
|
+
var MODEL_DIRECTIVES = ["provider", "name", "reasoning", "apiKey", "baseUrl"];
|
|
158656
158665
|
var MCP_DIRECTIVES = {
|
|
158657
158666
|
transport: { transport: "both", repeatable: false },
|
|
158658
158667
|
command: { transport: "stdio", repeatable: false },
|
|
@@ -158665,15 +158674,6 @@ var MCP_DIRECTIVES = {
|
|
|
158665
158674
|
};
|
|
158666
158675
|
var MCP_DIRECTIVE_NAMES = Object.keys(MCP_DIRECTIVES);
|
|
158667
158676
|
var MCP_SESSION_SCOPES = ["run", "agent", "call"];
|
|
158668
|
-
function splitCommandParts(value) {
|
|
158669
|
-
const parts = [];
|
|
158670
|
-
const pattern = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
158671
|
-
let match2;
|
|
158672
|
-
while ((match2 = pattern.exec(value)) !== null) {
|
|
158673
|
-
parts.push(match2[1] ?? match2[2] ?? match2[3]);
|
|
158674
|
-
}
|
|
158675
|
-
return parts;
|
|
158676
|
-
}
|
|
158677
158677
|
function splitNamedDirective(value) {
|
|
158678
158678
|
const match2 = value.trim().match(/^(\S+)\s+(.+)$/);
|
|
158679
158679
|
if (!match2) {
|
|
@@ -158691,6 +158691,7 @@ function splitHeaderDirective(value) {
|
|
|
158691
158691
|
}
|
|
158692
158692
|
var LIMIT_DIRECTIVES = {
|
|
158693
158693
|
max_tokens: "maxTokens",
|
|
158694
|
+
max_input_tokens: "maxInputTokens",
|
|
158694
158695
|
max_depth: "maxDepth",
|
|
158695
158696
|
max_invocations: "maxInvocations",
|
|
158696
158697
|
max_turns: "maxTurns",
|
|
@@ -158997,7 +158998,7 @@ end mcp
|
|
|
158997
158998
|
mcp.invalid = true;
|
|
158998
158999
|
}
|
|
158999
159000
|
}
|
|
159000
|
-
if (resolvedTransport === "stdio" && mcp.
|
|
159001
|
+
if (resolvedTransport === "stdio" && !mcp.commandTemplate) {
|
|
159001
159002
|
errors.push(parseError(
|
|
159002
159003
|
mcp.lineNumber,
|
|
159003
159004
|
`MCP server '${mcp.alias}' uses transport stdio and requires a command directive.`,
|
|
@@ -159050,7 +159051,7 @@ end mcp
|
|
|
159050
159051
|
mcpServers.set(mcp.alias.toLowerCase(), {
|
|
159051
159052
|
alias: mcp.alias,
|
|
159052
159053
|
transportTemplate: transport.value,
|
|
159053
|
-
|
|
159054
|
+
...mcp.commandTemplate ? { commandTemplate: mcp.commandTemplate } : {},
|
|
159054
159055
|
...mcp.values.cwd ? { cwdTemplate: mcp.values.cwd.value } : {},
|
|
159055
159056
|
...mcp.envTemplates.length > 0 ? { envTemplates: mcp.envTemplates } : {},
|
|
159056
159057
|
...mcp.values.url ? { urlTemplate: mcp.values.url.value } : {},
|
|
@@ -159125,6 +159126,23 @@ end mcp
|
|
|
159125
159126
|
));
|
|
159126
159127
|
model.invalid = true;
|
|
159127
159128
|
}
|
|
159129
|
+
const reasoning = model.values.reasoning;
|
|
159130
|
+
if (reasoning && !reasoning.value.includes("{{") && !AGENT_REASONING_EFFORTS.some((effort) => effort === reasoning.value.toLowerCase())) {
|
|
159131
|
+
errors.push(parseError(
|
|
159132
|
+
reasoning.lineNumber,
|
|
159133
|
+
`Unknown reasoning effort '${reasoning.value}' in model '${model.alias}'. Expected one of: ${AGENT_REASONING_EFFORTS.join(", ")}.`,
|
|
159134
|
+
"agent-model-reasoning-invalid"
|
|
159135
|
+
));
|
|
159136
|
+
model.invalid = true;
|
|
159137
|
+
}
|
|
159138
|
+
if (reasoning && provider && !provider.value.includes("{{") && provider.value.toLowerCase() !== "openai") {
|
|
159139
|
+
errors.push(parseError(
|
|
159140
|
+
reasoning.lineNumber,
|
|
159141
|
+
`Model '${model.alias}' can declare reasoning only with provider openai. Provider '${provider.value}' does not support this directive yet.`,
|
|
159142
|
+
"agent-model-reasoning-provider"
|
|
159143
|
+
));
|
|
159144
|
+
model.invalid = true;
|
|
159145
|
+
}
|
|
159128
159146
|
if (model.invalid || !provider || !name) {
|
|
159129
159147
|
return;
|
|
159130
159148
|
}
|
|
@@ -159133,6 +159151,7 @@ end mcp
|
|
|
159133
159151
|
providerTemplate: provider.value,
|
|
159134
159152
|
nameTemplate: name.value,
|
|
159135
159153
|
targetTemplate: `${provider.value}/${name.value}`,
|
|
159154
|
+
...reasoning ? { reasoningTemplate: reasoning.value } : {},
|
|
159136
159155
|
...model.values.apiKey ? { apiKeyTemplate: model.values.apiKey.value } : {},
|
|
159137
159156
|
...model.values.baseUrl ? { baseUrlTemplate: model.values.baseUrl.value } : {},
|
|
159138
159157
|
lineNumber: model.lineNumber,
|
|
@@ -159172,6 +159191,13 @@ end mcp
|
|
|
159172
159191
|
"agent-model-alias-unknown"
|
|
159173
159192
|
));
|
|
159174
159193
|
pending.invalid = true;
|
|
159194
|
+
} else if (model.alias !== pending.modelAlias.value) {
|
|
159195
|
+
errors.push(parseError(
|
|
159196
|
+
pending.modelAlias.lineNumber,
|
|
159197
|
+
`Model alias '${pending.modelAlias.value}' in agent '${pending.name}' does not match the declared alias '${model.alias}'. Model aliases are case-sensitive.`,
|
|
159198
|
+
"agent-model-alias-case-mismatch"
|
|
159199
|
+
));
|
|
159200
|
+
pending.invalid = true;
|
|
159175
159201
|
}
|
|
159176
159202
|
}
|
|
159177
159203
|
}
|
|
@@ -159207,6 +159233,7 @@ end mcp
|
|
|
159207
159233
|
accepts: pending.accepts,
|
|
159208
159234
|
returns: pending.returns,
|
|
159209
159235
|
maxTokens: pending.maxTokens?.value,
|
|
159236
|
+
maxInputTokens: pending.maxInputTokens?.value,
|
|
159210
159237
|
maxDepth: pending.maxDepth?.value,
|
|
159211
159238
|
maxInvocations: pending.maxInvocations?.value,
|
|
159212
159239
|
maxTurns: pending.maxTurns?.value,
|
|
@@ -159360,7 +159387,7 @@ end mcp
|
|
|
159360
159387
|
lineNumber: index
|
|
159361
159388
|
};
|
|
159362
159389
|
if (directive === "command") {
|
|
159363
|
-
pendingMcp.
|
|
159390
|
+
pendingMcp.commandTemplate = rawValue;
|
|
159364
159391
|
}
|
|
159365
159392
|
continue;
|
|
159366
159393
|
}
|
|
@@ -159495,7 +159522,6 @@ end model`,
|
|
|
159495
159522
|
alias,
|
|
159496
159523
|
lineNumber: index,
|
|
159497
159524
|
values: {},
|
|
159498
|
-
commandTemplates: [],
|
|
159499
159525
|
envTemplates: [],
|
|
159500
159526
|
headerTemplates: [],
|
|
159501
159527
|
sawDirective: false,
|
|
@@ -159611,29 +159637,38 @@ end model`,
|
|
|
159611
159637
|
}
|
|
159612
159638
|
const knowledgeGrantMatch = trimmed.match(/^knowledge(?:\s+(.*))?$/i);
|
|
159613
159639
|
if (knowledgeGrantMatch) {
|
|
159614
|
-
const
|
|
159615
|
-
|
|
159640
|
+
const rawValue = (knowledgeGrantMatch[1] ?? "").trim();
|
|
159641
|
+
const aliases = rawValue ? rawValue.split(",").map((part) => part.trim()) : [];
|
|
159642
|
+
if (aliases.length === 0 || aliases.some((alias) => !new RegExp(`^${IDENTIFIER}$`).test(alias))) {
|
|
159616
159643
|
errors.push(parseError(
|
|
159617
159644
|
index,
|
|
159618
|
-
`Invalid knowledge grant '${trimmed}' in agent '${pending.name}'. Expected: knowledge <Alias
|
|
159645
|
+
`Invalid knowledge grant '${trimmed}' in agent '${pending.name}'. Expected: knowledge <Alias>[, <Alias>\u2026].`,
|
|
159619
159646
|
"agent-knowledge-grant-invalid"
|
|
159620
159647
|
));
|
|
159621
159648
|
pending.invalid = true;
|
|
159622
|
-
|
|
159623
|
-
|
|
159624
|
-
|
|
159625
|
-
|
|
159626
|
-
|
|
159627
|
-
|
|
159628
|
-
|
|
159629
|
-
|
|
159630
|
-
|
|
159631
|
-
|
|
159632
|
-
|
|
159633
|
-
|
|
159634
|
-
|
|
159635
|
-
|
|
159636
|
-
|
|
159649
|
+
continue;
|
|
159650
|
+
}
|
|
159651
|
+
const granted = new Set(pending.knowledge.map((grant) => grant.alias.toLowerCase()));
|
|
159652
|
+
for (const alias of aliases) {
|
|
159653
|
+
if (granted.has(alias.toLowerCase())) {
|
|
159654
|
+
errors.push(parseError(
|
|
159655
|
+
index,
|
|
159656
|
+
`Agent '${pending.name}' grants knowledge '${alias}' more than once.`,
|
|
159657
|
+
"agent-knowledge-grant-duplicate"
|
|
159658
|
+
));
|
|
159659
|
+
pending.invalid = true;
|
|
159660
|
+
continue;
|
|
159661
|
+
}
|
|
159662
|
+
if (!knowledgeBases.has(alias.toLowerCase())) {
|
|
159663
|
+
errors.push(parseError(
|
|
159664
|
+
index,
|
|
159665
|
+
`Unknown knowledge alias '${alias}' in agent '${pending.name}'.`,
|
|
159666
|
+
"agent-knowledge-alias-unknown"
|
|
159667
|
+
));
|
|
159668
|
+
pending.invalid = true;
|
|
159669
|
+
continue;
|
|
159670
|
+
}
|
|
159671
|
+
granted.add(alias.toLowerCase());
|
|
159637
159672
|
pending.knowledge.push({ alias, lineNumber: index });
|
|
159638
159673
|
}
|
|
159639
159674
|
continue;
|
|
@@ -159948,6 +159983,7 @@ function isNonNegativeInteger(value) {
|
|
|
159948
159983
|
var AGENT_LIMIT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
159949
159984
|
"_comment",
|
|
159950
159985
|
"max_tokens",
|
|
159986
|
+
"max_input_tokens",
|
|
159951
159987
|
"max_depth",
|
|
159952
159988
|
"max_invocations",
|
|
159953
159989
|
"max_turns",
|
|
@@ -159957,7 +159993,7 @@ function hasOnlyKeys(value, allowedKeys) {
|
|
|
159957
159993
|
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
159958
159994
|
}
|
|
159959
159995
|
function hasValidNornAgentLimits(value) {
|
|
159960
|
-
return (value.max_tokens === void 0 || isPositiveInteger(value.max_tokens)) && (value.max_depth === void 0 || isPositiveInteger(value.max_depth)) && (value.max_invocations === void 0 || isPositiveInteger(value.max_invocations)) && (value.max_turns === void 0 || isPositiveInteger(value.max_turns)) && (value.contract_retries === void 0 || isNonNegativeInteger(value.contract_retries));
|
|
159996
|
+
return (value.max_tokens === void 0 || isPositiveInteger(value.max_tokens)) && (value.max_input_tokens === void 0 || isPositiveInteger(value.max_input_tokens)) && (value.max_depth === void 0 || isPositiveInteger(value.max_depth)) && (value.max_invocations === void 0 || isPositiveInteger(value.max_invocations)) && (value.max_turns === void 0 || isPositiveInteger(value.max_turns)) && (value.contract_retries === void 0 || isNonNegativeInteger(value.contract_retries));
|
|
159961
159997
|
}
|
|
159962
159998
|
function isNornAgentProviderConfig(value) {
|
|
159963
159999
|
if (!isObjectRecord(value)) {
|
|
@@ -159977,7 +160013,13 @@ function isNornAgentRecordingConfig(value) {
|
|
|
159977
160013
|
}
|
|
159978
160014
|
return hasOnlyKeys(value, /* @__PURE__ */ new Set(["_comment", "enabled"])) && (value.enabled === void 0 || typeof value.enabled === "boolean");
|
|
159979
160015
|
}
|
|
159980
|
-
var AGENT_PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
160016
|
+
var AGENT_PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
160017
|
+
"openai",
|
|
160018
|
+
"openai_compatible",
|
|
160019
|
+
"anthropic",
|
|
160020
|
+
"google",
|
|
160021
|
+
"local"
|
|
160022
|
+
]);
|
|
159981
160023
|
function isNornAgentsConfig(value) {
|
|
159982
160024
|
if (value === void 0) {
|
|
159983
160025
|
return true;
|
|
@@ -160419,7 +160461,7 @@ function extractImports(text) {
|
|
|
160419
160461
|
}
|
|
160420
160462
|
function sameMcpServerDeclaration(left, right) {
|
|
160421
160463
|
const named = (entries) => (entries ?? []).map((entry) => `${entry.name}=${entry.valueTemplate}`).join("\0");
|
|
160422
|
-
return left.transportTemplate === right.transportTemplate && left.
|
|
160464
|
+
return left.transportTemplate === right.transportTemplate && left.commandTemplate === right.commandTemplate && left.cwdTemplate === right.cwdTemplate && left.urlTemplate === right.urlTemplate && left.timeoutMs === right.timeoutMs && left.session === right.session && named(left.envTemplates) === named(right.envTemplates) && named(left.headerTemplates) === named(right.headerTemplates);
|
|
160423
160465
|
}
|
|
160424
160466
|
async function resolveImports(text, baseDir, readFile4, alreadyImported = /* @__PURE__ */ new Set(), importStack = /* @__PURE__ */ new Set(), sourceFilePath = path4.resolve(baseDir, "__norn_root__.norn"), sqlImportedPathsBySource = /* @__PURE__ */ new Map(), sqlOperationsBySource = /* @__PURE__ */ new Map(), agentImportedPathsBySource = /* @__PURE__ */ new Map(), agentDefinitionsBySource = /* @__PURE__ */ new Map(), mcpServersBySource = /* @__PURE__ */ new Map()) {
|
|
160425
160467
|
const imports = extractImports(text);
|
|
@@ -166666,6 +166708,68 @@ function encodeFormUrlEncodedBody(body) {
|
|
|
166666
166708
|
};
|
|
166667
166709
|
}
|
|
166668
166710
|
|
|
166711
|
+
// src/sequenceCancellation.ts
|
|
166712
|
+
var SEQUENCE_CANCELLED_MESSAGE = "Sequence run cancelled by user.";
|
|
166713
|
+
var SequenceCancelledError = class extends Error {
|
|
166714
|
+
constructor() {
|
|
166715
|
+
super(SEQUENCE_CANCELLED_MESSAGE);
|
|
166716
|
+
this.name = "SequenceCancelledError";
|
|
166717
|
+
}
|
|
166718
|
+
};
|
|
166719
|
+
function throwIfSequenceCancelled(signal) {
|
|
166720
|
+
if (signal?.aborted) {
|
|
166721
|
+
throw new SequenceCancelledError();
|
|
166722
|
+
}
|
|
166723
|
+
}
|
|
166724
|
+
function raceWithSequenceCancellation(operation, signal) {
|
|
166725
|
+
if (!signal) {
|
|
166726
|
+
return operation;
|
|
166727
|
+
}
|
|
166728
|
+
throwIfSequenceCancelled(signal);
|
|
166729
|
+
return new Promise((resolve28, reject) => {
|
|
166730
|
+
const cancel = () => {
|
|
166731
|
+
signal.removeEventListener("abort", cancel);
|
|
166732
|
+
reject(new SequenceCancelledError());
|
|
166733
|
+
};
|
|
166734
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
166735
|
+
if (signal.aborted) {
|
|
166736
|
+
cancel();
|
|
166737
|
+
return;
|
|
166738
|
+
}
|
|
166739
|
+
operation.then(
|
|
166740
|
+
(value) => {
|
|
166741
|
+
signal.removeEventListener("abort", cancel);
|
|
166742
|
+
resolve28(value);
|
|
166743
|
+
},
|
|
166744
|
+
(error2) => {
|
|
166745
|
+
signal.removeEventListener("abort", cancel);
|
|
166746
|
+
reject(error2);
|
|
166747
|
+
}
|
|
166748
|
+
);
|
|
166749
|
+
});
|
|
166750
|
+
}
|
|
166751
|
+
function cancellableDelay(ms, signal) {
|
|
166752
|
+
if (!signal) {
|
|
166753
|
+
return new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
166754
|
+
}
|
|
166755
|
+
throwIfSequenceCancelled(signal);
|
|
166756
|
+
return new Promise((resolve28, reject) => {
|
|
166757
|
+
const timer = setTimeout(() => {
|
|
166758
|
+
signal.removeEventListener("abort", cancel);
|
|
166759
|
+
resolve28();
|
|
166760
|
+
}, ms);
|
|
166761
|
+
const cancel = () => {
|
|
166762
|
+
clearTimeout(timer);
|
|
166763
|
+
signal.removeEventListener("abort", cancel);
|
|
166764
|
+
reject(new SequenceCancelledError());
|
|
166765
|
+
};
|
|
166766
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
166767
|
+
if (signal.aborted) {
|
|
166768
|
+
cancel();
|
|
166769
|
+
}
|
|
166770
|
+
});
|
|
166771
|
+
}
|
|
166772
|
+
|
|
166669
166773
|
// src/httpClient.ts
|
|
166670
166774
|
var sharedCookieJar = new CookieJar();
|
|
166671
166775
|
var insecureHttpsAgent = new https2.Agent({ rejectUnauthorized: false });
|
|
@@ -166688,11 +166792,8 @@ async function getAllCookies(jar) {
|
|
|
166688
166792
|
secure: Boolean(c.secure)
|
|
166689
166793
|
}));
|
|
166690
166794
|
}
|
|
166691
|
-
async function sendRequest(request, retryOptions) {
|
|
166692
|
-
return sendRequestWithJar(request, sharedCookieJar, retryOptions);
|
|
166693
|
-
}
|
|
166694
|
-
function sleep(ms) {
|
|
166695
|
-
return new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
166795
|
+
async function sendRequest(request, retryOptions, signal) {
|
|
166796
|
+
return sendRequestWithJar(request, sharedCookieJar, retryOptions, signal);
|
|
166696
166797
|
}
|
|
166697
166798
|
function shouldRetry(response, error2) {
|
|
166698
166799
|
if (error2) {
|
|
@@ -166703,13 +166804,14 @@ function shouldRetry(response, error2) {
|
|
|
166703
166804
|
}
|
|
166704
166805
|
return false;
|
|
166705
166806
|
}
|
|
166706
|
-
async function sendRequestWithJar(request, jar, retryOptions) {
|
|
166807
|
+
async function sendRequestWithJar(request, jar, retryOptions, signal) {
|
|
166707
166808
|
const totalAttempts = (retryOptions?.retryCount ?? 0) + 1;
|
|
166708
166809
|
const backoffMs = retryOptions?.backoffMs ?? 1e3;
|
|
166709
166810
|
const retriedErrors = [];
|
|
166710
166811
|
let lastError = null;
|
|
166711
166812
|
let attemptsMade = 0;
|
|
166712
166813
|
for (let attempt = 1; attempt <= totalAttempts; attempt++) {
|
|
166814
|
+
throwIfSequenceCancelled(signal);
|
|
166713
166815
|
attemptsMade = attempt;
|
|
166714
166816
|
const startTime = Date.now();
|
|
166715
166817
|
const maxRedirects = 10;
|
|
@@ -166722,6 +166824,7 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166722
166824
|
let sentRequestHeaders = {};
|
|
166723
166825
|
try {
|
|
166724
166826
|
while (redirectCount <= maxRedirects) {
|
|
166827
|
+
throwIfSequenceCancelled(signal);
|
|
166725
166828
|
const existingCookies = await jar.getCookies(currentUrl);
|
|
166726
166829
|
const cookieHeader = existingCookies.map((c) => `${c.key}=${c.value}`).join("; ");
|
|
166727
166830
|
const headers = { ...request.headers };
|
|
@@ -166776,7 +166879,8 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166776
166879
|
timeout: getRequestTimeoutMs(),
|
|
166777
166880
|
maxRedirects: 0,
|
|
166778
166881
|
validateStatus: () => true,
|
|
166779
|
-
httpsAgent: getHttpsAgent()
|
|
166882
|
+
httpsAgent: getHttpsAgent(),
|
|
166883
|
+
signal
|
|
166780
166884
|
});
|
|
166781
166885
|
const setCookieHeader = response.headers["set-cookie"];
|
|
166782
166886
|
if (setCookieHeader) {
|
|
@@ -166811,7 +166915,7 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166811
166915
|
if (retryOptions?.onRetry) {
|
|
166812
166916
|
retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
|
|
166813
166917
|
}
|
|
166814
|
-
await
|
|
166918
|
+
await cancellableDelay(waitMs, signal);
|
|
166815
166919
|
continue;
|
|
166816
166920
|
}
|
|
166817
166921
|
const cookies = await getAllCookies(jar);
|
|
@@ -166834,6 +166938,9 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166834
166938
|
}
|
|
166835
166939
|
return result;
|
|
166836
166940
|
} catch (error2) {
|
|
166941
|
+
if (signal?.aborted) {
|
|
166942
|
+
throw new SequenceCancelledError();
|
|
166943
|
+
}
|
|
166837
166944
|
const errorMessage = error2.message || String(error2);
|
|
166838
166945
|
const effectiveUrl = currentUrl || request.url;
|
|
166839
166946
|
const isUrlError = /invalid url/i.test(errorMessage) || /unsupported protocol/i.test(errorMessage);
|
|
@@ -166876,7 +166983,7 @@ URL used: ${effectiveUrl}`);
|
|
|
166876
166983
|
if (retryOptions?.onRetry) {
|
|
166877
166984
|
retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
|
|
166878
166985
|
}
|
|
166879
|
-
await
|
|
166986
|
+
await cancellableDelay(waitMs, signal);
|
|
166880
166987
|
continue;
|
|
166881
166988
|
}
|
|
166882
166989
|
throw lastError;
|
|
@@ -167080,7 +167187,8 @@ function isRunCommand(line2) {
|
|
|
167080
167187
|
const trimmed = line2.trim();
|
|
167081
167188
|
return /^(var\s+[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*)?run\s+(bash|powershell|pwsh|js)\s+/i.test(trimmed);
|
|
167082
167189
|
}
|
|
167083
|
-
async function runScript(type, scriptPath, args, workingDir, variables = {}, captureVar) {
|
|
167190
|
+
async function runScript(type, scriptPath, args, workingDir, variables = {}, captureVar, signal) {
|
|
167191
|
+
throwIfSequenceCancelled(signal);
|
|
167084
167192
|
const startTime = Date.now();
|
|
167085
167193
|
const resolvedPath = path5.isAbsolute(scriptPath) ? scriptPath : path5.resolve(workingDir, scriptPath);
|
|
167086
167194
|
let command;
|
|
@@ -167111,7 +167219,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167111
167219
|
captureVar
|
|
167112
167220
|
};
|
|
167113
167221
|
}
|
|
167114
|
-
return new Promise((resolve28) => {
|
|
167222
|
+
return new Promise((resolve28, reject) => {
|
|
167115
167223
|
const env4 = {
|
|
167116
167224
|
...process.env,
|
|
167117
167225
|
// Pass variables as environment variables with NORN_ prefix
|
|
@@ -167128,6 +167236,28 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167128
167236
|
});
|
|
167129
167237
|
let stdout = "";
|
|
167130
167238
|
let stderr = "";
|
|
167239
|
+
let settled = false;
|
|
167240
|
+
const cancel = () => {
|
|
167241
|
+
if (settled) {
|
|
167242
|
+
return;
|
|
167243
|
+
}
|
|
167244
|
+
settled = true;
|
|
167245
|
+
signal?.removeEventListener("abort", cancel);
|
|
167246
|
+
child.kill("SIGTERM");
|
|
167247
|
+
reject(new SequenceCancelledError());
|
|
167248
|
+
};
|
|
167249
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
167250
|
+
if (signal?.aborted) {
|
|
167251
|
+
cancel();
|
|
167252
|
+
}
|
|
167253
|
+
const finish = (result) => {
|
|
167254
|
+
if (settled) {
|
|
167255
|
+
return;
|
|
167256
|
+
}
|
|
167257
|
+
settled = true;
|
|
167258
|
+
signal?.removeEventListener("abort", cancel);
|
|
167259
|
+
resolve28(result);
|
|
167260
|
+
};
|
|
167131
167261
|
child.stdout.on("data", (data) => {
|
|
167132
167262
|
stdout += data.toString();
|
|
167133
167263
|
});
|
|
@@ -167135,7 +167265,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167135
167265
|
stderr += data.toString();
|
|
167136
167266
|
});
|
|
167137
167267
|
child.on("error", (err) => {
|
|
167138
|
-
|
|
167268
|
+
finish({
|
|
167139
167269
|
success: false,
|
|
167140
167270
|
output: cleanScriptOutput(stdout),
|
|
167141
167271
|
error: `Failed to execute script: ${err.message}`,
|
|
@@ -167149,7 +167279,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167149
167279
|
child.on("close", (code) => {
|
|
167150
167280
|
const exitCode = code ?? 0;
|
|
167151
167281
|
const cleanedOutput = cleanScriptOutput(stdout);
|
|
167152
|
-
|
|
167282
|
+
finish({
|
|
167153
167283
|
success: exitCode === 0,
|
|
167154
167284
|
output: cleanedOutput,
|
|
167155
167285
|
error: stderr.trim(),
|
|
@@ -168730,7 +168860,8 @@ function buildAdapterError(message, stderr, stdout) {
|
|
|
168730
168860
|
}
|
|
168731
168861
|
return new Error(details.join("\n"));
|
|
168732
168862
|
}
|
|
168733
|
-
async function runExternalSqlAdapter(command, request, workingDir) {
|
|
168863
|
+
async function runExternalSqlAdapter(command, request, workingDir, signal) {
|
|
168864
|
+
throwIfSequenceCancelled(signal);
|
|
168734
168865
|
if (!command.length) {
|
|
168735
168866
|
throw new Error("SQL adapter command is empty");
|
|
168736
168867
|
}
|
|
@@ -168743,11 +168874,25 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168743
168874
|
let stdout = "";
|
|
168744
168875
|
let stderr = "";
|
|
168745
168876
|
let settled = false;
|
|
168877
|
+
const cancel = () => {
|
|
168878
|
+
if (settled) {
|
|
168879
|
+
return;
|
|
168880
|
+
}
|
|
168881
|
+
settled = true;
|
|
168882
|
+
signal?.removeEventListener("abort", cancel);
|
|
168883
|
+
child.kill("SIGTERM");
|
|
168884
|
+
reject(new SequenceCancelledError());
|
|
168885
|
+
};
|
|
168886
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
168887
|
+
if (signal?.aborted) {
|
|
168888
|
+
cancel();
|
|
168889
|
+
}
|
|
168746
168890
|
const fail3 = (error2) => {
|
|
168747
168891
|
if (settled) {
|
|
168748
168892
|
return;
|
|
168749
168893
|
}
|
|
168750
168894
|
settled = true;
|
|
168895
|
+
signal?.removeEventListener("abort", cancel);
|
|
168751
168896
|
reject(error2);
|
|
168752
168897
|
};
|
|
168753
168898
|
const succeed = (response) => {
|
|
@@ -168755,6 +168900,7 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168755
168900
|
return;
|
|
168756
168901
|
}
|
|
168757
168902
|
settled = true;
|
|
168903
|
+
signal?.removeEventListener("abort", cancel);
|
|
168758
168904
|
resolve28(response);
|
|
168759
168905
|
};
|
|
168760
168906
|
child.stdout.on("data", (chunk) => {
|
|
@@ -168812,11 +168958,11 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168812
168958
|
}
|
|
168813
168959
|
});
|
|
168814
168960
|
}
|
|
168815
|
-
async function runSqlAdapter(target, request, workingDir) {
|
|
168961
|
+
async function runSqlAdapter(target, request, workingDir, signal) {
|
|
168816
168962
|
if (target.kind === "builtin") {
|
|
168817
|
-
return runBuiltInSqlAdapter(target.adapterId, request);
|
|
168963
|
+
return raceWithSequenceCancellation(runBuiltInSqlAdapter(target.adapterId, request), signal);
|
|
168818
168964
|
}
|
|
168819
|
-
return runExternalSqlAdapter(target.command, request, workingDir);
|
|
168965
|
+
return runExternalSqlAdapter(target.command, request, workingDir, signal);
|
|
168820
168966
|
}
|
|
168821
168967
|
|
|
168822
168968
|
// src/mcpClient.ts
|
|
@@ -168831,10 +168977,10 @@ var util3;
|
|
|
168831
168977
|
function assertIs2(_arg) {
|
|
168832
168978
|
}
|
|
168833
168979
|
util4.assertIs = assertIs2;
|
|
168834
|
-
function
|
|
168980
|
+
function assertNever6(_x) {
|
|
168835
168981
|
throw new Error();
|
|
168836
168982
|
}
|
|
168837
|
-
util4.assertNever =
|
|
168983
|
+
util4.assertNever = assertNever6;
|
|
168838
168984
|
util4.arrayToEnum = (items) => {
|
|
168839
168985
|
const obj = {};
|
|
168840
168986
|
for (const item of items) {
|
|
@@ -184623,6 +184769,15 @@ function resolveTemplateString(value, envVariables) {
|
|
|
184623
184769
|
const scopedVariables = attachEnvironmentScope({}, envVariables);
|
|
184624
184770
|
return substituteVariables(value, scopedVariables);
|
|
184625
184771
|
}
|
|
184772
|
+
function splitCommandLine(value) {
|
|
184773
|
+
const parts = [];
|
|
184774
|
+
const pattern = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
184775
|
+
let match2;
|
|
184776
|
+
while ((match2 = pattern.exec(value)) !== null) {
|
|
184777
|
+
parts.push(match2[1] ?? match2[2] ?? match2[3]);
|
|
184778
|
+
}
|
|
184779
|
+
return parts;
|
|
184780
|
+
}
|
|
184626
184781
|
function resolveCommandParts2(originPath, command, envVariables) {
|
|
184627
184782
|
const configDir = path10.dirname(originPath);
|
|
184628
184783
|
return command.map((part, index) => {
|
|
@@ -184751,9 +184906,16 @@ function resolveNamedTemplates(entries, declaration, directive, envVariables) {
|
|
|
184751
184906
|
function resolveMcpServerDeclaration(declaration, envVariables) {
|
|
184752
184907
|
const transport = resolveTemplate(declaration.transportTemplate, declaration, "transport", envVariables).toLowerCase();
|
|
184753
184908
|
if (transport === "stdio") {
|
|
184754
|
-
const
|
|
184755
|
-
|
|
184909
|
+
const resolvedCommand = resolveTemplate(
|
|
184910
|
+
declaration.commandTemplate ?? "",
|
|
184911
|
+
declaration,
|
|
184912
|
+
"command",
|
|
184913
|
+
envVariables
|
|
184756
184914
|
);
|
|
184915
|
+
const command = splitCommandLine(resolvedCommand);
|
|
184916
|
+
if (command.length === 0) {
|
|
184917
|
+
throw new Error(`MCP server '${declaration.alias}' resolved to an empty command.`);
|
|
184918
|
+
}
|
|
184757
184919
|
return {
|
|
184758
184920
|
transport: "stdio",
|
|
184759
184921
|
// Reuse the config path's own resolution so a bare name stays a PATH lookup and a
|
|
@@ -186229,15 +186391,155 @@ function describeUnmetExpectations(verdict) {
|
|
|
186229
186391
|
|
|
186230
186392
|
// src/agents/providers/providerUtils.ts
|
|
186231
186393
|
var import_crypto6 = require("crypto");
|
|
186394
|
+
|
|
186395
|
+
// src/agents/toolResultContext.ts
|
|
186396
|
+
var MAX_INLINE_TOOL_RESULT_TOKENS = 2e4;
|
|
186397
|
+
var MAX_INLINE_TOOL_RESULT_CHARACTERS = MAX_INLINE_TOOL_RESULT_TOKENS * 4;
|
|
186398
|
+
var MAX_RETAINED_INLINE_TOOL_RESULTS = 3;
|
|
186399
|
+
var TOOL_RESULT_PREVIEW_CHARACTERS = 2e3;
|
|
186400
|
+
var TOOL_RESULT_READ_CHARACTERS = 12e3;
|
|
186401
|
+
function outputToText(output2) {
|
|
186402
|
+
if (typeof output2 === "string") {
|
|
186403
|
+
return output2;
|
|
186404
|
+
}
|
|
186405
|
+
if (output2 === void 0) {
|
|
186406
|
+
return "";
|
|
186407
|
+
}
|
|
186408
|
+
try {
|
|
186409
|
+
return JSON.stringify(output2);
|
|
186410
|
+
} catch {
|
|
186411
|
+
return String(output2);
|
|
186412
|
+
}
|
|
186413
|
+
}
|
|
186414
|
+
function referenceText(input2) {
|
|
186415
|
+
return JSON.stringify({
|
|
186416
|
+
nornToolResult: {
|
|
186417
|
+
status: input2.released ? "released_from_context" : "offloaded",
|
|
186418
|
+
handle: input2.handle,
|
|
186419
|
+
tool: input2.toolName,
|
|
186420
|
+
originalCharacters: input2.originalCharacters,
|
|
186421
|
+
estimatedTokens: input2.estimatedTokens,
|
|
186422
|
+
...input2.preview !== void 0 ? { preview: input2.preview } : {},
|
|
186423
|
+
instruction: `Use norn_read_tool_result with handle '${input2.handle}' to read or search bounded portions.`
|
|
186424
|
+
}
|
|
186425
|
+
});
|
|
186426
|
+
}
|
|
186427
|
+
var PreparedAgentToolResult = class {
|
|
186428
|
+
constructor(recordedOutput, immediateOutput, immediateText, historyPlaceholder) {
|
|
186429
|
+
this.recordedOutput = recordedOutput;
|
|
186430
|
+
this.immediateOutput = immediateOutput;
|
|
186431
|
+
this.immediateText = immediateText;
|
|
186432
|
+
this.historyPlaceholder = historyPlaceholder;
|
|
186433
|
+
}
|
|
186434
|
+
};
|
|
186435
|
+
var AgentToolResultStore = class {
|
|
186436
|
+
results = /* @__PURE__ */ new Map();
|
|
186437
|
+
nextHandle = 1;
|
|
186438
|
+
prepare(toolName2, output2) {
|
|
186439
|
+
const text = outputToText(output2);
|
|
186440
|
+
const handle = `tool-result-${this.nextHandle++}`;
|
|
186441
|
+
const estimatedTokens = Math.ceil(text.length / 4);
|
|
186442
|
+
const stored = { handle, toolName: toolName2, text, estimatedTokens };
|
|
186443
|
+
this.results.set(handle, stored);
|
|
186444
|
+
const historyPlaceholder = referenceText({
|
|
186445
|
+
handle,
|
|
186446
|
+
toolName: toolName2,
|
|
186447
|
+
originalCharacters: text.length,
|
|
186448
|
+
estimatedTokens,
|
|
186449
|
+
released: true
|
|
186450
|
+
});
|
|
186451
|
+
if (text.length <= MAX_INLINE_TOOL_RESULT_CHARACTERS) {
|
|
186452
|
+
return new PreparedAgentToolResult(output2, output2, text, historyPlaceholder);
|
|
186453
|
+
}
|
|
186454
|
+
const offloadedReference = referenceText({
|
|
186455
|
+
handle,
|
|
186456
|
+
toolName: toolName2,
|
|
186457
|
+
originalCharacters: text.length,
|
|
186458
|
+
estimatedTokens,
|
|
186459
|
+
preview: text.slice(0, TOOL_RESULT_PREVIEW_CHARACTERS),
|
|
186460
|
+
released: false
|
|
186461
|
+
});
|
|
186462
|
+
return new PreparedAgentToolResult(output2, offloadedReference, offloadedReference, historyPlaceholder);
|
|
186463
|
+
}
|
|
186464
|
+
read(input2) {
|
|
186465
|
+
const handle = typeof input2.handle === "string" ? input2.handle : "";
|
|
186466
|
+
const stored = this.results.get(handle);
|
|
186467
|
+
if (!stored) {
|
|
186468
|
+
return { error: `Unknown or expired tool-result handle '${handle}'.` };
|
|
186469
|
+
}
|
|
186470
|
+
const query = typeof input2.query === "string" ? input2.query.trim() : "";
|
|
186471
|
+
if (query) {
|
|
186472
|
+
return this.search(stored, query);
|
|
186473
|
+
}
|
|
186474
|
+
const requestedOffset = typeof input2.offset === "number" && Number.isSafeInteger(input2.offset) ? input2.offset : 0;
|
|
186475
|
+
const offset = Math.max(0, Math.min(requestedOffset, stored.text.length));
|
|
186476
|
+
const text = stored.text.slice(offset, offset + TOOL_RESULT_READ_CHARACTERS);
|
|
186477
|
+
return {
|
|
186478
|
+
handle,
|
|
186479
|
+
tool: stored.toolName,
|
|
186480
|
+
offset,
|
|
186481
|
+
returnedCharacters: text.length,
|
|
186482
|
+
totalCharacters: stored.text.length,
|
|
186483
|
+
hasMore: offset + text.length < stored.text.length,
|
|
186484
|
+
text
|
|
186485
|
+
};
|
|
186486
|
+
}
|
|
186487
|
+
search(stored, query) {
|
|
186488
|
+
const haystack = stored.text.toLocaleLowerCase();
|
|
186489
|
+
const needle = query.toLocaleLowerCase();
|
|
186490
|
+
const matches = [];
|
|
186491
|
+
let from = 0;
|
|
186492
|
+
while (matches.length < 5) {
|
|
186493
|
+
const index = haystack.indexOf(needle, from);
|
|
186494
|
+
if (index < 0) {
|
|
186495
|
+
break;
|
|
186496
|
+
}
|
|
186497
|
+
const start = Math.max(0, index - 300);
|
|
186498
|
+
const end = Math.min(stored.text.length, index + query.length + 500);
|
|
186499
|
+
matches.push({ offset: start, text: stored.text.slice(start, end) });
|
|
186500
|
+
from = Math.max(index + needle.length, index + 1);
|
|
186501
|
+
}
|
|
186502
|
+
return {
|
|
186503
|
+
handle: stored.handle,
|
|
186504
|
+
tool: stored.toolName,
|
|
186505
|
+
query,
|
|
186506
|
+
totalCharacters: stored.text.length,
|
|
186507
|
+
matches
|
|
186508
|
+
};
|
|
186509
|
+
}
|
|
186510
|
+
};
|
|
186511
|
+
var AgentToolResultHistory = class {
|
|
186512
|
+
retained = [];
|
|
186513
|
+
retain(replaceWithReference) {
|
|
186514
|
+
this.retained.push(replaceWithReference);
|
|
186515
|
+
while (this.retained.length > MAX_RETAINED_INLINE_TOOL_RESULTS) {
|
|
186516
|
+
this.retained.shift()?.();
|
|
186517
|
+
}
|
|
186518
|
+
}
|
|
186519
|
+
};
|
|
186520
|
+
function normalizePreparedAgentToolResult(output2) {
|
|
186521
|
+
if (output2 instanceof PreparedAgentToolResult) {
|
|
186522
|
+
return output2;
|
|
186523
|
+
}
|
|
186524
|
+
return {
|
|
186525
|
+
recordedOutput: output2,
|
|
186526
|
+
immediateOutput: output2,
|
|
186527
|
+
immediateText: outputToText(output2),
|
|
186528
|
+
historyPlaceholder: "[Older tool result released from active context by Norn.]"
|
|
186529
|
+
};
|
|
186530
|
+
}
|
|
186531
|
+
|
|
186532
|
+
// src/agents/providers/providerUtils.ts
|
|
186232
186533
|
var PROVIDER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/;
|
|
186233
186534
|
var PROVIDER_NAME_MAX_LENGTH = 64;
|
|
186234
186535
|
var AgentTurnLimitError = class extends Error {
|
|
186235
|
-
constructor(provider, maxTurns, toolCallCount, lastToolName) {
|
|
186536
|
+
constructor(provider, maxTurns, toolCallCount, lastToolName, usage) {
|
|
186236
186537
|
super(`${provider} tool loop reached its ${maxTurns}-turn limit before the model finished.`);
|
|
186237
186538
|
this.provider = provider;
|
|
186238
186539
|
this.maxTurns = maxTurns;
|
|
186239
186540
|
this.toolCallCount = toolCallCount;
|
|
186240
186541
|
this.lastToolName = lastToolName;
|
|
186542
|
+
this.usage = usage;
|
|
186241
186543
|
this.name = "AgentTurnLimitError";
|
|
186242
186544
|
}
|
|
186243
186545
|
};
|
|
@@ -186310,19 +186612,6 @@ function agentInputToText(input2) {
|
|
|
186310
186612
|
return String(input2);
|
|
186311
186613
|
}
|
|
186312
186614
|
}
|
|
186313
|
-
function providerToolOutputToText(output2) {
|
|
186314
|
-
if (typeof output2 === "string") {
|
|
186315
|
-
return output2;
|
|
186316
|
-
}
|
|
186317
|
-
if (output2 === void 0) {
|
|
186318
|
-
return "";
|
|
186319
|
-
}
|
|
186320
|
-
try {
|
|
186321
|
-
return JSON.stringify(output2);
|
|
186322
|
-
} catch {
|
|
186323
|
-
return String(output2);
|
|
186324
|
-
}
|
|
186325
|
-
}
|
|
186326
186615
|
function tryParseStructuredAgentOutput(text, hasSchema) {
|
|
186327
186616
|
if (!hasSchema) {
|
|
186328
186617
|
return void 0;
|
|
@@ -186405,7 +186694,70 @@ function createRecordedToolCall(records, name, input2, kind) {
|
|
|
186405
186694
|
|
|
186406
186695
|
// src/agents/providers/anthropicAdapter.ts
|
|
186407
186696
|
init_sdk();
|
|
186408
|
-
|
|
186697
|
+
|
|
186698
|
+
// src/agents/agentTokenBudget.ts
|
|
186699
|
+
function estimateSerializedInputTokens(value) {
|
|
186700
|
+
let text;
|
|
186701
|
+
try {
|
|
186702
|
+
text = JSON.stringify(value) ?? "";
|
|
186703
|
+
} catch {
|
|
186704
|
+
text = String(value);
|
|
186705
|
+
}
|
|
186706
|
+
return Math.ceil(text.length / 3);
|
|
186707
|
+
}
|
|
186708
|
+
function formatAgentInputTokenLimitError(agentName, outcome) {
|
|
186709
|
+
const next = outcome.estimatedNextInputTokens === void 0 ? "" : ` The next request was estimated at ${outcome.estimatedNextInputTokens} input tokens.`;
|
|
186710
|
+
return `Agent '${agentName}' reached the top-level run's max_input_tokens budget (${outcome.usedInputTokens}/${outcome.maxInputTokens}) and stopped before continuing.${next} Raise max_input_tokens in ${outcome.sourcePath}:${outcome.lineNumber + 1}, or under 'agents' in norn.config.json.`;
|
|
186711
|
+
}
|
|
186712
|
+
function sumAgentTurnUsage(turns) {
|
|
186713
|
+
return {
|
|
186714
|
+
inputTokens: turns.reduce((total, turn) => total + turn.inputTokens, 0),
|
|
186715
|
+
outputTokens: turns.reduce((total, turn) => total + turn.outputTokens, 0),
|
|
186716
|
+
turns: turns.map((turn) => ({ ...turn }))
|
|
186717
|
+
};
|
|
186718
|
+
}
|
|
186719
|
+
var AgentInputTokenLimitError = class extends Error {
|
|
186720
|
+
constructor(provider, maxInputTokens, usedInputTokens, usage, estimatedNextInputTokens) {
|
|
186721
|
+
const reason = estimatedNextInputTokens === void 0 ? `after using ${usedInputTokens}` : `before an estimated ${estimatedNextInputTokens}-token request with ${usedInputTokens} already used`;
|
|
186722
|
+
super(`${provider} agent input budget ${maxInputTokens} was reached ${reason}.`);
|
|
186723
|
+
this.provider = provider;
|
|
186724
|
+
this.maxInputTokens = maxInputTokens;
|
|
186725
|
+
this.usedInputTokens = usedInputTokens;
|
|
186726
|
+
this.usage = usage;
|
|
186727
|
+
this.estimatedNextInputTokens = estimatedNextInputTokens;
|
|
186728
|
+
this.name = "AgentInputTokenLimitError";
|
|
186729
|
+
}
|
|
186730
|
+
};
|
|
186731
|
+
function assertInputBudgetAllowsCall(provider, budget, estimatedNextInputTokens, turns) {
|
|
186732
|
+
if (!budget || budget.usedInputTokens + estimatedNextInputTokens <= budget.maxInputTokens) {
|
|
186733
|
+
return;
|
|
186734
|
+
}
|
|
186735
|
+
throw new AgentInputTokenLimitError(
|
|
186736
|
+
provider,
|
|
186737
|
+
budget.maxInputTokens,
|
|
186738
|
+
budget.usedInputTokens,
|
|
186739
|
+
sumAgentTurnUsage(turns),
|
|
186740
|
+
estimatedNextInputTokens
|
|
186741
|
+
);
|
|
186742
|
+
}
|
|
186743
|
+
function recordAgentTurnUsage(provider, budget, turns, usage) {
|
|
186744
|
+
const turn = { turn: turns.length + 1, ...usage };
|
|
186745
|
+
turns.push(turn);
|
|
186746
|
+
if (!budget) {
|
|
186747
|
+
return;
|
|
186748
|
+
}
|
|
186749
|
+
budget.usedInputTokens += turn.inputTokens;
|
|
186750
|
+
if (budget.usedInputTokens > budget.maxInputTokens) {
|
|
186751
|
+
throw new AgentInputTokenLimitError(
|
|
186752
|
+
provider,
|
|
186753
|
+
budget.maxInputTokens,
|
|
186754
|
+
budget.usedInputTokens,
|
|
186755
|
+
sumAgentTurnUsage(turns)
|
|
186756
|
+
);
|
|
186757
|
+
}
|
|
186758
|
+
}
|
|
186759
|
+
|
|
186760
|
+
// src/agents/providers/anthropicAdapter.ts
|
|
186409
186761
|
function supportsAdaptiveThinking(modelId) {
|
|
186410
186762
|
return /^claude-(?:opus-(?:4-(?:[6-9]|\d{2,})|[5-9])|sonnet-(?:4-[6-9]|[5-9])|fable-[5-9]|mythos(?:-[5-9]|-preview))/i.test(modelId);
|
|
186411
186763
|
}
|
|
@@ -186487,67 +186839,136 @@ var AnthropicAgentAdapter = class {
|
|
|
186487
186839
|
})),
|
|
186488
186840
|
inputMessage
|
|
186489
186841
|
];
|
|
186490
|
-
|
|
186491
|
-
|
|
186492
|
-
|
|
186493
|
-
if (request.tools.length > 0) {
|
|
186494
|
-
const runnableTools = prepareAgentProviderTools(request.tools).map(({ tool, providerName }) => {
|
|
186495
|
-
if (tool.inputSchema.type !== "object") {
|
|
186496
|
-
throw new Error(`Tool '${tool.name}' must expose an object input schema.`);
|
|
186497
|
-
}
|
|
186498
|
-
return betaTool({
|
|
186499
|
-
name: providerName,
|
|
186500
|
-
description: tool.description || `Run ${tool.name}`,
|
|
186501
|
-
inputSchema: tool.inputSchema,
|
|
186502
|
-
run: async (rawInput) => {
|
|
186503
|
-
const input2 = parseToolInput(rawInput);
|
|
186504
|
-
const recorded = createRecordedToolCall(toolCalls, tool.name, input2, tool.kind);
|
|
186505
|
-
try {
|
|
186506
|
-
const output2 = await tool.execute(input2);
|
|
186507
|
-
recorded.complete(output2);
|
|
186508
|
-
return providerToolOutputToText(output2);
|
|
186509
|
-
} catch (error2) {
|
|
186510
|
-
const output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
186511
|
-
recorded.complete(output2);
|
|
186512
|
-
if (error2 instanceof AgentToolFatalError) {
|
|
186513
|
-
throw error2;
|
|
186514
|
-
}
|
|
186515
|
-
return providerToolOutputToText(output2);
|
|
186516
|
-
}
|
|
186517
|
-
}
|
|
186518
|
-
});
|
|
186519
|
-
});
|
|
186520
|
-
const runner = client.beta.messages.toolRunner({
|
|
186842
|
+
const turns = [];
|
|
186843
|
+
if (request.tools.length === 0) {
|
|
186844
|
+
const call = {
|
|
186521
186845
|
model: request.modelId,
|
|
186522
186846
|
max_tokens: request.maxTokens,
|
|
186523
186847
|
system: request.systemPrompt,
|
|
186524
186848
|
messages,
|
|
186525
|
-
tools: runnableTools,
|
|
186526
|
-
tool_choice: { type: "auto", disable_parallel_tool_use: true },
|
|
186527
186849
|
output_config: outputConfig,
|
|
186528
|
-
thinking
|
|
186529
|
-
|
|
186530
|
-
|
|
186850
|
+
thinking
|
|
186851
|
+
};
|
|
186852
|
+
assertInputBudgetAllowsCall(
|
|
186853
|
+
this.provider,
|
|
186854
|
+
request.inputTokenBudget,
|
|
186855
|
+
estimateSerializedInputTokens(call),
|
|
186856
|
+
turns
|
|
186857
|
+
);
|
|
186858
|
+
const finalMessage = await client.messages.create(
|
|
186859
|
+
call,
|
|
186860
|
+
request.signal ? { signal: request.signal } : void 0
|
|
186861
|
+
);
|
|
186862
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
186863
|
+
inputTokens: finalMessage.usage.input_tokens + (finalMessage.usage.cache_creation_input_tokens ?? 0) + (finalMessage.usage.cache_read_input_tokens ?? 0),
|
|
186864
|
+
outputTokens: finalMessage.usage.output_tokens,
|
|
186865
|
+
...typeof finalMessage.usage.cache_read_input_tokens === "number" ? { cachedInputTokens: finalMessage.usage.cache_read_input_tokens } : {},
|
|
186866
|
+
...typeof finalMessage.usage.cache_creation_input_tokens === "number" ? { cacheWriteInputTokens: finalMessage.usage.cache_creation_input_tokens } : {}
|
|
186531
186867
|
});
|
|
186532
|
-
|
|
186533
|
-
|
|
186534
|
-
|
|
186535
|
-
|
|
186536
|
-
|
|
186868
|
+
return this.completeResponse(request, finalMessage, toolCalls, turns);
|
|
186869
|
+
}
|
|
186870
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
186871
|
+
const betaMessages = messages;
|
|
186872
|
+
const toolsByProviderName = new Map(
|
|
186873
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared.tool])
|
|
186874
|
+
);
|
|
186875
|
+
const tools = preparedTools.map(({ tool, providerName }) => {
|
|
186876
|
+
if (tool.inputSchema.type !== "object") {
|
|
186877
|
+
throw new Error(`Tool '${tool.name}' must expose an object input schema.`);
|
|
186537
186878
|
}
|
|
186538
|
-
|
|
186539
|
-
|
|
186540
|
-
|
|
186879
|
+
return {
|
|
186880
|
+
name: providerName,
|
|
186881
|
+
description: tool.description || `Run ${tool.name}`,
|
|
186882
|
+
input_schema: tool.inputSchema
|
|
186883
|
+
};
|
|
186884
|
+
});
|
|
186885
|
+
const toolHistory = new AgentToolResultHistory();
|
|
186886
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
186887
|
+
const call = {
|
|
186541
186888
|
model: request.modelId,
|
|
186542
186889
|
max_tokens: request.maxTokens,
|
|
186543
186890
|
system: request.systemPrompt,
|
|
186544
|
-
messages,
|
|
186891
|
+
messages: betaMessages,
|
|
186892
|
+
tools,
|
|
186893
|
+
tool_choice: { type: "auto", disable_parallel_tool_use: true },
|
|
186545
186894
|
output_config: outputConfig,
|
|
186546
186895
|
thinking
|
|
186896
|
+
};
|
|
186897
|
+
assertInputBudgetAllowsCall(
|
|
186898
|
+
this.provider,
|
|
186899
|
+
request.inputTokenBudget,
|
|
186900
|
+
estimateSerializedInputTokens(call),
|
|
186901
|
+
turns
|
|
186902
|
+
);
|
|
186903
|
+
const response = await client.beta.messages.create(
|
|
186904
|
+
call,
|
|
186905
|
+
request.signal ? { signal: request.signal } : void 0
|
|
186906
|
+
);
|
|
186907
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
186908
|
+
inputTokens: response.usage.input_tokens + (response.usage.cache_creation_input_tokens ?? 0) + (response.usage.cache_read_input_tokens ?? 0),
|
|
186909
|
+
outputTokens: response.usage.output_tokens,
|
|
186910
|
+
...typeof response.usage.cache_read_input_tokens === "number" ? { cachedInputTokens: response.usage.cache_read_input_tokens } : {},
|
|
186911
|
+
...typeof response.usage.cache_creation_input_tokens === "number" ? { cacheWriteInputTokens: response.usage.cache_creation_input_tokens } : {}
|
|
186912
|
+
});
|
|
186913
|
+
const calls = response.content.filter((block) => block.type === "tool_use");
|
|
186914
|
+
if (calls.length === 0) {
|
|
186915
|
+
return this.completeResponse(request, response, toolCalls, turns);
|
|
186916
|
+
}
|
|
186917
|
+
if (turn >= request.maxTurns) {
|
|
186918
|
+
throw new AgentTurnLimitError(
|
|
186919
|
+
this.provider,
|
|
186920
|
+
request.maxTurns,
|
|
186921
|
+
toolCalls.length,
|
|
186922
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186923
|
+
sumAgentTurnUsage(turns)
|
|
186924
|
+
);
|
|
186925
|
+
}
|
|
186926
|
+
betaMessages.push({
|
|
186927
|
+
role: "assistant",
|
|
186928
|
+
content: response.content
|
|
186547
186929
|
});
|
|
186548
|
-
|
|
186549
|
-
|
|
186930
|
+
const resultBlocks = [];
|
|
186931
|
+
for (const callBlock of calls) {
|
|
186932
|
+
const tool = toolsByProviderName.get(callBlock.name);
|
|
186933
|
+
if (!tool) {
|
|
186934
|
+
throw new Error(`Anthropic requested unknown tool '${callBlock.name}'.`);
|
|
186935
|
+
}
|
|
186936
|
+
const input2 = parseToolInput(callBlock.input);
|
|
186937
|
+
const recorded = createRecordedToolCall(toolCalls, tool.name, input2, tool.kind);
|
|
186938
|
+
let preparedOutput;
|
|
186939
|
+
try {
|
|
186940
|
+
const output2 = await tool.execute(input2);
|
|
186941
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
186942
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
186943
|
+
} catch (error2) {
|
|
186944
|
+
const output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
186945
|
+
recorded.complete(output2);
|
|
186946
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
186947
|
+
throw error2;
|
|
186948
|
+
}
|
|
186949
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
186950
|
+
}
|
|
186951
|
+
const resultBlock = {
|
|
186952
|
+
type: "tool_result",
|
|
186953
|
+
tool_use_id: callBlock.id,
|
|
186954
|
+
content: preparedOutput.immediateText
|
|
186955
|
+
};
|
|
186956
|
+
resultBlocks.push(resultBlock);
|
|
186957
|
+
toolHistory.retain(() => {
|
|
186958
|
+
resultBlock.content = preparedOutput.historyPlaceholder;
|
|
186959
|
+
});
|
|
186960
|
+
}
|
|
186961
|
+
betaMessages.push({ role: "user", content: resultBlocks });
|
|
186550
186962
|
}
|
|
186963
|
+
throw new AgentTurnLimitError(
|
|
186964
|
+
this.provider,
|
|
186965
|
+
request.maxTurns,
|
|
186966
|
+
toolCalls.length,
|
|
186967
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186968
|
+
sumAgentTurnUsage(turns)
|
|
186969
|
+
);
|
|
186970
|
+
}
|
|
186971
|
+
completeResponse(request, finalMessage, toolCalls, turns) {
|
|
186551
186972
|
const text = getVisibleText(finalMessage, Boolean(request.outputSchema));
|
|
186552
186973
|
if (finalMessage.stop_reason === "refusal") {
|
|
186553
186974
|
throw new AgentProviderRefusalError(`Anthropic model refused the request${text ? `: ${text}` : "."}`, text);
|
|
@@ -186560,7 +186981,8 @@ var AnthropicAgentAdapter = class {
|
|
|
186560
186981
|
this.provider,
|
|
186561
186982
|
request.maxTurns,
|
|
186562
186983
|
toolCalls.length,
|
|
186563
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
186984
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186985
|
+
sumAgentTurnUsage(turns)
|
|
186564
186986
|
);
|
|
186565
186987
|
}
|
|
186566
186988
|
if (finalMessage.stop_reason === "model_context_window_exceeded") {
|
|
@@ -186573,7 +186995,7 @@ var AnthropicAgentAdapter = class {
|
|
|
186573
186995
|
text,
|
|
186574
186996
|
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
186575
186997
|
toolCalls,
|
|
186576
|
-
usage:
|
|
186998
|
+
usage: sumAgentTurnUsage(turns),
|
|
186577
186999
|
resolvedModelId: finalMessage.model || request.modelId
|
|
186578
187000
|
};
|
|
186579
187001
|
}
|
|
@@ -186759,6 +187181,7 @@ var GoogleAgentAdapter = class {
|
|
|
186759
187181
|
const config2 = {
|
|
186760
187182
|
systemInstruction: request.systemPrompt,
|
|
186761
187183
|
maxOutputTokens: request.maxTokens,
|
|
187184
|
+
...request.signal ? { abortSignal: request.signal } : {},
|
|
186762
187185
|
...request.outputSchema ? {
|
|
186763
187186
|
responseMimeType: "application/json",
|
|
186764
187187
|
responseJsonSchema: request.outputSchema
|
|
@@ -186777,18 +187200,28 @@ var GoogleAgentAdapter = class {
|
|
|
186777
187200
|
automaticFunctionCalling: { disable: true }
|
|
186778
187201
|
} : {}
|
|
186779
187202
|
};
|
|
186780
|
-
let inputTokens = 0;
|
|
186781
|
-
let outputTokens = 0;
|
|
186782
187203
|
let resolvedModelId2 = request.modelId;
|
|
187204
|
+
const turns = [];
|
|
187205
|
+
const toolHistory = new AgentToolResultHistory();
|
|
186783
187206
|
for (let turn = 0; turn < request.maxTurns; turn++) {
|
|
187207
|
+
const estimatedInputTokens = estimateSerializedInputTokens({ contents, config: config2 });
|
|
187208
|
+
assertInputBudgetAllowsCall(
|
|
187209
|
+
this.provider,
|
|
187210
|
+
request.inputTokenBudget,
|
|
187211
|
+
estimatedInputTokens,
|
|
187212
|
+
turns
|
|
187213
|
+
);
|
|
186784
187214
|
const response = await client.models.generateContent({
|
|
186785
187215
|
model: request.modelId,
|
|
186786
187216
|
contents,
|
|
186787
187217
|
config: config2
|
|
186788
187218
|
});
|
|
186789
187219
|
const usage = response.usageMetadata;
|
|
186790
|
-
|
|
186791
|
-
|
|
187220
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
187221
|
+
inputTokens: usage ? (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0) : estimatedInputTokens,
|
|
187222
|
+
outputTokens: (usage?.candidatesTokenCount ?? 0) + (usage?.thoughtsTokenCount ?? 0),
|
|
187223
|
+
...usage?.cachedContentTokenCount !== void 0 ? { cachedInputTokens: usage.cachedContentTokenCount } : {}
|
|
187224
|
+
});
|
|
186792
187225
|
resolvedModelId2 = response.modelVersion || resolvedModelId2;
|
|
186793
187226
|
const requestedCalls = getFunctionCalls(response);
|
|
186794
187227
|
const text = getVisibleText2(
|
|
@@ -186803,7 +187236,7 @@ var GoogleAgentAdapter = class {
|
|
|
186803
187236
|
text,
|
|
186804
187237
|
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
186805
187238
|
toolCalls,
|
|
186806
|
-
usage:
|
|
187239
|
+
usage: sumAgentTurnUsage(turns),
|
|
186807
187240
|
resolvedModelId: resolvedModelId2
|
|
186808
187241
|
};
|
|
186809
187242
|
}
|
|
@@ -186817,7 +187250,8 @@ var GoogleAgentAdapter = class {
|
|
|
186817
187250
|
this.provider,
|
|
186818
187251
|
request.maxTurns,
|
|
186819
187252
|
toolCalls.length,
|
|
186820
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
187253
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
187254
|
+
sumAgentTurnUsage(turns)
|
|
186821
187255
|
);
|
|
186822
187256
|
}
|
|
186823
187257
|
const modelContent = getCandidate(response)?.content;
|
|
@@ -186838,8 +187272,12 @@ var GoogleAgentAdapter = class {
|
|
|
186838
187272
|
let responseBody;
|
|
186839
187273
|
try {
|
|
186840
187274
|
const output2 = await tool.execute(input2);
|
|
186841
|
-
|
|
186842
|
-
|
|
187275
|
+
const preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
187276
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
187277
|
+
responseBody = { output: preparedOutput.immediateOutput };
|
|
187278
|
+
toolHistory.retain(() => {
|
|
187279
|
+
responseBody.output = preparedOutput.historyPlaceholder;
|
|
187280
|
+
});
|
|
186843
187281
|
} catch (error2) {
|
|
186844
187282
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
186845
187283
|
const output2 = { error: message };
|
|
@@ -186864,7 +187302,8 @@ var GoogleAgentAdapter = class {
|
|
|
186864
187302
|
this.provider,
|
|
186865
187303
|
request.maxTurns,
|
|
186866
187304
|
toolCalls.length,
|
|
186867
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
187305
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
187306
|
+
sumAgentTurnUsage(turns)
|
|
186868
187307
|
);
|
|
186869
187308
|
}
|
|
186870
187309
|
};
|
|
@@ -187108,7 +187547,7 @@ var safeJSON2 = (text) => {
|
|
|
187108
187547
|
};
|
|
187109
187548
|
|
|
187110
187549
|
// node_modules/openai/internal/utils/sleep.mjs
|
|
187111
|
-
var
|
|
187550
|
+
var sleep3 = (ms) => new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
187112
187551
|
|
|
187113
187552
|
// node_modules/openai/version.mjs
|
|
187114
187553
|
var VERSION4 = "6.49.0";
|
|
@@ -194427,7 +194866,7 @@ var Runs = class extends APIResource2 {
|
|
|
194427
194866
|
}
|
|
194428
194867
|
}
|
|
194429
194868
|
}
|
|
194430
|
-
await
|
|
194869
|
+
await sleep3(sleepInterval);
|
|
194431
194870
|
break;
|
|
194432
194871
|
//We return the run in any terminal state.
|
|
194433
194872
|
case "requires_action":
|
|
@@ -195036,7 +195475,7 @@ var Files4 = class extends APIResource2 {
|
|
|
195036
195475
|
const start = Date.now();
|
|
195037
195476
|
let file2 = await this.retrieve(id);
|
|
195038
195477
|
while (!file2.status || !TERMINAL_STATES.has(file2.status)) {
|
|
195039
|
-
await
|
|
195478
|
+
await sleep3(pollInterval);
|
|
195040
195479
|
file2 = await this.retrieve(id);
|
|
195041
195480
|
if (Date.now() - start > maxWait) {
|
|
195042
195481
|
throw new APIConnectionTimeoutError3({
|
|
@@ -196732,7 +197171,7 @@ var FileBatches = class extends APIResource2 {
|
|
|
196732
197171
|
}
|
|
196733
197172
|
}
|
|
196734
197173
|
}
|
|
196735
|
-
await
|
|
197174
|
+
await sleep3(sleepInterval);
|
|
196736
197175
|
break;
|
|
196737
197176
|
case "failed":
|
|
196738
197177
|
case "cancelled":
|
|
@@ -196872,7 +197311,7 @@ var Files5 = class extends APIResource2 {
|
|
|
196872
197311
|
}
|
|
196873
197312
|
}
|
|
196874
197313
|
}
|
|
196875
|
-
await
|
|
197314
|
+
await sleep3(sleepInterval);
|
|
196876
197315
|
break;
|
|
196877
197316
|
case "failed":
|
|
196878
197317
|
case "completed":
|
|
@@ -197648,7 +198087,7 @@ var OpenAI = class {
|
|
|
197648
198087
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
197649
198088
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
197650
198089
|
}
|
|
197651
|
-
await
|
|
198090
|
+
await sleep3(timeoutMillis);
|
|
197652
198091
|
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
197653
198092
|
}
|
|
197654
198093
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -197816,6 +198255,93 @@ function isUndiciDispatcherVersionMismatchError(error2) {
|
|
|
197816
198255
|
return false;
|
|
197817
198256
|
}
|
|
197818
198257
|
|
|
198258
|
+
// node_modules/openai/lib/responses/ResponseInputItems.mjs
|
|
198259
|
+
function toResponseInputItems(items) {
|
|
198260
|
+
const inputItems = [];
|
|
198261
|
+
for (const item of items) {
|
|
198262
|
+
const inputItem = toResponseInputItem(item);
|
|
198263
|
+
if (inputItem) {
|
|
198264
|
+
inputItems.push(inputItem);
|
|
198265
|
+
}
|
|
198266
|
+
}
|
|
198267
|
+
return inputItems;
|
|
198268
|
+
}
|
|
198269
|
+
function toResponseInputItem(item) {
|
|
198270
|
+
switch (item.type) {
|
|
198271
|
+
case "additional_tools": {
|
|
198272
|
+
if (item.role !== "developer") {
|
|
198273
|
+
return null;
|
|
198274
|
+
}
|
|
198275
|
+
return stripCreatedBy(item);
|
|
198276
|
+
}
|
|
198277
|
+
case "shell_call_output": {
|
|
198278
|
+
const output2 = item.output.map((chunk) => stripCreatedBy(chunk));
|
|
198279
|
+
return {
|
|
198280
|
+
...stripCreatedBy(item),
|
|
198281
|
+
output: output2
|
|
198282
|
+
};
|
|
198283
|
+
}
|
|
198284
|
+
case "computer_call_output": {
|
|
198285
|
+
const { created_by: _createdBy, ...withoutCreatedBy } = item;
|
|
198286
|
+
if (withoutCreatedBy.status === "failed") {
|
|
198287
|
+
return null;
|
|
198288
|
+
}
|
|
198289
|
+
return withoutCreatedBy;
|
|
198290
|
+
}
|
|
198291
|
+
case "custom_tool_call_output": {
|
|
198292
|
+
if ("status" in item && item.status !== "completed") {
|
|
198293
|
+
return null;
|
|
198294
|
+
}
|
|
198295
|
+
const { created_by: _createdBy, status: _status, ...inputItem } = item;
|
|
198296
|
+
return inputItem;
|
|
198297
|
+
}
|
|
198298
|
+
case "apply_patch_call":
|
|
198299
|
+
case "apply_patch_call_output":
|
|
198300
|
+
case "code_interpreter_call":
|
|
198301
|
+
case "compaction":
|
|
198302
|
+
case "compaction_trigger":
|
|
198303
|
+
case "computer_call":
|
|
198304
|
+
case "custom_tool_call":
|
|
198305
|
+
case "file_search_call":
|
|
198306
|
+
case "function_call":
|
|
198307
|
+
case "function_call_output":
|
|
198308
|
+
case "image_generation_call":
|
|
198309
|
+
case "item_reference":
|
|
198310
|
+
case "local_shell_call":
|
|
198311
|
+
case "local_shell_call_output":
|
|
198312
|
+
case "mcp_approval_request":
|
|
198313
|
+
case "mcp_approval_response":
|
|
198314
|
+
case "mcp_call":
|
|
198315
|
+
case "mcp_list_tools":
|
|
198316
|
+
case "message":
|
|
198317
|
+
case "program":
|
|
198318
|
+
case "program_output":
|
|
198319
|
+
case "reasoning":
|
|
198320
|
+
case "shell_call":
|
|
198321
|
+
case "tool_search_call":
|
|
198322
|
+
case "tool_search_output":
|
|
198323
|
+
case "web_search_call":
|
|
198324
|
+
case null:
|
|
198325
|
+
case void 0: {
|
|
198326
|
+
return stripCreatedBy(item);
|
|
198327
|
+
}
|
|
198328
|
+
default: {
|
|
198329
|
+
return assertNever5(item);
|
|
198330
|
+
}
|
|
198331
|
+
}
|
|
198332
|
+
}
|
|
198333
|
+
function stripCreatedBy(item) {
|
|
198334
|
+
if (!("created_by" in item)) {
|
|
198335
|
+
return item;
|
|
198336
|
+
}
|
|
198337
|
+
const { created_by: _createdBy, ...rest } = item;
|
|
198338
|
+
return rest;
|
|
198339
|
+
}
|
|
198340
|
+
function assertNever5(value) {
|
|
198341
|
+
const type = value.type;
|
|
198342
|
+
throw new TypeError(`Unsupported response item type: ${String(type)}`);
|
|
198343
|
+
}
|
|
198344
|
+
|
|
197819
198345
|
// src/agents/providers/openaiAdapter.ts
|
|
197820
198346
|
function parseToolArguments(raw) {
|
|
197821
198347
|
const parsed = JSON.parse(raw);
|
|
@@ -197825,7 +198351,251 @@ function parseToolArguments(raw) {
|
|
|
197825
198351
|
return parsed;
|
|
197826
198352
|
}
|
|
197827
198353
|
var OpenAIAgentAdapter = class {
|
|
197828
|
-
|
|
198354
|
+
provider = "openai";
|
|
198355
|
+
createClient(request) {
|
|
198356
|
+
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "OPENAI_API_KEY");
|
|
198357
|
+
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "OPENAI_BASE_URL");
|
|
198358
|
+
try {
|
|
198359
|
+
return new OpenAI({
|
|
198360
|
+
...apiKey ? { apiKey } : {},
|
|
198361
|
+
...baseURL ? { baseURL } : {}
|
|
198362
|
+
});
|
|
198363
|
+
} catch (error2) {
|
|
198364
|
+
if (error2 instanceof Error && error2.message.includes("Missing credentials")) {
|
|
198365
|
+
throw new Error(
|
|
198366
|
+
"OpenAI authentication failed. Add an apiKey directive to the model block, for example: apiKey {{$env.OPENAI_API_KEY}}.",
|
|
198367
|
+
{ cause: error2 }
|
|
198368
|
+
);
|
|
198369
|
+
}
|
|
198370
|
+
throw error2;
|
|
198371
|
+
}
|
|
198372
|
+
}
|
|
198373
|
+
async run(request) {
|
|
198374
|
+
if (request.provider !== this.provider) {
|
|
198375
|
+
throw new Error(`The openai provider adapter cannot run a ${request.provider} request.`);
|
|
198376
|
+
}
|
|
198377
|
+
try {
|
|
198378
|
+
return await this.runRequest(request);
|
|
198379
|
+
} catch (error2) {
|
|
198380
|
+
if (error2 instanceof AgentProviderRefusalError) {
|
|
198381
|
+
throw error2;
|
|
198382
|
+
}
|
|
198383
|
+
if (error2 instanceof OpenAI.APIError) {
|
|
198384
|
+
if (isAgentProviderMaxTokensRejection(error2)) {
|
|
198385
|
+
throw new AgentProviderMaxTokensError(
|
|
198386
|
+
this.provider,
|
|
198387
|
+
request.maxTokens,
|
|
198388
|
+
error2.message,
|
|
198389
|
+
error2
|
|
198390
|
+
);
|
|
198391
|
+
}
|
|
198392
|
+
const status = error2.status ? ` (HTTP ${error2.status})` : "";
|
|
198393
|
+
const requestId = error2.requestID ? ` [request ${error2.requestID}]` : "";
|
|
198394
|
+
throw new Error(`OpenAI API request failed${status}: ${error2.message}${requestId}`, {
|
|
198395
|
+
cause: error2
|
|
198396
|
+
});
|
|
198397
|
+
}
|
|
198398
|
+
throw error2;
|
|
198399
|
+
}
|
|
198400
|
+
}
|
|
198401
|
+
async runRequest(request) {
|
|
198402
|
+
const client = this.createClient(request);
|
|
198403
|
+
const toolCalls = [];
|
|
198404
|
+
const input2 = [
|
|
198405
|
+
...(request.conversation ?? []).map((message) => ({
|
|
198406
|
+
type: "message",
|
|
198407
|
+
role: message.role,
|
|
198408
|
+
content: message.content
|
|
198409
|
+
})),
|
|
198410
|
+
{
|
|
198411
|
+
type: "message",
|
|
198412
|
+
role: "user",
|
|
198413
|
+
content: agentInputToText(request.input)
|
|
198414
|
+
}
|
|
198415
|
+
];
|
|
198416
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
198417
|
+
const tools = preparedTools.map(({ tool, providerName }) => ({
|
|
198418
|
+
type: "function",
|
|
198419
|
+
name: providerName,
|
|
198420
|
+
description: tool.description || `Run ${tool.name}`,
|
|
198421
|
+
parameters: tool.inputSchema,
|
|
198422
|
+
strict: false
|
|
198423
|
+
}));
|
|
198424
|
+
const toolsByProviderName = new Map(
|
|
198425
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared])
|
|
198426
|
+
);
|
|
198427
|
+
const text = request.outputSchema ? {
|
|
198428
|
+
format: {
|
|
198429
|
+
type: "json_schema",
|
|
198430
|
+
name: toProviderSchemaName(request.outputSchemaName),
|
|
198431
|
+
schema: request.outputSchema,
|
|
198432
|
+
strict: true
|
|
198433
|
+
}
|
|
198434
|
+
} : void 0;
|
|
198435
|
+
let resolvedModelId2 = request.modelId;
|
|
198436
|
+
const turns = [];
|
|
198437
|
+
const toolHistory = new AgentToolResultHistory();
|
|
198438
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
198439
|
+
const estimatedInputTokens = estimateSerializedInputTokens({
|
|
198440
|
+
instructions: request.systemPrompt,
|
|
198441
|
+
input: input2,
|
|
198442
|
+
tools,
|
|
198443
|
+
text
|
|
198444
|
+
});
|
|
198445
|
+
assertInputBudgetAllowsCall(
|
|
198446
|
+
this.provider,
|
|
198447
|
+
request.inputTokenBudget,
|
|
198448
|
+
estimatedInputTokens,
|
|
198449
|
+
turns
|
|
198450
|
+
);
|
|
198451
|
+
const response = await client.responses.create({
|
|
198452
|
+
model: request.modelId,
|
|
198453
|
+
instructions: request.systemPrompt,
|
|
198454
|
+
input: input2,
|
|
198455
|
+
max_output_tokens: request.maxTokens,
|
|
198456
|
+
store: false,
|
|
198457
|
+
parallel_tool_calls: false,
|
|
198458
|
+
...request.reasoningEffort ? { reasoning: { effort: request.reasoningEffort } } : {},
|
|
198459
|
+
...tools.length > 0 ? {
|
|
198460
|
+
tools,
|
|
198461
|
+
tool_choice: "auto",
|
|
198462
|
+
include: ["reasoning.encrypted_content"]
|
|
198463
|
+
} : {},
|
|
198464
|
+
...text ? { text } : {}
|
|
198465
|
+
}, request.signal ? { signal: request.signal } : void 0);
|
|
198466
|
+
resolvedModelId2 = response.model || request.modelId;
|
|
198467
|
+
const turnInputTokens = response.usage?.input_tokens ?? estimatedInputTokens;
|
|
198468
|
+
const turnOutputTokens = response.usage?.output_tokens ?? 0;
|
|
198469
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
198470
|
+
inputTokens: turnInputTokens,
|
|
198471
|
+
outputTokens: turnOutputTokens,
|
|
198472
|
+
...response.usage?.input_tokens_details?.cached_tokens !== void 0 ? { cachedInputTokens: response.usage.input_tokens_details.cached_tokens } : {},
|
|
198473
|
+
...response.usage?.input_tokens_details?.cache_write_tokens !== void 0 ? { cacheWriteInputTokens: response.usage.input_tokens_details.cache_write_tokens } : {}
|
|
198474
|
+
});
|
|
198475
|
+
const refusal = response.output.filter((item) => item.type === "message").flatMap((message) => message.content).find((content) => content.type === "refusal");
|
|
198476
|
+
if (refusal?.type === "refusal") {
|
|
198477
|
+
throw new AgentProviderRefusalError(
|
|
198478
|
+
`OpenAI model refused the request: ${refusal.refusal}`,
|
|
198479
|
+
response.output_text || refusal.refusal
|
|
198480
|
+
);
|
|
198481
|
+
}
|
|
198482
|
+
if (response.error) {
|
|
198483
|
+
throw new Error(`OpenAI response failed: ${response.error.message}`);
|
|
198484
|
+
}
|
|
198485
|
+
const calls = response.output.filter((item) => item.type === "function_call");
|
|
198486
|
+
if (calls.length === 0) {
|
|
198487
|
+
this.assertCompleted(response, request);
|
|
198488
|
+
const responseText = response.output_text || "";
|
|
198489
|
+
return {
|
|
198490
|
+
text: responseText,
|
|
198491
|
+
parsed: tryParseStructuredAgentOutput(responseText, Boolean(request.outputSchema)),
|
|
198492
|
+
toolCalls,
|
|
198493
|
+
usage: sumAgentTurnUsage(turns),
|
|
198494
|
+
resolvedModelId: resolvedModelId2
|
|
198495
|
+
};
|
|
198496
|
+
}
|
|
198497
|
+
if (turn >= request.maxTurns) {
|
|
198498
|
+
throw new AgentTurnLimitError(
|
|
198499
|
+
this.provider,
|
|
198500
|
+
request.maxTurns,
|
|
198501
|
+
toolCalls.length,
|
|
198502
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198503
|
+
sumAgentTurnUsage(turns)
|
|
198504
|
+
);
|
|
198505
|
+
}
|
|
198506
|
+
input2.push(...toResponseInputItems(response.output));
|
|
198507
|
+
for (const call of calls) {
|
|
198508
|
+
const prepared = toolsByProviderName.get(call.name);
|
|
198509
|
+
if (!prepared) {
|
|
198510
|
+
throw new Error(`OpenAI requested unknown agent tool '${call.name}'.`);
|
|
198511
|
+
}
|
|
198512
|
+
let toolInput = {};
|
|
198513
|
+
let output2;
|
|
198514
|
+
try {
|
|
198515
|
+
toolInput = parseToolArguments(call.arguments);
|
|
198516
|
+
const recorded = createRecordedToolCall(
|
|
198517
|
+
toolCalls,
|
|
198518
|
+
prepared.tool.name,
|
|
198519
|
+
toolInput,
|
|
198520
|
+
prepared.tool.kind
|
|
198521
|
+
);
|
|
198522
|
+
try {
|
|
198523
|
+
output2 = await prepared.tool.execute(toolInput);
|
|
198524
|
+
recorded.complete(normalizePreparedAgentToolResult(output2).recordedOutput);
|
|
198525
|
+
} catch (error2) {
|
|
198526
|
+
output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
198527
|
+
recorded.complete(output2);
|
|
198528
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198529
|
+
throw error2;
|
|
198530
|
+
}
|
|
198531
|
+
}
|
|
198532
|
+
} catch (error2) {
|
|
198533
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198534
|
+
throw error2;
|
|
198535
|
+
}
|
|
198536
|
+
output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
198537
|
+
const recorded = createRecordedToolCall(
|
|
198538
|
+
toolCalls,
|
|
198539
|
+
prepared.tool.name,
|
|
198540
|
+
toolInput,
|
|
198541
|
+
prepared.tool.kind
|
|
198542
|
+
);
|
|
198543
|
+
recorded.complete(output2);
|
|
198544
|
+
}
|
|
198545
|
+
const preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
198546
|
+
const outputItem = {
|
|
198547
|
+
type: "function_call_output",
|
|
198548
|
+
call_id: call.call_id,
|
|
198549
|
+
output: preparedOutput.immediateText
|
|
198550
|
+
};
|
|
198551
|
+
input2.push(outputItem);
|
|
198552
|
+
toolHistory.retain(() => {
|
|
198553
|
+
outputItem.output = preparedOutput.historyPlaceholder;
|
|
198554
|
+
});
|
|
198555
|
+
}
|
|
198556
|
+
}
|
|
198557
|
+
throw new AgentTurnLimitError(
|
|
198558
|
+
this.provider,
|
|
198559
|
+
request.maxTurns,
|
|
198560
|
+
toolCalls.length,
|
|
198561
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198562
|
+
sumAgentTurnUsage(turns)
|
|
198563
|
+
);
|
|
198564
|
+
}
|
|
198565
|
+
assertCompleted(response, request) {
|
|
198566
|
+
if (response.status === "incomplete") {
|
|
198567
|
+
if (response.incomplete_details?.reason === "content_filter") {
|
|
198568
|
+
throw new AgentProviderRefusalError(
|
|
198569
|
+
"OpenAI blocked the response through its content filter.",
|
|
198570
|
+
response.output_text || ""
|
|
198571
|
+
);
|
|
198572
|
+
}
|
|
198573
|
+
if (response.incomplete_details?.reason === "max_output_tokens") {
|
|
198574
|
+
throw new Error(
|
|
198575
|
+
`OpenAI model reached its ${request.maxTokens}-token completion limit before finishing.`
|
|
198576
|
+
);
|
|
198577
|
+
}
|
|
198578
|
+
throw new Error("OpenAI returned an incomplete response.");
|
|
198579
|
+
}
|
|
198580
|
+
if (response.status === "failed" || response.status === "cancelled") {
|
|
198581
|
+
throw new Error(`OpenAI response ended with status '${response.status}'.`);
|
|
198582
|
+
}
|
|
198583
|
+
if (response.status === "in_progress" || response.status === "queued") {
|
|
198584
|
+
throw new Error(`OpenAI returned unexpected non-terminal status '${response.status}'.`);
|
|
198585
|
+
}
|
|
198586
|
+
}
|
|
198587
|
+
};
|
|
198588
|
+
|
|
198589
|
+
// src/agents/providers/openaiCompatibleAdapter.ts
|
|
198590
|
+
function parseToolArguments2(raw) {
|
|
198591
|
+
const parsed = JSON.parse(raw);
|
|
198592
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
198593
|
+
throw new Error("Tool input must be a JSON object.");
|
|
198594
|
+
}
|
|
198595
|
+
return parsed;
|
|
198596
|
+
}
|
|
198597
|
+
var OpenAICompatibleAgentAdapter = class {
|
|
198598
|
+
constructor(provider = "openai_compatible") {
|
|
197829
198599
|
this.provider = provider;
|
|
197830
198600
|
}
|
|
197831
198601
|
createClient(request) {
|
|
@@ -197839,17 +198609,19 @@ var OpenAIAgentAdapter = class {
|
|
|
197839
198609
|
const apiKey2 = request.credentials?.apiKey ?? getEnvironmentValue(request.environment, "LOCAL_API_KEY") ?? "norn-local";
|
|
197840
198610
|
return new OpenAI({ apiKey: apiKey2, baseURL: baseURL2 });
|
|
197841
198611
|
}
|
|
197842
|
-
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "
|
|
197843
|
-
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "
|
|
198612
|
+
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "OPENAI_COMPATIBLE_API_KEY") ?? "norn-openai-compatible";
|
|
198613
|
+
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "OPENAI_COMPATIBLE_BASE_URL");
|
|
198614
|
+
if (!baseURL) {
|
|
198615
|
+
throw new Error(
|
|
198616
|
+
"An OpenAI-compatible model needs an endpoint. Add a baseUrl directive to the model block, or set OPENAI_COMPATIBLE_BASE_URL in .nornenv or the process environment."
|
|
198617
|
+
);
|
|
198618
|
+
}
|
|
197844
198619
|
try {
|
|
197845
|
-
return new OpenAI({
|
|
197846
|
-
...apiKey ? { apiKey } : {},
|
|
197847
|
-
...baseURL ? { baseURL } : {}
|
|
197848
|
-
});
|
|
198620
|
+
return new OpenAI({ apiKey, baseURL });
|
|
197849
198621
|
} catch (error2) {
|
|
197850
198622
|
if (error2 instanceof Error && error2.message.includes("Missing credentials")) {
|
|
197851
198623
|
throw new Error(
|
|
197852
|
-
"OpenAI authentication failed. Add an apiKey directive to the model block
|
|
198624
|
+
"OpenAI-compatible authentication failed. Add an apiKey directive to the model block.",
|
|
197853
198625
|
{ cause: error2 }
|
|
197854
198626
|
);
|
|
197855
198627
|
}
|
|
@@ -197875,7 +198647,7 @@ var OpenAIAgentAdapter = class {
|
|
|
197875
198647
|
error2
|
|
197876
198648
|
);
|
|
197877
198649
|
}
|
|
197878
|
-
const providerLabel = this.provider === "local" ? "Local OpenAI-compatible" : "OpenAI";
|
|
198650
|
+
const providerLabel = this.provider === "local" ? "Local OpenAI-compatible" : "OpenAI-compatible";
|
|
197879
198651
|
const status = error2.status ? ` (HTTP ${error2.status})` : "";
|
|
197880
198652
|
const requestId = error2.requestID ? ` [request ${error2.requestID}]` : "";
|
|
197881
198653
|
throw new Error(`${providerLabel} API request failed${status}: ${error2.message}${requestId}`, {
|
|
@@ -197904,82 +198676,128 @@ var OpenAIAgentAdapter = class {
|
|
|
197904
198676
|
strict: true
|
|
197905
198677
|
}
|
|
197906
198678
|
} : void 0;
|
|
197907
|
-
const tokenLimit =
|
|
197908
|
-
let text = "";
|
|
198679
|
+
const tokenLimit = { max_tokens: request.maxTokens };
|
|
197909
198680
|
let resolvedModelId2 = request.modelId;
|
|
197910
|
-
|
|
197911
|
-
|
|
197912
|
-
|
|
197913
|
-
|
|
197914
|
-
|
|
197915
|
-
|
|
197916
|
-
|
|
197917
|
-
|
|
197918
|
-
|
|
197919
|
-
|
|
197920
|
-
|
|
198681
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
198682
|
+
const toolsByProviderName = new Map(
|
|
198683
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared.tool])
|
|
198684
|
+
);
|
|
198685
|
+
const tools = preparedTools.map(({ tool, providerName }) => ({
|
|
198686
|
+
type: "function",
|
|
198687
|
+
function: {
|
|
198688
|
+
name: providerName,
|
|
198689
|
+
description: tool.description || `Run ${tool.name}`,
|
|
198690
|
+
parameters: tool.inputSchema
|
|
198691
|
+
}
|
|
198692
|
+
}));
|
|
198693
|
+
const turns = [];
|
|
198694
|
+
const toolHistory = new AgentToolResultHistory();
|
|
198695
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
198696
|
+
const call = {
|
|
198697
|
+
model: request.modelId,
|
|
198698
|
+
messages,
|
|
198699
|
+
...tools.length > 0 ? {
|
|
198700
|
+
tools,
|
|
198701
|
+
tool_choice: "auto",
|
|
198702
|
+
parallel_tool_calls: false
|
|
198703
|
+
} : {},
|
|
198704
|
+
response_format: responseFormat,
|
|
198705
|
+
...tokenLimit
|
|
198706
|
+
};
|
|
198707
|
+
const estimatedInputTokens = estimateSerializedInputTokens(call);
|
|
198708
|
+
assertInputBudgetAllowsCall(
|
|
198709
|
+
this.provider,
|
|
198710
|
+
request.inputTokenBudget,
|
|
198711
|
+
estimatedInputTokens,
|
|
198712
|
+
turns
|
|
198713
|
+
);
|
|
198714
|
+
const completion = await client.chat.completions.create(
|
|
198715
|
+
call,
|
|
198716
|
+
request.signal ? { signal: request.signal } : void 0
|
|
198717
|
+
);
|
|
198718
|
+
const message = completion.choices[0]?.message;
|
|
198719
|
+
if (!message) {
|
|
198720
|
+
throw new Error("OpenAI returned no assistant message.");
|
|
198721
|
+
}
|
|
198722
|
+
resolvedModelId2 = completion.model || request.modelId;
|
|
198723
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
198724
|
+
inputTokens: completion.usage?.prompt_tokens ?? estimatedInputTokens,
|
|
198725
|
+
outputTokens: completion.usage?.completion_tokens ?? 0,
|
|
198726
|
+
...completion.usage?.prompt_tokens_details?.cached_tokens !== void 0 ? { cachedInputTokens: completion.usage.prompt_tokens_details.cached_tokens } : {}
|
|
198727
|
+
});
|
|
198728
|
+
const requestedCalls = message.tool_calls?.filter((call2) => call2.type === "function") ?? [];
|
|
198729
|
+
const text = message.content || "";
|
|
198730
|
+
if (requestedCalls.length === 0) {
|
|
198731
|
+
this.assertCompleted(message, completion.choices[0]?.finish_reason, text, request, toolCalls);
|
|
198732
|
+
return {
|
|
198733
|
+
text,
|
|
198734
|
+
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
198735
|
+
toolCalls,
|
|
198736
|
+
usage: sumAgentTurnUsage(turns),
|
|
198737
|
+
resolvedModelId: resolvedModelId2
|
|
198738
|
+
};
|
|
198739
|
+
}
|
|
198740
|
+
if (turn >= request.maxTurns) {
|
|
198741
|
+
throw new AgentTurnLimitError(
|
|
198742
|
+
this.provider,
|
|
198743
|
+
request.maxTurns,
|
|
198744
|
+
toolCalls.length,
|
|
198745
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198746
|
+
sumAgentTurnUsage(turns)
|
|
198747
|
+
);
|
|
198748
|
+
}
|
|
198749
|
+
messages.push(message);
|
|
198750
|
+
for (const callItem of requestedCalls) {
|
|
198751
|
+
const tool = toolsByProviderName.get(callItem.function.name);
|
|
198752
|
+
let input2 = {};
|
|
198753
|
+
let preparedOutput;
|
|
198754
|
+
if (!tool) {
|
|
198755
|
+
preparedOutput = normalizePreparedAgentToolResult({
|
|
198756
|
+
error: `Unknown tool '${callItem.function.name}'.`
|
|
198757
|
+
});
|
|
198758
|
+
} else {
|
|
198759
|
+
try {
|
|
198760
|
+
input2 = parseToolArguments2(callItem.function.arguments);
|
|
197921
198761
|
const recorded = createRecordedToolCall(toolCalls, tool.name, input2, tool.kind);
|
|
197922
198762
|
try {
|
|
197923
198763
|
const output2 = await tool.execute(input2);
|
|
197924
|
-
|
|
197925
|
-
|
|
198764
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
198765
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
197926
198766
|
} catch (error2) {
|
|
197927
198767
|
const output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
197928
198768
|
recorded.complete(output2);
|
|
197929
198769
|
if (error2 instanceof AgentToolFatalError) {
|
|
197930
198770
|
throw error2;
|
|
197931
198771
|
}
|
|
197932
|
-
|
|
198772
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
197933
198773
|
}
|
|
198774
|
+
} catch (error2) {
|
|
198775
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198776
|
+
throw error2;
|
|
198777
|
+
}
|
|
198778
|
+
preparedOutput = normalizePreparedAgentToolResult({
|
|
198779
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
198780
|
+
});
|
|
197934
198781
|
}
|
|
197935
198782
|
}
|
|
197936
|
-
|
|
197937
|
-
|
|
197938
|
-
|
|
197939
|
-
|
|
197940
|
-
|
|
197941
|
-
|
|
197942
|
-
|
|
197943
|
-
|
|
197944
|
-
|
|
197945
|
-
}, { maxChatCompletions: request.maxTurns });
|
|
197946
|
-
const [finalCompletion, usage] = await Promise.all([
|
|
197947
|
-
runner.finalChatCompletion(),
|
|
197948
|
-
runner.totalUsage()
|
|
197949
|
-
]);
|
|
197950
|
-
const finalChoice = finalCompletion.choices[0];
|
|
197951
|
-
if (!finalChoice) {
|
|
197952
|
-
throw new Error("OpenAI returned no completion choice.");
|
|
197953
|
-
}
|
|
197954
|
-
text = finalChoice.message.content || "";
|
|
197955
|
-
this.assertCompleted(finalChoice.message, finalChoice.finish_reason, text, request, toolCalls);
|
|
197956
|
-
resolvedModelId2 = finalCompletion.model || request.modelId;
|
|
197957
|
-
inputTokens = usage.prompt_tokens;
|
|
197958
|
-
outputTokens = usage.completion_tokens;
|
|
197959
|
-
} else {
|
|
197960
|
-
const completion = await client.chat.completions.create({
|
|
197961
|
-
model: request.modelId,
|
|
197962
|
-
messages,
|
|
197963
|
-
response_format: responseFormat,
|
|
197964
|
-
...tokenLimit
|
|
197965
|
-
});
|
|
197966
|
-
const message = completion.choices[0]?.message;
|
|
197967
|
-
if (!message) {
|
|
197968
|
-
throw new Error("OpenAI returned no assistant message.");
|
|
198783
|
+
const toolMessage = {
|
|
198784
|
+
role: "tool",
|
|
198785
|
+
tool_call_id: callItem.id,
|
|
198786
|
+
content: preparedOutput.immediateText
|
|
198787
|
+
};
|
|
198788
|
+
messages.push(toolMessage);
|
|
198789
|
+
toolHistory.retain(() => {
|
|
198790
|
+
toolMessage.content = preparedOutput.historyPlaceholder;
|
|
198791
|
+
});
|
|
197969
198792
|
}
|
|
197970
|
-
text = message.content || "";
|
|
197971
|
-
this.assertCompleted(message, completion.choices[0]?.finish_reason, text, request, toolCalls);
|
|
197972
|
-
resolvedModelId2 = completion.model || request.modelId;
|
|
197973
|
-
inputTokens = completion.usage?.prompt_tokens ?? 0;
|
|
197974
|
-
outputTokens = completion.usage?.completion_tokens ?? 0;
|
|
197975
198793
|
}
|
|
197976
|
-
|
|
197977
|
-
|
|
197978
|
-
|
|
197979
|
-
toolCalls,
|
|
197980
|
-
|
|
197981
|
-
|
|
197982
|
-
|
|
198794
|
+
throw new AgentTurnLimitError(
|
|
198795
|
+
this.provider,
|
|
198796
|
+
request.maxTurns,
|
|
198797
|
+
toolCalls.length,
|
|
198798
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198799
|
+
sumAgentTurnUsage(turns)
|
|
198800
|
+
);
|
|
197983
198801
|
}
|
|
197984
198802
|
assertCompleted(message, finishReason, rawText, request, toolCalls) {
|
|
197985
198803
|
if (message.refusal) {
|
|
@@ -198020,8 +198838,9 @@ var StaticAgentProviderRegistry = class {
|
|
|
198020
198838
|
};
|
|
198021
198839
|
function createDefaultAgentProviderRegistry() {
|
|
198022
198840
|
return new StaticAgentProviderRegistry([
|
|
198023
|
-
new OpenAIAgentAdapter(
|
|
198024
|
-
new
|
|
198841
|
+
new OpenAIAgentAdapter(),
|
|
198842
|
+
new OpenAICompatibleAgentAdapter("openai_compatible"),
|
|
198843
|
+
new OpenAICompatibleAgentAdapter("local"),
|
|
198025
198844
|
new AnthropicAgentAdapter(),
|
|
198026
198845
|
new GoogleAgentAdapter()
|
|
198027
198846
|
]);
|
|
@@ -198223,21 +199042,15 @@ function getContractDisplaySeverity(assertion) {
|
|
|
198223
199042
|
// src/knowledge/knowledgeTypes.ts
|
|
198224
199043
|
var KNOWLEDGE_TOKEN_ESTIMATOR_VERSION = "knowledge-token-estimate-v1";
|
|
198225
199044
|
|
|
198226
|
-
// src/agents/agentTypes.ts
|
|
198227
|
-
var DEFAULT_AGENT_MAX_TOKENS = 16e3;
|
|
198228
|
-
var DEFAULT_LOCAL_AGENT_MAX_TOKENS = 4096;
|
|
198229
|
-
var DEFAULT_AGENT_MAX_DEPTH = 5;
|
|
198230
|
-
var DEFAULT_AGENT_MAX_INVOCATIONS = 25;
|
|
198231
|
-
var DEFAULT_AGENT_MAX_TURNS = 100;
|
|
198232
|
-
var DEFAULT_AGENT_CONTRACT_RETRIES = 2;
|
|
198233
|
-
|
|
198234
199045
|
// src/agents/agentConfig.ts
|
|
198235
199046
|
function resolveAgentRuntimeLimits(startPath, provider, agent) {
|
|
198236
199047
|
const loadedConfig = startPath && findNearestConfigFile(startPath, NORN_CONFIG_FILENAME) ? loadNornConfig(startPath).config.agents : void 0;
|
|
198237
199048
|
const providerConfig = loadedConfig?.providers?.[provider];
|
|
198238
199049
|
const defaultMaxTokens = provider === "local" ? DEFAULT_LOCAL_AGENT_MAX_TOKENS : DEFAULT_AGENT_MAX_TOKENS;
|
|
199050
|
+
const maxInputTokens = agent.maxInputTokens ?? providerConfig?.max_input_tokens ?? loadedConfig?.max_input_tokens;
|
|
198239
199051
|
return {
|
|
198240
199052
|
maxTokens: agent.maxTokens ?? providerConfig?.max_tokens ?? loadedConfig?.max_tokens ?? defaultMaxTokens,
|
|
199053
|
+
...maxInputTokens !== void 0 ? { maxInputTokens } : {},
|
|
198241
199054
|
maxDepth: agent.maxDepth ?? providerConfig?.max_depth ?? loadedConfig?.max_depth ?? DEFAULT_AGENT_MAX_DEPTH,
|
|
198242
199055
|
maxInvocations: agent.maxInvocations ?? providerConfig?.max_invocations ?? loadedConfig?.max_invocations ?? DEFAULT_AGENT_MAX_INVOCATIONS,
|
|
198243
199056
|
maxTurns: agent.maxTurns ?? providerConfig?.max_turns ?? loadedConfig?.max_turns ?? DEFAULT_AGENT_MAX_TURNS,
|
|
@@ -198421,7 +199234,7 @@ function adaptAgentSchemaForGeneration(original, provider) {
|
|
|
198421
199234
|
if (provider === "anthropic" && containsRecursiveReference(original)) {
|
|
198422
199235
|
throw new AgentSchemaAdaptationError("Anthropic structured outputs do not support recursive JSON Schemas.");
|
|
198423
199236
|
}
|
|
198424
|
-
if ((provider === "openai" || provider === "local") && getMaximumObjectDepth(original) > 5) {
|
|
199237
|
+
if ((provider === "openai" || provider === "openai_compatible" || provider === "local") && getMaximumObjectDepth(original) > 5) {
|
|
198425
199238
|
throw new AgentSchemaAdaptationError("Norn limits OpenAI generation schemas to at most 5 nested object levels.");
|
|
198426
199239
|
}
|
|
198427
199240
|
const strippedKeywords = /* @__PURE__ */ new Set();
|
|
@@ -198477,7 +199290,7 @@ function adaptAgentSchemaForGeneration(original, provider) {
|
|
|
198477
199290
|
transformed.additionalProperties = false;
|
|
198478
199291
|
additionalPropertiesChanges++;
|
|
198479
199292
|
}
|
|
198480
|
-
if ((provider === "openai" || provider === "local") && properties) {
|
|
199293
|
+
if ((provider === "openai" || provider === "openai_compatible" || provider === "local") && properties) {
|
|
198481
199294
|
const authoredRequired = new Set(
|
|
198482
199295
|
Array.isArray(schemaValue.required) ? schemaValue.required.filter((entry) => typeof entry === "string") : []
|
|
198483
199296
|
);
|
|
@@ -198531,6 +199344,19 @@ var DEFAULT_TOOL_INPUT_SCHEMA = {
|
|
|
198531
199344
|
required: ["input"],
|
|
198532
199345
|
additionalProperties: false
|
|
198533
199346
|
};
|
|
199347
|
+
function mergeAgentUsage(left, right) {
|
|
199348
|
+
const leftTurns = left.turns ?? [];
|
|
199349
|
+
const rightTurns = right.turns ?? [];
|
|
199350
|
+
const turns = [...leftTurns, ...rightTurns].map((turn, index) => ({
|
|
199351
|
+
...turn,
|
|
199352
|
+
turn: index + 1
|
|
199353
|
+
}));
|
|
199354
|
+
return {
|
|
199355
|
+
inputTokens: left.inputTokens + right.inputTokens,
|
|
199356
|
+
outputTokens: left.outputTokens + right.outputTokens,
|
|
199357
|
+
...turns.length > 0 ? { turns } : {}
|
|
199358
|
+
};
|
|
199359
|
+
}
|
|
198534
199360
|
function emptyAgentResult(hasReturns = false) {
|
|
198535
199361
|
return {
|
|
198536
199362
|
...hasReturns ? { body: void 0 } : {},
|
|
@@ -198546,16 +199372,36 @@ function resolveAgentModelTarget(template, runtimeVariables) {
|
|
|
198546
199372
|
if (/\{\{[^}]+\}\}/.test(resolved)) {
|
|
198547
199373
|
throw new Error(`Could not resolve model target '${template}'.`);
|
|
198548
199374
|
}
|
|
198549
|
-
const match2 = resolved.match(/^(openai|anthropic|google|local)\/(.+)$/i);
|
|
199375
|
+
const match2 = resolved.match(/^(openai|openai_compatible|anthropic|google|local)\/(.+)$/i);
|
|
198550
199376
|
if (!match2 || !match2[2].trim()) {
|
|
198551
199377
|
throw new Error(
|
|
198552
|
-
`Invalid resolved model '${resolved}'. Expected openai/<model>, anthropic/<model>, google/<model>, or local/<model>.`
|
|
199378
|
+
`Invalid resolved model '${resolved}'. Expected openai/<model>, openai_compatible/<model>, anthropic/<model>, google/<model>, or local/<model>.`
|
|
198553
199379
|
);
|
|
198554
199380
|
}
|
|
198555
199381
|
const provider = match2[1].toLowerCase();
|
|
198556
199382
|
const modelId = match2[2].trim();
|
|
198557
199383
|
return { provider, modelId, displayName: `${provider}/${modelId}` };
|
|
198558
199384
|
}
|
|
199385
|
+
function resolveAgentReasoningEffort(model, provider, runtimeVariables) {
|
|
199386
|
+
if (model.reasoningTemplate === void 0) {
|
|
199387
|
+
return void 0;
|
|
199388
|
+
}
|
|
199389
|
+
const resolved = substituteVariables(model.reasoningTemplate, runtimeVariables).trim().toLowerCase();
|
|
199390
|
+
if (/\{\{[^}]+\}\}/.test(resolved)) {
|
|
199391
|
+
throw new Error(`Could not resolve reasoning for model '${model.alias}'.`);
|
|
199392
|
+
}
|
|
199393
|
+
if (provider !== "openai") {
|
|
199394
|
+
throw new Error(
|
|
199395
|
+
`Model '${model.alias}' can declare reasoning only with provider openai; the resolved provider is '${provider}'.`
|
|
199396
|
+
);
|
|
199397
|
+
}
|
|
199398
|
+
if (!AGENT_REASONING_EFFORTS.some((effort) => effort === resolved)) {
|
|
199399
|
+
throw new Error(
|
|
199400
|
+
`Invalid resolved reasoning effort '${resolved}' for model '${model.alias}'. Expected one of: ${AGENT_REASONING_EFFORTS.join(", ")}.`
|
|
199401
|
+
);
|
|
199402
|
+
}
|
|
199403
|
+
return resolved;
|
|
199404
|
+
}
|
|
198559
199405
|
function resolveAgentModelCredentials(model, runtimeVariables) {
|
|
198560
199406
|
const resolveField = (template, directive) => {
|
|
198561
199407
|
if (template === void 0) {
|
|
@@ -198660,8 +199506,11 @@ var AgentInvocationRunner = class {
|
|
|
198660
199506
|
definitions = /* @__PURE__ */ new Map();
|
|
198661
199507
|
conversations = /* @__PURE__ */ new Map();
|
|
198662
199508
|
invocationBudget;
|
|
199509
|
+
inputTokenBudget;
|
|
198663
199510
|
invocationCount = 0;
|
|
199511
|
+
toolResultStore = new AgentToolResultStore();
|
|
198664
199512
|
async run(agent, input2) {
|
|
199513
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
198665
199514
|
const rootInvocationIndex2 = this.options.rootInvocationIndex ?? 1;
|
|
198666
199515
|
if (!Number.isSafeInteger(rootInvocationIndex2) || rootInvocationIndex2 < 1) {
|
|
198667
199516
|
throw new Error(`Agent root invocation index must be a positive integer, received '${rootInvocationIndex2}'.`);
|
|
@@ -198750,6 +199599,7 @@ var AgentInvocationRunner = class {
|
|
|
198750
199599
|
provider: request.provider,
|
|
198751
199600
|
modelId: request.modelId,
|
|
198752
199601
|
displayModel: request.displayModel,
|
|
199602
|
+
...request.reasoningEffort ? { reasoningEffort: request.reasoningEffort } : {},
|
|
198753
199603
|
systemPrompt: request.systemPrompt,
|
|
198754
199604
|
input: cloneSnapshotValue(request.input, null),
|
|
198755
199605
|
conversation: (request.conversation ?? []).map((message) => ({ ...message })),
|
|
@@ -198757,6 +199607,7 @@ var AgentInvocationRunner = class {
|
|
|
198757
199607
|
...request.outputSchema ? { outputSchema: cloneSnapshotValue(request.outputSchema, {}) } : {},
|
|
198758
199608
|
...request.outputSchemaName ? { outputSchemaName: request.outputSchemaName } : {},
|
|
198759
199609
|
maxTokens: request.maxTokens,
|
|
199610
|
+
...request.inputTokenBudget ? { maxInputTokens: request.inputTokenBudget.maxInputTokens } : {},
|
|
198760
199611
|
maxTurns: request.maxTurns,
|
|
198761
199612
|
...mcpServerGrants?.length ? { mcpServerGrants: mcpServerGrants.map((grant) => ({
|
|
198762
199613
|
alias: grant.alias,
|
|
@@ -198775,7 +199626,25 @@ var AgentInvocationRunner = class {
|
|
|
198775
199626
|
routingRule: knowledge.routing.rule,
|
|
198776
199627
|
selectedDomainIds: knowledge.assembly.selectedDomainIds,
|
|
198777
199628
|
estimatedTokens: knowledge.assembly.estimatedTokens,
|
|
198778
|
-
estimatorVersion: KNOWLEDGE_TOKEN_ESTIMATOR_VERSION
|
|
199629
|
+
estimatorVersion: KNOWLEDGE_TOKEN_ESTIMATOR_VERSION,
|
|
199630
|
+
domains: knowledge.projection.domains.map((domain2) => {
|
|
199631
|
+
const selected = knowledge.assembly.selectedDomainIds.includes(domain2.encodedId);
|
|
199632
|
+
return {
|
|
199633
|
+
domainId: domain2.encodedId,
|
|
199634
|
+
declarationAlias: domain2.declarationAlias,
|
|
199635
|
+
sourcePath: domain2.sourcePath,
|
|
199636
|
+
domainPath: domain2.ref.domainPath,
|
|
199637
|
+
disposition: selected ? domain2.estimatedTokens <= knowledge.config.domainInlineTokenLimit ? "inline" : "index" : "manifest",
|
|
199638
|
+
estimatedTokens: domain2.estimatedTokens,
|
|
199639
|
+
topicCount: domain2.topics.length,
|
|
199640
|
+
topics: domain2.topics.map((topic) => ({
|
|
199641
|
+
topicHash: topic.topicHash,
|
|
199642
|
+
...topic.headingText ? { heading: topic.headingText } : {},
|
|
199643
|
+
estimatedTokens: topic.estimatedTokens,
|
|
199644
|
+
itemPaths: [...new Set(topic.occurrences.map((occurrence) => occurrence.ref.itemPath))].sort()
|
|
199645
|
+
}))
|
|
199646
|
+
};
|
|
199647
|
+
})
|
|
198779
199648
|
} } : {}
|
|
198780
199649
|
};
|
|
198781
199650
|
}
|
|
@@ -198796,7 +199665,7 @@ var AgentInvocationRunner = class {
|
|
|
198796
199665
|
try {
|
|
198797
199666
|
const output2 = await execute(input2, context);
|
|
198798
199667
|
record2.output = cloneSnapshotValue(output2, null);
|
|
198799
|
-
return output2;
|
|
199668
|
+
return definition.kind === "context" ? output2 : this.toolResultStore.prepare(definition.name, output2);
|
|
198800
199669
|
} catch (error2) {
|
|
198801
199670
|
record2.output = getToolErrorOutput(error2);
|
|
198802
199671
|
throw error2;
|
|
@@ -198839,6 +199708,7 @@ var AgentInvocationRunner = class {
|
|
|
198839
199708
|
return hop;
|
|
198840
199709
|
}
|
|
198841
199710
|
async invokeAgent(agent, input2, depth, parentInvocationId, ancestors, conversation, hopPath) {
|
|
199711
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
198842
199712
|
const startedAt = Date.now();
|
|
198843
199713
|
const invocationId = this.nextInvocationId();
|
|
198844
199714
|
const hop = {
|
|
@@ -198869,6 +199739,7 @@ var AgentInvocationRunner = class {
|
|
|
198869
199739
|
let resolvedModel;
|
|
198870
199740
|
let fatalToolError;
|
|
198871
199741
|
let preparedKnowledge;
|
|
199742
|
+
let accumulatedProviderUsage = { inputTokens: 0, outputTokens: 0 };
|
|
198872
199743
|
try {
|
|
198873
199744
|
const requestOverride = await this.options.resolveRequestOverride?.(hopPath);
|
|
198874
199745
|
const authoredModel = requestOverride?.provider && requestOverride.modelId ? void 0 : resolveAgentModelTarget(
|
|
@@ -198883,6 +199754,7 @@ var AgentInvocationRunner = class {
|
|
|
198883
199754
|
modelId,
|
|
198884
199755
|
displayName: requestOverride?.displayModel ?? `${provider}/${modelId}`
|
|
198885
199756
|
};
|
|
199757
|
+
const reasoningEffort = requestOverride ? requestOverride.reasoningEffort : resolveAgentReasoningEffort(agent.model, provider, this.options.runtimeVariables);
|
|
198886
199758
|
hop.output.model = resolvedModel.displayName;
|
|
198887
199759
|
const configuredLimits = resolveAgentRuntimeLimits(
|
|
198888
199760
|
this.options.startPath,
|
|
@@ -198891,7 +199763,8 @@ var AgentInvocationRunner = class {
|
|
|
198891
199763
|
);
|
|
198892
199764
|
const limits = {
|
|
198893
199765
|
...configuredLimits,
|
|
198894
|
-
...requestOverride?.maxTokens !== void 0 ? { maxTokens: requestOverride.maxTokens } : {}
|
|
199766
|
+
...requestOverride?.maxTokens !== void 0 ? { maxTokens: requestOverride.maxTokens } : {},
|
|
199767
|
+
...requestOverride?.maxInputTokens !== void 0 ? { maxInputTokens: requestOverride.maxInputTokens } : {}
|
|
198895
199768
|
};
|
|
198896
199769
|
if (!this.invocationBudget) {
|
|
198897
199770
|
this.invocationBudget = {
|
|
@@ -198899,6 +199772,12 @@ var AgentInvocationRunner = class {
|
|
|
198899
199772
|
maxInvocations: limits.maxInvocations
|
|
198900
199773
|
};
|
|
198901
199774
|
}
|
|
199775
|
+
if (depth === 0 && limits.maxInputTokens !== void 0) {
|
|
199776
|
+
this.inputTokenBudget = {
|
|
199777
|
+
maxInputTokens: limits.maxInputTokens,
|
|
199778
|
+
usedInputTokens: 0
|
|
199779
|
+
};
|
|
199780
|
+
}
|
|
198902
199781
|
this.invocationCount++;
|
|
198903
199782
|
this.addDefinition(agent, resolvedModel);
|
|
198904
199783
|
const authoredSystemPrompt = requestOverride?.systemPrompt ?? substituteVariables(
|
|
@@ -198954,6 +199833,7 @@ var AgentInvocationRunner = class {
|
|
|
198954
199833
|
provider: resolvedModel.provider,
|
|
198955
199834
|
modelId: resolvedModel.modelId,
|
|
198956
199835
|
displayModel: resolvedModel.displayName,
|
|
199836
|
+
...reasoningEffort ? { reasoningEffort } : {},
|
|
198957
199837
|
systemPrompt,
|
|
198958
199838
|
input: input2,
|
|
198959
199839
|
conversation,
|
|
@@ -198961,9 +199841,11 @@ var AgentInvocationRunner = class {
|
|
|
198961
199841
|
outputSchema,
|
|
198962
199842
|
outputSchemaName,
|
|
198963
199843
|
maxTokens: limits.maxTokens,
|
|
199844
|
+
...this.inputTokenBudget ? { inputTokenBudget: this.inputTokenBudget } : {},
|
|
198964
199845
|
maxTurns: limits.maxTurns,
|
|
198965
199846
|
environment: this.options.environment,
|
|
198966
|
-
...credentials ? { credentials } : {}
|
|
199847
|
+
...credentials ? { credentials } : {},
|
|
199848
|
+
...this.options.signal ? { signal: this.options.signal } : {}
|
|
198967
199849
|
};
|
|
198968
199850
|
hop.request = this.createRequestSnapshot(
|
|
198969
199851
|
providerRequest,
|
|
@@ -198985,6 +199867,10 @@ var AgentInvocationRunner = class {
|
|
|
198985
199867
|
...providerRequest,
|
|
198986
199868
|
conversation: correctionConversation
|
|
198987
199869
|
});
|
|
199870
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199871
|
+
accumulatedProviderUsage,
|
|
199872
|
+
providerResponse.usage
|
|
199873
|
+
);
|
|
198988
199874
|
hop.providerCompleted = true;
|
|
198989
199875
|
if (fatalToolError) {
|
|
198990
199876
|
throw fatalToolError;
|
|
@@ -198995,7 +199881,7 @@ var AgentInvocationRunner = class {
|
|
|
198995
199881
|
text: providerResponse.text,
|
|
198996
199882
|
toolCalls,
|
|
198997
199883
|
model: `${resolvedModel.provider}/${providerResponse.resolvedModelId}`,
|
|
198998
|
-
usage:
|
|
199884
|
+
usage: accumulatedProviderUsage,
|
|
198999
199885
|
ms: Date.now() - startedAt
|
|
199000
199886
|
};
|
|
199001
199887
|
const returnValue = providerResponse.parsed !== void 0 ? providerResponse.parsed : providerResponse.text;
|
|
@@ -199033,10 +199919,32 @@ var AgentInvocationRunner = class {
|
|
|
199033
199919
|
}
|
|
199034
199920
|
hop.success = true;
|
|
199035
199921
|
} catch (error2) {
|
|
199922
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
199036
199923
|
const reportedError = fatalToolError ?? error2;
|
|
199037
199924
|
if (reportedError instanceof AgentProviderMaxTokensError) {
|
|
199038
199925
|
hop.error = formatAgentProviderMaxTokensError(agent.name, reportedError);
|
|
199926
|
+
} else if (reportedError instanceof AgentInputTokenLimitError) {
|
|
199927
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199928
|
+
accumulatedProviderUsage,
|
|
199929
|
+
reportedError.usage
|
|
199930
|
+
);
|
|
199931
|
+
hop.output.usage = accumulatedProviderUsage;
|
|
199932
|
+
hop.inputTokenLimit = {
|
|
199933
|
+
maxInputTokens: reportedError.maxInputTokens,
|
|
199934
|
+
usedInputTokens: reportedError.usedInputTokens,
|
|
199935
|
+
...reportedError.estimatedNextInputTokens !== void 0 ? { estimatedNextInputTokens: reportedError.estimatedNextInputTokens } : {},
|
|
199936
|
+
sourcePath: agent.sourcePath,
|
|
199937
|
+
lineNumber: agent.lineNumber
|
|
199938
|
+
};
|
|
199939
|
+
hop.error = formatAgentInputTokenLimitError(agent.name, hop.inputTokenLimit);
|
|
199039
199940
|
} else if (reportedError instanceof AgentTurnLimitError) {
|
|
199941
|
+
if (reportedError.usage) {
|
|
199942
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199943
|
+
accumulatedProviderUsage,
|
|
199944
|
+
reportedError.usage
|
|
199945
|
+
);
|
|
199946
|
+
hop.output.usage = accumulatedProviderUsage;
|
|
199947
|
+
}
|
|
199040
199948
|
hop.turnLimit = {
|
|
199041
199949
|
maxTurns: reportedError.maxTurns,
|
|
199042
199950
|
toolCallCount: reportedError.toolCallCount,
|
|
@@ -199097,10 +200005,12 @@ var AgentInvocationRunner = class {
|
|
|
199097
200005
|
overrideKeys.add(key);
|
|
199098
200006
|
}
|
|
199099
200007
|
let callerLimitBreaches = 0;
|
|
199100
|
-
if (agent.callableAgents.some((reference) => reference.name.toLowerCase()
|
|
199101
|
-
throw new Error(
|
|
200008
|
+
if (agent.callableAgents.some((reference) => ["load_knowledge", "norn_read_tool_result"].includes(reference.name.toLowerCase()))) {
|
|
200009
|
+
throw new Error(
|
|
200010
|
+
"Agent names 'load_knowledge' and 'norn_read_tool_result' are reserved by Norn."
|
|
200011
|
+
);
|
|
199102
200012
|
}
|
|
199103
|
-
if (knowledge) {
|
|
200013
|
+
if (knowledge?.hasLoadableKnowledge) {
|
|
199104
200014
|
const offeredOverride = requestToolsOverride?.find((tool) => tool.kind === "knowledge");
|
|
199105
200015
|
providerTools.push(this.createRecordedProviderTool(parentHop, {
|
|
199106
200016
|
name: "load_knowledge",
|
|
@@ -199403,6 +200313,25 @@ var AgentInvocationRunner = class {
|
|
|
199403
200313
|
return Object.prototype.hasOwnProperty.call(child.output, "body") ? child.output.body : child.output.text;
|
|
199404
200314
|
}));
|
|
199405
200315
|
}
|
|
200316
|
+
const offeredContext = requestToolsOverride?.find((tool) => tool.kind === "context");
|
|
200317
|
+
if (!requestToolsOverride && providerTools.length > 0 || offeredContext) {
|
|
200318
|
+
providerTools.push(this.createRecordedProviderTool(parentHop, {
|
|
200319
|
+
name: "norn_read_tool_result",
|
|
200320
|
+
providerName: offeredContext?.providerName ?? "norn_read_tool_result",
|
|
200321
|
+
kind: "context",
|
|
200322
|
+
description: offeredContext?.description ?? "Read or search a bounded portion of a tool result that Norn offloaded from active context.",
|
|
200323
|
+
inputSchema: offeredContext?.inputSchema ?? {
|
|
200324
|
+
type: "object",
|
|
200325
|
+
properties: {
|
|
200326
|
+
handle: { type: "string" },
|
|
200327
|
+
offset: { type: "integer", minimum: 0 },
|
|
200328
|
+
query: { type: "string" }
|
|
200329
|
+
},
|
|
200330
|
+
required: ["handle"],
|
|
200331
|
+
additionalProperties: false
|
|
200332
|
+
}
|
|
200333
|
+
}, async (input2) => this.toolResultStore.read(input2)));
|
|
200334
|
+
}
|
|
199406
200335
|
if (requestToolsOverride) {
|
|
199407
200336
|
const currentKeys = new Set(providerTools.map(
|
|
199408
200337
|
(tool) => `${tool.kind ?? ""}\0${tool.name.toLowerCase()}`
|
|
@@ -200542,6 +201471,18 @@ function normalizeHopForDisk(hop, projectRoot) {
|
|
|
200542
201471
|
...extended.request !== void 0 ? {
|
|
200543
201472
|
request: relativizeTopLevelSourcePaths(extended.request, projectRoot, true)
|
|
200544
201473
|
} : {},
|
|
201474
|
+
...hop.turnLimit ? {
|
|
201475
|
+
turnLimit: {
|
|
201476
|
+
...hop.turnLimit,
|
|
201477
|
+
sourcePath: path26.isAbsolute(hop.turnLimit.sourcePath) ? projectRelativePath(projectRoot, hop.turnLimit.sourcePath) : hop.turnLimit.sourcePath
|
|
201478
|
+
}
|
|
201479
|
+
} : {},
|
|
201480
|
+
...hop.inputTokenLimit ? {
|
|
201481
|
+
inputTokenLimit: {
|
|
201482
|
+
...hop.inputTokenLimit,
|
|
201483
|
+
sourcePath: path26.isAbsolute(hop.inputTokenLimit.sourcePath) ? projectRelativePath(projectRoot, hop.inputTokenLimit.sourcePath) : hop.inputTokenLimit.sourcePath
|
|
201484
|
+
}
|
|
201485
|
+
} : {},
|
|
200545
201486
|
children: hop.children.map((child) => normalizeHopForDisk(child, projectRoot))
|
|
200546
201487
|
};
|
|
200547
201488
|
return normalized;
|
|
@@ -200709,28 +201650,35 @@ function isSafeProjectRelativePath(value) {
|
|
|
200709
201650
|
return isRelativePath(value) && !normalizePathSeparators(value).split("/").includes("..");
|
|
200710
201651
|
}
|
|
200711
201652
|
function isAgentToolCall(value) {
|
|
200712
|
-
return isObjectRecord2(value) && typeof value.name === "string" && (value.kind === void 0 || value.kind === "mcp" || value.kind === "agent" || value.kind === "knowledge") && isObjectRecord2(value.input) && isFiniteNonNegativeNumber(value.ms) && (value.childInvocationId === void 0 || typeof value.childInvocationId === "string");
|
|
201653
|
+
return isObjectRecord2(value) && typeof value.name === "string" && (value.kind === void 0 || value.kind === "mcp" || value.kind === "agent" || value.kind === "knowledge" || value.kind === "context") && isObjectRecord2(value.input) && isFiniteNonNegativeNumber(value.ms) && (value.childInvocationId === void 0 || typeof value.childInvocationId === "string");
|
|
201654
|
+
}
|
|
201655
|
+
function isAgentKnowledgeTopicSnapshot(value) {
|
|
201656
|
+
return isObjectRecord2(value) && typeof value.topicHash === "string" && (value.heading === void 0 || typeof value.heading === "string") && isFiniteNonNegativeNumber(value.estimatedTokens) && isStringArray(value.itemPaths);
|
|
201657
|
+
}
|
|
201658
|
+
function isAgentKnowledgeDomainSnapshot(value) {
|
|
201659
|
+
return isObjectRecord2(value) && typeof value.domainId === "string" && typeof value.declarationAlias === "string" && typeof value.sourcePath === "string" && value.sourcePath.length > 0 && typeof value.domainPath === "string" && ["inline", "index", "manifest"].includes(String(value.disposition)) && isFiniteNonNegativeNumber(value.estimatedTokens) && Number.isSafeInteger(value.topicCount) && value.topicCount >= 0 && Array.isArray(value.topics) && value.topics.every(isAgentKnowledgeTopicSnapshot);
|
|
200713
201660
|
}
|
|
200714
201661
|
function isAgentRequestSnapshot(value) {
|
|
200715
|
-
if (!isObjectRecord2(value) || !["openai", "anthropic", "google", "local"].includes(String(value.provider)) || typeof value.modelId !== "string" || typeof value.displayModel !== "string" || typeof value.systemPrompt !== "string" || !Array.isArray(value.conversation) || !Array.isArray(value.tools) || !Number.isSafeInteger(value.maxTokens) || value.maxTokens <= 0 || !/^[0-9a-f]{64}$/.test(String(value.promptHash))) {
|
|
201662
|
+
if (!isObjectRecord2(value) || !["openai", "openai_compatible", "anthropic", "google", "local"].includes(String(value.provider)) || typeof value.modelId !== "string" || typeof value.displayModel !== "string" || typeof value.systemPrompt !== "string" || !Array.isArray(value.conversation) || !Array.isArray(value.tools) || !Number.isSafeInteger(value.maxTokens) || value.maxTokens <= 0 || !/^[0-9a-f]{64}$/.test(String(value.promptHash))) {
|
|
200716
201663
|
return false;
|
|
200717
201664
|
}
|
|
200718
201665
|
const validConversation = value.conversation.every(
|
|
200719
201666
|
(message) => isObjectRecord2(message) && (message.role === "user" || message.role === "assistant") && typeof message.content === "string"
|
|
200720
201667
|
);
|
|
200721
201668
|
const validTools = value.tools.every(
|
|
200722
|
-
(tool) => isObjectRecord2(tool) && typeof tool.name === "string" && typeof tool.providerName === "string" && (tool.kind === void 0 || tool.kind === "mcp" || tool.kind === "agent" || tool.kind === "knowledge") && (tool.description === void 0 || typeof tool.description === "string") && isObjectRecord2(tool.inputSchema)
|
|
201669
|
+
(tool) => isObjectRecord2(tool) && typeof tool.name === "string" && typeof tool.providerName === "string" && (tool.kind === void 0 || tool.kind === "mcp" || tool.kind === "agent" || tool.kind === "knowledge" || tool.kind === "context") && (tool.description === void 0 || typeof tool.description === "string") && isObjectRecord2(tool.inputSchema)
|
|
200723
201670
|
);
|
|
200724
201671
|
const validKnowledge = value.knowledge === void 0 || isObjectRecord2(value.knowledge) && typeof value.knowledge.runId === "string" && typeof value.knowledge.snapshotId === "string" && isStringArray(value.knowledge.declarationIds) && ["exact_entity", "lexical_unique", "lexical_ambiguous", "no_match"].includes(
|
|
200725
201672
|
String(value.knowledge.routingRule)
|
|
200726
|
-
) && isStringArray(value.knowledge.selectedDomainIds) && isFiniteNonNegativeNumber(value.knowledge.estimatedTokens) && typeof value.knowledge.estimatorVersion === "string";
|
|
200727
|
-
return validConversation && validTools && validKnowledge && (value.outputSchema === void 0 || isObjectRecord2(value.outputSchema)) && (value.outputSchemaName === void 0 || typeof value.outputSchemaName === "string") && (value.sourcePath === void 0 || isSafeProjectRelativePath(value.sourcePath)) && isSafeProjectRelativePath(value.agentSourcePath) && Number.isSafeInteger(value.agentLineNumber) && value.agentLineNumber >= 0 && (value.sequenceName === void 0 || typeof value.sequenceName === "string") && (value.runLineNumber === void 0 || Number.isSafeInteger(value.runLineNumber));
|
|
201673
|
+
) && isStringArray(value.knowledge.selectedDomainIds) && isFiniteNonNegativeNumber(value.knowledge.estimatedTokens) && typeof value.knowledge.estimatorVersion === "string" && (value.knowledge.domains === void 0 || Array.isArray(value.knowledge.domains) && value.knowledge.domains.every(isAgentKnowledgeDomainSnapshot));
|
|
201674
|
+
return validConversation && validTools && validKnowledge && (value.reasoningEffort === void 0 || ["none", "low", "medium", "high", "xhigh", "max"].includes(String(value.reasoningEffort))) && (value.outputSchema === void 0 || isObjectRecord2(value.outputSchema)) && (value.outputSchemaName === void 0 || typeof value.outputSchemaName === "string") && (value.maxInputTokens === void 0 || Number.isSafeInteger(value.maxInputTokens) && value.maxInputTokens > 0) && (value.maxTurns === void 0 || Number.isSafeInteger(value.maxTurns) && value.maxTurns > 0) && (value.sourcePath === void 0 || isSafeProjectRelativePath(value.sourcePath)) && isSafeProjectRelativePath(value.agentSourcePath) && Number.isSafeInteger(value.agentLineNumber) && value.agentLineNumber >= 0 && (value.sequenceName === void 0 || typeof value.sequenceName === "string") && (value.runLineNumber === void 0 || Number.isSafeInteger(value.runLineNumber));
|
|
200728
201675
|
}
|
|
200729
201676
|
function isAgentResult(value) {
|
|
200730
201677
|
if (!isObjectRecord2(value) || typeof value.text !== "string" || typeof value.model !== "string" || !Array.isArray(value.toolCalls) || !value.toolCalls.every(isAgentToolCall) || !isFiniteNonNegativeNumber(value.ms) || !isObjectRecord2(value.usage)) {
|
|
200731
201678
|
return false;
|
|
200732
201679
|
}
|
|
200733
|
-
|
|
201680
|
+
const validTurns = value.usage.turns === void 0 || Array.isArray(value.usage.turns) && value.usage.turns.every((turn, index) => isObjectRecord2(turn) && turn.turn === index + 1 && isFiniteNonNegativeNumber(turn.inputTokens) && isFiniteNonNegativeNumber(turn.outputTokens) && (turn.cachedInputTokens === void 0 || isFiniteNonNegativeNumber(turn.cachedInputTokens)) && (turn.cacheWriteInputTokens === void 0 || isFiniteNonNegativeNumber(turn.cacheWriteInputTokens)));
|
|
201681
|
+
return isFiniteNonNegativeNumber(value.usage.inputTokens) && isFiniteNonNegativeNumber(value.usage.outputTokens) && validTurns;
|
|
200734
201682
|
}
|
|
200735
201683
|
function isAgentContract(value) {
|
|
200736
201684
|
return isObjectRecord2(value) && (value.kind === "accepts" || value.kind === "returns") && typeof value.path === "string" && isObjectRecord2(value.assertion);
|
|
@@ -200742,7 +201690,7 @@ function isAgentHop(value) {
|
|
|
200742
201690
|
if (!isObjectRecord2(value) || typeof value.invocationId !== "string" || typeof value.agent !== "string" || typeof value.success !== "boolean" || !Number.isSafeInteger(value.depth) || value.depth < 0 || typeof value.cycle !== "boolean" || !isAgentResult(value.output) || !Array.isArray(value.children) || !Array.isArray(value.retries) || !isStringArray(value.warnings)) {
|
|
200743
201691
|
return false;
|
|
200744
201692
|
}
|
|
200745
|
-
return (value.parentInvocationId === void 0 || typeof value.parentInvocationId === "string") && (value.hopPath === void 0 || typeof value.hopPath === "string") && (value.request === void 0 || isAgentRequestSnapshot(value.request)) && (value.providerAttempted === void 0 || typeof value.providerAttempted === "boolean") && (value.providerCompleted === void 0 || typeof value.providerCompleted === "boolean") && (value.contractExhausted === void 0 || typeof value.contractExhausted === "boolean") && (value.error === void 0 || typeof value.error === "string") && (value.accepts === void 0 || isAgentContract(value.accepts)) && (value.returns === void 0 || isAgentContract(value.returns)) && value.retries.every(isAgentRetry) && value.children.every(isAgentHop);
|
|
201693
|
+
return (value.parentInvocationId === void 0 || typeof value.parentInvocationId === "string") && (value.hopPath === void 0 || typeof value.hopPath === "string") && (value.request === void 0 || isAgentRequestSnapshot(value.request)) && (value.providerAttempted === void 0 || typeof value.providerAttempted === "boolean") && (value.providerCompleted === void 0 || typeof value.providerCompleted === "boolean") && (value.contractExhausted === void 0 || typeof value.contractExhausted === "boolean") && (value.inputTokenLimit === void 0 || isObjectRecord2(value.inputTokenLimit) && Number.isSafeInteger(value.inputTokenLimit.maxInputTokens) && value.inputTokenLimit.maxInputTokens > 0 && isFiniteNonNegativeNumber(value.inputTokenLimit.usedInputTokens) && (value.inputTokenLimit.estimatedNextInputTokens === void 0 || isFiniteNonNegativeNumber(value.inputTokenLimit.estimatedNextInputTokens)) && isSafeProjectRelativePath(value.inputTokenLimit.sourcePath) && Number.isSafeInteger(value.inputTokenLimit.lineNumber) && value.inputTokenLimit.lineNumber >= 0) && (value.error === void 0 || typeof value.error === "string") && (value.accepts === void 0 || isAgentContract(value.accepts)) && (value.returns === void 0 || isAgentContract(value.returns)) && value.retries.every(isAgentRetry) && value.children.every(isAgentHop);
|
|
200746
201694
|
}
|
|
200747
201695
|
function isAgentTrace(value) {
|
|
200748
201696
|
if (!isObjectRecord2(value) || !Array.isArray(value.agents) || !Array.isArray(value.hops)) {
|
|
@@ -202959,6 +203907,14 @@ function readKnowledgeSnapshot(startPath, snapshotId, options = {}) {
|
|
|
202959
203907
|
function encodeKnowledgeId(parts) {
|
|
202960
203908
|
return Buffer.from(canonicalJson(parts), "utf8").toString("base64url");
|
|
202961
203909
|
}
|
|
203910
|
+
function decodeKnowledgeId(value) {
|
|
203911
|
+
try {
|
|
203912
|
+
const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
203913
|
+
return Array.isArray(parsed) ? parsed : void 0;
|
|
203914
|
+
} catch {
|
|
203915
|
+
return void 0;
|
|
203916
|
+
}
|
|
203917
|
+
}
|
|
202962
203918
|
|
|
202963
203919
|
// src/knowledge/knowledgeAssembly.ts
|
|
202964
203920
|
function estimateKnowledgeTokens(rendered) {
|
|
@@ -202998,10 +203954,10 @@ function renderKnowledgeTopicIndex(domain2) {
|
|
|
202998
203954
|
}))
|
|
202999
203955
|
};
|
|
203000
203956
|
}
|
|
203001
|
-
function renderKnowledgeDomainBodies(domain2) {
|
|
203957
|
+
function renderKnowledgeDomainBodies(domain2, topics = domain2.topics) {
|
|
203002
203958
|
return {
|
|
203003
203959
|
domainId: domain2.encodedId,
|
|
203004
|
-
topics:
|
|
203960
|
+
topics: topics.map((topic) => ({
|
|
203005
203961
|
topicHash: topic.topicHash,
|
|
203006
203962
|
heading: topic.headingText,
|
|
203007
203963
|
body: topic.body,
|
|
@@ -203363,20 +204319,30 @@ var KnowledgeRunCoordinator = class {
|
|
|
203363
204319
|
const routing = routeKnowledge(this.projectRoot, input2, projection, config2, agent.name);
|
|
203364
204320
|
const assembly = assembleKnowledgePrompt(authoredSystemPrompt, projection, routing, config2, agent.name);
|
|
203365
204321
|
const loadEvents = [];
|
|
204322
|
+
const loadedTopicHashes = new Set(assembly.initiallyLoadedTopics.map((topic) => topic.topicHash));
|
|
204323
|
+
const loadedTopicIndexes = new Set(projection.domains.filter((domain2) => assembly.selectedDomainIds.includes(domain2.encodedId) && domain2.estimatedTokens > config2.domainInlineTokenLimit).map((domain2) => domain2.encodedId));
|
|
204324
|
+
const loadableDomains = projection.domains.filter(
|
|
204325
|
+
(domain2) => domain2.topics.some((topic) => !loadedTopicHashes.has(topic.topicHash)) || domain2.estimatedTokens > config2.domainInlineTokenLimit && !loadedTopicIndexes.has(domain2.encodedId)
|
|
204326
|
+
);
|
|
204327
|
+
const loadableTopicHashes = [...new Set(loadableDomains.flatMap((domain2) => domain2.topics).filter((topic) => !loadedTopicHashes.has(topic.topicHash)).map((topic) => topic.topicHash))];
|
|
203366
204328
|
let usedTokens = 0;
|
|
203367
204329
|
const tool = {
|
|
203368
204330
|
name: "load_knowledge",
|
|
203369
204331
|
providerName: "norn_load_knowledge",
|
|
203370
204332
|
kind: "knowledge",
|
|
203371
|
-
description: "Load
|
|
204333
|
+
description: "Load only knowledge that remains available. Never request a domain listed in norn_routed_knowledge.inlineDomainIds; those bodies were already supplied. For an oversized routed domain whose topic index was supplied, request a specific topicHash rather than the domain index again.",
|
|
203372
204334
|
inputSchema: { type: "object", properties: {
|
|
203373
|
-
domainId: { type: "string" },
|
|
203374
|
-
topicHash: { type: "string" },
|
|
204335
|
+
domainId: { type: "string", enum: loadableDomains.map((domain2) => domain2.encodedId) },
|
|
204336
|
+
topicHash: { type: "string", enum: loadableTopicHashes },
|
|
203375
204337
|
occurrenceId: { type: "string" }
|
|
203376
204338
|
}, required: ["domainId"], additionalProperties: false },
|
|
203377
204339
|
execute: async (raw) => {
|
|
203378
204340
|
const request = raw;
|
|
203379
204341
|
const before = usedTokens;
|
|
204342
|
+
const alreadyLoaded = () => ({
|
|
204343
|
+
alreadyLoaded: true,
|
|
204344
|
+
message: "This knowledge has already been loaded."
|
|
204345
|
+
});
|
|
203380
204346
|
const refuse = (code, message) => {
|
|
203381
204347
|
loadEvents.push({
|
|
203382
204348
|
order: loadEvents.length + 1,
|
|
@@ -203402,6 +204368,8 @@ var KnowledgeRunCoordinator = class {
|
|
|
203402
204368
|
return refuse("unknown_or_ungranted_domain", "The requested domain ID is unknown or not granted.");
|
|
203403
204369
|
}
|
|
203404
204370
|
let value;
|
|
204371
|
+
let newlyLoadedTopicHashes = [];
|
|
204372
|
+
let loadedTopicIndex = false;
|
|
203405
204373
|
if (request.topicHash) {
|
|
203406
204374
|
const topic = domain2.topics.find((item) => item.topicHash === request.topicHash);
|
|
203407
204375
|
if (!topic) {
|
|
@@ -203423,6 +204391,9 @@ var KnowledgeRunCoordinator = class {
|
|
|
203423
204391
|
return refuse("unknown_or_ungranted_occurrence", "The occurrence ID is not exposed by this domain.");
|
|
203424
204392
|
}
|
|
203425
204393
|
}
|
|
204394
|
+
if (loadedTopicHashes.has(topic.topicHash)) {
|
|
204395
|
+
return alreadyLoaded();
|
|
204396
|
+
}
|
|
203426
204397
|
value = { domainId: domain2.encodedId, topic: {
|
|
203427
204398
|
topicHash: topic.topicHash,
|
|
203428
204399
|
heading: topic.headingText,
|
|
@@ -203434,8 +204405,22 @@ var KnowledgeRunCoordinator = class {
|
|
|
203434
204405
|
useWhen: item.metadata.useWhen?.value
|
|
203435
204406
|
}))
|
|
203436
204407
|
} };
|
|
204408
|
+
newlyLoadedTopicHashes = [topic.topicHash];
|
|
203437
204409
|
} else {
|
|
203438
|
-
|
|
204410
|
+
if (domain2.estimatedTokens <= config2.domainInlineTokenLimit) {
|
|
204411
|
+
const unloadedTopics = domain2.topics.filter((topic) => !loadedTopicHashes.has(topic.topicHash));
|
|
204412
|
+
if (!unloadedTopics.length) {
|
|
204413
|
+
return alreadyLoaded();
|
|
204414
|
+
}
|
|
204415
|
+
value = renderKnowledgeDomainBodies(domain2, unloadedTopics);
|
|
204416
|
+
newlyLoadedTopicHashes = unloadedTopics.map((topic) => topic.topicHash);
|
|
204417
|
+
} else {
|
|
204418
|
+
if (loadedTopicIndexes.has(domain2.encodedId)) {
|
|
204419
|
+
return alreadyLoaded();
|
|
204420
|
+
}
|
|
204421
|
+
value = renderKnowledgeTopicIndex(domain2);
|
|
204422
|
+
loadedTopicIndex = true;
|
|
204423
|
+
}
|
|
203439
204424
|
}
|
|
203440
204425
|
const output2 = escapedCanonicalKnowledgeJson(value);
|
|
203441
204426
|
const estimatedTokens = estimateKnowledgeTokens(output2);
|
|
@@ -203443,11 +204428,18 @@ var KnowledgeRunCoordinator = class {
|
|
|
203443
204428
|
return refuse("tool_token_limit", `The request would exceed knowledge.toolTokenLimit=${config2.toolTokenLimit}.`);
|
|
203444
204429
|
}
|
|
203445
204430
|
usedTokens += estimatedTokens;
|
|
204431
|
+
for (const topicHash of newlyLoadedTopicHashes) {
|
|
204432
|
+
loadedTopicHashes.add(topicHash);
|
|
204433
|
+
}
|
|
204434
|
+
if (loadedTopicIndex) {
|
|
204435
|
+
loadedTopicIndexes.add(domain2.encodedId);
|
|
204436
|
+
}
|
|
203446
204437
|
loadEvents.push({
|
|
203447
204438
|
order: loadEvents.length + 1,
|
|
203448
204439
|
request,
|
|
203449
204440
|
accepted: true,
|
|
203450
204441
|
estimatedTokens,
|
|
204442
|
+
loadedTopicHashes: newlyLoadedTopicHashes,
|
|
203451
204443
|
budgetBefore: before,
|
|
203452
204444
|
budgetAfter: usedTokens
|
|
203453
204445
|
});
|
|
@@ -203455,7 +204447,17 @@ var KnowledgeRunCoordinator = class {
|
|
|
203455
204447
|
}
|
|
203456
204448
|
};
|
|
203457
204449
|
void invocationId;
|
|
203458
|
-
return {
|
|
204450
|
+
return {
|
|
204451
|
+
runId: this.runId,
|
|
204452
|
+
snapshotId,
|
|
204453
|
+
projection,
|
|
204454
|
+
routing,
|
|
204455
|
+
assembly,
|
|
204456
|
+
tool,
|
|
204457
|
+
hasLoadableKnowledge: loadableDomains.length > 0,
|
|
204458
|
+
loadEvents,
|
|
204459
|
+
config: config2
|
|
204460
|
+
};
|
|
203459
204461
|
}
|
|
203460
204462
|
recordInvocation(agent, hop, knowledge) {
|
|
203461
204463
|
this.invocations.push({ agent, hop, knowledge });
|
|
@@ -203510,7 +204512,8 @@ var KnowledgeRunCoordinator = class {
|
|
|
203510
204512
|
accepts: item.hop.accepts,
|
|
203511
204513
|
returns: item.hop.returns,
|
|
203512
204514
|
judge: item.hop.judge,
|
|
203513
|
-
turnLimit: item.hop.turnLimit
|
|
204515
|
+
turnLimit: item.hop.turnLimit,
|
|
204516
|
+
inputTokenLimit: item.hop.inputTokenLimit
|
|
203514
204517
|
})
|
|
203515
204518
|
);
|
|
203516
204519
|
if (!item.knowledge) {
|
|
@@ -203614,7 +204617,11 @@ var KnowledgeRunCoordinator = class {
|
|
|
203614
204617
|
event.estimatedTokens
|
|
203615
204618
|
);
|
|
203616
204619
|
} else if (event.accepted) {
|
|
204620
|
+
const loadedTopicHashes = event.loadedTopicHashes ? new Set(event.loadedTopicHashes) : void 0;
|
|
203617
204621
|
for (const topic of domain2.topics) {
|
|
204622
|
+
if (loadedTopicHashes && !loadedTopicHashes.has(topic.topicHash)) {
|
|
204623
|
+
continue;
|
|
204624
|
+
}
|
|
203618
204625
|
for (const occurrence of topic.occurrences) {
|
|
203619
204626
|
index.run(
|
|
203620
204627
|
`INSERT OR REPLACE INTO run_topics(run_id, invocation_id,
|
|
@@ -204824,9 +205831,6 @@ function valueToString2(value) {
|
|
|
204824
205831
|
}
|
|
204825
205832
|
return String(value);
|
|
204826
205833
|
}
|
|
204827
|
-
function sleep5(ms) {
|
|
204828
|
-
return new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
204829
|
-
}
|
|
204830
205834
|
function isIfCommand(line2) {
|
|
204831
205835
|
return /^if\s+.+$/i.test(line2.trim());
|
|
204832
205836
|
}
|
|
@@ -205333,6 +206337,10 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205333
206337
|
};
|
|
205334
206338
|
const runtimeVariables = copyEnvironmentScope({ ...fileVariables, ...sequenceArgs }, fileVariables);
|
|
205335
206339
|
const mcpSessionManager = executionContext?.mcpSessionManager ?? new McpSessionManager();
|
|
206340
|
+
const cancelMcpSessions = () => {
|
|
206341
|
+
void mcpSessionManager.closeAll();
|
|
206342
|
+
};
|
|
206343
|
+
executionContext?.signal?.addEventListener("abort", cancelMcpSessions, { once: true });
|
|
205336
206344
|
const agentProviderRegistry = executionContext?.agentProviderRegistry ?? createDefaultAgentProviderRegistry();
|
|
205337
206345
|
const agentWarningKeys = executionContext?.agentWarningKeys ?? /* @__PURE__ */ new Set();
|
|
205338
206346
|
const agentEventLog = executionContext?.agentEventLog ?? [];
|
|
@@ -205547,6 +206555,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205547
206555
|
}
|
|
205548
206556
|
};
|
|
205549
206557
|
for (const step of steps) {
|
|
206558
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205550
206559
|
if (step.type === "judge") {
|
|
205551
206560
|
const parsedJudge = parseJudgeStep(step);
|
|
205552
206561
|
const blockingError = parsedJudge.errors[0];
|
|
@@ -205644,6 +206653,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205644
206653
|
try {
|
|
205645
206654
|
await preflightAgentGraph(definition, scope);
|
|
205646
206655
|
} catch (error2) {
|
|
206656
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205647
206657
|
await mcpSessionManager.closeScope(MCP_PREFLIGHT_SCOPE);
|
|
205648
206658
|
const message = `Agent '${definition.name}' tool preflight failed: ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
205649
206659
|
errors.push(message);
|
|
@@ -205663,8 +206673,10 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205663
206673
|
await mcpSessionManager.closeScope(MCP_PREFLIGHT_SCOPE);
|
|
205664
206674
|
}
|
|
205665
206675
|
for (let stepIdx = 0; stepIdx < steps.length; stepIdx++) {
|
|
206676
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205666
206677
|
const step = steps[stepIdx];
|
|
205667
206678
|
await emitBeforeStep(step, stepIdx);
|
|
206679
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205668
206680
|
const stepStartTime = Date.now();
|
|
205669
206681
|
try {
|
|
205670
206682
|
if (step.type === "if") {
|
|
@@ -205752,7 +206764,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205752
206764
|
if (step.type === "wait") {
|
|
205753
206765
|
const durationMs = parseWaitCommand(step.content);
|
|
205754
206766
|
reportProgress(stepIdx, "wait", `wait: ${durationMs}ms`);
|
|
205755
|
-
await
|
|
206767
|
+
await cancellableDelay(durationMs, executionContext?.signal);
|
|
205756
206768
|
const stepResult = createPrintStepResult(
|
|
205757
206769
|
stepIdx,
|
|
205758
206770
|
stepStartTime,
|
|
@@ -205954,6 +206966,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205954
206966
|
runLineNumber: debugLocation.absoluteLine,
|
|
205955
206967
|
rootInvocationIndex: rootInvocationIndex2,
|
|
205956
206968
|
knowledgeCoordinator,
|
|
206969
|
+
signal: executionContext?.signal,
|
|
205957
206970
|
expandMcpServerGrants: (_hopPath, grantedAgent) => mcpGrantExpansions.get(agentDefinitionKey(grantedAgent)) ?? expandMcpGrantsLive(grantedAgent),
|
|
205958
206971
|
onInvocationProgress: (agentEvent) => {
|
|
205959
206972
|
const recordedEvent = cloneSerializableValue(agentEvent);
|
|
@@ -206012,6 +207025,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
206012
207025
|
}
|
|
206013
207026
|
}
|
|
206014
207027
|
} catch (error2) {
|
|
207028
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206015
207029
|
execution.error = error2 instanceof Error ? error2.message : String(error2);
|
|
206016
207030
|
}
|
|
206017
207031
|
const stepResult = {
|
|
@@ -206090,6 +207104,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206090
207104
|
runLineNumber: debugLocation.absoluteLine,
|
|
206091
207105
|
rootInvocationIndex: rootInvocationIndex2,
|
|
206092
207106
|
knowledgeCoordinator,
|
|
207107
|
+
signal: executionContext?.signal,
|
|
206093
207108
|
expandMcpServerGrants: (_hopPath, grantedAgent) => mcpGrantExpansions.get(agentDefinitionKey(grantedAgent)) ?? expandMcpGrantsLive(grantedAgent),
|
|
206094
207109
|
onInvocationProgress: (agentEvent) => {
|
|
206095
207110
|
const recordedEvent = cloneSerializableValue(agentEvent);
|
|
@@ -206116,6 +207131,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206116
207131
|
addTraceDefinition(definition);
|
|
206117
207132
|
}
|
|
206118
207133
|
} catch (error2) {
|
|
207134
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206119
207135
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
206120
207136
|
if (agent?.returns) {
|
|
206121
207137
|
output2 = { ...output2, body: void 0 };
|
|
@@ -206314,7 +207330,8 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206314
207330
|
workingDir: adapterWorkingDir
|
|
206315
207331
|
}
|
|
206316
207332
|
},
|
|
206317
|
-
adapterWorkingDir
|
|
207333
|
+
adapterWorkingDir,
|
|
207334
|
+
executionContext?.signal
|
|
206318
207335
|
);
|
|
206319
207336
|
let storedValue;
|
|
206320
207337
|
let sqlResult;
|
|
@@ -206361,6 +207378,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206361
207378
|
const description = operation.type === "query" ? `run sql ${operation.name} \u2192 ${sqlResult.rowCount ?? 0} row(s)` : `run sql ${operation.name} \u2192 ${sqlResult.affectedRows ?? 0} affected`;
|
|
206362
207379
|
reportProgress(stepIdx, "sql", description, stepResult);
|
|
206363
207380
|
} catch (error2) {
|
|
207381
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206364
207382
|
errors.push(`SQL execution failed for '${operation.name}': ${error2.message || String(error2)}`);
|
|
206365
207383
|
await emitFailure(`SQL execution failed for '${operation.name}'`, step, stepIdx);
|
|
206366
207384
|
return {
|
|
@@ -206414,6 +207432,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206414
207432
|
orderedSteps.push(stepResult);
|
|
206415
207433
|
reportProgress(stepIdx, "mcp", `run mcp list ${parsed.serverAlias} \u2192 ${listResult.tools.length} tool(s)`, stepResult);
|
|
206416
207434
|
} catch (error2) {
|
|
207435
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206417
207436
|
const message = `MCP list failed for '${parsed.serverAlias}': ${error2?.message || String(error2)}`;
|
|
206418
207437
|
errors.push(message);
|
|
206419
207438
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206465,6 +207484,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206465
207484
|
parsed.toolName
|
|
206466
207485
|
);
|
|
206467
207486
|
} catch (error2) {
|
|
207487
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206468
207488
|
const message = `MCP call failed for '${parsed.serverAlias}.${parsed.toolName}': ${error2?.message || String(error2)}`;
|
|
206469
207489
|
errors.push(message);
|
|
206470
207490
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206534,6 +207554,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206534
207554
|
};
|
|
206535
207555
|
}
|
|
206536
207556
|
} catch (error2) {
|
|
207557
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206537
207558
|
const message = `MCP call failed for '${parsed.serverAlias}.${parsed.toolName}': ${error2?.message || String(error2)}`;
|
|
206538
207559
|
errors.push(message);
|
|
206539
207560
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206596,7 +207617,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206596
207617
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] ${requestDescription} - waiting ${waitMs}ms`, void 0);
|
|
206597
207618
|
}
|
|
206598
207619
|
} : void 0;
|
|
206599
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
207620
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
206600
207621
|
addResponse(response);
|
|
206601
207622
|
runContractValidation(preparedRequest.endpointName, response, step, stepIdx);
|
|
206602
207623
|
responseIndexToVariable.set(responses.length, parsed.varName);
|
|
@@ -206622,6 +207643,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206622
207643
|
}
|
|
206623
207644
|
}
|
|
206624
207645
|
} catch (error2) {
|
|
207646
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206625
207647
|
const userMessage = formatUserFacingError(
|
|
206626
207648
|
error2,
|
|
206627
207649
|
buildRequestValidationContext(stepIdx + 1, void 0, void 0, `var ${parsed.varName}`)
|
|
@@ -206674,7 +207696,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
206674
207696
|
substitutedArgs,
|
|
206675
207697
|
workingDir || process.cwd(),
|
|
206676
207698
|
runtimeVariables,
|
|
206677
|
-
parsed.captureAs
|
|
207699
|
+
parsed.captureAs,
|
|
207700
|
+
executionContext?.signal
|
|
206678
207701
|
);
|
|
206679
207702
|
scriptResults.push(result);
|
|
206680
207703
|
const stepResult = {
|
|
@@ -206707,6 +207730,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206707
207730
|
runtimeVariables[parsed.captureAs] = outputValue;
|
|
206708
207731
|
}
|
|
206709
207732
|
} catch (error2) {
|
|
207733
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206710
207734
|
errors.push(`Script execution error: ${error2.message}`);
|
|
206711
207735
|
return {
|
|
206712
207736
|
name: "",
|
|
@@ -206812,7 +207836,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
206812
207836
|
agentEventLog,
|
|
206813
207837
|
agentRootInvocationCounts,
|
|
206814
207838
|
recordAgentRuns: executionContext?.recordAgentRuns,
|
|
206815
|
-
knowledgeCoordinator
|
|
207839
|
+
knowledgeCoordinator,
|
|
207840
|
+
signal: executionContext?.signal
|
|
206816
207841
|
};
|
|
206817
207842
|
const subResult = await runSequenceWithJar(
|
|
206818
207843
|
targetSequence.content,
|
|
@@ -206905,7 +207930,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206905
207930
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] run ${targetName} - waiting ${waitMs}ms`, void 0);
|
|
206906
207931
|
}
|
|
206907
207932
|
} : void 0;
|
|
206908
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
207933
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
206909
207934
|
addResponse(response);
|
|
206910
207935
|
const stepResult = {
|
|
206911
207936
|
type: "request",
|
|
@@ -206927,6 +207952,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206927
207952
|
}
|
|
206928
207953
|
}
|
|
206929
207954
|
} catch (error2) {
|
|
207955
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206930
207956
|
const userMessage = formatUserFacingError(
|
|
206931
207957
|
error2,
|
|
206932
207958
|
buildRequestValidationContext(stepIdx + 1, requestMethod || void 0, requestUrl || void 0, targetName)
|
|
@@ -207016,7 +208042,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207016
208042
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] var ${varName} = run ${sequenceName} - waiting ${waitMs}ms`, void 0);
|
|
207017
208043
|
}
|
|
207018
208044
|
} : void 0;
|
|
207019
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
208045
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
207020
208046
|
addResponse(response);
|
|
207021
208047
|
responseIndexToVariable.set(responses.length, varName);
|
|
207022
208048
|
const stepResult = {
|
|
@@ -207047,6 +208073,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207047
208073
|
}
|
|
207048
208074
|
}
|
|
207049
208075
|
} catch (error2) {
|
|
208076
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
207050
208077
|
const userMessage = formatUserFacingError(
|
|
207051
208078
|
error2,
|
|
207052
208079
|
buildRequestValidationContext(stepIdx + 1, requestMethod || void 0, requestUrl || void 0, `${varName} = run ${sequenceName}`)
|
|
@@ -207132,7 +208159,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
207132
208159
|
agentEventLog,
|
|
207133
208160
|
agentRootInvocationCounts,
|
|
207134
208161
|
recordAgentRuns: executionContext?.recordAgentRuns,
|
|
207135
|
-
knowledgeCoordinator
|
|
208162
|
+
knowledgeCoordinator,
|
|
208163
|
+
signal: executionContext?.signal
|
|
207136
208164
|
};
|
|
207137
208165
|
const subResult = await runSequenceWithJar(
|
|
207138
208166
|
targetSequence.content,
|
|
@@ -207224,7 +208252,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207224
208252
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] ${requestDescription} - waiting ${waitMs}ms`, void 0);
|
|
207225
208253
|
}
|
|
207226
208254
|
} : void 0;
|
|
207227
|
-
const response = cookieJar ? await sendRequestWithJar(parsed, cookieJar, retryOpts) : await sendRequest(parsed, retryOpts);
|
|
208255
|
+
const response = cookieJar ? await sendRequestWithJar(parsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(parsed, retryOpts, executionContext?.signal);
|
|
207228
208256
|
addResponse(response);
|
|
207229
208257
|
const stepResult = {
|
|
207230
208258
|
type: "request",
|
|
@@ -207247,6 +208275,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207247
208275
|
}
|
|
207248
208276
|
}
|
|
207249
208277
|
} catch (error2) {
|
|
208278
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
207250
208279
|
const userMessage = formatUserFacingError(
|
|
207251
208280
|
error2,
|
|
207252
208281
|
buildRequestValidationContext(stepIdx + 1)
|
|
@@ -207272,7 +208301,9 @@ ${indentMultiline(userMessage)}`;
|
|
|
207272
208301
|
}
|
|
207273
208302
|
}
|
|
207274
208303
|
} finally {
|
|
207275
|
-
|
|
208304
|
+
if (!executionContext?.signal?.aborted) {
|
|
208305
|
+
await emitAfterStep(step, stepIdx);
|
|
208306
|
+
}
|
|
207276
208307
|
}
|
|
207277
208308
|
}
|
|
207278
208309
|
return {
|
|
@@ -207288,16 +208319,23 @@ ${indentMultiline(userMessage)}`;
|
|
|
207288
208319
|
agentTrace,
|
|
207289
208320
|
completed: true
|
|
207290
208321
|
};
|
|
208322
|
+
} catch (error2) {
|
|
208323
|
+
if (executionContext?.signal?.aborted) {
|
|
208324
|
+
throw new SequenceCancelledError();
|
|
208325
|
+
}
|
|
208326
|
+
throw error2;
|
|
207291
208327
|
} finally {
|
|
208328
|
+
executionContext?.signal?.removeEventListener("abort", cancelMcpSessions);
|
|
208329
|
+
const wasCancelled = executionContext?.signal?.aborted === true;
|
|
207292
208330
|
let recordingPath;
|
|
207293
|
-
const shouldRecordAgentRun = nestingDepth === 0 && agentTrace.hops.length > 0 && (executionContext?.recordAgentRuns ?? executionContext?.agentProviderRegistry === void 0);
|
|
208331
|
+
const shouldRecordAgentRun = !wasCancelled && nestingDepth === 0 && agentTrace.hops.length > 0 && (executionContext?.recordAgentRuns ?? executionContext?.agentProviderRegistry === void 0);
|
|
207294
208332
|
if (shouldRecordAgentRun && executionContext?.filePath) {
|
|
207295
208333
|
try {
|
|
207296
208334
|
recordingPath = writeAgentRunRecording({
|
|
207297
208335
|
sourcePath: executionContext.filePath,
|
|
207298
208336
|
sequenceName: executionContext.sequenceName || "sequence",
|
|
207299
208337
|
...executionContext.environment?.activeEnvironment ? { environmentName: executionContext.environment.activeEnvironment } : {},
|
|
207300
|
-
success: errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
208338
|
+
success: !wasCancelled && errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
207301
208339
|
durationMs: Date.now() - startTime,
|
|
207302
208340
|
...knowledgeCoordinator?.pinnedSnapshotId ? {
|
|
207303
208341
|
runId: knowledgeCoordinator.runId,
|
|
@@ -207322,7 +208360,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207322
208360
|
environmentName: executionContext.environment?.activeEnvironment,
|
|
207323
208361
|
startedAt: new Date(startTime),
|
|
207324
208362
|
durationMs: Date.now() - startTime,
|
|
207325
|
-
success: errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
208363
|
+
success: !wasCancelled && errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
207326
208364
|
recordingPath,
|
|
207327
208365
|
secrets: resolveAgentRecordingSecretValues(
|
|
207328
208366
|
executionContext.filePath,
|
|
@@ -207654,6 +208692,20 @@ function redactAgentRequestForJson(request, redaction) {
|
|
|
207654
208692
|
agentSourcePath: redactString(request.agentSourcePath, redaction),
|
|
207655
208693
|
sourcePath: request.sourcePath ? redactString(request.sourcePath, redaction) : void 0,
|
|
207656
208694
|
sequenceName: request.sequenceName ? redactString(request.sequenceName, redaction) : void 0,
|
|
208695
|
+
knowledge: request.knowledge ? {
|
|
208696
|
+
...request.knowledge,
|
|
208697
|
+
domains: request.knowledge.domains?.map((domain2) => ({
|
|
208698
|
+
...domain2,
|
|
208699
|
+
declarationAlias: redactString(domain2.declarationAlias, redaction),
|
|
208700
|
+
sourcePath: redactString(domain2.sourcePath, redaction),
|
|
208701
|
+
domainPath: redactString(domain2.domainPath, redaction),
|
|
208702
|
+
topics: domain2.topics.map((topic) => ({
|
|
208703
|
+
...topic,
|
|
208704
|
+
heading: topic.heading ? redactString(topic.heading, redaction) : void 0,
|
|
208705
|
+
itemPaths: topic.itemPaths.map((itemPath) => redactString(itemPath, redaction))
|
|
208706
|
+
}))
|
|
208707
|
+
}))
|
|
208708
|
+
} : void 0,
|
|
207657
208709
|
promptHash: (0, import_crypto11.createHash)("sha256").update(systemPrompt, "utf8").digest("hex")
|
|
207658
208710
|
};
|
|
207659
208711
|
}
|
|
@@ -207673,6 +208725,10 @@ function redactAgentHopForJson(hop, redaction) {
|
|
|
207673
208725
|
sourcePath: redactString(hop.turnLimit.sourcePath, redaction),
|
|
207674
208726
|
...hop.turnLimit.lastToolName ? { lastToolName: redactString(hop.turnLimit.lastToolName, redaction) } : {}
|
|
207675
208727
|
} : void 0,
|
|
208728
|
+
inputTokenLimit: hop.inputTokenLimit ? {
|
|
208729
|
+
...hop.inputTokenLimit,
|
|
208730
|
+
sourcePath: redactString(hop.inputTokenLimit.sourcePath, redaction)
|
|
208731
|
+
} : void 0,
|
|
207676
208732
|
warnings: hop.warnings.map((warning) => redactString(warning, redaction)),
|
|
207677
208733
|
accepts: redactAgentContractForJson(hop.accepts, redaction),
|
|
207678
208734
|
returns: redactAgentContractForJson(hop.returns, redaction),
|
|
@@ -207689,7 +208745,7 @@ function redactAgentHopForJson(hop, redaction) {
|
|
|
207689
208745
|
body: redactBody(hop.output.body, redaction),
|
|
207690
208746
|
text: typeof redactedText === "string" ? redactedText : String(redactedText ?? ""),
|
|
207691
208747
|
model: redactString(hop.output.model, redaction),
|
|
207692
|
-
toolCalls: hop.output.toolCalls.map((toolCall) => ({
|
|
208748
|
+
toolCalls: hop.output.toolCalls.filter((toolCall) => toolCall.kind !== "context" && !(toolCall.kind === "knowledge" && toolCall.output && typeof toolCall.output === "object" && !Array.isArray(toolCall.output) && toolCall.output.alreadyLoaded === true)).map((toolCall) => ({
|
|
207693
208749
|
...toolCall,
|
|
207694
208750
|
name: redactString(toolCall.name, redaction),
|
|
207695
208751
|
input: redactBody(toolCall.input, redaction),
|
|
@@ -207929,6 +208985,9 @@ function isFailedToolResult(value) {
|
|
|
207929
208985
|
const record2 = value;
|
|
207930
208986
|
return Object.keys(record2).length === 1 && typeof record2.error === "string";
|
|
207931
208987
|
}
|
|
208988
|
+
function isKnowledgeAlreadyLoaded(value) {
|
|
208989
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value) && value.alreadyLoaded === true);
|
|
208990
|
+
}
|
|
207932
208991
|
function getReplyValue(hop) {
|
|
207933
208992
|
if (hop.output.text.trim().length > 0) {
|
|
207934
208993
|
return { present: true, value: hop.output.text };
|
|
@@ -208006,6 +209065,9 @@ function formatAgentHopAtDepth(hop, options, displayDepth) {
|
|
|
208006
209065
|
const renderedChildren = /* @__PURE__ */ new Set();
|
|
208007
209066
|
const childrenByInvocationId = new Map(hop.children.map((child) => [child.invocationId, child]));
|
|
208008
209067
|
for (const toolCall of hop.output.toolCalls) {
|
|
209068
|
+
if (toolCall.kind === "context" || toolCall.kind === "knowledge" && isKnowledgeAlreadyLoaded(toolCall.output)) {
|
|
209069
|
+
continue;
|
|
209070
|
+
}
|
|
208009
209071
|
if (toolCall.kind === "agent" || toolCall.childInvocationId) {
|
|
208010
209072
|
const child = toolCall.childInvocationId ? childrenByInvocationId.get(toolCall.childInvocationId) : void 0;
|
|
208011
209073
|
if (child) {
|
|
@@ -210854,6 +211916,42 @@ async function runK8sRunbooks(text, options = {}) {
|
|
|
210854
211916
|
var import_util8 = require("util");
|
|
210855
211917
|
|
|
210856
211918
|
// src/agents/agentHopPresentation.ts
|
|
211919
|
+
function buildAgentKnowledgePresentation(knowledge) {
|
|
211920
|
+
if (!knowledge) {
|
|
211921
|
+
return void 0;
|
|
211922
|
+
}
|
|
211923
|
+
const domains = knowledge.domains ? knowledge.domains.map((domain2) => ({
|
|
211924
|
+
domainId: domain2.domainId,
|
|
211925
|
+
declarationAlias: domain2.declarationAlias,
|
|
211926
|
+
sourcePath: domain2.sourcePath,
|
|
211927
|
+
domainPath: domain2.domainPath,
|
|
211928
|
+
disposition: domain2.disposition,
|
|
211929
|
+
estimatedTokens: domain2.estimatedTokens,
|
|
211930
|
+
topicCount: domain2.topicCount,
|
|
211931
|
+
topics: domain2.topics.map((topic) => ({
|
|
211932
|
+
topicHash: topic.topicHash,
|
|
211933
|
+
...topic.heading ? { heading: topic.heading } : {},
|
|
211934
|
+
estimatedTokens: topic.estimatedTokens,
|
|
211935
|
+
itemPaths: [...topic.itemPaths]
|
|
211936
|
+
}))
|
|
211937
|
+
})) : knowledge.selectedDomainIds.map((domainId) => {
|
|
211938
|
+
const parts = decodeKnowledgeId(domainId);
|
|
211939
|
+
const domainPath = typeof parts?.[2] === "string" ? parts[2] : "Recorded domain";
|
|
211940
|
+
return {
|
|
211941
|
+
domainId,
|
|
211942
|
+
domainPath,
|
|
211943
|
+
disposition: "selected",
|
|
211944
|
+
topics: []
|
|
211945
|
+
};
|
|
211946
|
+
});
|
|
211947
|
+
return {
|
|
211948
|
+
routingRule: knowledge.routingRule,
|
|
211949
|
+
estimatedTokens: knowledge.estimatedTokens,
|
|
211950
|
+
estimatorVersion: knowledge.estimatorVersion,
|
|
211951
|
+
detailsComplete: knowledge.domains !== void 0,
|
|
211952
|
+
domains
|
|
211953
|
+
};
|
|
211954
|
+
}
|
|
210857
211955
|
function isSameAgentContract(left, right) {
|
|
210858
211956
|
return Boolean(
|
|
210859
211957
|
left && right && left.kind === right.kind && left.path === right.path && left.assertion.passed === right.assertion.passed && left.assertion.expression === right.assertion.expression && left.assertion.error === right.assertion.error
|
|
@@ -210906,15 +212004,25 @@ function deriveAgentHopPresentation(hop) {
|
|
|
210906
212004
|
...hop.turnLimit.lastToolName ? { lastToolName: hop.turnLimit.lastToolName } : {}
|
|
210907
212005
|
}
|
|
210908
212006
|
} : {},
|
|
212007
|
+
...hop.inputTokenLimit ? {
|
|
212008
|
+
inputTokenLimit: {
|
|
212009
|
+
maxInputTokens: hop.inputTokenLimit.maxInputTokens,
|
|
212010
|
+
usedInputTokens: hop.inputTokenLimit.usedInputTokens,
|
|
212011
|
+
...hop.inputTokenLimit.estimatedNextInputTokens !== void 0 ? { estimatedNextInputTokens: hop.inputTokenLimit.estimatedNextInputTokens } : {}
|
|
212012
|
+
}
|
|
212013
|
+
} : {},
|
|
212014
|
+
...hop.request?.maxInputTokens !== void 0 ? { maxInputTokens: hop.request.maxInputTokens } : {},
|
|
210909
212015
|
...hop.error ? { error: hop.error } : {},
|
|
210910
212016
|
warnings: [...hop.warnings],
|
|
210911
212017
|
...hop.judge ? { judge: buildAgentJudgePresentation(hop.judge) } : {},
|
|
212018
|
+
...hop.request?.knowledge ? { knowledge: buildAgentKnowledgePresentation(hop.request.knowledge) } : {},
|
|
210912
212019
|
output: {
|
|
210913
212020
|
model: hop.output.model,
|
|
210914
212021
|
ms: hop.output.ms,
|
|
210915
212022
|
usage: {
|
|
210916
212023
|
inputTokens: hop.output.usage.inputTokens,
|
|
210917
|
-
outputTokens: hop.output.usage.outputTokens
|
|
212024
|
+
outputTokens: hop.output.usage.outputTokens,
|
|
212025
|
+
...hop.output.usage.turns ? { turns: hop.output.usage.turns.map((turn) => ({ ...turn })) } : {}
|
|
210918
212026
|
},
|
|
210919
212027
|
text: hop.output.text,
|
|
210920
212028
|
...Object.prototype.hasOwnProperty.call(hop.output, "body") && hop.output.body !== void 0 ? { body: hop.output.body } : {},
|
|
@@ -211008,7 +212116,13 @@ var ReplayAgentProviderAdapter = class {
|
|
|
211008
212116
|
};
|
|
211009
212117
|
|
|
211010
212118
|
// src/agents/agentReplay.ts
|
|
211011
|
-
var PROVIDERS = [
|
|
212119
|
+
var PROVIDERS = [
|
|
212120
|
+
"openai",
|
|
212121
|
+
"openai_compatible",
|
|
212122
|
+
"anthropic",
|
|
212123
|
+
"google",
|
|
212124
|
+
"local"
|
|
212125
|
+
];
|
|
211012
212126
|
function normalizedPath(value) {
|
|
211013
212127
|
return value.replace(/\\/g, "/").toLowerCase();
|
|
211014
212128
|
}
|
|
@@ -211034,7 +212148,10 @@ function recordedProviderResponse(hop, provider) {
|
|
|
211034
212148
|
text: hop.output.text,
|
|
211035
212149
|
...hasOwn4(hop.output, "body") ? { parsed: structuredClone(hop.output.body) } : {},
|
|
211036
212150
|
toolCalls: cloneToolCalls(hop.output.toolCalls),
|
|
211037
|
-
usage: {
|
|
212151
|
+
usage: {
|
|
212152
|
+
...hop.output.usage,
|
|
212153
|
+
...hop.output.usage.turns ? { turns: hop.output.usage.turns.map((turn) => ({ ...turn })) } : {}
|
|
212154
|
+
},
|
|
211038
212155
|
resolvedModelId: resolvedModelId(hop, provider)
|
|
211039
212156
|
};
|
|
211040
212157
|
}
|
|
@@ -211196,8 +212313,10 @@ var ReplayCoordinator = class {
|
|
|
211196
212313
|
provider: hop.request.provider,
|
|
211197
212314
|
modelId: hop.request.modelId,
|
|
211198
212315
|
displayModel: hop.request.displayModel,
|
|
212316
|
+
...hop.request.reasoningEffort ? { reasoningEffort: hop.request.reasoningEffort } : {},
|
|
211199
212317
|
systemPrompt: hop.request.systemPrompt,
|
|
211200
212318
|
maxTokens: hop.request.maxTokens,
|
|
212319
|
+
...hop.request.maxInputTokens !== void 0 ? { maxInputTokens: hop.request.maxInputTokens } : {},
|
|
211201
212320
|
tools: hop.request.tools.map((tool) => ({
|
|
211202
212321
|
...tool,
|
|
211203
212322
|
inputSchema: structuredClone(tool.inputSchema)
|
|
@@ -211375,7 +212494,8 @@ var ReplayCoordinator = class {
|
|
|
211375
212494
|
let actualOutput;
|
|
211376
212495
|
let actualError;
|
|
211377
212496
|
try {
|
|
211378
|
-
|
|
212497
|
+
const executed = await currentTool.execute(structuredClone(recordedCall.input));
|
|
212498
|
+
actualOutput = normalizePreparedAgentToolResult(executed).recordedOutput;
|
|
211379
212499
|
} catch (error2) {
|
|
211380
212500
|
if (kind === "mcp") {
|
|
211381
212501
|
throw error2;
|