norn-cli 3.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1374 -260
- package/dist/knowledgeIndexWorker.js +68 -22
- 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 },
|
|
@@ -158691,6 +158700,7 @@ function splitHeaderDirective(value) {
|
|
|
158691
158700
|
}
|
|
158692
158701
|
var LIMIT_DIRECTIVES = {
|
|
158693
158702
|
max_tokens: "maxTokens",
|
|
158703
|
+
max_input_tokens: "maxInputTokens",
|
|
158694
158704
|
max_depth: "maxDepth",
|
|
158695
158705
|
max_invocations: "maxInvocations",
|
|
158696
158706
|
max_turns: "maxTurns",
|
|
@@ -159125,6 +159135,23 @@ end mcp
|
|
|
159125
159135
|
));
|
|
159126
159136
|
model.invalid = true;
|
|
159127
159137
|
}
|
|
159138
|
+
const reasoning = model.values.reasoning;
|
|
159139
|
+
if (reasoning && !reasoning.value.includes("{{") && !AGENT_REASONING_EFFORTS.some((effort) => effort === reasoning.value.toLowerCase())) {
|
|
159140
|
+
errors.push(parseError(
|
|
159141
|
+
reasoning.lineNumber,
|
|
159142
|
+
`Unknown reasoning effort '${reasoning.value}' in model '${model.alias}'. Expected one of: ${AGENT_REASONING_EFFORTS.join(", ")}.`,
|
|
159143
|
+
"agent-model-reasoning-invalid"
|
|
159144
|
+
));
|
|
159145
|
+
model.invalid = true;
|
|
159146
|
+
}
|
|
159147
|
+
if (reasoning && provider && !provider.value.includes("{{") && provider.value.toLowerCase() !== "openai") {
|
|
159148
|
+
errors.push(parseError(
|
|
159149
|
+
reasoning.lineNumber,
|
|
159150
|
+
`Model '${model.alias}' can declare reasoning only with provider openai. Provider '${provider.value}' does not support this directive yet.`,
|
|
159151
|
+
"agent-model-reasoning-provider"
|
|
159152
|
+
));
|
|
159153
|
+
model.invalid = true;
|
|
159154
|
+
}
|
|
159128
159155
|
if (model.invalid || !provider || !name) {
|
|
159129
159156
|
return;
|
|
159130
159157
|
}
|
|
@@ -159133,6 +159160,7 @@ end mcp
|
|
|
159133
159160
|
providerTemplate: provider.value,
|
|
159134
159161
|
nameTemplate: name.value,
|
|
159135
159162
|
targetTemplate: `${provider.value}/${name.value}`,
|
|
159163
|
+
...reasoning ? { reasoningTemplate: reasoning.value } : {},
|
|
159136
159164
|
...model.values.apiKey ? { apiKeyTemplate: model.values.apiKey.value } : {},
|
|
159137
159165
|
...model.values.baseUrl ? { baseUrlTemplate: model.values.baseUrl.value } : {},
|
|
159138
159166
|
lineNumber: model.lineNumber,
|
|
@@ -159172,6 +159200,13 @@ end mcp
|
|
|
159172
159200
|
"agent-model-alias-unknown"
|
|
159173
159201
|
));
|
|
159174
159202
|
pending.invalid = true;
|
|
159203
|
+
} else if (model.alias !== pending.modelAlias.value) {
|
|
159204
|
+
errors.push(parseError(
|
|
159205
|
+
pending.modelAlias.lineNumber,
|
|
159206
|
+
`Model alias '${pending.modelAlias.value}' in agent '${pending.name}' does not match the declared alias '${model.alias}'. Model aliases are case-sensitive.`,
|
|
159207
|
+
"agent-model-alias-case-mismatch"
|
|
159208
|
+
));
|
|
159209
|
+
pending.invalid = true;
|
|
159175
159210
|
}
|
|
159176
159211
|
}
|
|
159177
159212
|
}
|
|
@@ -159207,6 +159242,7 @@ end mcp
|
|
|
159207
159242
|
accepts: pending.accepts,
|
|
159208
159243
|
returns: pending.returns,
|
|
159209
159244
|
maxTokens: pending.maxTokens?.value,
|
|
159245
|
+
maxInputTokens: pending.maxInputTokens?.value,
|
|
159210
159246
|
maxDepth: pending.maxDepth?.value,
|
|
159211
159247
|
maxInvocations: pending.maxInvocations?.value,
|
|
159212
159248
|
maxTurns: pending.maxTurns?.value,
|
|
@@ -159611,29 +159647,38 @@ end model`,
|
|
|
159611
159647
|
}
|
|
159612
159648
|
const knowledgeGrantMatch = trimmed.match(/^knowledge(?:\s+(.*))?$/i);
|
|
159613
159649
|
if (knowledgeGrantMatch) {
|
|
159614
|
-
const
|
|
159615
|
-
|
|
159650
|
+
const rawValue = (knowledgeGrantMatch[1] ?? "").trim();
|
|
159651
|
+
const aliases = rawValue ? rawValue.split(",").map((part) => part.trim()) : [];
|
|
159652
|
+
if (aliases.length === 0 || aliases.some((alias) => !new RegExp(`^${IDENTIFIER}$`).test(alias))) {
|
|
159616
159653
|
errors.push(parseError(
|
|
159617
159654
|
index,
|
|
159618
|
-
`Invalid knowledge grant '${trimmed}' in agent '${pending.name}'. Expected: knowledge <Alias
|
|
159655
|
+
`Invalid knowledge grant '${trimmed}' in agent '${pending.name}'. Expected: knowledge <Alias>[, <Alias>\u2026].`,
|
|
159619
159656
|
"agent-knowledge-grant-invalid"
|
|
159620
159657
|
));
|
|
159621
159658
|
pending.invalid = true;
|
|
159622
|
-
|
|
159623
|
-
|
|
159624
|
-
|
|
159625
|
-
|
|
159626
|
-
|
|
159627
|
-
|
|
159628
|
-
|
|
159629
|
-
|
|
159630
|
-
|
|
159631
|
-
|
|
159632
|
-
|
|
159633
|
-
|
|
159634
|
-
|
|
159635
|
-
|
|
159636
|
-
|
|
159659
|
+
continue;
|
|
159660
|
+
}
|
|
159661
|
+
const granted = new Set(pending.knowledge.map((grant) => grant.alias.toLowerCase()));
|
|
159662
|
+
for (const alias of aliases) {
|
|
159663
|
+
if (granted.has(alias.toLowerCase())) {
|
|
159664
|
+
errors.push(parseError(
|
|
159665
|
+
index,
|
|
159666
|
+
`Agent '${pending.name}' grants knowledge '${alias}' more than once.`,
|
|
159667
|
+
"agent-knowledge-grant-duplicate"
|
|
159668
|
+
));
|
|
159669
|
+
pending.invalid = true;
|
|
159670
|
+
continue;
|
|
159671
|
+
}
|
|
159672
|
+
if (!knowledgeBases.has(alias.toLowerCase())) {
|
|
159673
|
+
errors.push(parseError(
|
|
159674
|
+
index,
|
|
159675
|
+
`Unknown knowledge alias '${alias}' in agent '${pending.name}'.`,
|
|
159676
|
+
"agent-knowledge-alias-unknown"
|
|
159677
|
+
));
|
|
159678
|
+
pending.invalid = true;
|
|
159679
|
+
continue;
|
|
159680
|
+
}
|
|
159681
|
+
granted.add(alias.toLowerCase());
|
|
159637
159682
|
pending.knowledge.push({ alias, lineNumber: index });
|
|
159638
159683
|
}
|
|
159639
159684
|
continue;
|
|
@@ -159948,6 +159993,7 @@ function isNonNegativeInteger(value) {
|
|
|
159948
159993
|
var AGENT_LIMIT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
159949
159994
|
"_comment",
|
|
159950
159995
|
"max_tokens",
|
|
159996
|
+
"max_input_tokens",
|
|
159951
159997
|
"max_depth",
|
|
159952
159998
|
"max_invocations",
|
|
159953
159999
|
"max_turns",
|
|
@@ -159957,7 +160003,7 @@ function hasOnlyKeys(value, allowedKeys) {
|
|
|
159957
160003
|
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
159958
160004
|
}
|
|
159959
160005
|
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));
|
|
160006
|
+
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
160007
|
}
|
|
159962
160008
|
function isNornAgentProviderConfig(value) {
|
|
159963
160009
|
if (!isObjectRecord(value)) {
|
|
@@ -159977,7 +160023,13 @@ function isNornAgentRecordingConfig(value) {
|
|
|
159977
160023
|
}
|
|
159978
160024
|
return hasOnlyKeys(value, /* @__PURE__ */ new Set(["_comment", "enabled"])) && (value.enabled === void 0 || typeof value.enabled === "boolean");
|
|
159979
160025
|
}
|
|
159980
|
-
var AGENT_PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
160026
|
+
var AGENT_PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
160027
|
+
"openai",
|
|
160028
|
+
"openai_compatible",
|
|
160029
|
+
"anthropic",
|
|
160030
|
+
"google",
|
|
160031
|
+
"local"
|
|
160032
|
+
]);
|
|
159981
160033
|
function isNornAgentsConfig(value) {
|
|
159982
160034
|
if (value === void 0) {
|
|
159983
160035
|
return true;
|
|
@@ -166666,6 +166718,68 @@ function encodeFormUrlEncodedBody(body) {
|
|
|
166666
166718
|
};
|
|
166667
166719
|
}
|
|
166668
166720
|
|
|
166721
|
+
// src/sequenceCancellation.ts
|
|
166722
|
+
var SEQUENCE_CANCELLED_MESSAGE = "Sequence run cancelled by user.";
|
|
166723
|
+
var SequenceCancelledError = class extends Error {
|
|
166724
|
+
constructor() {
|
|
166725
|
+
super(SEQUENCE_CANCELLED_MESSAGE);
|
|
166726
|
+
this.name = "SequenceCancelledError";
|
|
166727
|
+
}
|
|
166728
|
+
};
|
|
166729
|
+
function throwIfSequenceCancelled(signal) {
|
|
166730
|
+
if (signal?.aborted) {
|
|
166731
|
+
throw new SequenceCancelledError();
|
|
166732
|
+
}
|
|
166733
|
+
}
|
|
166734
|
+
function raceWithSequenceCancellation(operation, signal) {
|
|
166735
|
+
if (!signal) {
|
|
166736
|
+
return operation;
|
|
166737
|
+
}
|
|
166738
|
+
throwIfSequenceCancelled(signal);
|
|
166739
|
+
return new Promise((resolve28, reject) => {
|
|
166740
|
+
const cancel = () => {
|
|
166741
|
+
signal.removeEventListener("abort", cancel);
|
|
166742
|
+
reject(new SequenceCancelledError());
|
|
166743
|
+
};
|
|
166744
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
166745
|
+
if (signal.aborted) {
|
|
166746
|
+
cancel();
|
|
166747
|
+
return;
|
|
166748
|
+
}
|
|
166749
|
+
operation.then(
|
|
166750
|
+
(value) => {
|
|
166751
|
+
signal.removeEventListener("abort", cancel);
|
|
166752
|
+
resolve28(value);
|
|
166753
|
+
},
|
|
166754
|
+
(error2) => {
|
|
166755
|
+
signal.removeEventListener("abort", cancel);
|
|
166756
|
+
reject(error2);
|
|
166757
|
+
}
|
|
166758
|
+
);
|
|
166759
|
+
});
|
|
166760
|
+
}
|
|
166761
|
+
function cancellableDelay(ms, signal) {
|
|
166762
|
+
if (!signal) {
|
|
166763
|
+
return new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
166764
|
+
}
|
|
166765
|
+
throwIfSequenceCancelled(signal);
|
|
166766
|
+
return new Promise((resolve28, reject) => {
|
|
166767
|
+
const timer = setTimeout(() => {
|
|
166768
|
+
signal.removeEventListener("abort", cancel);
|
|
166769
|
+
resolve28();
|
|
166770
|
+
}, ms);
|
|
166771
|
+
const cancel = () => {
|
|
166772
|
+
clearTimeout(timer);
|
|
166773
|
+
signal.removeEventListener("abort", cancel);
|
|
166774
|
+
reject(new SequenceCancelledError());
|
|
166775
|
+
};
|
|
166776
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
166777
|
+
if (signal.aborted) {
|
|
166778
|
+
cancel();
|
|
166779
|
+
}
|
|
166780
|
+
});
|
|
166781
|
+
}
|
|
166782
|
+
|
|
166669
166783
|
// src/httpClient.ts
|
|
166670
166784
|
var sharedCookieJar = new CookieJar();
|
|
166671
166785
|
var insecureHttpsAgent = new https2.Agent({ rejectUnauthorized: false });
|
|
@@ -166688,11 +166802,8 @@ async function getAllCookies(jar) {
|
|
|
166688
166802
|
secure: Boolean(c.secure)
|
|
166689
166803
|
}));
|
|
166690
166804
|
}
|
|
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));
|
|
166805
|
+
async function sendRequest(request, retryOptions, signal) {
|
|
166806
|
+
return sendRequestWithJar(request, sharedCookieJar, retryOptions, signal);
|
|
166696
166807
|
}
|
|
166697
166808
|
function shouldRetry(response, error2) {
|
|
166698
166809
|
if (error2) {
|
|
@@ -166703,13 +166814,14 @@ function shouldRetry(response, error2) {
|
|
|
166703
166814
|
}
|
|
166704
166815
|
return false;
|
|
166705
166816
|
}
|
|
166706
|
-
async function sendRequestWithJar(request, jar, retryOptions) {
|
|
166817
|
+
async function sendRequestWithJar(request, jar, retryOptions, signal) {
|
|
166707
166818
|
const totalAttempts = (retryOptions?.retryCount ?? 0) + 1;
|
|
166708
166819
|
const backoffMs = retryOptions?.backoffMs ?? 1e3;
|
|
166709
166820
|
const retriedErrors = [];
|
|
166710
166821
|
let lastError = null;
|
|
166711
166822
|
let attemptsMade = 0;
|
|
166712
166823
|
for (let attempt = 1; attempt <= totalAttempts; attempt++) {
|
|
166824
|
+
throwIfSequenceCancelled(signal);
|
|
166713
166825
|
attemptsMade = attempt;
|
|
166714
166826
|
const startTime = Date.now();
|
|
166715
166827
|
const maxRedirects = 10;
|
|
@@ -166722,6 +166834,7 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166722
166834
|
let sentRequestHeaders = {};
|
|
166723
166835
|
try {
|
|
166724
166836
|
while (redirectCount <= maxRedirects) {
|
|
166837
|
+
throwIfSequenceCancelled(signal);
|
|
166725
166838
|
const existingCookies = await jar.getCookies(currentUrl);
|
|
166726
166839
|
const cookieHeader = existingCookies.map((c) => `${c.key}=${c.value}`).join("; ");
|
|
166727
166840
|
const headers = { ...request.headers };
|
|
@@ -166776,7 +166889,8 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166776
166889
|
timeout: getRequestTimeoutMs(),
|
|
166777
166890
|
maxRedirects: 0,
|
|
166778
166891
|
validateStatus: () => true,
|
|
166779
|
-
httpsAgent: getHttpsAgent()
|
|
166892
|
+
httpsAgent: getHttpsAgent(),
|
|
166893
|
+
signal
|
|
166780
166894
|
});
|
|
166781
166895
|
const setCookieHeader = response.headers["set-cookie"];
|
|
166782
166896
|
if (setCookieHeader) {
|
|
@@ -166811,7 +166925,7 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166811
166925
|
if (retryOptions?.onRetry) {
|
|
166812
166926
|
retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
|
|
166813
166927
|
}
|
|
166814
|
-
await
|
|
166928
|
+
await cancellableDelay(waitMs, signal);
|
|
166815
166929
|
continue;
|
|
166816
166930
|
}
|
|
166817
166931
|
const cookies = await getAllCookies(jar);
|
|
@@ -166834,6 +166948,9 @@ async function sendRequestWithJar(request, jar, retryOptions) {
|
|
|
166834
166948
|
}
|
|
166835
166949
|
return result;
|
|
166836
166950
|
} catch (error2) {
|
|
166951
|
+
if (signal?.aborted) {
|
|
166952
|
+
throw new SequenceCancelledError();
|
|
166953
|
+
}
|
|
166837
166954
|
const errorMessage = error2.message || String(error2);
|
|
166838
166955
|
const effectiveUrl = currentUrl || request.url;
|
|
166839
166956
|
const isUrlError = /invalid url/i.test(errorMessage) || /unsupported protocol/i.test(errorMessage);
|
|
@@ -166876,7 +166993,7 @@ URL used: ${effectiveUrl}`);
|
|
|
166876
166993
|
if (retryOptions?.onRetry) {
|
|
166877
166994
|
retryOptions.onRetry(attempt, totalAttempts, errorMessage, waitMs);
|
|
166878
166995
|
}
|
|
166879
|
-
await
|
|
166996
|
+
await cancellableDelay(waitMs, signal);
|
|
166880
166997
|
continue;
|
|
166881
166998
|
}
|
|
166882
166999
|
throw lastError;
|
|
@@ -167080,7 +167197,8 @@ function isRunCommand(line2) {
|
|
|
167080
167197
|
const trimmed = line2.trim();
|
|
167081
167198
|
return /^(var\s+[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*)?run\s+(bash|powershell|pwsh|js)\s+/i.test(trimmed);
|
|
167082
167199
|
}
|
|
167083
|
-
async function runScript(type, scriptPath, args, workingDir, variables = {}, captureVar) {
|
|
167200
|
+
async function runScript(type, scriptPath, args, workingDir, variables = {}, captureVar, signal) {
|
|
167201
|
+
throwIfSequenceCancelled(signal);
|
|
167084
167202
|
const startTime = Date.now();
|
|
167085
167203
|
const resolvedPath = path5.isAbsolute(scriptPath) ? scriptPath : path5.resolve(workingDir, scriptPath);
|
|
167086
167204
|
let command;
|
|
@@ -167111,7 +167229,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167111
167229
|
captureVar
|
|
167112
167230
|
};
|
|
167113
167231
|
}
|
|
167114
|
-
return new Promise((resolve28) => {
|
|
167232
|
+
return new Promise((resolve28, reject) => {
|
|
167115
167233
|
const env4 = {
|
|
167116
167234
|
...process.env,
|
|
167117
167235
|
// Pass variables as environment variables with NORN_ prefix
|
|
@@ -167128,6 +167246,28 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167128
167246
|
});
|
|
167129
167247
|
let stdout = "";
|
|
167130
167248
|
let stderr = "";
|
|
167249
|
+
let settled = false;
|
|
167250
|
+
const cancel = () => {
|
|
167251
|
+
if (settled) {
|
|
167252
|
+
return;
|
|
167253
|
+
}
|
|
167254
|
+
settled = true;
|
|
167255
|
+
signal?.removeEventListener("abort", cancel);
|
|
167256
|
+
child.kill("SIGTERM");
|
|
167257
|
+
reject(new SequenceCancelledError());
|
|
167258
|
+
};
|
|
167259
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
167260
|
+
if (signal?.aborted) {
|
|
167261
|
+
cancel();
|
|
167262
|
+
}
|
|
167263
|
+
const finish = (result) => {
|
|
167264
|
+
if (settled) {
|
|
167265
|
+
return;
|
|
167266
|
+
}
|
|
167267
|
+
settled = true;
|
|
167268
|
+
signal?.removeEventListener("abort", cancel);
|
|
167269
|
+
resolve28(result);
|
|
167270
|
+
};
|
|
167131
167271
|
child.stdout.on("data", (data) => {
|
|
167132
167272
|
stdout += data.toString();
|
|
167133
167273
|
});
|
|
@@ -167135,7 +167275,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167135
167275
|
stderr += data.toString();
|
|
167136
167276
|
});
|
|
167137
167277
|
child.on("error", (err) => {
|
|
167138
|
-
|
|
167278
|
+
finish({
|
|
167139
167279
|
success: false,
|
|
167140
167280
|
output: cleanScriptOutput(stdout),
|
|
167141
167281
|
error: `Failed to execute script: ${err.message}`,
|
|
@@ -167149,7 +167289,7 @@ async function runScript(type, scriptPath, args, workingDir, variables = {}, cap
|
|
|
167149
167289
|
child.on("close", (code) => {
|
|
167150
167290
|
const exitCode = code ?? 0;
|
|
167151
167291
|
const cleanedOutput = cleanScriptOutput(stdout);
|
|
167152
|
-
|
|
167292
|
+
finish({
|
|
167153
167293
|
success: exitCode === 0,
|
|
167154
167294
|
output: cleanedOutput,
|
|
167155
167295
|
error: stderr.trim(),
|
|
@@ -168730,7 +168870,8 @@ function buildAdapterError(message, stderr, stdout) {
|
|
|
168730
168870
|
}
|
|
168731
168871
|
return new Error(details.join("\n"));
|
|
168732
168872
|
}
|
|
168733
|
-
async function runExternalSqlAdapter(command, request, workingDir) {
|
|
168873
|
+
async function runExternalSqlAdapter(command, request, workingDir, signal) {
|
|
168874
|
+
throwIfSequenceCancelled(signal);
|
|
168734
168875
|
if (!command.length) {
|
|
168735
168876
|
throw new Error("SQL adapter command is empty");
|
|
168736
168877
|
}
|
|
@@ -168743,11 +168884,25 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168743
168884
|
let stdout = "";
|
|
168744
168885
|
let stderr = "";
|
|
168745
168886
|
let settled = false;
|
|
168887
|
+
const cancel = () => {
|
|
168888
|
+
if (settled) {
|
|
168889
|
+
return;
|
|
168890
|
+
}
|
|
168891
|
+
settled = true;
|
|
168892
|
+
signal?.removeEventListener("abort", cancel);
|
|
168893
|
+
child.kill("SIGTERM");
|
|
168894
|
+
reject(new SequenceCancelledError());
|
|
168895
|
+
};
|
|
168896
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
168897
|
+
if (signal?.aborted) {
|
|
168898
|
+
cancel();
|
|
168899
|
+
}
|
|
168746
168900
|
const fail3 = (error2) => {
|
|
168747
168901
|
if (settled) {
|
|
168748
168902
|
return;
|
|
168749
168903
|
}
|
|
168750
168904
|
settled = true;
|
|
168905
|
+
signal?.removeEventListener("abort", cancel);
|
|
168751
168906
|
reject(error2);
|
|
168752
168907
|
};
|
|
168753
168908
|
const succeed = (response) => {
|
|
@@ -168755,6 +168910,7 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168755
168910
|
return;
|
|
168756
168911
|
}
|
|
168757
168912
|
settled = true;
|
|
168913
|
+
signal?.removeEventListener("abort", cancel);
|
|
168758
168914
|
resolve28(response);
|
|
168759
168915
|
};
|
|
168760
168916
|
child.stdout.on("data", (chunk) => {
|
|
@@ -168812,11 +168968,11 @@ async function runExternalSqlAdapter(command, request, workingDir) {
|
|
|
168812
168968
|
}
|
|
168813
168969
|
});
|
|
168814
168970
|
}
|
|
168815
|
-
async function runSqlAdapter(target, request, workingDir) {
|
|
168971
|
+
async function runSqlAdapter(target, request, workingDir, signal) {
|
|
168816
168972
|
if (target.kind === "builtin") {
|
|
168817
|
-
return runBuiltInSqlAdapter(target.adapterId, request);
|
|
168973
|
+
return raceWithSequenceCancellation(runBuiltInSqlAdapter(target.adapterId, request), signal);
|
|
168818
168974
|
}
|
|
168819
|
-
return runExternalSqlAdapter(target.command, request, workingDir);
|
|
168975
|
+
return runExternalSqlAdapter(target.command, request, workingDir, signal);
|
|
168820
168976
|
}
|
|
168821
168977
|
|
|
168822
168978
|
// src/mcpClient.ts
|
|
@@ -168831,10 +168987,10 @@ var util3;
|
|
|
168831
168987
|
function assertIs2(_arg) {
|
|
168832
168988
|
}
|
|
168833
168989
|
util4.assertIs = assertIs2;
|
|
168834
|
-
function
|
|
168990
|
+
function assertNever6(_x) {
|
|
168835
168991
|
throw new Error();
|
|
168836
168992
|
}
|
|
168837
|
-
util4.assertNever =
|
|
168993
|
+
util4.assertNever = assertNever6;
|
|
168838
168994
|
util4.arrayToEnum = (items) => {
|
|
168839
168995
|
const obj = {};
|
|
168840
168996
|
for (const item of items) {
|
|
@@ -186229,15 +186385,155 @@ function describeUnmetExpectations(verdict) {
|
|
|
186229
186385
|
|
|
186230
186386
|
// src/agents/providers/providerUtils.ts
|
|
186231
186387
|
var import_crypto6 = require("crypto");
|
|
186388
|
+
|
|
186389
|
+
// src/agents/toolResultContext.ts
|
|
186390
|
+
var MAX_INLINE_TOOL_RESULT_TOKENS = 2e4;
|
|
186391
|
+
var MAX_INLINE_TOOL_RESULT_CHARACTERS = MAX_INLINE_TOOL_RESULT_TOKENS * 4;
|
|
186392
|
+
var MAX_RETAINED_INLINE_TOOL_RESULTS = 3;
|
|
186393
|
+
var TOOL_RESULT_PREVIEW_CHARACTERS = 2e3;
|
|
186394
|
+
var TOOL_RESULT_READ_CHARACTERS = 12e3;
|
|
186395
|
+
function outputToText(output2) {
|
|
186396
|
+
if (typeof output2 === "string") {
|
|
186397
|
+
return output2;
|
|
186398
|
+
}
|
|
186399
|
+
if (output2 === void 0) {
|
|
186400
|
+
return "";
|
|
186401
|
+
}
|
|
186402
|
+
try {
|
|
186403
|
+
return JSON.stringify(output2);
|
|
186404
|
+
} catch {
|
|
186405
|
+
return String(output2);
|
|
186406
|
+
}
|
|
186407
|
+
}
|
|
186408
|
+
function referenceText(input2) {
|
|
186409
|
+
return JSON.stringify({
|
|
186410
|
+
nornToolResult: {
|
|
186411
|
+
status: input2.released ? "released_from_context" : "offloaded",
|
|
186412
|
+
handle: input2.handle,
|
|
186413
|
+
tool: input2.toolName,
|
|
186414
|
+
originalCharacters: input2.originalCharacters,
|
|
186415
|
+
estimatedTokens: input2.estimatedTokens,
|
|
186416
|
+
...input2.preview !== void 0 ? { preview: input2.preview } : {},
|
|
186417
|
+
instruction: `Use norn_read_tool_result with handle '${input2.handle}' to read or search bounded portions.`
|
|
186418
|
+
}
|
|
186419
|
+
});
|
|
186420
|
+
}
|
|
186421
|
+
var PreparedAgentToolResult = class {
|
|
186422
|
+
constructor(recordedOutput, immediateOutput, immediateText, historyPlaceholder) {
|
|
186423
|
+
this.recordedOutput = recordedOutput;
|
|
186424
|
+
this.immediateOutput = immediateOutput;
|
|
186425
|
+
this.immediateText = immediateText;
|
|
186426
|
+
this.historyPlaceholder = historyPlaceholder;
|
|
186427
|
+
}
|
|
186428
|
+
};
|
|
186429
|
+
var AgentToolResultStore = class {
|
|
186430
|
+
results = /* @__PURE__ */ new Map();
|
|
186431
|
+
nextHandle = 1;
|
|
186432
|
+
prepare(toolName2, output2) {
|
|
186433
|
+
const text = outputToText(output2);
|
|
186434
|
+
const handle = `tool-result-${this.nextHandle++}`;
|
|
186435
|
+
const estimatedTokens = Math.ceil(text.length / 4);
|
|
186436
|
+
const stored = { handle, toolName: toolName2, text, estimatedTokens };
|
|
186437
|
+
this.results.set(handle, stored);
|
|
186438
|
+
const historyPlaceholder = referenceText({
|
|
186439
|
+
handle,
|
|
186440
|
+
toolName: toolName2,
|
|
186441
|
+
originalCharacters: text.length,
|
|
186442
|
+
estimatedTokens,
|
|
186443
|
+
released: true
|
|
186444
|
+
});
|
|
186445
|
+
if (text.length <= MAX_INLINE_TOOL_RESULT_CHARACTERS) {
|
|
186446
|
+
return new PreparedAgentToolResult(output2, output2, text, historyPlaceholder);
|
|
186447
|
+
}
|
|
186448
|
+
const offloadedReference = referenceText({
|
|
186449
|
+
handle,
|
|
186450
|
+
toolName: toolName2,
|
|
186451
|
+
originalCharacters: text.length,
|
|
186452
|
+
estimatedTokens,
|
|
186453
|
+
preview: text.slice(0, TOOL_RESULT_PREVIEW_CHARACTERS),
|
|
186454
|
+
released: false
|
|
186455
|
+
});
|
|
186456
|
+
return new PreparedAgentToolResult(output2, offloadedReference, offloadedReference, historyPlaceholder);
|
|
186457
|
+
}
|
|
186458
|
+
read(input2) {
|
|
186459
|
+
const handle = typeof input2.handle === "string" ? input2.handle : "";
|
|
186460
|
+
const stored = this.results.get(handle);
|
|
186461
|
+
if (!stored) {
|
|
186462
|
+
return { error: `Unknown or expired tool-result handle '${handle}'.` };
|
|
186463
|
+
}
|
|
186464
|
+
const query = typeof input2.query === "string" ? input2.query.trim() : "";
|
|
186465
|
+
if (query) {
|
|
186466
|
+
return this.search(stored, query);
|
|
186467
|
+
}
|
|
186468
|
+
const requestedOffset = typeof input2.offset === "number" && Number.isSafeInteger(input2.offset) ? input2.offset : 0;
|
|
186469
|
+
const offset = Math.max(0, Math.min(requestedOffset, stored.text.length));
|
|
186470
|
+
const text = stored.text.slice(offset, offset + TOOL_RESULT_READ_CHARACTERS);
|
|
186471
|
+
return {
|
|
186472
|
+
handle,
|
|
186473
|
+
tool: stored.toolName,
|
|
186474
|
+
offset,
|
|
186475
|
+
returnedCharacters: text.length,
|
|
186476
|
+
totalCharacters: stored.text.length,
|
|
186477
|
+
hasMore: offset + text.length < stored.text.length,
|
|
186478
|
+
text
|
|
186479
|
+
};
|
|
186480
|
+
}
|
|
186481
|
+
search(stored, query) {
|
|
186482
|
+
const haystack = stored.text.toLocaleLowerCase();
|
|
186483
|
+
const needle = query.toLocaleLowerCase();
|
|
186484
|
+
const matches = [];
|
|
186485
|
+
let from = 0;
|
|
186486
|
+
while (matches.length < 5) {
|
|
186487
|
+
const index = haystack.indexOf(needle, from);
|
|
186488
|
+
if (index < 0) {
|
|
186489
|
+
break;
|
|
186490
|
+
}
|
|
186491
|
+
const start = Math.max(0, index - 300);
|
|
186492
|
+
const end = Math.min(stored.text.length, index + query.length + 500);
|
|
186493
|
+
matches.push({ offset: start, text: stored.text.slice(start, end) });
|
|
186494
|
+
from = Math.max(index + needle.length, index + 1);
|
|
186495
|
+
}
|
|
186496
|
+
return {
|
|
186497
|
+
handle: stored.handle,
|
|
186498
|
+
tool: stored.toolName,
|
|
186499
|
+
query,
|
|
186500
|
+
totalCharacters: stored.text.length,
|
|
186501
|
+
matches
|
|
186502
|
+
};
|
|
186503
|
+
}
|
|
186504
|
+
};
|
|
186505
|
+
var AgentToolResultHistory = class {
|
|
186506
|
+
retained = [];
|
|
186507
|
+
retain(replaceWithReference) {
|
|
186508
|
+
this.retained.push(replaceWithReference);
|
|
186509
|
+
while (this.retained.length > MAX_RETAINED_INLINE_TOOL_RESULTS) {
|
|
186510
|
+
this.retained.shift()?.();
|
|
186511
|
+
}
|
|
186512
|
+
}
|
|
186513
|
+
};
|
|
186514
|
+
function normalizePreparedAgentToolResult(output2) {
|
|
186515
|
+
if (output2 instanceof PreparedAgentToolResult) {
|
|
186516
|
+
return output2;
|
|
186517
|
+
}
|
|
186518
|
+
return {
|
|
186519
|
+
recordedOutput: output2,
|
|
186520
|
+
immediateOutput: output2,
|
|
186521
|
+
immediateText: outputToText(output2),
|
|
186522
|
+
historyPlaceholder: "[Older tool result released from active context by Norn.]"
|
|
186523
|
+
};
|
|
186524
|
+
}
|
|
186525
|
+
|
|
186526
|
+
// src/agents/providers/providerUtils.ts
|
|
186232
186527
|
var PROVIDER_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/;
|
|
186233
186528
|
var PROVIDER_NAME_MAX_LENGTH = 64;
|
|
186234
186529
|
var AgentTurnLimitError = class extends Error {
|
|
186235
|
-
constructor(provider, maxTurns, toolCallCount, lastToolName) {
|
|
186530
|
+
constructor(provider, maxTurns, toolCallCount, lastToolName, usage) {
|
|
186236
186531
|
super(`${provider} tool loop reached its ${maxTurns}-turn limit before the model finished.`);
|
|
186237
186532
|
this.provider = provider;
|
|
186238
186533
|
this.maxTurns = maxTurns;
|
|
186239
186534
|
this.toolCallCount = toolCallCount;
|
|
186240
186535
|
this.lastToolName = lastToolName;
|
|
186536
|
+
this.usage = usage;
|
|
186241
186537
|
this.name = "AgentTurnLimitError";
|
|
186242
186538
|
}
|
|
186243
186539
|
};
|
|
@@ -186310,19 +186606,6 @@ function agentInputToText(input2) {
|
|
|
186310
186606
|
return String(input2);
|
|
186311
186607
|
}
|
|
186312
186608
|
}
|
|
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
186609
|
function tryParseStructuredAgentOutput(text, hasSchema) {
|
|
186327
186610
|
if (!hasSchema) {
|
|
186328
186611
|
return void 0;
|
|
@@ -186405,7 +186688,70 @@ function createRecordedToolCall(records, name, input2, kind) {
|
|
|
186405
186688
|
|
|
186406
186689
|
// src/agents/providers/anthropicAdapter.ts
|
|
186407
186690
|
init_sdk();
|
|
186408
|
-
|
|
186691
|
+
|
|
186692
|
+
// src/agents/agentTokenBudget.ts
|
|
186693
|
+
function estimateSerializedInputTokens(value) {
|
|
186694
|
+
let text;
|
|
186695
|
+
try {
|
|
186696
|
+
text = JSON.stringify(value) ?? "";
|
|
186697
|
+
} catch {
|
|
186698
|
+
text = String(value);
|
|
186699
|
+
}
|
|
186700
|
+
return Math.ceil(text.length / 3);
|
|
186701
|
+
}
|
|
186702
|
+
function formatAgentInputTokenLimitError(agentName, outcome) {
|
|
186703
|
+
const next = outcome.estimatedNextInputTokens === void 0 ? "" : ` The next request was estimated at ${outcome.estimatedNextInputTokens} input tokens.`;
|
|
186704
|
+
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.`;
|
|
186705
|
+
}
|
|
186706
|
+
function sumAgentTurnUsage(turns) {
|
|
186707
|
+
return {
|
|
186708
|
+
inputTokens: turns.reduce((total, turn) => total + turn.inputTokens, 0),
|
|
186709
|
+
outputTokens: turns.reduce((total, turn) => total + turn.outputTokens, 0),
|
|
186710
|
+
turns: turns.map((turn) => ({ ...turn }))
|
|
186711
|
+
};
|
|
186712
|
+
}
|
|
186713
|
+
var AgentInputTokenLimitError = class extends Error {
|
|
186714
|
+
constructor(provider, maxInputTokens, usedInputTokens, usage, estimatedNextInputTokens) {
|
|
186715
|
+
const reason = estimatedNextInputTokens === void 0 ? `after using ${usedInputTokens}` : `before an estimated ${estimatedNextInputTokens}-token request with ${usedInputTokens} already used`;
|
|
186716
|
+
super(`${provider} agent input budget ${maxInputTokens} was reached ${reason}.`);
|
|
186717
|
+
this.provider = provider;
|
|
186718
|
+
this.maxInputTokens = maxInputTokens;
|
|
186719
|
+
this.usedInputTokens = usedInputTokens;
|
|
186720
|
+
this.usage = usage;
|
|
186721
|
+
this.estimatedNextInputTokens = estimatedNextInputTokens;
|
|
186722
|
+
this.name = "AgentInputTokenLimitError";
|
|
186723
|
+
}
|
|
186724
|
+
};
|
|
186725
|
+
function assertInputBudgetAllowsCall(provider, budget, estimatedNextInputTokens, turns) {
|
|
186726
|
+
if (!budget || budget.usedInputTokens + estimatedNextInputTokens <= budget.maxInputTokens) {
|
|
186727
|
+
return;
|
|
186728
|
+
}
|
|
186729
|
+
throw new AgentInputTokenLimitError(
|
|
186730
|
+
provider,
|
|
186731
|
+
budget.maxInputTokens,
|
|
186732
|
+
budget.usedInputTokens,
|
|
186733
|
+
sumAgentTurnUsage(turns),
|
|
186734
|
+
estimatedNextInputTokens
|
|
186735
|
+
);
|
|
186736
|
+
}
|
|
186737
|
+
function recordAgentTurnUsage(provider, budget, turns, usage) {
|
|
186738
|
+
const turn = { turn: turns.length + 1, ...usage };
|
|
186739
|
+
turns.push(turn);
|
|
186740
|
+
if (!budget) {
|
|
186741
|
+
return;
|
|
186742
|
+
}
|
|
186743
|
+
budget.usedInputTokens += turn.inputTokens;
|
|
186744
|
+
if (budget.usedInputTokens > budget.maxInputTokens) {
|
|
186745
|
+
throw new AgentInputTokenLimitError(
|
|
186746
|
+
provider,
|
|
186747
|
+
budget.maxInputTokens,
|
|
186748
|
+
budget.usedInputTokens,
|
|
186749
|
+
sumAgentTurnUsage(turns)
|
|
186750
|
+
);
|
|
186751
|
+
}
|
|
186752
|
+
}
|
|
186753
|
+
|
|
186754
|
+
// src/agents/providers/anthropicAdapter.ts
|
|
186409
186755
|
function supportsAdaptiveThinking(modelId) {
|
|
186410
186756
|
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
186757
|
}
|
|
@@ -186487,67 +186833,136 @@ var AnthropicAgentAdapter = class {
|
|
|
186487
186833
|
})),
|
|
186488
186834
|
inputMessage
|
|
186489
186835
|
];
|
|
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({
|
|
186836
|
+
const turns = [];
|
|
186837
|
+
if (request.tools.length === 0) {
|
|
186838
|
+
const call = {
|
|
186521
186839
|
model: request.modelId,
|
|
186522
186840
|
max_tokens: request.maxTokens,
|
|
186523
186841
|
system: request.systemPrompt,
|
|
186524
186842
|
messages,
|
|
186525
|
-
tools: runnableTools,
|
|
186526
|
-
tool_choice: { type: "auto", disable_parallel_tool_use: true },
|
|
186527
186843
|
output_config: outputConfig,
|
|
186528
|
-
thinking
|
|
186529
|
-
|
|
186530
|
-
|
|
186844
|
+
thinking
|
|
186845
|
+
};
|
|
186846
|
+
assertInputBudgetAllowsCall(
|
|
186847
|
+
this.provider,
|
|
186848
|
+
request.inputTokenBudget,
|
|
186849
|
+
estimateSerializedInputTokens(call),
|
|
186850
|
+
turns
|
|
186851
|
+
);
|
|
186852
|
+
const finalMessage = await client.messages.create(
|
|
186853
|
+
call,
|
|
186854
|
+
request.signal ? { signal: request.signal } : void 0
|
|
186855
|
+
);
|
|
186856
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
186857
|
+
inputTokens: finalMessage.usage.input_tokens + (finalMessage.usage.cache_creation_input_tokens ?? 0) + (finalMessage.usage.cache_read_input_tokens ?? 0),
|
|
186858
|
+
outputTokens: finalMessage.usage.output_tokens,
|
|
186859
|
+
...typeof finalMessage.usage.cache_read_input_tokens === "number" ? { cachedInputTokens: finalMessage.usage.cache_read_input_tokens } : {},
|
|
186860
|
+
...typeof finalMessage.usage.cache_creation_input_tokens === "number" ? { cacheWriteInputTokens: finalMessage.usage.cache_creation_input_tokens } : {}
|
|
186531
186861
|
});
|
|
186532
|
-
|
|
186533
|
-
|
|
186534
|
-
|
|
186535
|
-
|
|
186536
|
-
|
|
186862
|
+
return this.completeResponse(request, finalMessage, toolCalls, turns);
|
|
186863
|
+
}
|
|
186864
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
186865
|
+
const betaMessages = messages;
|
|
186866
|
+
const toolsByProviderName = new Map(
|
|
186867
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared.tool])
|
|
186868
|
+
);
|
|
186869
|
+
const tools = preparedTools.map(({ tool, providerName }) => {
|
|
186870
|
+
if (tool.inputSchema.type !== "object") {
|
|
186871
|
+
throw new Error(`Tool '${tool.name}' must expose an object input schema.`);
|
|
186537
186872
|
}
|
|
186538
|
-
|
|
186539
|
-
|
|
186540
|
-
|
|
186873
|
+
return {
|
|
186874
|
+
name: providerName,
|
|
186875
|
+
description: tool.description || `Run ${tool.name}`,
|
|
186876
|
+
input_schema: tool.inputSchema
|
|
186877
|
+
};
|
|
186878
|
+
});
|
|
186879
|
+
const toolHistory = new AgentToolResultHistory();
|
|
186880
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
186881
|
+
const call = {
|
|
186541
186882
|
model: request.modelId,
|
|
186542
186883
|
max_tokens: request.maxTokens,
|
|
186543
186884
|
system: request.systemPrompt,
|
|
186544
|
-
messages,
|
|
186885
|
+
messages: betaMessages,
|
|
186886
|
+
tools,
|
|
186887
|
+
tool_choice: { type: "auto", disable_parallel_tool_use: true },
|
|
186545
186888
|
output_config: outputConfig,
|
|
186546
186889
|
thinking
|
|
186890
|
+
};
|
|
186891
|
+
assertInputBudgetAllowsCall(
|
|
186892
|
+
this.provider,
|
|
186893
|
+
request.inputTokenBudget,
|
|
186894
|
+
estimateSerializedInputTokens(call),
|
|
186895
|
+
turns
|
|
186896
|
+
);
|
|
186897
|
+
const response = await client.beta.messages.create(
|
|
186898
|
+
call,
|
|
186899
|
+
request.signal ? { signal: request.signal } : void 0
|
|
186900
|
+
);
|
|
186901
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
186902
|
+
inputTokens: response.usage.input_tokens + (response.usage.cache_creation_input_tokens ?? 0) + (response.usage.cache_read_input_tokens ?? 0),
|
|
186903
|
+
outputTokens: response.usage.output_tokens,
|
|
186904
|
+
...typeof response.usage.cache_read_input_tokens === "number" ? { cachedInputTokens: response.usage.cache_read_input_tokens } : {},
|
|
186905
|
+
...typeof response.usage.cache_creation_input_tokens === "number" ? { cacheWriteInputTokens: response.usage.cache_creation_input_tokens } : {}
|
|
186906
|
+
});
|
|
186907
|
+
const calls = response.content.filter((block) => block.type === "tool_use");
|
|
186908
|
+
if (calls.length === 0) {
|
|
186909
|
+
return this.completeResponse(request, response, toolCalls, turns);
|
|
186910
|
+
}
|
|
186911
|
+
if (turn >= request.maxTurns) {
|
|
186912
|
+
throw new AgentTurnLimitError(
|
|
186913
|
+
this.provider,
|
|
186914
|
+
request.maxTurns,
|
|
186915
|
+
toolCalls.length,
|
|
186916
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186917
|
+
sumAgentTurnUsage(turns)
|
|
186918
|
+
);
|
|
186919
|
+
}
|
|
186920
|
+
betaMessages.push({
|
|
186921
|
+
role: "assistant",
|
|
186922
|
+
content: response.content
|
|
186547
186923
|
});
|
|
186548
|
-
|
|
186549
|
-
|
|
186924
|
+
const resultBlocks = [];
|
|
186925
|
+
for (const callBlock of calls) {
|
|
186926
|
+
const tool = toolsByProviderName.get(callBlock.name);
|
|
186927
|
+
if (!tool) {
|
|
186928
|
+
throw new Error(`Anthropic requested unknown tool '${callBlock.name}'.`);
|
|
186929
|
+
}
|
|
186930
|
+
const input2 = parseToolInput(callBlock.input);
|
|
186931
|
+
const recorded = createRecordedToolCall(toolCalls, tool.name, input2, tool.kind);
|
|
186932
|
+
let preparedOutput;
|
|
186933
|
+
try {
|
|
186934
|
+
const output2 = await tool.execute(input2);
|
|
186935
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
186936
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
186937
|
+
} catch (error2) {
|
|
186938
|
+
const output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
186939
|
+
recorded.complete(output2);
|
|
186940
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
186941
|
+
throw error2;
|
|
186942
|
+
}
|
|
186943
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
186944
|
+
}
|
|
186945
|
+
const resultBlock = {
|
|
186946
|
+
type: "tool_result",
|
|
186947
|
+
tool_use_id: callBlock.id,
|
|
186948
|
+
content: preparedOutput.immediateText
|
|
186949
|
+
};
|
|
186950
|
+
resultBlocks.push(resultBlock);
|
|
186951
|
+
toolHistory.retain(() => {
|
|
186952
|
+
resultBlock.content = preparedOutput.historyPlaceholder;
|
|
186953
|
+
});
|
|
186954
|
+
}
|
|
186955
|
+
betaMessages.push({ role: "user", content: resultBlocks });
|
|
186550
186956
|
}
|
|
186957
|
+
throw new AgentTurnLimitError(
|
|
186958
|
+
this.provider,
|
|
186959
|
+
request.maxTurns,
|
|
186960
|
+
toolCalls.length,
|
|
186961
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186962
|
+
sumAgentTurnUsage(turns)
|
|
186963
|
+
);
|
|
186964
|
+
}
|
|
186965
|
+
completeResponse(request, finalMessage, toolCalls, turns) {
|
|
186551
186966
|
const text = getVisibleText(finalMessage, Boolean(request.outputSchema));
|
|
186552
186967
|
if (finalMessage.stop_reason === "refusal") {
|
|
186553
186968
|
throw new AgentProviderRefusalError(`Anthropic model refused the request${text ? `: ${text}` : "."}`, text);
|
|
@@ -186560,7 +186975,8 @@ var AnthropicAgentAdapter = class {
|
|
|
186560
186975
|
this.provider,
|
|
186561
186976
|
request.maxTurns,
|
|
186562
186977
|
toolCalls.length,
|
|
186563
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
186978
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
186979
|
+
sumAgentTurnUsage(turns)
|
|
186564
186980
|
);
|
|
186565
186981
|
}
|
|
186566
186982
|
if (finalMessage.stop_reason === "model_context_window_exceeded") {
|
|
@@ -186573,7 +186989,7 @@ var AnthropicAgentAdapter = class {
|
|
|
186573
186989
|
text,
|
|
186574
186990
|
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
186575
186991
|
toolCalls,
|
|
186576
|
-
usage:
|
|
186992
|
+
usage: sumAgentTurnUsage(turns),
|
|
186577
186993
|
resolvedModelId: finalMessage.model || request.modelId
|
|
186578
186994
|
};
|
|
186579
186995
|
}
|
|
@@ -186759,6 +187175,7 @@ var GoogleAgentAdapter = class {
|
|
|
186759
187175
|
const config2 = {
|
|
186760
187176
|
systemInstruction: request.systemPrompt,
|
|
186761
187177
|
maxOutputTokens: request.maxTokens,
|
|
187178
|
+
...request.signal ? { abortSignal: request.signal } : {},
|
|
186762
187179
|
...request.outputSchema ? {
|
|
186763
187180
|
responseMimeType: "application/json",
|
|
186764
187181
|
responseJsonSchema: request.outputSchema
|
|
@@ -186777,18 +187194,28 @@ var GoogleAgentAdapter = class {
|
|
|
186777
187194
|
automaticFunctionCalling: { disable: true }
|
|
186778
187195
|
} : {}
|
|
186779
187196
|
};
|
|
186780
|
-
let inputTokens = 0;
|
|
186781
|
-
let outputTokens = 0;
|
|
186782
187197
|
let resolvedModelId2 = request.modelId;
|
|
187198
|
+
const turns = [];
|
|
187199
|
+
const toolHistory = new AgentToolResultHistory();
|
|
186783
187200
|
for (let turn = 0; turn < request.maxTurns; turn++) {
|
|
187201
|
+
const estimatedInputTokens = estimateSerializedInputTokens({ contents, config: config2 });
|
|
187202
|
+
assertInputBudgetAllowsCall(
|
|
187203
|
+
this.provider,
|
|
187204
|
+
request.inputTokenBudget,
|
|
187205
|
+
estimatedInputTokens,
|
|
187206
|
+
turns
|
|
187207
|
+
);
|
|
186784
187208
|
const response = await client.models.generateContent({
|
|
186785
187209
|
model: request.modelId,
|
|
186786
187210
|
contents,
|
|
186787
187211
|
config: config2
|
|
186788
187212
|
});
|
|
186789
187213
|
const usage = response.usageMetadata;
|
|
186790
|
-
|
|
186791
|
-
|
|
187214
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
187215
|
+
inputTokens: usage ? (usage.promptTokenCount ?? 0) + (usage.toolUsePromptTokenCount ?? 0) : estimatedInputTokens,
|
|
187216
|
+
outputTokens: (usage?.candidatesTokenCount ?? 0) + (usage?.thoughtsTokenCount ?? 0),
|
|
187217
|
+
...usage?.cachedContentTokenCount !== void 0 ? { cachedInputTokens: usage.cachedContentTokenCount } : {}
|
|
187218
|
+
});
|
|
186792
187219
|
resolvedModelId2 = response.modelVersion || resolvedModelId2;
|
|
186793
187220
|
const requestedCalls = getFunctionCalls(response);
|
|
186794
187221
|
const text = getVisibleText2(
|
|
@@ -186803,7 +187230,7 @@ var GoogleAgentAdapter = class {
|
|
|
186803
187230
|
text,
|
|
186804
187231
|
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
186805
187232
|
toolCalls,
|
|
186806
|
-
usage:
|
|
187233
|
+
usage: sumAgentTurnUsage(turns),
|
|
186807
187234
|
resolvedModelId: resolvedModelId2
|
|
186808
187235
|
};
|
|
186809
187236
|
}
|
|
@@ -186817,7 +187244,8 @@ var GoogleAgentAdapter = class {
|
|
|
186817
187244
|
this.provider,
|
|
186818
187245
|
request.maxTurns,
|
|
186819
187246
|
toolCalls.length,
|
|
186820
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
187247
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
187248
|
+
sumAgentTurnUsage(turns)
|
|
186821
187249
|
);
|
|
186822
187250
|
}
|
|
186823
187251
|
const modelContent = getCandidate(response)?.content;
|
|
@@ -186838,8 +187266,12 @@ var GoogleAgentAdapter = class {
|
|
|
186838
187266
|
let responseBody;
|
|
186839
187267
|
try {
|
|
186840
187268
|
const output2 = await tool.execute(input2);
|
|
186841
|
-
|
|
186842
|
-
|
|
187269
|
+
const preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
187270
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
187271
|
+
responseBody = { output: preparedOutput.immediateOutput };
|
|
187272
|
+
toolHistory.retain(() => {
|
|
187273
|
+
responseBody.output = preparedOutput.historyPlaceholder;
|
|
187274
|
+
});
|
|
186843
187275
|
} catch (error2) {
|
|
186844
187276
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
186845
187277
|
const output2 = { error: message };
|
|
@@ -186864,7 +187296,8 @@ var GoogleAgentAdapter = class {
|
|
|
186864
187296
|
this.provider,
|
|
186865
187297
|
request.maxTurns,
|
|
186866
187298
|
toolCalls.length,
|
|
186867
|
-
toolCalls[toolCalls.length - 1]?.name
|
|
187299
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
187300
|
+
sumAgentTurnUsage(turns)
|
|
186868
187301
|
);
|
|
186869
187302
|
}
|
|
186870
187303
|
};
|
|
@@ -187108,7 +187541,7 @@ var safeJSON2 = (text) => {
|
|
|
187108
187541
|
};
|
|
187109
187542
|
|
|
187110
187543
|
// node_modules/openai/internal/utils/sleep.mjs
|
|
187111
|
-
var
|
|
187544
|
+
var sleep3 = (ms) => new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
187112
187545
|
|
|
187113
187546
|
// node_modules/openai/version.mjs
|
|
187114
187547
|
var VERSION4 = "6.49.0";
|
|
@@ -194427,7 +194860,7 @@ var Runs = class extends APIResource2 {
|
|
|
194427
194860
|
}
|
|
194428
194861
|
}
|
|
194429
194862
|
}
|
|
194430
|
-
await
|
|
194863
|
+
await sleep3(sleepInterval);
|
|
194431
194864
|
break;
|
|
194432
194865
|
//We return the run in any terminal state.
|
|
194433
194866
|
case "requires_action":
|
|
@@ -195036,7 +195469,7 @@ var Files4 = class extends APIResource2 {
|
|
|
195036
195469
|
const start = Date.now();
|
|
195037
195470
|
let file2 = await this.retrieve(id);
|
|
195038
195471
|
while (!file2.status || !TERMINAL_STATES.has(file2.status)) {
|
|
195039
|
-
await
|
|
195472
|
+
await sleep3(pollInterval);
|
|
195040
195473
|
file2 = await this.retrieve(id);
|
|
195041
195474
|
if (Date.now() - start > maxWait) {
|
|
195042
195475
|
throw new APIConnectionTimeoutError3({
|
|
@@ -196732,7 +197165,7 @@ var FileBatches = class extends APIResource2 {
|
|
|
196732
197165
|
}
|
|
196733
197166
|
}
|
|
196734
197167
|
}
|
|
196735
|
-
await
|
|
197168
|
+
await sleep3(sleepInterval);
|
|
196736
197169
|
break;
|
|
196737
197170
|
case "failed":
|
|
196738
197171
|
case "cancelled":
|
|
@@ -196872,7 +197305,7 @@ var Files5 = class extends APIResource2 {
|
|
|
196872
197305
|
}
|
|
196873
197306
|
}
|
|
196874
197307
|
}
|
|
196875
|
-
await
|
|
197308
|
+
await sleep3(sleepInterval);
|
|
196876
197309
|
break;
|
|
196877
197310
|
case "failed":
|
|
196878
197311
|
case "completed":
|
|
@@ -197648,7 +198081,7 @@ var OpenAI = class {
|
|
|
197648
198081
|
const maxRetries = options.maxRetries ?? this.maxRetries;
|
|
197649
198082
|
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
|
|
197650
198083
|
}
|
|
197651
|
-
await
|
|
198084
|
+
await sleep3(timeoutMillis);
|
|
197652
198085
|
return this.makeRequest(options, retriesRemaining - 1, requestLogID);
|
|
197653
198086
|
}
|
|
197654
198087
|
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
|
|
@@ -197816,6 +198249,93 @@ function isUndiciDispatcherVersionMismatchError(error2) {
|
|
|
197816
198249
|
return false;
|
|
197817
198250
|
}
|
|
197818
198251
|
|
|
198252
|
+
// node_modules/openai/lib/responses/ResponseInputItems.mjs
|
|
198253
|
+
function toResponseInputItems(items) {
|
|
198254
|
+
const inputItems = [];
|
|
198255
|
+
for (const item of items) {
|
|
198256
|
+
const inputItem = toResponseInputItem(item);
|
|
198257
|
+
if (inputItem) {
|
|
198258
|
+
inputItems.push(inputItem);
|
|
198259
|
+
}
|
|
198260
|
+
}
|
|
198261
|
+
return inputItems;
|
|
198262
|
+
}
|
|
198263
|
+
function toResponseInputItem(item) {
|
|
198264
|
+
switch (item.type) {
|
|
198265
|
+
case "additional_tools": {
|
|
198266
|
+
if (item.role !== "developer") {
|
|
198267
|
+
return null;
|
|
198268
|
+
}
|
|
198269
|
+
return stripCreatedBy(item);
|
|
198270
|
+
}
|
|
198271
|
+
case "shell_call_output": {
|
|
198272
|
+
const output2 = item.output.map((chunk) => stripCreatedBy(chunk));
|
|
198273
|
+
return {
|
|
198274
|
+
...stripCreatedBy(item),
|
|
198275
|
+
output: output2
|
|
198276
|
+
};
|
|
198277
|
+
}
|
|
198278
|
+
case "computer_call_output": {
|
|
198279
|
+
const { created_by: _createdBy, ...withoutCreatedBy } = item;
|
|
198280
|
+
if (withoutCreatedBy.status === "failed") {
|
|
198281
|
+
return null;
|
|
198282
|
+
}
|
|
198283
|
+
return withoutCreatedBy;
|
|
198284
|
+
}
|
|
198285
|
+
case "custom_tool_call_output": {
|
|
198286
|
+
if ("status" in item && item.status !== "completed") {
|
|
198287
|
+
return null;
|
|
198288
|
+
}
|
|
198289
|
+
const { created_by: _createdBy, status: _status, ...inputItem } = item;
|
|
198290
|
+
return inputItem;
|
|
198291
|
+
}
|
|
198292
|
+
case "apply_patch_call":
|
|
198293
|
+
case "apply_patch_call_output":
|
|
198294
|
+
case "code_interpreter_call":
|
|
198295
|
+
case "compaction":
|
|
198296
|
+
case "compaction_trigger":
|
|
198297
|
+
case "computer_call":
|
|
198298
|
+
case "custom_tool_call":
|
|
198299
|
+
case "file_search_call":
|
|
198300
|
+
case "function_call":
|
|
198301
|
+
case "function_call_output":
|
|
198302
|
+
case "image_generation_call":
|
|
198303
|
+
case "item_reference":
|
|
198304
|
+
case "local_shell_call":
|
|
198305
|
+
case "local_shell_call_output":
|
|
198306
|
+
case "mcp_approval_request":
|
|
198307
|
+
case "mcp_approval_response":
|
|
198308
|
+
case "mcp_call":
|
|
198309
|
+
case "mcp_list_tools":
|
|
198310
|
+
case "message":
|
|
198311
|
+
case "program":
|
|
198312
|
+
case "program_output":
|
|
198313
|
+
case "reasoning":
|
|
198314
|
+
case "shell_call":
|
|
198315
|
+
case "tool_search_call":
|
|
198316
|
+
case "tool_search_output":
|
|
198317
|
+
case "web_search_call":
|
|
198318
|
+
case null:
|
|
198319
|
+
case void 0: {
|
|
198320
|
+
return stripCreatedBy(item);
|
|
198321
|
+
}
|
|
198322
|
+
default: {
|
|
198323
|
+
return assertNever5(item);
|
|
198324
|
+
}
|
|
198325
|
+
}
|
|
198326
|
+
}
|
|
198327
|
+
function stripCreatedBy(item) {
|
|
198328
|
+
if (!("created_by" in item)) {
|
|
198329
|
+
return item;
|
|
198330
|
+
}
|
|
198331
|
+
const { created_by: _createdBy, ...rest } = item;
|
|
198332
|
+
return rest;
|
|
198333
|
+
}
|
|
198334
|
+
function assertNever5(value) {
|
|
198335
|
+
const type = value.type;
|
|
198336
|
+
throw new TypeError(`Unsupported response item type: ${String(type)}`);
|
|
198337
|
+
}
|
|
198338
|
+
|
|
197819
198339
|
// src/agents/providers/openaiAdapter.ts
|
|
197820
198340
|
function parseToolArguments(raw) {
|
|
197821
198341
|
const parsed = JSON.parse(raw);
|
|
@@ -197825,7 +198345,251 @@ function parseToolArguments(raw) {
|
|
|
197825
198345
|
return parsed;
|
|
197826
198346
|
}
|
|
197827
198347
|
var OpenAIAgentAdapter = class {
|
|
197828
|
-
|
|
198348
|
+
provider = "openai";
|
|
198349
|
+
createClient(request) {
|
|
198350
|
+
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "OPENAI_API_KEY");
|
|
198351
|
+
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "OPENAI_BASE_URL");
|
|
198352
|
+
try {
|
|
198353
|
+
return new OpenAI({
|
|
198354
|
+
...apiKey ? { apiKey } : {},
|
|
198355
|
+
...baseURL ? { baseURL } : {}
|
|
198356
|
+
});
|
|
198357
|
+
} catch (error2) {
|
|
198358
|
+
if (error2 instanceof Error && error2.message.includes("Missing credentials")) {
|
|
198359
|
+
throw new Error(
|
|
198360
|
+
"OpenAI authentication failed. Add an apiKey directive to the model block, for example: apiKey {{$env.OPENAI_API_KEY}}.",
|
|
198361
|
+
{ cause: error2 }
|
|
198362
|
+
);
|
|
198363
|
+
}
|
|
198364
|
+
throw error2;
|
|
198365
|
+
}
|
|
198366
|
+
}
|
|
198367
|
+
async run(request) {
|
|
198368
|
+
if (request.provider !== this.provider) {
|
|
198369
|
+
throw new Error(`The openai provider adapter cannot run a ${request.provider} request.`);
|
|
198370
|
+
}
|
|
198371
|
+
try {
|
|
198372
|
+
return await this.runRequest(request);
|
|
198373
|
+
} catch (error2) {
|
|
198374
|
+
if (error2 instanceof AgentProviderRefusalError) {
|
|
198375
|
+
throw error2;
|
|
198376
|
+
}
|
|
198377
|
+
if (error2 instanceof OpenAI.APIError) {
|
|
198378
|
+
if (isAgentProviderMaxTokensRejection(error2)) {
|
|
198379
|
+
throw new AgentProviderMaxTokensError(
|
|
198380
|
+
this.provider,
|
|
198381
|
+
request.maxTokens,
|
|
198382
|
+
error2.message,
|
|
198383
|
+
error2
|
|
198384
|
+
);
|
|
198385
|
+
}
|
|
198386
|
+
const status = error2.status ? ` (HTTP ${error2.status})` : "";
|
|
198387
|
+
const requestId = error2.requestID ? ` [request ${error2.requestID}]` : "";
|
|
198388
|
+
throw new Error(`OpenAI API request failed${status}: ${error2.message}${requestId}`, {
|
|
198389
|
+
cause: error2
|
|
198390
|
+
});
|
|
198391
|
+
}
|
|
198392
|
+
throw error2;
|
|
198393
|
+
}
|
|
198394
|
+
}
|
|
198395
|
+
async runRequest(request) {
|
|
198396
|
+
const client = this.createClient(request);
|
|
198397
|
+
const toolCalls = [];
|
|
198398
|
+
const input2 = [
|
|
198399
|
+
...(request.conversation ?? []).map((message) => ({
|
|
198400
|
+
type: "message",
|
|
198401
|
+
role: message.role,
|
|
198402
|
+
content: message.content
|
|
198403
|
+
})),
|
|
198404
|
+
{
|
|
198405
|
+
type: "message",
|
|
198406
|
+
role: "user",
|
|
198407
|
+
content: agentInputToText(request.input)
|
|
198408
|
+
}
|
|
198409
|
+
];
|
|
198410
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
198411
|
+
const tools = preparedTools.map(({ tool, providerName }) => ({
|
|
198412
|
+
type: "function",
|
|
198413
|
+
name: providerName,
|
|
198414
|
+
description: tool.description || `Run ${tool.name}`,
|
|
198415
|
+
parameters: tool.inputSchema,
|
|
198416
|
+
strict: false
|
|
198417
|
+
}));
|
|
198418
|
+
const toolsByProviderName = new Map(
|
|
198419
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared])
|
|
198420
|
+
);
|
|
198421
|
+
const text = request.outputSchema ? {
|
|
198422
|
+
format: {
|
|
198423
|
+
type: "json_schema",
|
|
198424
|
+
name: toProviderSchemaName(request.outputSchemaName),
|
|
198425
|
+
schema: request.outputSchema,
|
|
198426
|
+
strict: true
|
|
198427
|
+
}
|
|
198428
|
+
} : void 0;
|
|
198429
|
+
let resolvedModelId2 = request.modelId;
|
|
198430
|
+
const turns = [];
|
|
198431
|
+
const toolHistory = new AgentToolResultHistory();
|
|
198432
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
198433
|
+
const estimatedInputTokens = estimateSerializedInputTokens({
|
|
198434
|
+
instructions: request.systemPrompt,
|
|
198435
|
+
input: input2,
|
|
198436
|
+
tools,
|
|
198437
|
+
text
|
|
198438
|
+
});
|
|
198439
|
+
assertInputBudgetAllowsCall(
|
|
198440
|
+
this.provider,
|
|
198441
|
+
request.inputTokenBudget,
|
|
198442
|
+
estimatedInputTokens,
|
|
198443
|
+
turns
|
|
198444
|
+
);
|
|
198445
|
+
const response = await client.responses.create({
|
|
198446
|
+
model: request.modelId,
|
|
198447
|
+
instructions: request.systemPrompt,
|
|
198448
|
+
input: input2,
|
|
198449
|
+
max_output_tokens: request.maxTokens,
|
|
198450
|
+
store: false,
|
|
198451
|
+
parallel_tool_calls: false,
|
|
198452
|
+
...request.reasoningEffort ? { reasoning: { effort: request.reasoningEffort } } : {},
|
|
198453
|
+
...tools.length > 0 ? {
|
|
198454
|
+
tools,
|
|
198455
|
+
tool_choice: "auto",
|
|
198456
|
+
include: ["reasoning.encrypted_content"]
|
|
198457
|
+
} : {},
|
|
198458
|
+
...text ? { text } : {}
|
|
198459
|
+
}, request.signal ? { signal: request.signal } : void 0);
|
|
198460
|
+
resolvedModelId2 = response.model || request.modelId;
|
|
198461
|
+
const turnInputTokens = response.usage?.input_tokens ?? estimatedInputTokens;
|
|
198462
|
+
const turnOutputTokens = response.usage?.output_tokens ?? 0;
|
|
198463
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
198464
|
+
inputTokens: turnInputTokens,
|
|
198465
|
+
outputTokens: turnOutputTokens,
|
|
198466
|
+
...response.usage?.input_tokens_details?.cached_tokens !== void 0 ? { cachedInputTokens: response.usage.input_tokens_details.cached_tokens } : {},
|
|
198467
|
+
...response.usage?.input_tokens_details?.cache_write_tokens !== void 0 ? { cacheWriteInputTokens: response.usage.input_tokens_details.cache_write_tokens } : {}
|
|
198468
|
+
});
|
|
198469
|
+
const refusal = response.output.filter((item) => item.type === "message").flatMap((message) => message.content).find((content) => content.type === "refusal");
|
|
198470
|
+
if (refusal?.type === "refusal") {
|
|
198471
|
+
throw new AgentProviderRefusalError(
|
|
198472
|
+
`OpenAI model refused the request: ${refusal.refusal}`,
|
|
198473
|
+
response.output_text || refusal.refusal
|
|
198474
|
+
);
|
|
198475
|
+
}
|
|
198476
|
+
if (response.error) {
|
|
198477
|
+
throw new Error(`OpenAI response failed: ${response.error.message}`);
|
|
198478
|
+
}
|
|
198479
|
+
const calls = response.output.filter((item) => item.type === "function_call");
|
|
198480
|
+
if (calls.length === 0) {
|
|
198481
|
+
this.assertCompleted(response, request);
|
|
198482
|
+
const responseText = response.output_text || "";
|
|
198483
|
+
return {
|
|
198484
|
+
text: responseText,
|
|
198485
|
+
parsed: tryParseStructuredAgentOutput(responseText, Boolean(request.outputSchema)),
|
|
198486
|
+
toolCalls,
|
|
198487
|
+
usage: sumAgentTurnUsage(turns),
|
|
198488
|
+
resolvedModelId: resolvedModelId2
|
|
198489
|
+
};
|
|
198490
|
+
}
|
|
198491
|
+
if (turn >= request.maxTurns) {
|
|
198492
|
+
throw new AgentTurnLimitError(
|
|
198493
|
+
this.provider,
|
|
198494
|
+
request.maxTurns,
|
|
198495
|
+
toolCalls.length,
|
|
198496
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198497
|
+
sumAgentTurnUsage(turns)
|
|
198498
|
+
);
|
|
198499
|
+
}
|
|
198500
|
+
input2.push(...toResponseInputItems(response.output));
|
|
198501
|
+
for (const call of calls) {
|
|
198502
|
+
const prepared = toolsByProviderName.get(call.name);
|
|
198503
|
+
if (!prepared) {
|
|
198504
|
+
throw new Error(`OpenAI requested unknown agent tool '${call.name}'.`);
|
|
198505
|
+
}
|
|
198506
|
+
let toolInput = {};
|
|
198507
|
+
let output2;
|
|
198508
|
+
try {
|
|
198509
|
+
toolInput = parseToolArguments(call.arguments);
|
|
198510
|
+
const recorded = createRecordedToolCall(
|
|
198511
|
+
toolCalls,
|
|
198512
|
+
prepared.tool.name,
|
|
198513
|
+
toolInput,
|
|
198514
|
+
prepared.tool.kind
|
|
198515
|
+
);
|
|
198516
|
+
try {
|
|
198517
|
+
output2 = await prepared.tool.execute(toolInput);
|
|
198518
|
+
recorded.complete(normalizePreparedAgentToolResult(output2).recordedOutput);
|
|
198519
|
+
} catch (error2) {
|
|
198520
|
+
output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
198521
|
+
recorded.complete(output2);
|
|
198522
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198523
|
+
throw error2;
|
|
198524
|
+
}
|
|
198525
|
+
}
|
|
198526
|
+
} catch (error2) {
|
|
198527
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198528
|
+
throw error2;
|
|
198529
|
+
}
|
|
198530
|
+
output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
198531
|
+
const recorded = createRecordedToolCall(
|
|
198532
|
+
toolCalls,
|
|
198533
|
+
prepared.tool.name,
|
|
198534
|
+
toolInput,
|
|
198535
|
+
prepared.tool.kind
|
|
198536
|
+
);
|
|
198537
|
+
recorded.complete(output2);
|
|
198538
|
+
}
|
|
198539
|
+
const preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
198540
|
+
const outputItem = {
|
|
198541
|
+
type: "function_call_output",
|
|
198542
|
+
call_id: call.call_id,
|
|
198543
|
+
output: preparedOutput.immediateText
|
|
198544
|
+
};
|
|
198545
|
+
input2.push(outputItem);
|
|
198546
|
+
toolHistory.retain(() => {
|
|
198547
|
+
outputItem.output = preparedOutput.historyPlaceholder;
|
|
198548
|
+
});
|
|
198549
|
+
}
|
|
198550
|
+
}
|
|
198551
|
+
throw new AgentTurnLimitError(
|
|
198552
|
+
this.provider,
|
|
198553
|
+
request.maxTurns,
|
|
198554
|
+
toolCalls.length,
|
|
198555
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198556
|
+
sumAgentTurnUsage(turns)
|
|
198557
|
+
);
|
|
198558
|
+
}
|
|
198559
|
+
assertCompleted(response, request) {
|
|
198560
|
+
if (response.status === "incomplete") {
|
|
198561
|
+
if (response.incomplete_details?.reason === "content_filter") {
|
|
198562
|
+
throw new AgentProviderRefusalError(
|
|
198563
|
+
"OpenAI blocked the response through its content filter.",
|
|
198564
|
+
response.output_text || ""
|
|
198565
|
+
);
|
|
198566
|
+
}
|
|
198567
|
+
if (response.incomplete_details?.reason === "max_output_tokens") {
|
|
198568
|
+
throw new Error(
|
|
198569
|
+
`OpenAI model reached its ${request.maxTokens}-token completion limit before finishing.`
|
|
198570
|
+
);
|
|
198571
|
+
}
|
|
198572
|
+
throw new Error("OpenAI returned an incomplete response.");
|
|
198573
|
+
}
|
|
198574
|
+
if (response.status === "failed" || response.status === "cancelled") {
|
|
198575
|
+
throw new Error(`OpenAI response ended with status '${response.status}'.`);
|
|
198576
|
+
}
|
|
198577
|
+
if (response.status === "in_progress" || response.status === "queued") {
|
|
198578
|
+
throw new Error(`OpenAI returned unexpected non-terminal status '${response.status}'.`);
|
|
198579
|
+
}
|
|
198580
|
+
}
|
|
198581
|
+
};
|
|
198582
|
+
|
|
198583
|
+
// src/agents/providers/openaiCompatibleAdapter.ts
|
|
198584
|
+
function parseToolArguments2(raw) {
|
|
198585
|
+
const parsed = JSON.parse(raw);
|
|
198586
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
198587
|
+
throw new Error("Tool input must be a JSON object.");
|
|
198588
|
+
}
|
|
198589
|
+
return parsed;
|
|
198590
|
+
}
|
|
198591
|
+
var OpenAICompatibleAgentAdapter = class {
|
|
198592
|
+
constructor(provider = "openai_compatible") {
|
|
197829
198593
|
this.provider = provider;
|
|
197830
198594
|
}
|
|
197831
198595
|
createClient(request) {
|
|
@@ -197839,17 +198603,19 @@ var OpenAIAgentAdapter = class {
|
|
|
197839
198603
|
const apiKey2 = request.credentials?.apiKey ?? getEnvironmentValue(request.environment, "LOCAL_API_KEY") ?? "norn-local";
|
|
197840
198604
|
return new OpenAI({ apiKey: apiKey2, baseURL: baseURL2 });
|
|
197841
198605
|
}
|
|
197842
|
-
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "
|
|
197843
|
-
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "
|
|
198606
|
+
const apiKey = request.credentials?.apiKey ?? getScopedEnvironmentValue(request.environment, "OPENAI_COMPATIBLE_API_KEY") ?? "norn-openai-compatible";
|
|
198607
|
+
const baseURL = request.credentials?.baseUrl ?? getScopedEnvironmentValue(request.environment, "OPENAI_COMPATIBLE_BASE_URL");
|
|
198608
|
+
if (!baseURL) {
|
|
198609
|
+
throw new Error(
|
|
198610
|
+
"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."
|
|
198611
|
+
);
|
|
198612
|
+
}
|
|
197844
198613
|
try {
|
|
197845
|
-
return new OpenAI({
|
|
197846
|
-
...apiKey ? { apiKey } : {},
|
|
197847
|
-
...baseURL ? { baseURL } : {}
|
|
197848
|
-
});
|
|
198614
|
+
return new OpenAI({ apiKey, baseURL });
|
|
197849
198615
|
} catch (error2) {
|
|
197850
198616
|
if (error2 instanceof Error && error2.message.includes("Missing credentials")) {
|
|
197851
198617
|
throw new Error(
|
|
197852
|
-
"OpenAI authentication failed. Add an apiKey directive to the model block
|
|
198618
|
+
"OpenAI-compatible authentication failed. Add an apiKey directive to the model block.",
|
|
197853
198619
|
{ cause: error2 }
|
|
197854
198620
|
);
|
|
197855
198621
|
}
|
|
@@ -197875,7 +198641,7 @@ var OpenAIAgentAdapter = class {
|
|
|
197875
198641
|
error2
|
|
197876
198642
|
);
|
|
197877
198643
|
}
|
|
197878
|
-
const providerLabel = this.provider === "local" ? "Local OpenAI-compatible" : "OpenAI";
|
|
198644
|
+
const providerLabel = this.provider === "local" ? "Local OpenAI-compatible" : "OpenAI-compatible";
|
|
197879
198645
|
const status = error2.status ? ` (HTTP ${error2.status})` : "";
|
|
197880
198646
|
const requestId = error2.requestID ? ` [request ${error2.requestID}]` : "";
|
|
197881
198647
|
throw new Error(`${providerLabel} API request failed${status}: ${error2.message}${requestId}`, {
|
|
@@ -197904,82 +198670,128 @@ var OpenAIAgentAdapter = class {
|
|
|
197904
198670
|
strict: true
|
|
197905
198671
|
}
|
|
197906
198672
|
} : void 0;
|
|
197907
|
-
const tokenLimit =
|
|
197908
|
-
let text = "";
|
|
198673
|
+
const tokenLimit = { max_tokens: request.maxTokens };
|
|
197909
198674
|
let resolvedModelId2 = request.modelId;
|
|
197910
|
-
|
|
197911
|
-
|
|
197912
|
-
|
|
197913
|
-
|
|
197914
|
-
|
|
197915
|
-
|
|
197916
|
-
|
|
197917
|
-
|
|
197918
|
-
|
|
197919
|
-
|
|
197920
|
-
|
|
198675
|
+
const preparedTools = prepareAgentProviderTools(request.tools);
|
|
198676
|
+
const toolsByProviderName = new Map(
|
|
198677
|
+
preparedTools.map((prepared) => [prepared.providerName, prepared.tool])
|
|
198678
|
+
);
|
|
198679
|
+
const tools = preparedTools.map(({ tool, providerName }) => ({
|
|
198680
|
+
type: "function",
|
|
198681
|
+
function: {
|
|
198682
|
+
name: providerName,
|
|
198683
|
+
description: tool.description || `Run ${tool.name}`,
|
|
198684
|
+
parameters: tool.inputSchema
|
|
198685
|
+
}
|
|
198686
|
+
}));
|
|
198687
|
+
const turns = [];
|
|
198688
|
+
const toolHistory = new AgentToolResultHistory();
|
|
198689
|
+
for (let turn = 1; turn <= request.maxTurns; turn++) {
|
|
198690
|
+
const call = {
|
|
198691
|
+
model: request.modelId,
|
|
198692
|
+
messages,
|
|
198693
|
+
...tools.length > 0 ? {
|
|
198694
|
+
tools,
|
|
198695
|
+
tool_choice: "auto",
|
|
198696
|
+
parallel_tool_calls: false
|
|
198697
|
+
} : {},
|
|
198698
|
+
response_format: responseFormat,
|
|
198699
|
+
...tokenLimit
|
|
198700
|
+
};
|
|
198701
|
+
const estimatedInputTokens = estimateSerializedInputTokens(call);
|
|
198702
|
+
assertInputBudgetAllowsCall(
|
|
198703
|
+
this.provider,
|
|
198704
|
+
request.inputTokenBudget,
|
|
198705
|
+
estimatedInputTokens,
|
|
198706
|
+
turns
|
|
198707
|
+
);
|
|
198708
|
+
const completion = await client.chat.completions.create(
|
|
198709
|
+
call,
|
|
198710
|
+
request.signal ? { signal: request.signal } : void 0
|
|
198711
|
+
);
|
|
198712
|
+
const message = completion.choices[0]?.message;
|
|
198713
|
+
if (!message) {
|
|
198714
|
+
throw new Error("OpenAI returned no assistant message.");
|
|
198715
|
+
}
|
|
198716
|
+
resolvedModelId2 = completion.model || request.modelId;
|
|
198717
|
+
recordAgentTurnUsage(this.provider, request.inputTokenBudget, turns, {
|
|
198718
|
+
inputTokens: completion.usage?.prompt_tokens ?? estimatedInputTokens,
|
|
198719
|
+
outputTokens: completion.usage?.completion_tokens ?? 0,
|
|
198720
|
+
...completion.usage?.prompt_tokens_details?.cached_tokens !== void 0 ? { cachedInputTokens: completion.usage.prompt_tokens_details.cached_tokens } : {}
|
|
198721
|
+
});
|
|
198722
|
+
const requestedCalls = message.tool_calls?.filter((call2) => call2.type === "function") ?? [];
|
|
198723
|
+
const text = message.content || "";
|
|
198724
|
+
if (requestedCalls.length === 0) {
|
|
198725
|
+
this.assertCompleted(message, completion.choices[0]?.finish_reason, text, request, toolCalls);
|
|
198726
|
+
return {
|
|
198727
|
+
text,
|
|
198728
|
+
parsed: tryParseStructuredAgentOutput(text, Boolean(request.outputSchema)),
|
|
198729
|
+
toolCalls,
|
|
198730
|
+
usage: sumAgentTurnUsage(turns),
|
|
198731
|
+
resolvedModelId: resolvedModelId2
|
|
198732
|
+
};
|
|
198733
|
+
}
|
|
198734
|
+
if (turn >= request.maxTurns) {
|
|
198735
|
+
throw new AgentTurnLimitError(
|
|
198736
|
+
this.provider,
|
|
198737
|
+
request.maxTurns,
|
|
198738
|
+
toolCalls.length,
|
|
198739
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198740
|
+
sumAgentTurnUsage(turns)
|
|
198741
|
+
);
|
|
198742
|
+
}
|
|
198743
|
+
messages.push(message);
|
|
198744
|
+
for (const callItem of requestedCalls) {
|
|
198745
|
+
const tool = toolsByProviderName.get(callItem.function.name);
|
|
198746
|
+
let input2 = {};
|
|
198747
|
+
let preparedOutput;
|
|
198748
|
+
if (!tool) {
|
|
198749
|
+
preparedOutput = normalizePreparedAgentToolResult({
|
|
198750
|
+
error: `Unknown tool '${callItem.function.name}'.`
|
|
198751
|
+
});
|
|
198752
|
+
} else {
|
|
198753
|
+
try {
|
|
198754
|
+
input2 = parseToolArguments2(callItem.function.arguments);
|
|
197921
198755
|
const recorded = createRecordedToolCall(toolCalls, tool.name, input2, tool.kind);
|
|
197922
198756
|
try {
|
|
197923
198757
|
const output2 = await tool.execute(input2);
|
|
197924
|
-
|
|
197925
|
-
|
|
198758
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
198759
|
+
recorded.complete(preparedOutput.recordedOutput);
|
|
197926
198760
|
} catch (error2) {
|
|
197927
198761
|
const output2 = { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
197928
198762
|
recorded.complete(output2);
|
|
197929
198763
|
if (error2 instanceof AgentToolFatalError) {
|
|
197930
198764
|
throw error2;
|
|
197931
198765
|
}
|
|
197932
|
-
|
|
198766
|
+
preparedOutput = normalizePreparedAgentToolResult(output2);
|
|
197933
198767
|
}
|
|
198768
|
+
} catch (error2) {
|
|
198769
|
+
if (error2 instanceof AgentToolFatalError) {
|
|
198770
|
+
throw error2;
|
|
198771
|
+
}
|
|
198772
|
+
preparedOutput = normalizePreparedAgentToolResult({
|
|
198773
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
198774
|
+
});
|
|
197934
198775
|
}
|
|
197935
198776
|
}
|
|
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.");
|
|
198777
|
+
const toolMessage = {
|
|
198778
|
+
role: "tool",
|
|
198779
|
+
tool_call_id: callItem.id,
|
|
198780
|
+
content: preparedOutput.immediateText
|
|
198781
|
+
};
|
|
198782
|
+
messages.push(toolMessage);
|
|
198783
|
+
toolHistory.retain(() => {
|
|
198784
|
+
toolMessage.content = preparedOutput.historyPlaceholder;
|
|
198785
|
+
});
|
|
197969
198786
|
}
|
|
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
198787
|
}
|
|
197976
|
-
|
|
197977
|
-
|
|
197978
|
-
|
|
197979
|
-
toolCalls,
|
|
197980
|
-
|
|
197981
|
-
|
|
197982
|
-
|
|
198788
|
+
throw new AgentTurnLimitError(
|
|
198789
|
+
this.provider,
|
|
198790
|
+
request.maxTurns,
|
|
198791
|
+
toolCalls.length,
|
|
198792
|
+
toolCalls[toolCalls.length - 1]?.name,
|
|
198793
|
+
sumAgentTurnUsage(turns)
|
|
198794
|
+
);
|
|
197983
198795
|
}
|
|
197984
198796
|
assertCompleted(message, finishReason, rawText, request, toolCalls) {
|
|
197985
198797
|
if (message.refusal) {
|
|
@@ -198020,8 +198832,9 @@ var StaticAgentProviderRegistry = class {
|
|
|
198020
198832
|
};
|
|
198021
198833
|
function createDefaultAgentProviderRegistry() {
|
|
198022
198834
|
return new StaticAgentProviderRegistry([
|
|
198023
|
-
new OpenAIAgentAdapter(
|
|
198024
|
-
new
|
|
198835
|
+
new OpenAIAgentAdapter(),
|
|
198836
|
+
new OpenAICompatibleAgentAdapter("openai_compatible"),
|
|
198837
|
+
new OpenAICompatibleAgentAdapter("local"),
|
|
198025
198838
|
new AnthropicAgentAdapter(),
|
|
198026
198839
|
new GoogleAgentAdapter()
|
|
198027
198840
|
]);
|
|
@@ -198223,21 +199036,15 @@ function getContractDisplaySeverity(assertion) {
|
|
|
198223
199036
|
// src/knowledge/knowledgeTypes.ts
|
|
198224
199037
|
var KNOWLEDGE_TOKEN_ESTIMATOR_VERSION = "knowledge-token-estimate-v1";
|
|
198225
199038
|
|
|
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
199039
|
// src/agents/agentConfig.ts
|
|
198235
199040
|
function resolveAgentRuntimeLimits(startPath, provider, agent) {
|
|
198236
199041
|
const loadedConfig = startPath && findNearestConfigFile(startPath, NORN_CONFIG_FILENAME) ? loadNornConfig(startPath).config.agents : void 0;
|
|
198237
199042
|
const providerConfig = loadedConfig?.providers?.[provider];
|
|
198238
199043
|
const defaultMaxTokens = provider === "local" ? DEFAULT_LOCAL_AGENT_MAX_TOKENS : DEFAULT_AGENT_MAX_TOKENS;
|
|
199044
|
+
const maxInputTokens = agent.maxInputTokens ?? providerConfig?.max_input_tokens ?? loadedConfig?.max_input_tokens;
|
|
198239
199045
|
return {
|
|
198240
199046
|
maxTokens: agent.maxTokens ?? providerConfig?.max_tokens ?? loadedConfig?.max_tokens ?? defaultMaxTokens,
|
|
199047
|
+
...maxInputTokens !== void 0 ? { maxInputTokens } : {},
|
|
198241
199048
|
maxDepth: agent.maxDepth ?? providerConfig?.max_depth ?? loadedConfig?.max_depth ?? DEFAULT_AGENT_MAX_DEPTH,
|
|
198242
199049
|
maxInvocations: agent.maxInvocations ?? providerConfig?.max_invocations ?? loadedConfig?.max_invocations ?? DEFAULT_AGENT_MAX_INVOCATIONS,
|
|
198243
199050
|
maxTurns: agent.maxTurns ?? providerConfig?.max_turns ?? loadedConfig?.max_turns ?? DEFAULT_AGENT_MAX_TURNS,
|
|
@@ -198421,7 +199228,7 @@ function adaptAgentSchemaForGeneration(original, provider) {
|
|
|
198421
199228
|
if (provider === "anthropic" && containsRecursiveReference(original)) {
|
|
198422
199229
|
throw new AgentSchemaAdaptationError("Anthropic structured outputs do not support recursive JSON Schemas.");
|
|
198423
199230
|
}
|
|
198424
|
-
if ((provider === "openai" || provider === "local") && getMaximumObjectDepth(original) > 5) {
|
|
199231
|
+
if ((provider === "openai" || provider === "openai_compatible" || provider === "local") && getMaximumObjectDepth(original) > 5) {
|
|
198425
199232
|
throw new AgentSchemaAdaptationError("Norn limits OpenAI generation schemas to at most 5 nested object levels.");
|
|
198426
199233
|
}
|
|
198427
199234
|
const strippedKeywords = /* @__PURE__ */ new Set();
|
|
@@ -198477,7 +199284,7 @@ function adaptAgentSchemaForGeneration(original, provider) {
|
|
|
198477
199284
|
transformed.additionalProperties = false;
|
|
198478
199285
|
additionalPropertiesChanges++;
|
|
198479
199286
|
}
|
|
198480
|
-
if ((provider === "openai" || provider === "local") && properties) {
|
|
199287
|
+
if ((provider === "openai" || provider === "openai_compatible" || provider === "local") && properties) {
|
|
198481
199288
|
const authoredRequired = new Set(
|
|
198482
199289
|
Array.isArray(schemaValue.required) ? schemaValue.required.filter((entry) => typeof entry === "string") : []
|
|
198483
199290
|
);
|
|
@@ -198531,6 +199338,19 @@ var DEFAULT_TOOL_INPUT_SCHEMA = {
|
|
|
198531
199338
|
required: ["input"],
|
|
198532
199339
|
additionalProperties: false
|
|
198533
199340
|
};
|
|
199341
|
+
function mergeAgentUsage(left, right) {
|
|
199342
|
+
const leftTurns = left.turns ?? [];
|
|
199343
|
+
const rightTurns = right.turns ?? [];
|
|
199344
|
+
const turns = [...leftTurns, ...rightTurns].map((turn, index) => ({
|
|
199345
|
+
...turn,
|
|
199346
|
+
turn: index + 1
|
|
199347
|
+
}));
|
|
199348
|
+
return {
|
|
199349
|
+
inputTokens: left.inputTokens + right.inputTokens,
|
|
199350
|
+
outputTokens: left.outputTokens + right.outputTokens,
|
|
199351
|
+
...turns.length > 0 ? { turns } : {}
|
|
199352
|
+
};
|
|
199353
|
+
}
|
|
198534
199354
|
function emptyAgentResult(hasReturns = false) {
|
|
198535
199355
|
return {
|
|
198536
199356
|
...hasReturns ? { body: void 0 } : {},
|
|
@@ -198546,16 +199366,36 @@ function resolveAgentModelTarget(template, runtimeVariables) {
|
|
|
198546
199366
|
if (/\{\{[^}]+\}\}/.test(resolved)) {
|
|
198547
199367
|
throw new Error(`Could not resolve model target '${template}'.`);
|
|
198548
199368
|
}
|
|
198549
|
-
const match2 = resolved.match(/^(openai|anthropic|google|local)\/(.+)$/i);
|
|
199369
|
+
const match2 = resolved.match(/^(openai|openai_compatible|anthropic|google|local)\/(.+)$/i);
|
|
198550
199370
|
if (!match2 || !match2[2].trim()) {
|
|
198551
199371
|
throw new Error(
|
|
198552
|
-
`Invalid resolved model '${resolved}'. Expected openai/<model>, anthropic/<model>, google/<model>, or local/<model>.`
|
|
199372
|
+
`Invalid resolved model '${resolved}'. Expected openai/<model>, openai_compatible/<model>, anthropic/<model>, google/<model>, or local/<model>.`
|
|
198553
199373
|
);
|
|
198554
199374
|
}
|
|
198555
199375
|
const provider = match2[1].toLowerCase();
|
|
198556
199376
|
const modelId = match2[2].trim();
|
|
198557
199377
|
return { provider, modelId, displayName: `${provider}/${modelId}` };
|
|
198558
199378
|
}
|
|
199379
|
+
function resolveAgentReasoningEffort(model, provider, runtimeVariables) {
|
|
199380
|
+
if (model.reasoningTemplate === void 0) {
|
|
199381
|
+
return void 0;
|
|
199382
|
+
}
|
|
199383
|
+
const resolved = substituteVariables(model.reasoningTemplate, runtimeVariables).trim().toLowerCase();
|
|
199384
|
+
if (/\{\{[^}]+\}\}/.test(resolved)) {
|
|
199385
|
+
throw new Error(`Could not resolve reasoning for model '${model.alias}'.`);
|
|
199386
|
+
}
|
|
199387
|
+
if (provider !== "openai") {
|
|
199388
|
+
throw new Error(
|
|
199389
|
+
`Model '${model.alias}' can declare reasoning only with provider openai; the resolved provider is '${provider}'.`
|
|
199390
|
+
);
|
|
199391
|
+
}
|
|
199392
|
+
if (!AGENT_REASONING_EFFORTS.some((effort) => effort === resolved)) {
|
|
199393
|
+
throw new Error(
|
|
199394
|
+
`Invalid resolved reasoning effort '${resolved}' for model '${model.alias}'. Expected one of: ${AGENT_REASONING_EFFORTS.join(", ")}.`
|
|
199395
|
+
);
|
|
199396
|
+
}
|
|
199397
|
+
return resolved;
|
|
199398
|
+
}
|
|
198559
199399
|
function resolveAgentModelCredentials(model, runtimeVariables) {
|
|
198560
199400
|
const resolveField = (template, directive) => {
|
|
198561
199401
|
if (template === void 0) {
|
|
@@ -198660,8 +199500,11 @@ var AgentInvocationRunner = class {
|
|
|
198660
199500
|
definitions = /* @__PURE__ */ new Map();
|
|
198661
199501
|
conversations = /* @__PURE__ */ new Map();
|
|
198662
199502
|
invocationBudget;
|
|
199503
|
+
inputTokenBudget;
|
|
198663
199504
|
invocationCount = 0;
|
|
199505
|
+
toolResultStore = new AgentToolResultStore();
|
|
198664
199506
|
async run(agent, input2) {
|
|
199507
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
198665
199508
|
const rootInvocationIndex2 = this.options.rootInvocationIndex ?? 1;
|
|
198666
199509
|
if (!Number.isSafeInteger(rootInvocationIndex2) || rootInvocationIndex2 < 1) {
|
|
198667
199510
|
throw new Error(`Agent root invocation index must be a positive integer, received '${rootInvocationIndex2}'.`);
|
|
@@ -198750,6 +199593,7 @@ var AgentInvocationRunner = class {
|
|
|
198750
199593
|
provider: request.provider,
|
|
198751
199594
|
modelId: request.modelId,
|
|
198752
199595
|
displayModel: request.displayModel,
|
|
199596
|
+
...request.reasoningEffort ? { reasoningEffort: request.reasoningEffort } : {},
|
|
198753
199597
|
systemPrompt: request.systemPrompt,
|
|
198754
199598
|
input: cloneSnapshotValue(request.input, null),
|
|
198755
199599
|
conversation: (request.conversation ?? []).map((message) => ({ ...message })),
|
|
@@ -198757,6 +199601,7 @@ var AgentInvocationRunner = class {
|
|
|
198757
199601
|
...request.outputSchema ? { outputSchema: cloneSnapshotValue(request.outputSchema, {}) } : {},
|
|
198758
199602
|
...request.outputSchemaName ? { outputSchemaName: request.outputSchemaName } : {},
|
|
198759
199603
|
maxTokens: request.maxTokens,
|
|
199604
|
+
...request.inputTokenBudget ? { maxInputTokens: request.inputTokenBudget.maxInputTokens } : {},
|
|
198760
199605
|
maxTurns: request.maxTurns,
|
|
198761
199606
|
...mcpServerGrants?.length ? { mcpServerGrants: mcpServerGrants.map((grant) => ({
|
|
198762
199607
|
alias: grant.alias,
|
|
@@ -198775,7 +199620,25 @@ var AgentInvocationRunner = class {
|
|
|
198775
199620
|
routingRule: knowledge.routing.rule,
|
|
198776
199621
|
selectedDomainIds: knowledge.assembly.selectedDomainIds,
|
|
198777
199622
|
estimatedTokens: knowledge.assembly.estimatedTokens,
|
|
198778
|
-
estimatorVersion: KNOWLEDGE_TOKEN_ESTIMATOR_VERSION
|
|
199623
|
+
estimatorVersion: KNOWLEDGE_TOKEN_ESTIMATOR_VERSION,
|
|
199624
|
+
domains: knowledge.projection.domains.map((domain2) => {
|
|
199625
|
+
const selected = knowledge.assembly.selectedDomainIds.includes(domain2.encodedId);
|
|
199626
|
+
return {
|
|
199627
|
+
domainId: domain2.encodedId,
|
|
199628
|
+
declarationAlias: domain2.declarationAlias,
|
|
199629
|
+
sourcePath: domain2.sourcePath,
|
|
199630
|
+
domainPath: domain2.ref.domainPath,
|
|
199631
|
+
disposition: selected ? domain2.estimatedTokens <= knowledge.config.domainInlineTokenLimit ? "inline" : "index" : "manifest",
|
|
199632
|
+
estimatedTokens: domain2.estimatedTokens,
|
|
199633
|
+
topicCount: domain2.topics.length,
|
|
199634
|
+
topics: domain2.topics.map((topic) => ({
|
|
199635
|
+
topicHash: topic.topicHash,
|
|
199636
|
+
...topic.headingText ? { heading: topic.headingText } : {},
|
|
199637
|
+
estimatedTokens: topic.estimatedTokens,
|
|
199638
|
+
itemPaths: [...new Set(topic.occurrences.map((occurrence) => occurrence.ref.itemPath))].sort()
|
|
199639
|
+
}))
|
|
199640
|
+
};
|
|
199641
|
+
})
|
|
198779
199642
|
} } : {}
|
|
198780
199643
|
};
|
|
198781
199644
|
}
|
|
@@ -198796,7 +199659,7 @@ var AgentInvocationRunner = class {
|
|
|
198796
199659
|
try {
|
|
198797
199660
|
const output2 = await execute(input2, context);
|
|
198798
199661
|
record2.output = cloneSnapshotValue(output2, null);
|
|
198799
|
-
return output2;
|
|
199662
|
+
return definition.kind === "context" ? output2 : this.toolResultStore.prepare(definition.name, output2);
|
|
198800
199663
|
} catch (error2) {
|
|
198801
199664
|
record2.output = getToolErrorOutput(error2);
|
|
198802
199665
|
throw error2;
|
|
@@ -198839,6 +199702,7 @@ var AgentInvocationRunner = class {
|
|
|
198839
199702
|
return hop;
|
|
198840
199703
|
}
|
|
198841
199704
|
async invokeAgent(agent, input2, depth, parentInvocationId, ancestors, conversation, hopPath) {
|
|
199705
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
198842
199706
|
const startedAt = Date.now();
|
|
198843
199707
|
const invocationId = this.nextInvocationId();
|
|
198844
199708
|
const hop = {
|
|
@@ -198869,6 +199733,7 @@ var AgentInvocationRunner = class {
|
|
|
198869
199733
|
let resolvedModel;
|
|
198870
199734
|
let fatalToolError;
|
|
198871
199735
|
let preparedKnowledge;
|
|
199736
|
+
let accumulatedProviderUsage = { inputTokens: 0, outputTokens: 0 };
|
|
198872
199737
|
try {
|
|
198873
199738
|
const requestOverride = await this.options.resolveRequestOverride?.(hopPath);
|
|
198874
199739
|
const authoredModel = requestOverride?.provider && requestOverride.modelId ? void 0 : resolveAgentModelTarget(
|
|
@@ -198883,6 +199748,7 @@ var AgentInvocationRunner = class {
|
|
|
198883
199748
|
modelId,
|
|
198884
199749
|
displayName: requestOverride?.displayModel ?? `${provider}/${modelId}`
|
|
198885
199750
|
};
|
|
199751
|
+
const reasoningEffort = requestOverride ? requestOverride.reasoningEffort : resolveAgentReasoningEffort(agent.model, provider, this.options.runtimeVariables);
|
|
198886
199752
|
hop.output.model = resolvedModel.displayName;
|
|
198887
199753
|
const configuredLimits = resolveAgentRuntimeLimits(
|
|
198888
199754
|
this.options.startPath,
|
|
@@ -198891,7 +199757,8 @@ var AgentInvocationRunner = class {
|
|
|
198891
199757
|
);
|
|
198892
199758
|
const limits = {
|
|
198893
199759
|
...configuredLimits,
|
|
198894
|
-
...requestOverride?.maxTokens !== void 0 ? { maxTokens: requestOverride.maxTokens } : {}
|
|
199760
|
+
...requestOverride?.maxTokens !== void 0 ? { maxTokens: requestOverride.maxTokens } : {},
|
|
199761
|
+
...requestOverride?.maxInputTokens !== void 0 ? { maxInputTokens: requestOverride.maxInputTokens } : {}
|
|
198895
199762
|
};
|
|
198896
199763
|
if (!this.invocationBudget) {
|
|
198897
199764
|
this.invocationBudget = {
|
|
@@ -198899,6 +199766,12 @@ var AgentInvocationRunner = class {
|
|
|
198899
199766
|
maxInvocations: limits.maxInvocations
|
|
198900
199767
|
};
|
|
198901
199768
|
}
|
|
199769
|
+
if (depth === 0 && limits.maxInputTokens !== void 0) {
|
|
199770
|
+
this.inputTokenBudget = {
|
|
199771
|
+
maxInputTokens: limits.maxInputTokens,
|
|
199772
|
+
usedInputTokens: 0
|
|
199773
|
+
};
|
|
199774
|
+
}
|
|
198902
199775
|
this.invocationCount++;
|
|
198903
199776
|
this.addDefinition(agent, resolvedModel);
|
|
198904
199777
|
const authoredSystemPrompt = requestOverride?.systemPrompt ?? substituteVariables(
|
|
@@ -198954,6 +199827,7 @@ var AgentInvocationRunner = class {
|
|
|
198954
199827
|
provider: resolvedModel.provider,
|
|
198955
199828
|
modelId: resolvedModel.modelId,
|
|
198956
199829
|
displayModel: resolvedModel.displayName,
|
|
199830
|
+
...reasoningEffort ? { reasoningEffort } : {},
|
|
198957
199831
|
systemPrompt,
|
|
198958
199832
|
input: input2,
|
|
198959
199833
|
conversation,
|
|
@@ -198961,9 +199835,11 @@ var AgentInvocationRunner = class {
|
|
|
198961
199835
|
outputSchema,
|
|
198962
199836
|
outputSchemaName,
|
|
198963
199837
|
maxTokens: limits.maxTokens,
|
|
199838
|
+
...this.inputTokenBudget ? { inputTokenBudget: this.inputTokenBudget } : {},
|
|
198964
199839
|
maxTurns: limits.maxTurns,
|
|
198965
199840
|
environment: this.options.environment,
|
|
198966
|
-
...credentials ? { credentials } : {}
|
|
199841
|
+
...credentials ? { credentials } : {},
|
|
199842
|
+
...this.options.signal ? { signal: this.options.signal } : {}
|
|
198967
199843
|
};
|
|
198968
199844
|
hop.request = this.createRequestSnapshot(
|
|
198969
199845
|
providerRequest,
|
|
@@ -198985,6 +199861,10 @@ var AgentInvocationRunner = class {
|
|
|
198985
199861
|
...providerRequest,
|
|
198986
199862
|
conversation: correctionConversation
|
|
198987
199863
|
});
|
|
199864
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199865
|
+
accumulatedProviderUsage,
|
|
199866
|
+
providerResponse.usage
|
|
199867
|
+
);
|
|
198988
199868
|
hop.providerCompleted = true;
|
|
198989
199869
|
if (fatalToolError) {
|
|
198990
199870
|
throw fatalToolError;
|
|
@@ -198995,7 +199875,7 @@ var AgentInvocationRunner = class {
|
|
|
198995
199875
|
text: providerResponse.text,
|
|
198996
199876
|
toolCalls,
|
|
198997
199877
|
model: `${resolvedModel.provider}/${providerResponse.resolvedModelId}`,
|
|
198998
|
-
usage:
|
|
199878
|
+
usage: accumulatedProviderUsage,
|
|
198999
199879
|
ms: Date.now() - startedAt
|
|
199000
199880
|
};
|
|
199001
199881
|
const returnValue = providerResponse.parsed !== void 0 ? providerResponse.parsed : providerResponse.text;
|
|
@@ -199033,10 +199913,32 @@ var AgentInvocationRunner = class {
|
|
|
199033
199913
|
}
|
|
199034
199914
|
hop.success = true;
|
|
199035
199915
|
} catch (error2) {
|
|
199916
|
+
throwIfSequenceCancelled(this.options.signal);
|
|
199036
199917
|
const reportedError = fatalToolError ?? error2;
|
|
199037
199918
|
if (reportedError instanceof AgentProviderMaxTokensError) {
|
|
199038
199919
|
hop.error = formatAgentProviderMaxTokensError(agent.name, reportedError);
|
|
199920
|
+
} else if (reportedError instanceof AgentInputTokenLimitError) {
|
|
199921
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199922
|
+
accumulatedProviderUsage,
|
|
199923
|
+
reportedError.usage
|
|
199924
|
+
);
|
|
199925
|
+
hop.output.usage = accumulatedProviderUsage;
|
|
199926
|
+
hop.inputTokenLimit = {
|
|
199927
|
+
maxInputTokens: reportedError.maxInputTokens,
|
|
199928
|
+
usedInputTokens: reportedError.usedInputTokens,
|
|
199929
|
+
...reportedError.estimatedNextInputTokens !== void 0 ? { estimatedNextInputTokens: reportedError.estimatedNextInputTokens } : {},
|
|
199930
|
+
sourcePath: agent.sourcePath,
|
|
199931
|
+
lineNumber: agent.lineNumber
|
|
199932
|
+
};
|
|
199933
|
+
hop.error = formatAgentInputTokenLimitError(agent.name, hop.inputTokenLimit);
|
|
199039
199934
|
} else if (reportedError instanceof AgentTurnLimitError) {
|
|
199935
|
+
if (reportedError.usage) {
|
|
199936
|
+
accumulatedProviderUsage = mergeAgentUsage(
|
|
199937
|
+
accumulatedProviderUsage,
|
|
199938
|
+
reportedError.usage
|
|
199939
|
+
);
|
|
199940
|
+
hop.output.usage = accumulatedProviderUsage;
|
|
199941
|
+
}
|
|
199040
199942
|
hop.turnLimit = {
|
|
199041
199943
|
maxTurns: reportedError.maxTurns,
|
|
199042
199944
|
toolCallCount: reportedError.toolCallCount,
|
|
@@ -199097,10 +199999,12 @@ var AgentInvocationRunner = class {
|
|
|
199097
199999
|
overrideKeys.add(key);
|
|
199098
200000
|
}
|
|
199099
200001
|
let callerLimitBreaches = 0;
|
|
199100
|
-
if (agent.callableAgents.some((reference) => reference.name.toLowerCase()
|
|
199101
|
-
throw new Error(
|
|
200002
|
+
if (agent.callableAgents.some((reference) => ["load_knowledge", "norn_read_tool_result"].includes(reference.name.toLowerCase()))) {
|
|
200003
|
+
throw new Error(
|
|
200004
|
+
"Agent names 'load_knowledge' and 'norn_read_tool_result' are reserved by Norn."
|
|
200005
|
+
);
|
|
199102
200006
|
}
|
|
199103
|
-
if (knowledge) {
|
|
200007
|
+
if (knowledge?.hasLoadableKnowledge) {
|
|
199104
200008
|
const offeredOverride = requestToolsOverride?.find((tool) => tool.kind === "knowledge");
|
|
199105
200009
|
providerTools.push(this.createRecordedProviderTool(parentHop, {
|
|
199106
200010
|
name: "load_knowledge",
|
|
@@ -199403,6 +200307,25 @@ var AgentInvocationRunner = class {
|
|
|
199403
200307
|
return Object.prototype.hasOwnProperty.call(child.output, "body") ? child.output.body : child.output.text;
|
|
199404
200308
|
}));
|
|
199405
200309
|
}
|
|
200310
|
+
const offeredContext = requestToolsOverride?.find((tool) => tool.kind === "context");
|
|
200311
|
+
if (!requestToolsOverride && providerTools.length > 0 || offeredContext) {
|
|
200312
|
+
providerTools.push(this.createRecordedProviderTool(parentHop, {
|
|
200313
|
+
name: "norn_read_tool_result",
|
|
200314
|
+
providerName: offeredContext?.providerName ?? "norn_read_tool_result",
|
|
200315
|
+
kind: "context",
|
|
200316
|
+
description: offeredContext?.description ?? "Read or search a bounded portion of a tool result that Norn offloaded from active context.",
|
|
200317
|
+
inputSchema: offeredContext?.inputSchema ?? {
|
|
200318
|
+
type: "object",
|
|
200319
|
+
properties: {
|
|
200320
|
+
handle: { type: "string" },
|
|
200321
|
+
offset: { type: "integer", minimum: 0 },
|
|
200322
|
+
query: { type: "string" }
|
|
200323
|
+
},
|
|
200324
|
+
required: ["handle"],
|
|
200325
|
+
additionalProperties: false
|
|
200326
|
+
}
|
|
200327
|
+
}, async (input2) => this.toolResultStore.read(input2)));
|
|
200328
|
+
}
|
|
199406
200329
|
if (requestToolsOverride) {
|
|
199407
200330
|
const currentKeys = new Set(providerTools.map(
|
|
199408
200331
|
(tool) => `${tool.kind ?? ""}\0${tool.name.toLowerCase()}`
|
|
@@ -200542,6 +201465,18 @@ function normalizeHopForDisk(hop, projectRoot) {
|
|
|
200542
201465
|
...extended.request !== void 0 ? {
|
|
200543
201466
|
request: relativizeTopLevelSourcePaths(extended.request, projectRoot, true)
|
|
200544
201467
|
} : {},
|
|
201468
|
+
...hop.turnLimit ? {
|
|
201469
|
+
turnLimit: {
|
|
201470
|
+
...hop.turnLimit,
|
|
201471
|
+
sourcePath: path26.isAbsolute(hop.turnLimit.sourcePath) ? projectRelativePath(projectRoot, hop.turnLimit.sourcePath) : hop.turnLimit.sourcePath
|
|
201472
|
+
}
|
|
201473
|
+
} : {},
|
|
201474
|
+
...hop.inputTokenLimit ? {
|
|
201475
|
+
inputTokenLimit: {
|
|
201476
|
+
...hop.inputTokenLimit,
|
|
201477
|
+
sourcePath: path26.isAbsolute(hop.inputTokenLimit.sourcePath) ? projectRelativePath(projectRoot, hop.inputTokenLimit.sourcePath) : hop.inputTokenLimit.sourcePath
|
|
201478
|
+
}
|
|
201479
|
+
} : {},
|
|
200545
201480
|
children: hop.children.map((child) => normalizeHopForDisk(child, projectRoot))
|
|
200546
201481
|
};
|
|
200547
201482
|
return normalized;
|
|
@@ -200709,28 +201644,35 @@ function isSafeProjectRelativePath(value) {
|
|
|
200709
201644
|
return isRelativePath(value) && !normalizePathSeparators(value).split("/").includes("..");
|
|
200710
201645
|
}
|
|
200711
201646
|
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");
|
|
201647
|
+
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");
|
|
201648
|
+
}
|
|
201649
|
+
function isAgentKnowledgeTopicSnapshot(value) {
|
|
201650
|
+
return isObjectRecord2(value) && typeof value.topicHash === "string" && (value.heading === void 0 || typeof value.heading === "string") && isFiniteNonNegativeNumber(value.estimatedTokens) && isStringArray(value.itemPaths);
|
|
201651
|
+
}
|
|
201652
|
+
function isAgentKnowledgeDomainSnapshot(value) {
|
|
201653
|
+
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
201654
|
}
|
|
200714
201655
|
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))) {
|
|
201656
|
+
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
201657
|
return false;
|
|
200717
201658
|
}
|
|
200718
201659
|
const validConversation = value.conversation.every(
|
|
200719
201660
|
(message) => isObjectRecord2(message) && (message.role === "user" || message.role === "assistant") && typeof message.content === "string"
|
|
200720
201661
|
);
|
|
200721
201662
|
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)
|
|
201663
|
+
(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
201664
|
);
|
|
200724
201665
|
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
201666
|
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));
|
|
201667
|
+
) && 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));
|
|
201668
|
+
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
201669
|
}
|
|
200729
201670
|
function isAgentResult(value) {
|
|
200730
201671
|
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
201672
|
return false;
|
|
200732
201673
|
}
|
|
200733
|
-
|
|
201674
|
+
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)));
|
|
201675
|
+
return isFiniteNonNegativeNumber(value.usage.inputTokens) && isFiniteNonNegativeNumber(value.usage.outputTokens) && validTurns;
|
|
200734
201676
|
}
|
|
200735
201677
|
function isAgentContract(value) {
|
|
200736
201678
|
return isObjectRecord2(value) && (value.kind === "accepts" || value.kind === "returns") && typeof value.path === "string" && isObjectRecord2(value.assertion);
|
|
@@ -200742,7 +201684,7 @@ function isAgentHop(value) {
|
|
|
200742
201684
|
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
201685
|
return false;
|
|
200744
201686
|
}
|
|
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);
|
|
201687
|
+
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
201688
|
}
|
|
200747
201689
|
function isAgentTrace(value) {
|
|
200748
201690
|
if (!isObjectRecord2(value) || !Array.isArray(value.agents) || !Array.isArray(value.hops)) {
|
|
@@ -202959,6 +203901,14 @@ function readKnowledgeSnapshot(startPath, snapshotId, options = {}) {
|
|
|
202959
203901
|
function encodeKnowledgeId(parts) {
|
|
202960
203902
|
return Buffer.from(canonicalJson(parts), "utf8").toString("base64url");
|
|
202961
203903
|
}
|
|
203904
|
+
function decodeKnowledgeId(value) {
|
|
203905
|
+
try {
|
|
203906
|
+
const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
203907
|
+
return Array.isArray(parsed) ? parsed : void 0;
|
|
203908
|
+
} catch {
|
|
203909
|
+
return void 0;
|
|
203910
|
+
}
|
|
203911
|
+
}
|
|
202962
203912
|
|
|
202963
203913
|
// src/knowledge/knowledgeAssembly.ts
|
|
202964
203914
|
function estimateKnowledgeTokens(rendered) {
|
|
@@ -202998,10 +203948,10 @@ function renderKnowledgeTopicIndex(domain2) {
|
|
|
202998
203948
|
}))
|
|
202999
203949
|
};
|
|
203000
203950
|
}
|
|
203001
|
-
function renderKnowledgeDomainBodies(domain2) {
|
|
203951
|
+
function renderKnowledgeDomainBodies(domain2, topics = domain2.topics) {
|
|
203002
203952
|
return {
|
|
203003
203953
|
domainId: domain2.encodedId,
|
|
203004
|
-
topics:
|
|
203954
|
+
topics: topics.map((topic) => ({
|
|
203005
203955
|
topicHash: topic.topicHash,
|
|
203006
203956
|
heading: topic.headingText,
|
|
203007
203957
|
body: topic.body,
|
|
@@ -203363,20 +204313,30 @@ var KnowledgeRunCoordinator = class {
|
|
|
203363
204313
|
const routing = routeKnowledge(this.projectRoot, input2, projection, config2, agent.name);
|
|
203364
204314
|
const assembly = assembleKnowledgePrompt(authoredSystemPrompt, projection, routing, config2, agent.name);
|
|
203365
204315
|
const loadEvents = [];
|
|
204316
|
+
const loadedTopicHashes = new Set(assembly.initiallyLoadedTopics.map((topic) => topic.topicHash));
|
|
204317
|
+
const loadedTopicIndexes = new Set(projection.domains.filter((domain2) => assembly.selectedDomainIds.includes(domain2.encodedId) && domain2.estimatedTokens > config2.domainInlineTokenLimit).map((domain2) => domain2.encodedId));
|
|
204318
|
+
const loadableDomains = projection.domains.filter(
|
|
204319
|
+
(domain2) => domain2.topics.some((topic) => !loadedTopicHashes.has(topic.topicHash)) || domain2.estimatedTokens > config2.domainInlineTokenLimit && !loadedTopicIndexes.has(domain2.encodedId)
|
|
204320
|
+
);
|
|
204321
|
+
const loadableTopicHashes = [...new Set(loadableDomains.flatMap((domain2) => domain2.topics).filter((topic) => !loadedTopicHashes.has(topic.topicHash)).map((topic) => topic.topicHash))];
|
|
203366
204322
|
let usedTokens = 0;
|
|
203367
204323
|
const tool = {
|
|
203368
204324
|
name: "load_knowledge",
|
|
203369
204325
|
providerName: "norn_load_knowledge",
|
|
203370
204326
|
kind: "knowledge",
|
|
203371
|
-
description: "Load
|
|
204327
|
+
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
204328
|
inputSchema: { type: "object", properties: {
|
|
203373
|
-
domainId: { type: "string" },
|
|
203374
|
-
topicHash: { type: "string" },
|
|
204329
|
+
domainId: { type: "string", enum: loadableDomains.map((domain2) => domain2.encodedId) },
|
|
204330
|
+
topicHash: { type: "string", enum: loadableTopicHashes },
|
|
203375
204331
|
occurrenceId: { type: "string" }
|
|
203376
204332
|
}, required: ["domainId"], additionalProperties: false },
|
|
203377
204333
|
execute: async (raw) => {
|
|
203378
204334
|
const request = raw;
|
|
203379
204335
|
const before = usedTokens;
|
|
204336
|
+
const alreadyLoaded = () => ({
|
|
204337
|
+
alreadyLoaded: true,
|
|
204338
|
+
message: "This knowledge has already been loaded."
|
|
204339
|
+
});
|
|
203380
204340
|
const refuse = (code, message) => {
|
|
203381
204341
|
loadEvents.push({
|
|
203382
204342
|
order: loadEvents.length + 1,
|
|
@@ -203402,6 +204362,8 @@ var KnowledgeRunCoordinator = class {
|
|
|
203402
204362
|
return refuse("unknown_or_ungranted_domain", "The requested domain ID is unknown or not granted.");
|
|
203403
204363
|
}
|
|
203404
204364
|
let value;
|
|
204365
|
+
let newlyLoadedTopicHashes = [];
|
|
204366
|
+
let loadedTopicIndex = false;
|
|
203405
204367
|
if (request.topicHash) {
|
|
203406
204368
|
const topic = domain2.topics.find((item) => item.topicHash === request.topicHash);
|
|
203407
204369
|
if (!topic) {
|
|
@@ -203423,6 +204385,9 @@ var KnowledgeRunCoordinator = class {
|
|
|
203423
204385
|
return refuse("unknown_or_ungranted_occurrence", "The occurrence ID is not exposed by this domain.");
|
|
203424
204386
|
}
|
|
203425
204387
|
}
|
|
204388
|
+
if (loadedTopicHashes.has(topic.topicHash)) {
|
|
204389
|
+
return alreadyLoaded();
|
|
204390
|
+
}
|
|
203426
204391
|
value = { domainId: domain2.encodedId, topic: {
|
|
203427
204392
|
topicHash: topic.topicHash,
|
|
203428
204393
|
heading: topic.headingText,
|
|
@@ -203434,8 +204399,22 @@ var KnowledgeRunCoordinator = class {
|
|
|
203434
204399
|
useWhen: item.metadata.useWhen?.value
|
|
203435
204400
|
}))
|
|
203436
204401
|
} };
|
|
204402
|
+
newlyLoadedTopicHashes = [topic.topicHash];
|
|
203437
204403
|
} else {
|
|
203438
|
-
|
|
204404
|
+
if (domain2.estimatedTokens <= config2.domainInlineTokenLimit) {
|
|
204405
|
+
const unloadedTopics = domain2.topics.filter((topic) => !loadedTopicHashes.has(topic.topicHash));
|
|
204406
|
+
if (!unloadedTopics.length) {
|
|
204407
|
+
return alreadyLoaded();
|
|
204408
|
+
}
|
|
204409
|
+
value = renderKnowledgeDomainBodies(domain2, unloadedTopics);
|
|
204410
|
+
newlyLoadedTopicHashes = unloadedTopics.map((topic) => topic.topicHash);
|
|
204411
|
+
} else {
|
|
204412
|
+
if (loadedTopicIndexes.has(domain2.encodedId)) {
|
|
204413
|
+
return alreadyLoaded();
|
|
204414
|
+
}
|
|
204415
|
+
value = renderKnowledgeTopicIndex(domain2);
|
|
204416
|
+
loadedTopicIndex = true;
|
|
204417
|
+
}
|
|
203439
204418
|
}
|
|
203440
204419
|
const output2 = escapedCanonicalKnowledgeJson(value);
|
|
203441
204420
|
const estimatedTokens = estimateKnowledgeTokens(output2);
|
|
@@ -203443,11 +204422,18 @@ var KnowledgeRunCoordinator = class {
|
|
|
203443
204422
|
return refuse("tool_token_limit", `The request would exceed knowledge.toolTokenLimit=${config2.toolTokenLimit}.`);
|
|
203444
204423
|
}
|
|
203445
204424
|
usedTokens += estimatedTokens;
|
|
204425
|
+
for (const topicHash of newlyLoadedTopicHashes) {
|
|
204426
|
+
loadedTopicHashes.add(topicHash);
|
|
204427
|
+
}
|
|
204428
|
+
if (loadedTopicIndex) {
|
|
204429
|
+
loadedTopicIndexes.add(domain2.encodedId);
|
|
204430
|
+
}
|
|
203446
204431
|
loadEvents.push({
|
|
203447
204432
|
order: loadEvents.length + 1,
|
|
203448
204433
|
request,
|
|
203449
204434
|
accepted: true,
|
|
203450
204435
|
estimatedTokens,
|
|
204436
|
+
loadedTopicHashes: newlyLoadedTopicHashes,
|
|
203451
204437
|
budgetBefore: before,
|
|
203452
204438
|
budgetAfter: usedTokens
|
|
203453
204439
|
});
|
|
@@ -203455,7 +204441,17 @@ var KnowledgeRunCoordinator = class {
|
|
|
203455
204441
|
}
|
|
203456
204442
|
};
|
|
203457
204443
|
void invocationId;
|
|
203458
|
-
return {
|
|
204444
|
+
return {
|
|
204445
|
+
runId: this.runId,
|
|
204446
|
+
snapshotId,
|
|
204447
|
+
projection,
|
|
204448
|
+
routing,
|
|
204449
|
+
assembly,
|
|
204450
|
+
tool,
|
|
204451
|
+
hasLoadableKnowledge: loadableDomains.length > 0,
|
|
204452
|
+
loadEvents,
|
|
204453
|
+
config: config2
|
|
204454
|
+
};
|
|
203459
204455
|
}
|
|
203460
204456
|
recordInvocation(agent, hop, knowledge) {
|
|
203461
204457
|
this.invocations.push({ agent, hop, knowledge });
|
|
@@ -203510,7 +204506,8 @@ var KnowledgeRunCoordinator = class {
|
|
|
203510
204506
|
accepts: item.hop.accepts,
|
|
203511
204507
|
returns: item.hop.returns,
|
|
203512
204508
|
judge: item.hop.judge,
|
|
203513
|
-
turnLimit: item.hop.turnLimit
|
|
204509
|
+
turnLimit: item.hop.turnLimit,
|
|
204510
|
+
inputTokenLimit: item.hop.inputTokenLimit
|
|
203514
204511
|
})
|
|
203515
204512
|
);
|
|
203516
204513
|
if (!item.knowledge) {
|
|
@@ -203614,7 +204611,11 @@ var KnowledgeRunCoordinator = class {
|
|
|
203614
204611
|
event.estimatedTokens
|
|
203615
204612
|
);
|
|
203616
204613
|
} else if (event.accepted) {
|
|
204614
|
+
const loadedTopicHashes = event.loadedTopicHashes ? new Set(event.loadedTopicHashes) : void 0;
|
|
203617
204615
|
for (const topic of domain2.topics) {
|
|
204616
|
+
if (loadedTopicHashes && !loadedTopicHashes.has(topic.topicHash)) {
|
|
204617
|
+
continue;
|
|
204618
|
+
}
|
|
203618
204619
|
for (const occurrence of topic.occurrences) {
|
|
203619
204620
|
index.run(
|
|
203620
204621
|
`INSERT OR REPLACE INTO run_topics(run_id, invocation_id,
|
|
@@ -204824,9 +205825,6 @@ function valueToString2(value) {
|
|
|
204824
205825
|
}
|
|
204825
205826
|
return String(value);
|
|
204826
205827
|
}
|
|
204827
|
-
function sleep5(ms) {
|
|
204828
|
-
return new Promise((resolve28) => setTimeout(resolve28, ms));
|
|
204829
|
-
}
|
|
204830
205828
|
function isIfCommand(line2) {
|
|
204831
205829
|
return /^if\s+.+$/i.test(line2.trim());
|
|
204832
205830
|
}
|
|
@@ -205333,6 +206331,10 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205333
206331
|
};
|
|
205334
206332
|
const runtimeVariables = copyEnvironmentScope({ ...fileVariables, ...sequenceArgs }, fileVariables);
|
|
205335
206333
|
const mcpSessionManager = executionContext?.mcpSessionManager ?? new McpSessionManager();
|
|
206334
|
+
const cancelMcpSessions = () => {
|
|
206335
|
+
void mcpSessionManager.closeAll();
|
|
206336
|
+
};
|
|
206337
|
+
executionContext?.signal?.addEventListener("abort", cancelMcpSessions, { once: true });
|
|
205336
206338
|
const agentProviderRegistry = executionContext?.agentProviderRegistry ?? createDefaultAgentProviderRegistry();
|
|
205337
206339
|
const agentWarningKeys = executionContext?.agentWarningKeys ?? /* @__PURE__ */ new Set();
|
|
205338
206340
|
const agentEventLog = executionContext?.agentEventLog ?? [];
|
|
@@ -205547,6 +206549,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205547
206549
|
}
|
|
205548
206550
|
};
|
|
205549
206551
|
for (const step of steps) {
|
|
206552
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205550
206553
|
if (step.type === "judge") {
|
|
205551
206554
|
const parsedJudge = parseJudgeStep(step);
|
|
205552
206555
|
const blockingError = parsedJudge.errors[0];
|
|
@@ -205644,6 +206647,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205644
206647
|
try {
|
|
205645
206648
|
await preflightAgentGraph(definition, scope);
|
|
205646
206649
|
} catch (error2) {
|
|
206650
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205647
206651
|
await mcpSessionManager.closeScope(MCP_PREFLIGHT_SCOPE);
|
|
205648
206652
|
const message = `Agent '${definition.name}' tool preflight failed: ${error2 instanceof Error ? error2.message : String(error2)}`;
|
|
205649
206653
|
errors.push(message);
|
|
@@ -205663,8 +206667,10 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205663
206667
|
await mcpSessionManager.closeScope(MCP_PREFLIGHT_SCOPE);
|
|
205664
206668
|
}
|
|
205665
206669
|
for (let stepIdx = 0; stepIdx < steps.length; stepIdx++) {
|
|
206670
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205666
206671
|
const step = steps[stepIdx];
|
|
205667
206672
|
await emitBeforeStep(step, stepIdx);
|
|
206673
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
205668
206674
|
const stepStartTime = Date.now();
|
|
205669
206675
|
try {
|
|
205670
206676
|
if (step.type === "if") {
|
|
@@ -205752,7 +206758,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205752
206758
|
if (step.type === "wait") {
|
|
205753
206759
|
const durationMs = parseWaitCommand(step.content);
|
|
205754
206760
|
reportProgress(stepIdx, "wait", `wait: ${durationMs}ms`);
|
|
205755
|
-
await
|
|
206761
|
+
await cancellableDelay(durationMs, executionContext?.signal);
|
|
205756
206762
|
const stepResult = createPrintStepResult(
|
|
205757
206763
|
stepIdx,
|
|
205758
206764
|
stepStartTime,
|
|
@@ -205954,6 +206960,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
205954
206960
|
runLineNumber: debugLocation.absoluteLine,
|
|
205955
206961
|
rootInvocationIndex: rootInvocationIndex2,
|
|
205956
206962
|
knowledgeCoordinator,
|
|
206963
|
+
signal: executionContext?.signal,
|
|
205957
206964
|
expandMcpServerGrants: (_hopPath, grantedAgent) => mcpGrantExpansions.get(agentDefinitionKey(grantedAgent)) ?? expandMcpGrantsLive(grantedAgent),
|
|
205958
206965
|
onInvocationProgress: (agentEvent) => {
|
|
205959
206966
|
const recordedEvent = cloneSerializableValue(agentEvent);
|
|
@@ -206012,6 +207019,7 @@ async function runSequenceWithJar(sequenceContent, fileVariables, cookieJar, wor
|
|
|
206012
207019
|
}
|
|
206013
207020
|
}
|
|
206014
207021
|
} catch (error2) {
|
|
207022
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206015
207023
|
execution.error = error2 instanceof Error ? error2.message : String(error2);
|
|
206016
207024
|
}
|
|
206017
207025
|
const stepResult = {
|
|
@@ -206090,6 +207098,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206090
207098
|
runLineNumber: debugLocation.absoluteLine,
|
|
206091
207099
|
rootInvocationIndex: rootInvocationIndex2,
|
|
206092
207100
|
knowledgeCoordinator,
|
|
207101
|
+
signal: executionContext?.signal,
|
|
206093
207102
|
expandMcpServerGrants: (_hopPath, grantedAgent) => mcpGrantExpansions.get(agentDefinitionKey(grantedAgent)) ?? expandMcpGrantsLive(grantedAgent),
|
|
206094
207103
|
onInvocationProgress: (agentEvent) => {
|
|
206095
207104
|
const recordedEvent = cloneSerializableValue(agentEvent);
|
|
@@ -206116,6 +207125,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206116
207125
|
addTraceDefinition(definition);
|
|
206117
207126
|
}
|
|
206118
207127
|
} catch (error2) {
|
|
207128
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206119
207129
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
206120
207130
|
if (agent?.returns) {
|
|
206121
207131
|
output2 = { ...output2, body: void 0 };
|
|
@@ -206314,7 +207324,8 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206314
207324
|
workingDir: adapterWorkingDir
|
|
206315
207325
|
}
|
|
206316
207326
|
},
|
|
206317
|
-
adapterWorkingDir
|
|
207327
|
+
adapterWorkingDir,
|
|
207328
|
+
executionContext?.signal
|
|
206318
207329
|
);
|
|
206319
207330
|
let storedValue;
|
|
206320
207331
|
let sqlResult;
|
|
@@ -206361,6 +207372,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206361
207372
|
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
207373
|
reportProgress(stepIdx, "sql", description, stepResult);
|
|
206363
207374
|
} catch (error2) {
|
|
207375
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206364
207376
|
errors.push(`SQL execution failed for '${operation.name}': ${error2.message || String(error2)}`);
|
|
206365
207377
|
await emitFailure(`SQL execution failed for '${operation.name}'`, step, stepIdx);
|
|
206366
207378
|
return {
|
|
@@ -206414,6 +207426,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206414
207426
|
orderedSteps.push(stepResult);
|
|
206415
207427
|
reportProgress(stepIdx, "mcp", `run mcp list ${parsed.serverAlias} \u2192 ${listResult.tools.length} tool(s)`, stepResult);
|
|
206416
207428
|
} catch (error2) {
|
|
207429
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206417
207430
|
const message = `MCP list failed for '${parsed.serverAlias}': ${error2?.message || String(error2)}`;
|
|
206418
207431
|
errors.push(message);
|
|
206419
207432
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206465,6 +207478,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206465
207478
|
parsed.toolName
|
|
206466
207479
|
);
|
|
206467
207480
|
} catch (error2) {
|
|
207481
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206468
207482
|
const message = `MCP call failed for '${parsed.serverAlias}.${parsed.toolName}': ${error2?.message || String(error2)}`;
|
|
206469
207483
|
errors.push(message);
|
|
206470
207484
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206534,6 +207548,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206534
207548
|
};
|
|
206535
207549
|
}
|
|
206536
207550
|
} catch (error2) {
|
|
207551
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206537
207552
|
const message = `MCP call failed for '${parsed.serverAlias}.${parsed.toolName}': ${error2?.message || String(error2)}`;
|
|
206538
207553
|
errors.push(message);
|
|
206539
207554
|
await emitFailure(message, step, stepIdx);
|
|
@@ -206596,7 +207611,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206596
207611
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] ${requestDescription} - waiting ${waitMs}ms`, void 0);
|
|
206597
207612
|
}
|
|
206598
207613
|
} : void 0;
|
|
206599
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
207614
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
206600
207615
|
addResponse(response);
|
|
206601
207616
|
runContractValidation(preparedRequest.endpointName, response, step, stepIdx);
|
|
206602
207617
|
responseIndexToVariable.set(responses.length, parsed.varName);
|
|
@@ -206622,6 +207637,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
206622
207637
|
}
|
|
206623
207638
|
}
|
|
206624
207639
|
} catch (error2) {
|
|
207640
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206625
207641
|
const userMessage = formatUserFacingError(
|
|
206626
207642
|
error2,
|
|
206627
207643
|
buildRequestValidationContext(stepIdx + 1, void 0, void 0, `var ${parsed.varName}`)
|
|
@@ -206674,7 +207690,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
206674
207690
|
substitutedArgs,
|
|
206675
207691
|
workingDir || process.cwd(),
|
|
206676
207692
|
runtimeVariables,
|
|
206677
|
-
parsed.captureAs
|
|
207693
|
+
parsed.captureAs,
|
|
207694
|
+
executionContext?.signal
|
|
206678
207695
|
);
|
|
206679
207696
|
scriptResults.push(result);
|
|
206680
207697
|
const stepResult = {
|
|
@@ -206707,6 +207724,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206707
207724
|
runtimeVariables[parsed.captureAs] = outputValue;
|
|
206708
207725
|
}
|
|
206709
207726
|
} catch (error2) {
|
|
207727
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206710
207728
|
errors.push(`Script execution error: ${error2.message}`);
|
|
206711
207729
|
return {
|
|
206712
207730
|
name: "",
|
|
@@ -206812,7 +207830,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
206812
207830
|
agentEventLog,
|
|
206813
207831
|
agentRootInvocationCounts,
|
|
206814
207832
|
recordAgentRuns: executionContext?.recordAgentRuns,
|
|
206815
|
-
knowledgeCoordinator
|
|
207833
|
+
knowledgeCoordinator,
|
|
207834
|
+
signal: executionContext?.signal
|
|
206816
207835
|
};
|
|
206817
207836
|
const subResult = await runSequenceWithJar(
|
|
206818
207837
|
targetSequence.content,
|
|
@@ -206905,7 +207924,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206905
207924
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] run ${targetName} - waiting ${waitMs}ms`, void 0);
|
|
206906
207925
|
}
|
|
206907
207926
|
} : void 0;
|
|
206908
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
207927
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
206909
207928
|
addResponse(response);
|
|
206910
207929
|
const stepResult = {
|
|
206911
207930
|
type: "request",
|
|
@@ -206927,6 +207946,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
206927
207946
|
}
|
|
206928
207947
|
}
|
|
206929
207948
|
} catch (error2) {
|
|
207949
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
206930
207950
|
const userMessage = formatUserFacingError(
|
|
206931
207951
|
error2,
|
|
206932
207952
|
buildRequestValidationContext(stepIdx + 1, requestMethod || void 0, requestUrl || void 0, targetName)
|
|
@@ -207016,7 +208036,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207016
208036
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] var ${varName} = run ${sequenceName} - waiting ${waitMs}ms`, void 0);
|
|
207017
208037
|
}
|
|
207018
208038
|
} : void 0;
|
|
207019
|
-
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts) : await sendRequest(requestParsed, retryOpts);
|
|
208039
|
+
const response = cookieJar ? await sendRequestWithJar(requestParsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(requestParsed, retryOpts, executionContext?.signal);
|
|
207020
208040
|
addResponse(response);
|
|
207021
208041
|
responseIndexToVariable.set(responses.length, varName);
|
|
207022
208042
|
const stepResult = {
|
|
@@ -207047,6 +208067,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207047
208067
|
}
|
|
207048
208068
|
}
|
|
207049
208069
|
} catch (error2) {
|
|
208070
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
207050
208071
|
const userMessage = formatUserFacingError(
|
|
207051
208072
|
error2,
|
|
207052
208073
|
buildRequestValidationContext(stepIdx + 1, requestMethod || void 0, requestUrl || void 0, `${varName} = run ${sequenceName}`)
|
|
@@ -207132,7 +208153,8 @@ ${indentMultiline(userMessage)}`;
|
|
|
207132
208153
|
agentEventLog,
|
|
207133
208154
|
agentRootInvocationCounts,
|
|
207134
208155
|
recordAgentRuns: executionContext?.recordAgentRuns,
|
|
207135
|
-
knowledgeCoordinator
|
|
208156
|
+
knowledgeCoordinator,
|
|
208157
|
+
signal: executionContext?.signal
|
|
207136
208158
|
};
|
|
207137
208159
|
const subResult = await runSequenceWithJar(
|
|
207138
208160
|
targetSequence.content,
|
|
@@ -207224,7 +208246,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207224
208246
|
reportProgress(stepIdx, "request", `[Retry ${attempt}/${total}] ${requestDescription} - waiting ${waitMs}ms`, void 0);
|
|
207225
208247
|
}
|
|
207226
208248
|
} : void 0;
|
|
207227
|
-
const response = cookieJar ? await sendRequestWithJar(parsed, cookieJar, retryOpts) : await sendRequest(parsed, retryOpts);
|
|
208249
|
+
const response = cookieJar ? await sendRequestWithJar(parsed, cookieJar, retryOpts, executionContext?.signal) : await sendRequest(parsed, retryOpts, executionContext?.signal);
|
|
207228
208250
|
addResponse(response);
|
|
207229
208251
|
const stepResult = {
|
|
207230
208252
|
type: "request",
|
|
@@ -207247,6 +208269,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207247
208269
|
}
|
|
207248
208270
|
}
|
|
207249
208271
|
} catch (error2) {
|
|
208272
|
+
throwIfSequenceCancelled(executionContext?.signal);
|
|
207250
208273
|
const userMessage = formatUserFacingError(
|
|
207251
208274
|
error2,
|
|
207252
208275
|
buildRequestValidationContext(stepIdx + 1)
|
|
@@ -207272,7 +208295,9 @@ ${indentMultiline(userMessage)}`;
|
|
|
207272
208295
|
}
|
|
207273
208296
|
}
|
|
207274
208297
|
} finally {
|
|
207275
|
-
|
|
208298
|
+
if (!executionContext?.signal?.aborted) {
|
|
208299
|
+
await emitAfterStep(step, stepIdx);
|
|
208300
|
+
}
|
|
207276
208301
|
}
|
|
207277
208302
|
}
|
|
207278
208303
|
return {
|
|
@@ -207288,16 +208313,23 @@ ${indentMultiline(userMessage)}`;
|
|
|
207288
208313
|
agentTrace,
|
|
207289
208314
|
completed: true
|
|
207290
208315
|
};
|
|
208316
|
+
} catch (error2) {
|
|
208317
|
+
if (executionContext?.signal?.aborted) {
|
|
208318
|
+
throw new SequenceCancelledError();
|
|
208319
|
+
}
|
|
208320
|
+
throw error2;
|
|
207291
208321
|
} finally {
|
|
208322
|
+
executionContext?.signal?.removeEventListener("abort", cancelMcpSessions);
|
|
208323
|
+
const wasCancelled = executionContext?.signal?.aborted === true;
|
|
207292
208324
|
let recordingPath;
|
|
207293
|
-
const shouldRecordAgentRun = nestingDepth === 0 && agentTrace.hops.length > 0 && (executionContext?.recordAgentRuns ?? executionContext?.agentProviderRegistry === void 0);
|
|
208325
|
+
const shouldRecordAgentRun = !wasCancelled && nestingDepth === 0 && agentTrace.hops.length > 0 && (executionContext?.recordAgentRuns ?? executionContext?.agentProviderRegistry === void 0);
|
|
207294
208326
|
if (shouldRecordAgentRun && executionContext?.filePath) {
|
|
207295
208327
|
try {
|
|
207296
208328
|
recordingPath = writeAgentRunRecording({
|
|
207297
208329
|
sourcePath: executionContext.filePath,
|
|
207298
208330
|
sequenceName: executionContext.sequenceName || "sequence",
|
|
207299
208331
|
...executionContext.environment?.activeEnvironment ? { environmentName: executionContext.environment.activeEnvironment } : {},
|
|
207300
|
-
success: errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
208332
|
+
success: !wasCancelled && errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
207301
208333
|
durationMs: Date.now() - startTime,
|
|
207302
208334
|
...knowledgeCoordinator?.pinnedSnapshotId ? {
|
|
207303
208335
|
runId: knowledgeCoordinator.runId,
|
|
@@ -207322,7 +208354,7 @@ ${indentMultiline(userMessage)}`;
|
|
|
207322
208354
|
environmentName: executionContext.environment?.activeEnvironment,
|
|
207323
208355
|
startedAt: new Date(startTime),
|
|
207324
208356
|
durationMs: Date.now() - startTime,
|
|
207325
|
-
success: errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
208357
|
+
success: !wasCancelled && errors.filter((error2) => !error2.startsWith("Warning")).length === 0 && contractViolations === 0 && agentFailures === 0,
|
|
207326
208358
|
recordingPath,
|
|
207327
208359
|
secrets: resolveAgentRecordingSecretValues(
|
|
207328
208360
|
executionContext.filePath,
|
|
@@ -207654,6 +208686,20 @@ function redactAgentRequestForJson(request, redaction) {
|
|
|
207654
208686
|
agentSourcePath: redactString(request.agentSourcePath, redaction),
|
|
207655
208687
|
sourcePath: request.sourcePath ? redactString(request.sourcePath, redaction) : void 0,
|
|
207656
208688
|
sequenceName: request.sequenceName ? redactString(request.sequenceName, redaction) : void 0,
|
|
208689
|
+
knowledge: request.knowledge ? {
|
|
208690
|
+
...request.knowledge,
|
|
208691
|
+
domains: request.knowledge.domains?.map((domain2) => ({
|
|
208692
|
+
...domain2,
|
|
208693
|
+
declarationAlias: redactString(domain2.declarationAlias, redaction),
|
|
208694
|
+
sourcePath: redactString(domain2.sourcePath, redaction),
|
|
208695
|
+
domainPath: redactString(domain2.domainPath, redaction),
|
|
208696
|
+
topics: domain2.topics.map((topic) => ({
|
|
208697
|
+
...topic,
|
|
208698
|
+
heading: topic.heading ? redactString(topic.heading, redaction) : void 0,
|
|
208699
|
+
itemPaths: topic.itemPaths.map((itemPath) => redactString(itemPath, redaction))
|
|
208700
|
+
}))
|
|
208701
|
+
}))
|
|
208702
|
+
} : void 0,
|
|
207657
208703
|
promptHash: (0, import_crypto11.createHash)("sha256").update(systemPrompt, "utf8").digest("hex")
|
|
207658
208704
|
};
|
|
207659
208705
|
}
|
|
@@ -207673,6 +208719,10 @@ function redactAgentHopForJson(hop, redaction) {
|
|
|
207673
208719
|
sourcePath: redactString(hop.turnLimit.sourcePath, redaction),
|
|
207674
208720
|
...hop.turnLimit.lastToolName ? { lastToolName: redactString(hop.turnLimit.lastToolName, redaction) } : {}
|
|
207675
208721
|
} : void 0,
|
|
208722
|
+
inputTokenLimit: hop.inputTokenLimit ? {
|
|
208723
|
+
...hop.inputTokenLimit,
|
|
208724
|
+
sourcePath: redactString(hop.inputTokenLimit.sourcePath, redaction)
|
|
208725
|
+
} : void 0,
|
|
207676
208726
|
warnings: hop.warnings.map((warning) => redactString(warning, redaction)),
|
|
207677
208727
|
accepts: redactAgentContractForJson(hop.accepts, redaction),
|
|
207678
208728
|
returns: redactAgentContractForJson(hop.returns, redaction),
|
|
@@ -207689,7 +208739,7 @@ function redactAgentHopForJson(hop, redaction) {
|
|
|
207689
208739
|
body: redactBody(hop.output.body, redaction),
|
|
207690
208740
|
text: typeof redactedText === "string" ? redactedText : String(redactedText ?? ""),
|
|
207691
208741
|
model: redactString(hop.output.model, redaction),
|
|
207692
|
-
toolCalls: hop.output.toolCalls.map((toolCall) => ({
|
|
208742
|
+
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
208743
|
...toolCall,
|
|
207694
208744
|
name: redactString(toolCall.name, redaction),
|
|
207695
208745
|
input: redactBody(toolCall.input, redaction),
|
|
@@ -207929,6 +208979,9 @@ function isFailedToolResult(value) {
|
|
|
207929
208979
|
const record2 = value;
|
|
207930
208980
|
return Object.keys(record2).length === 1 && typeof record2.error === "string";
|
|
207931
208981
|
}
|
|
208982
|
+
function isKnowledgeAlreadyLoaded(value) {
|
|
208983
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value) && value.alreadyLoaded === true);
|
|
208984
|
+
}
|
|
207932
208985
|
function getReplyValue(hop) {
|
|
207933
208986
|
if (hop.output.text.trim().length > 0) {
|
|
207934
208987
|
return { present: true, value: hop.output.text };
|
|
@@ -208006,6 +209059,9 @@ function formatAgentHopAtDepth(hop, options, displayDepth) {
|
|
|
208006
209059
|
const renderedChildren = /* @__PURE__ */ new Set();
|
|
208007
209060
|
const childrenByInvocationId = new Map(hop.children.map((child) => [child.invocationId, child]));
|
|
208008
209061
|
for (const toolCall of hop.output.toolCalls) {
|
|
209062
|
+
if (toolCall.kind === "context" || toolCall.kind === "knowledge" && isKnowledgeAlreadyLoaded(toolCall.output)) {
|
|
209063
|
+
continue;
|
|
209064
|
+
}
|
|
208009
209065
|
if (toolCall.kind === "agent" || toolCall.childInvocationId) {
|
|
208010
209066
|
const child = toolCall.childInvocationId ? childrenByInvocationId.get(toolCall.childInvocationId) : void 0;
|
|
208011
209067
|
if (child) {
|
|
@@ -210854,6 +211910,42 @@ async function runK8sRunbooks(text, options = {}) {
|
|
|
210854
211910
|
var import_util8 = require("util");
|
|
210855
211911
|
|
|
210856
211912
|
// src/agents/agentHopPresentation.ts
|
|
211913
|
+
function buildAgentKnowledgePresentation(knowledge) {
|
|
211914
|
+
if (!knowledge) {
|
|
211915
|
+
return void 0;
|
|
211916
|
+
}
|
|
211917
|
+
const domains = knowledge.domains ? knowledge.domains.map((domain2) => ({
|
|
211918
|
+
domainId: domain2.domainId,
|
|
211919
|
+
declarationAlias: domain2.declarationAlias,
|
|
211920
|
+
sourcePath: domain2.sourcePath,
|
|
211921
|
+
domainPath: domain2.domainPath,
|
|
211922
|
+
disposition: domain2.disposition,
|
|
211923
|
+
estimatedTokens: domain2.estimatedTokens,
|
|
211924
|
+
topicCount: domain2.topicCount,
|
|
211925
|
+
topics: domain2.topics.map((topic) => ({
|
|
211926
|
+
topicHash: topic.topicHash,
|
|
211927
|
+
...topic.heading ? { heading: topic.heading } : {},
|
|
211928
|
+
estimatedTokens: topic.estimatedTokens,
|
|
211929
|
+
itemPaths: [...topic.itemPaths]
|
|
211930
|
+
}))
|
|
211931
|
+
})) : knowledge.selectedDomainIds.map((domainId) => {
|
|
211932
|
+
const parts = decodeKnowledgeId(domainId);
|
|
211933
|
+
const domainPath = typeof parts?.[2] === "string" ? parts[2] : "Recorded domain";
|
|
211934
|
+
return {
|
|
211935
|
+
domainId,
|
|
211936
|
+
domainPath,
|
|
211937
|
+
disposition: "selected",
|
|
211938
|
+
topics: []
|
|
211939
|
+
};
|
|
211940
|
+
});
|
|
211941
|
+
return {
|
|
211942
|
+
routingRule: knowledge.routingRule,
|
|
211943
|
+
estimatedTokens: knowledge.estimatedTokens,
|
|
211944
|
+
estimatorVersion: knowledge.estimatorVersion,
|
|
211945
|
+
detailsComplete: knowledge.domains !== void 0,
|
|
211946
|
+
domains
|
|
211947
|
+
};
|
|
211948
|
+
}
|
|
210857
211949
|
function isSameAgentContract(left, right) {
|
|
210858
211950
|
return Boolean(
|
|
210859
211951
|
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 +211998,25 @@ function deriveAgentHopPresentation(hop) {
|
|
|
210906
211998
|
...hop.turnLimit.lastToolName ? { lastToolName: hop.turnLimit.lastToolName } : {}
|
|
210907
211999
|
}
|
|
210908
212000
|
} : {},
|
|
212001
|
+
...hop.inputTokenLimit ? {
|
|
212002
|
+
inputTokenLimit: {
|
|
212003
|
+
maxInputTokens: hop.inputTokenLimit.maxInputTokens,
|
|
212004
|
+
usedInputTokens: hop.inputTokenLimit.usedInputTokens,
|
|
212005
|
+
...hop.inputTokenLimit.estimatedNextInputTokens !== void 0 ? { estimatedNextInputTokens: hop.inputTokenLimit.estimatedNextInputTokens } : {}
|
|
212006
|
+
}
|
|
212007
|
+
} : {},
|
|
212008
|
+
...hop.request?.maxInputTokens !== void 0 ? { maxInputTokens: hop.request.maxInputTokens } : {},
|
|
210909
212009
|
...hop.error ? { error: hop.error } : {},
|
|
210910
212010
|
warnings: [...hop.warnings],
|
|
210911
212011
|
...hop.judge ? { judge: buildAgentJudgePresentation(hop.judge) } : {},
|
|
212012
|
+
...hop.request?.knowledge ? { knowledge: buildAgentKnowledgePresentation(hop.request.knowledge) } : {},
|
|
210912
212013
|
output: {
|
|
210913
212014
|
model: hop.output.model,
|
|
210914
212015
|
ms: hop.output.ms,
|
|
210915
212016
|
usage: {
|
|
210916
212017
|
inputTokens: hop.output.usage.inputTokens,
|
|
210917
|
-
outputTokens: hop.output.usage.outputTokens
|
|
212018
|
+
outputTokens: hop.output.usage.outputTokens,
|
|
212019
|
+
...hop.output.usage.turns ? { turns: hop.output.usage.turns.map((turn) => ({ ...turn })) } : {}
|
|
210918
212020
|
},
|
|
210919
212021
|
text: hop.output.text,
|
|
210920
212022
|
...Object.prototype.hasOwnProperty.call(hop.output, "body") && hop.output.body !== void 0 ? { body: hop.output.body } : {},
|
|
@@ -211008,7 +212110,13 @@ var ReplayAgentProviderAdapter = class {
|
|
|
211008
212110
|
};
|
|
211009
212111
|
|
|
211010
212112
|
// src/agents/agentReplay.ts
|
|
211011
|
-
var PROVIDERS = [
|
|
212113
|
+
var PROVIDERS = [
|
|
212114
|
+
"openai",
|
|
212115
|
+
"openai_compatible",
|
|
212116
|
+
"anthropic",
|
|
212117
|
+
"google",
|
|
212118
|
+
"local"
|
|
212119
|
+
];
|
|
211012
212120
|
function normalizedPath(value) {
|
|
211013
212121
|
return value.replace(/\\/g, "/").toLowerCase();
|
|
211014
212122
|
}
|
|
@@ -211034,7 +212142,10 @@ function recordedProviderResponse(hop, provider) {
|
|
|
211034
212142
|
text: hop.output.text,
|
|
211035
212143
|
...hasOwn4(hop.output, "body") ? { parsed: structuredClone(hop.output.body) } : {},
|
|
211036
212144
|
toolCalls: cloneToolCalls(hop.output.toolCalls),
|
|
211037
|
-
usage: {
|
|
212145
|
+
usage: {
|
|
212146
|
+
...hop.output.usage,
|
|
212147
|
+
...hop.output.usage.turns ? { turns: hop.output.usage.turns.map((turn) => ({ ...turn })) } : {}
|
|
212148
|
+
},
|
|
211038
212149
|
resolvedModelId: resolvedModelId(hop, provider)
|
|
211039
212150
|
};
|
|
211040
212151
|
}
|
|
@@ -211196,8 +212307,10 @@ var ReplayCoordinator = class {
|
|
|
211196
212307
|
provider: hop.request.provider,
|
|
211197
212308
|
modelId: hop.request.modelId,
|
|
211198
212309
|
displayModel: hop.request.displayModel,
|
|
212310
|
+
...hop.request.reasoningEffort ? { reasoningEffort: hop.request.reasoningEffort } : {},
|
|
211199
212311
|
systemPrompt: hop.request.systemPrompt,
|
|
211200
212312
|
maxTokens: hop.request.maxTokens,
|
|
212313
|
+
...hop.request.maxInputTokens !== void 0 ? { maxInputTokens: hop.request.maxInputTokens } : {},
|
|
211201
212314
|
tools: hop.request.tools.map((tool) => ({
|
|
211202
212315
|
...tool,
|
|
211203
212316
|
inputSchema: structuredClone(tool.inputSchema)
|
|
@@ -211375,7 +212488,8 @@ var ReplayCoordinator = class {
|
|
|
211375
212488
|
let actualOutput;
|
|
211376
212489
|
let actualError;
|
|
211377
212490
|
try {
|
|
211378
|
-
|
|
212491
|
+
const executed = await currentTool.execute(structuredClone(recordedCall.input));
|
|
212492
|
+
actualOutput = normalizePreparedAgentToolResult(executed).recordedOutput;
|
|
211379
212493
|
} catch (error2) {
|
|
211380
212494
|
if (kind === "mcp") {
|
|
211381
212495
|
throw error2;
|