open-multi-agent-kit 0.97.0 → 0.98.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -1
- package/README.md +41 -9
- package/dist/cli/args.d.ts +2 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +13 -189
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +194 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js +2 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/resource-paths.d.ts +4 -0
- package/dist/cli/resource-paths.d.ts.map +1 -0
- package/dist/cli/resource-paths.js +59 -0
- package/dist/cli/resource-paths.js.map +1 -0
- package/dist/commands/adaptorch-doctor-cli.d.ts +13 -0
- package/dist/commands/adaptorch-doctor-cli.d.ts.map +1 -0
- package/dist/commands/adaptorch-doctor-cli.js +115 -0
- package/dist/commands/adaptorch-doctor-cli.js.map +1 -0
- package/dist/commands/resource-doctor-cli.d.ts +4 -0
- package/dist/commands/resource-doctor-cli.d.ts.map +1 -1
- package/dist/commands/resource-doctor-cli.js +35 -5
- package/dist/commands/resource-doctor-cli.js.map +1 -1
- package/dist/core/adaptorch-bridge.d.ts +11 -13
- package/dist/core/adaptorch-bridge.d.ts.map +1 -1
- package/dist/core/adaptorch-bridge.js +11 -13
- package/dist/core/adaptorch-bridge.js.map +1 -1
- package/dist/core/agent-session-snapshot.d.ts +16 -0
- package/dist/core/agent-session-snapshot.d.ts.map +1 -0
- package/dist/core/agent-session-snapshot.js +111 -0
- package/dist/core/agent-session-snapshot.js.map +1 -0
- package/dist/core/agent-session.d.ts +5 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +27 -219
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-tool-settings.d.ts +10 -0
- package/dist/core/agent-tool-settings.d.ts.map +1 -1
- package/dist/core/agent-tool-settings.js +10 -1
- package/dist/core/agent-tool-settings.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +7 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +25 -61
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts +1 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/compaction/knowledge-triage-format.d.ts +9 -0
- package/dist/core/compaction/knowledge-triage-format.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage-format.js +71 -0
- package/dist/core/compaction/knowledge-triage-format.js.map +1 -0
- package/dist/core/compaction/knowledge-triage-types.d.ts +7 -0
- package/dist/core/compaction/knowledge-triage-types.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage-types.js +2 -0
- package/dist/core/compaction/knowledge-triage-types.js.map +1 -0
- package/dist/core/compaction/knowledge-triage.d.ts +29 -0
- package/dist/core/compaction/knowledge-triage.d.ts.map +1 -0
- package/dist/core/compaction/knowledge-triage.js +189 -0
- package/dist/core/compaction/knowledge-triage.js.map +1 -0
- package/dist/core/compaction/transaction.d.ts.map +1 -1
- package/dist/core/compaction/transaction.js +1 -1
- package/dist/core/compaction/transaction.js.map +1 -1
- package/dist/core/compaction/utils.d.ts +4 -0
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +37 -0
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/completion-sound-io.d.ts +14 -0
- package/dist/core/completion-sound-io.d.ts.map +1 -0
- package/dist/core/completion-sound-io.js +64 -0
- package/dist/core/completion-sound-io.js.map +1 -0
- package/dist/core/completion-sound.d.ts +4 -10
- package/dist/core/completion-sound.d.ts.map +1 -1
- package/dist/core/completion-sound.js +28 -58
- package/dist/core/completion-sound.js.map +1 -1
- package/dist/core/context-budget-relevance.d.ts +15 -2
- package/dist/core/context-budget-relevance.d.ts.map +1 -1
- package/dist/core/context-budget-relevance.js +21 -9
- package/dist/core/context-budget-relevance.js.map +1 -1
- package/dist/core/context-budget-system-prompt-items.d.ts +1 -1
- package/dist/core/context-budget-system-prompt-items.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt-items.js.map +1 -1
- package/dist/core/context-budget-system-prompt.d.ts +1 -1
- package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
- package/dist/core/context-budget-system-prompt.js.map +1 -1
- package/dist/core/context-file.d.ts +23 -0
- package/dist/core/context-file.d.ts.map +1 -0
- package/dist/core/context-file.js +17 -0
- package/dist/core/context-file.js.map +1 -0
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +6 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-prompt-policy.d.ts +1 -1
- package/dist/core/model-prompt-policy.d.ts.map +1 -1
- package/dist/core/model-prompt-policy.js.map +1 -1
- package/dist/core/prompt-settlement.d.ts +6 -3
- package/dist/core/prompt-settlement.d.ts.map +1 -1
- package/dist/core/prompt-settlement.js +10 -14
- package/dist/core/prompt-settlement.js.map +1 -1
- package/dist/core/reasoning-router-promotion.d.ts +41 -1
- package/dist/core/reasoning-router-promotion.d.ts.map +1 -1
- package/dist/core/reasoning-router-promotion.js +31 -2
- package/dist/core/reasoning-router-promotion.js.map +1 -1
- package/dist/core/reasoning-router-replay-stability.d.ts +65 -0
- package/dist/core/reasoning-router-replay-stability.d.ts.map +1 -0
- package/dist/core/reasoning-router-replay-stability.js +67 -0
- package/dist/core/reasoning-router-replay-stability.js.map +1 -0
- package/dist/core/reasoning-router-v4-weights.d.ts +6 -6
- package/dist/core/reasoning-router-v4-weights.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4-weights.js +3 -3
- package/dist/core/reasoning-router-v4-weights.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +6 -6
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/redaction.d.ts.map +1 -1
- package/dist/core/redaction.js +1 -1
- package/dist/core/redaction.js.map +1 -1
- package/dist/core/resource-admission.d.ts +2 -1
- package/dist/core/resource-admission.d.ts.map +1 -1
- package/dist/core/resource-admission.js +11 -0
- package/dist/core/resource-admission.js.map +1 -1
- package/dist/core/resource-governor-format.d.ts +1 -1
- package/dist/core/resource-governor-format.d.ts.map +1 -1
- package/dist/core/resource-governor-format.js.map +1 -1
- package/dist/core/resource-governor-settings.d.ts +6 -12
- package/dist/core/resource-governor-settings.d.ts.map +1 -1
- package/dist/core/resource-governor-settings.js.map +1 -1
- package/dist/core/resource-governor-types.d.ts +24 -0
- package/dist/core/resource-governor-types.d.ts.map +1 -0
- package/dist/core/resource-governor-types.js +15 -0
- package/dist/core/resource-governor-types.js.map +1 -0
- package/dist/core/resource-loader.d.ts +1 -7
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/resource-observation-journal.d.ts +2 -1
- package/dist/core/resource-observation-journal.d.ts.map +1 -1
- package/dist/core/resource-observation-journal.js +4 -3
- package/dist/core/resource-observation-journal.js.map +1 -1
- package/dist/core/resource-observation-report-reader.d.ts +7 -0
- package/dist/core/resource-observation-report-reader.d.ts.map +1 -0
- package/dist/core/resource-observation-report-reader.js +157 -0
- package/dist/core/resource-observation-report-reader.js.map +1 -0
- package/dist/core/resource-observation-report.d.ts +24 -0
- package/dist/core/resource-observation-report.d.ts.map +1 -0
- package/dist/core/resource-observation-report.js +101 -0
- package/dist/core/resource-observation-report.js.map +1 -0
- package/dist/core/router-feedback-collector.d.ts +1 -1
- package/dist/core/router-feedback-collector.d.ts.map +1 -1
- package/dist/core/router-feedback-collector.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts +33 -0
- package/dist/core/session-failure-cause.d.ts.map +1 -0
- package/dist/core/session-failure-cause.js +141 -0
- package/dist/core/session-failure-cause.js.map +1 -0
- package/dist/core/session-system-prompt.d.ts +1 -1
- package/dist/core/session-system-prompt.d.ts.map +1 -1
- package/dist/core/session-system-prompt.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +7 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/workload-classifier.d.ts +2 -10
- package/dist/core/workload-classifier.d.ts.map +1 -1
- package/dist/core/workload-classifier.js +17 -0
- package/dist/core/workload-classifier.js.map +1 -1
- package/dist/core/workload-family-matcher.d.ts +1 -1
- package/dist/core/workload-family-matcher.d.ts.map +1 -1
- package/dist/core/workload-family-matcher.js.map +1 -1
- package/dist/core/workload-shard-execution-types.d.ts +40 -0
- package/dist/core/workload-shard-execution-types.d.ts.map +1 -0
- package/dist/core/workload-shard-execution-types.js +14 -0
- package/dist/core/workload-shard-execution-types.js.map +1 -0
- package/dist/core/workload-shard-executor.d.ts +3 -27
- package/dist/core/workload-shard-executor.d.ts.map +1 -1
- package/dist/core/workload-shard-executor.js.map +1 -1
- package/dist/core/workload-shard-runner.d.ts +1 -1
- package/dist/core/workload-shard-runner.d.ts.map +1 -1
- package/dist/core/workload-shard-runner.js.map +1 -1
- package/dist/core/workload-types.d.ts +24 -0
- package/dist/core/workload-types.d.ts.map +1 -0
- package/dist/core/workload-types.js +15 -0
- package/dist/core/workload-types.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -47
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/theme/omk-control-panel.json +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +42 -33
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +14 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/docs/adaptorch-preview-spec.md +20 -18
- package/docs/adaptorch-preview.md +9 -9
- package/docs/compaction.md +24 -3
- package/docs/correctness-wall.md +10 -10
- package/docs/docs.json +12 -0
- package/docs/environment-variables.md +9 -2
- package/docs/index.md +3 -0
- package/docs/runtime-algorithms.md +359 -0
- package/docs/sdk.md +2 -2
- package/docs/settings.md +11 -10
- package/docs/usage.md +18 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -6
- package/dist/core/context-budget-governor.d.ts +0 -67
- package/dist/core/context-budget-governor.d.ts.map +0 -1
- package/dist/core/context-budget-governor.js +0 -224
- package/dist/core/context-budget-governor.js.map +0 -1
- package/dist/core/lean-ctx.d.ts +0 -99
- package/dist/core/lean-ctx.d.ts.map +0 -1
- package/dist/core/lean-ctx.js +0 -225
- package/dist/core/lean-ctx.js.map +0 -1
- package/dist/core/read-anchors.d.ts +0 -110
- package/dist/core/read-anchors.d.ts.map +0 -1
- package/dist/core/read-anchors.js +0 -193
- package/dist/core/read-anchors.js.map +0 -1
- package/dist/core/recovery-checkpoint.d.ts +0 -196
- package/dist/core/recovery-checkpoint.d.ts.map +0 -1
- package/dist/core/recovery-checkpoint.js +0 -382
- package/dist/core/recovery-checkpoint.js.map +0 -1
- package/dist/core/sandbox-policy-v2.d.ts +0 -49
- package/dist/core/sandbox-policy-v2.d.ts.map +0 -1
- package/dist/core/sandbox-policy-v2.js +0 -368
- package/dist/core/sandbox-policy-v2.js.map +0 -1
- package/dist/guardrails/audit-logger.d.ts +0 -4
- package/dist/guardrails/audit-logger.d.ts.map +0 -1
- package/dist/guardrails/audit-logger.js +0 -28
- package/dist/guardrails/audit-logger.js.map +0 -1
- package/dist/guardrails/freedomd-adapter.d.ts +0 -16
- package/dist/guardrails/freedomd-adapter.d.ts.map +0 -1
- package/dist/guardrails/freedomd-adapter.js +0 -87
- package/dist/guardrails/freedomd-adapter.js.map +0 -1
- package/dist/orchestration/lane-grant-auditor.d.ts +0 -4
- package/dist/orchestration/lane-grant-auditor.d.ts.map +0 -1
- package/dist/orchestration/lane-grant-auditor.js +0 -87
- package/dist/orchestration/lane-grant-auditor.js.map +0 -1
- package/dist/types/guardrails.d.ts +0 -61
- package/dist/types/guardrails.d.ts.map +0 -1
- package/dist/types/guardrails.js +0 -9
- package/dist/types/guardrails.js.map +0 -1
- package/dist/types/lane-grant.d.ts +0 -58
- package/dist/types/lane-grant.d.ts.map +0 -1
- package/dist/types/lane-grant.js +0 -9
- package/dist/types/lane-grant.js.map +0 -1
|
@@ -17,7 +17,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
17
17
|
import { basename, dirname, join as joinPath } from "node:path";
|
|
18
18
|
import { isDeepStrictEqual } from "node:util";
|
|
19
19
|
import { getVisionRouteModel } from "omk-agent-core";
|
|
20
|
-
import { clampThinkingLevel, cleanupSessionResources, deriveContextPromptCacheKey, getSupportedThinkingLevels,
|
|
20
|
+
import { clampThinkingLevel, cleanupSessionResources, deriveContextPromptCacheKey, getSupportedThinkingLevels, isBuiltinStreamFn, modelsAreEqual, resetApiProviders, } from "omk-ai";
|
|
21
21
|
import { APP_NAME, VERSION } from "../config.js";
|
|
22
22
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
23
23
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
@@ -72,12 +72,13 @@ function firstTextContent(result) {
|
|
|
72
72
|
}
|
|
73
73
|
return undefined;
|
|
74
74
|
}
|
|
75
|
+
import { createImmutableMessageSnapshot } from "./agent-session-snapshot.js";
|
|
75
76
|
import { redactCredentialShapedContent } from "./compaction/transaction.js";
|
|
76
77
|
import { selectContextFilesForModel } from "./model-prompt-policy.js";
|
|
77
78
|
import { findExactModelReferenceMatch } from "./model-resolver.js";
|
|
78
79
|
import { computePromptTokenBudget } from "./prompt-budget.js";
|
|
79
80
|
import { classifyPromptCacheTransition } from "./prompt-cache.js";
|
|
80
|
-
import
|
|
81
|
+
import * as promptSettlement from "./prompt-settlement.js";
|
|
81
82
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
82
83
|
import { isQuotaExhaustionMessage, isStickySafetyModel, isUpstreamUnavailableMessage, pickFailoverCandidate, resolveFailoverCandidates, resolveProviderResilience, sameModelRouteCandidates, shouldEjectStickySafetyModel, shouldHonorSafetyFailover, stickySafetyBlockMessage, } from "./provider-resilience.js";
|
|
83
84
|
import { computeRetryDelayMs, failoverModelKey, isFailoverTriggerError, isRetryableAssistantError, nextRetryAttempt, retryBudgetForAssistantError, } from "./provider-retry.js";
|
|
@@ -95,6 +96,7 @@ import { RunResourceLeaseController } from "./run-resource-lease.js";
|
|
|
95
96
|
import { SessionBashRuntime } from "./session-bash-runtime.js";
|
|
96
97
|
import { SessionBashService } from "./session-bash-service.js";
|
|
97
98
|
import { SessionCompactionService } from "./session-compaction-service.js";
|
|
99
|
+
import { preflightFailureCause, providerFailureCause, runtimeFailureCause, terminationMessage, } from "./session-failure-cause.js";
|
|
98
100
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
99
101
|
import { acquireSessionOwnerLeaseSync } from "./session-owner-lease.js";
|
|
100
102
|
import { assembleSessionSystemPrompt } from "./session-system-prompt.js";
|
|
@@ -171,103 +173,6 @@ function toolNameSetsEqual(left, right) {
|
|
|
171
173
|
return (normalizedLeft.length === normalizedRight.length &&
|
|
172
174
|
normalizedLeft.every((toolName, index) => toolName === normalizedRight[index]));
|
|
173
175
|
}
|
|
174
|
-
function snapshotContractError(reason) {
|
|
175
|
-
return new Error(`Finalized message replacement must be a plain serializable snapshot: ${reason}`);
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Clone a finalized message replacement into the JSON-compatible snapshot
|
|
179
|
-
* persisted by SessionManager. Undefined remains allowed as ordinary optional
|
|
180
|
-
* message data: JSON omits object properties with undefined values and writes
|
|
181
|
-
* undefined array elements as null.
|
|
182
|
-
*/
|
|
183
|
-
function clonePlainSnapshot(value, ancestors = new WeakSet(), copies = new WeakMap()) {
|
|
184
|
-
if (value === null)
|
|
185
|
-
return value;
|
|
186
|
-
switch (typeof value) {
|
|
187
|
-
case "string":
|
|
188
|
-
case "boolean":
|
|
189
|
-
case "undefined":
|
|
190
|
-
return value;
|
|
191
|
-
case "number":
|
|
192
|
-
if (!Number.isFinite(value)) {
|
|
193
|
-
throw snapshotContractError("non-finite number values are not allowed");
|
|
194
|
-
}
|
|
195
|
-
return value;
|
|
196
|
-
case "bigint":
|
|
197
|
-
throw snapshotContractError("bigint values are not allowed");
|
|
198
|
-
case "function":
|
|
199
|
-
case "symbol":
|
|
200
|
-
throw snapshotContractError(`${typeof value} values are not allowed`);
|
|
201
|
-
case "object":
|
|
202
|
-
break;
|
|
203
|
-
default:
|
|
204
|
-
throw snapshotContractError(`${typeof value} values are not allowed`);
|
|
205
|
-
}
|
|
206
|
-
if (ancestors.has(value)) {
|
|
207
|
-
throw snapshotContractError("cyclic values are not allowed");
|
|
208
|
-
}
|
|
209
|
-
if (copies.has(value)) {
|
|
210
|
-
return copies.get(value);
|
|
211
|
-
}
|
|
212
|
-
ancestors.add(value);
|
|
213
|
-
try {
|
|
214
|
-
if (Array.isArray(value)) {
|
|
215
|
-
const copy = [];
|
|
216
|
-
copy.length = value.length;
|
|
217
|
-
copies.set(value, copy);
|
|
218
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
219
|
-
if (key === "length")
|
|
220
|
-
continue;
|
|
221
|
-
if (typeof key !== "string" || !/^(0|[1-9]\d*)$/.test(key) || Number(key) >= value.length) {
|
|
222
|
-
throw snapshotContractError("arrays may only contain indexed values");
|
|
223
|
-
}
|
|
224
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
225
|
-
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
|
|
226
|
-
throw snapshotContractError("accessor or non-enumerable properties are not allowed");
|
|
227
|
-
}
|
|
228
|
-
copy[Number(key)] = clonePlainSnapshot(descriptor.value, ancestors, copies);
|
|
229
|
-
}
|
|
230
|
-
return copy;
|
|
231
|
-
}
|
|
232
|
-
const prototype = Object.getPrototypeOf(value);
|
|
233
|
-
if (prototype !== Object.prototype && prototype !== null) {
|
|
234
|
-
throw snapshotContractError("non-plain objects are not allowed");
|
|
235
|
-
}
|
|
236
|
-
const copy = Object.create(prototype);
|
|
237
|
-
copies.set(value, copy);
|
|
238
|
-
for (const key of Reflect.ownKeys(value)) {
|
|
239
|
-
if (typeof key !== "string") {
|
|
240
|
-
throw snapshotContractError("symbol-keyed properties are not allowed");
|
|
241
|
-
}
|
|
242
|
-
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
243
|
-
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
|
|
244
|
-
throw snapshotContractError("accessor or non-enumerable properties are not allowed");
|
|
245
|
-
}
|
|
246
|
-
Object.defineProperty(copy, key, {
|
|
247
|
-
value: clonePlainSnapshot(descriptor.value, ancestors, copies),
|
|
248
|
-
enumerable: true,
|
|
249
|
-
configurable: true,
|
|
250
|
-
writable: true,
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
return copy;
|
|
254
|
-
}
|
|
255
|
-
finally {
|
|
256
|
-
ancestors.delete(value);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
function freezeSnapshot(value, seen = new WeakSet()) {
|
|
260
|
-
if (value === null || typeof value !== "object" || seen.has(value))
|
|
261
|
-
return value;
|
|
262
|
-
seen.add(value);
|
|
263
|
-
for (const child of Object.values(value)) {
|
|
264
|
-
freezeSnapshot(child, seen);
|
|
265
|
-
}
|
|
266
|
-
return Object.freeze(value);
|
|
267
|
-
}
|
|
268
|
-
function createImmutableMessageSnapshot(message) {
|
|
269
|
-
return freezeSnapshot(clonePlainSnapshot(message));
|
|
270
|
-
}
|
|
271
176
|
// ============================================================================
|
|
272
177
|
// AgentSession Class
|
|
273
178
|
// ============================================================================
|
|
@@ -387,7 +292,7 @@ export class AgentSession {
|
|
|
387
292
|
_workspaceMutationCount = 0;
|
|
388
293
|
// Model registry for API key resolution
|
|
389
294
|
_modelRegistry;
|
|
390
|
-
/** Lazy
|
|
295
|
+
/** Lazy provider: representations persist per workspace by default; plans stay session-memory-only. */
|
|
391
296
|
_contextBudgetCacheProvider;
|
|
392
297
|
_contextCacheInvalidationSnapshot;
|
|
393
298
|
// Tool registry for extension getTools/setTools
|
|
@@ -599,87 +504,6 @@ export class AgentSession {
|
|
|
599
504
|
});
|
|
600
505
|
this._appendReplayEvent(event, details);
|
|
601
506
|
}
|
|
602
|
-
_terminationMessage(value, fallback) {
|
|
603
|
-
const redacted = redactSensitiveText(value?.trim() || fallback)
|
|
604
|
-
.replace(/\0/g, "")
|
|
605
|
-
.slice(0, 512);
|
|
606
|
-
return redacted || fallback;
|
|
607
|
-
}
|
|
608
|
-
_providerFailureCause(message) {
|
|
609
|
-
const text = message.errorMessage ?? "";
|
|
610
|
-
if (isContextOverflow(message, this.model?.contextWindow ?? 0)) {
|
|
611
|
-
return { area: "provider", code: "context_overflow" };
|
|
612
|
-
}
|
|
613
|
-
// Fable/Claude often emit stop_reason=refusal on benign turns (false positive).
|
|
614
|
-
// Match broadly so we never mislabel these as provider.protocol.
|
|
615
|
-
if (/stop_reason\s*=\s*(refusal|sensitive)|content\/safety stop|safety stop|provider\.refusal|kind=provider_refusal/i.test(text)) {
|
|
616
|
-
return { area: "provider", code: "refusal" };
|
|
617
|
-
}
|
|
618
|
-
// Quota/billing exhaustion is checked BEFORE the generic 401/403 auth
|
|
619
|
-
// patterns: "403 ... usage limit for this billing cycle" is transient per
|
|
620
|
-
// cycle and must fail over, not terminate the turn as an auth error.
|
|
621
|
-
if (isQuotaExhaustionMessage(text) || /rate.?limit|too many requests|429/i.test(text)) {
|
|
622
|
-
return { area: "provider", code: "rate_limit" };
|
|
623
|
-
}
|
|
624
|
-
if (/auth|unauthori[sz]ed|forbidden|invalid.?api.?key|no api key|401|403|\/login/i.test(text)) {
|
|
625
|
-
return { area: "provider", code: "auth" };
|
|
626
|
-
}
|
|
627
|
-
// Gateway/upstream 5xx and dropped streams are transport failures, not
|
|
628
|
-
// transcript-shape problems. Classify as network so the guidance points to
|
|
629
|
-
// retry/model-switch instead of the protocol sanitize path.
|
|
630
|
-
if (isUpstreamUnavailableMessage(text)) {
|
|
631
|
-
return { area: "provider", code: "network" };
|
|
632
|
-
}
|
|
633
|
-
// Kimi/K3 + OpenAI-compat: orphan tool results after dropped error assistants.
|
|
634
|
-
// Sanitize-and-retry (transform-messages drops orphans), not a hard tool fatal.
|
|
635
|
-
if (/tool_call_id\s+is\s+not\s+found|tool_call_id\s+not\s+found|unknown\s+tool_call_id/i.test(text)) {
|
|
636
|
-
return { area: "provider", code: "protocol" };
|
|
637
|
-
}
|
|
638
|
-
if (/tool.+timed? out|tool.+timeout/i.test(text))
|
|
639
|
-
return { area: "tool", code: "timeout" };
|
|
640
|
-
if (/\btool\b/i.test(text) && !/tool_call_id/i.test(text))
|
|
641
|
-
return { area: "tool", code: "fatal" };
|
|
642
|
-
if (/network|fetch failed|connection|socket|websocket|timed? out|timeout|dns|econn|^terminated$/i.test(text)) {
|
|
643
|
-
return { area: "provider", code: "network" };
|
|
644
|
-
}
|
|
645
|
-
return { area: "provider", code: "protocol" };
|
|
646
|
-
}
|
|
647
|
-
_classifyPreflightCause(message) {
|
|
648
|
-
if (!this.model || /no model|model selected|model is required/i.test(message)) {
|
|
649
|
-
return { area: "configuration", code: "invalid" };
|
|
650
|
-
}
|
|
651
|
-
if (isQuotaExhaustionMessage(message)) {
|
|
652
|
-
return { area: "provider", code: "rate_limit" };
|
|
653
|
-
}
|
|
654
|
-
if (/auth|api key|unauthori[sz]ed|forbidden|401|403|\/login/i.test(message)) {
|
|
655
|
-
return { area: "provider", code: "auth" };
|
|
656
|
-
}
|
|
657
|
-
if (isUpstreamUnavailableMessage(message)) {
|
|
658
|
-
return { area: "provider", code: "network" };
|
|
659
|
-
}
|
|
660
|
-
if (/context.+overflow|context window|too many tokens/i.test(message)) {
|
|
661
|
-
return { area: "provider", code: "context_overflow" };
|
|
662
|
-
}
|
|
663
|
-
if (/duplicate.?result/i.test(message))
|
|
664
|
-
return { area: "transcript", code: "duplicate_result" };
|
|
665
|
-
if (/orphan.?result/i.test(message))
|
|
666
|
-
return { area: "transcript", code: "orphan_result" };
|
|
667
|
-
if (/duplicate.?call/i.test(message))
|
|
668
|
-
return { area: "transcript", code: "duplicate_call_id" };
|
|
669
|
-
if (/transcript|missing.?result/i.test(message))
|
|
670
|
-
return { area: "transcript", code: "missing_result" };
|
|
671
|
-
if (/compaction/i.test(message))
|
|
672
|
-
return { area: "compaction", code: "failed" };
|
|
673
|
-
if (/fsync/i.test(message))
|
|
674
|
-
return { area: "persistence", code: "fsync_failed" };
|
|
675
|
-
if (/lock/i.test(message))
|
|
676
|
-
return { area: "persistence", code: "lock_failed" };
|
|
677
|
-
if (/append|persist|write/i.test(message))
|
|
678
|
-
return { area: "persistence", code: "append_failed" };
|
|
679
|
-
if (/tool/i.test(message))
|
|
680
|
-
return { area: "tool", code: "fatal" };
|
|
681
|
-
return { area: "internal", code: "unclassified" };
|
|
682
|
-
}
|
|
683
507
|
_classifyRunTermination(runId, event) {
|
|
684
508
|
const timestamp = new Date().toISOString();
|
|
685
509
|
let assistant;
|
|
@@ -708,11 +532,11 @@ export class AgentSession {
|
|
|
708
532
|
}
|
|
709
533
|
else if (assistant.stopReason === "aborted") {
|
|
710
534
|
cause = this._userAbortRequested ? { area: "user", code: "abort" } : { area: "provider", code: "abort" };
|
|
711
|
-
message =
|
|
535
|
+
message = terminationMessage(assistant.errorMessage, this._userAbortRequested ? "The user aborted the run." : "The provider aborted the run.");
|
|
712
536
|
}
|
|
713
537
|
else if (assistant.stopReason === "error") {
|
|
714
|
-
cause = this.
|
|
715
|
-
message =
|
|
538
|
+
cause = providerFailureCause(assistant, this.model?.contextWindow ?? 0);
|
|
539
|
+
message = terminationMessage(assistant.errorMessage, "The provider request failed.");
|
|
716
540
|
}
|
|
717
541
|
else {
|
|
718
542
|
cause = { area: "completed" };
|
|
@@ -742,24 +566,8 @@ export class AgentSession {
|
|
|
742
566
|
this._lastTermination = termination;
|
|
743
567
|
this._emit({ type: "session_termination", termination });
|
|
744
568
|
}
|
|
745
|
-
_runtimeFailureCause(error) {
|
|
746
|
-
if (this._pendingRuntimeTerminationCause)
|
|
747
|
-
return this._pendingRuntimeTerminationCause;
|
|
748
|
-
const code = typeof error === "object" && error !== null && "code" in error ? Reflect.get(error, "code") : undefined;
|
|
749
|
-
if (typeof code === "string" &&
|
|
750
|
-
new Set(["EACCES", "EDQUOT", "EFBIG", "EIO", "EISDIR", "EMFILE", "ENFILE", "ENOSPC", "EPERM", "EROFS"]).has(code)) {
|
|
751
|
-
return { area: "persistence", code: "append_failed" };
|
|
752
|
-
}
|
|
753
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
754
|
-
if (/compaction.+stale|session changed during compaction/i.test(message)) {
|
|
755
|
-
return { area: "compaction", code: "stale" };
|
|
756
|
-
}
|
|
757
|
-
if (/compaction/i.test(message))
|
|
758
|
-
return { area: "compaction", code: "failed" };
|
|
759
|
-
return { area: "internal", code: "unclassified" };
|
|
760
|
-
}
|
|
761
569
|
_publishRuntimeFailure(error) {
|
|
762
|
-
const cause = this.
|
|
570
|
+
const cause = this._pendingRuntimeTerminationCause ?? runtimeFailureCause(error);
|
|
763
571
|
const runId = this._activeRunId ?? `runtime-${randomUUID()}`;
|
|
764
572
|
const timestamp = new Date().toISOString();
|
|
765
573
|
let message = "The AgentSession runtime failed before completing the run.";
|
|
@@ -924,7 +732,7 @@ export class AgentSession {
|
|
|
924
732
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
925
733
|
}
|
|
926
734
|
async _getCompactionRequestAuth(model) {
|
|
927
|
-
if (this.agent.streamFn
|
|
735
|
+
if (isBuiltinStreamFn(this.agent.streamFn)) {
|
|
928
736
|
return this._getRequiredRequestAuth(model);
|
|
929
737
|
}
|
|
930
738
|
const result = await this._modelRegistry.getApiKeyAndHeaders(model);
|
|
@@ -1708,12 +1516,12 @@ export class AgentSession {
|
|
|
1708
1516
|
}
|
|
1709
1517
|
}
|
|
1710
1518
|
catch (error) {
|
|
1711
|
-
outcome =
|
|
1712
|
-
this._userAbortRequested || (error instanceof Error && /abort/i.test(error.message)) ? "aborted" : "failed";
|
|
1519
|
+
outcome = "failed";
|
|
1713
1520
|
this._publishRuntimeFailure(error);
|
|
1714
1521
|
throw error;
|
|
1715
1522
|
}
|
|
1716
1523
|
finally {
|
|
1524
|
+
outcome = promptSettlement.resolvePromptSettlementOutcome(outcome, this._lastTermination?.kind);
|
|
1717
1525
|
if (resourceLease !== null) {
|
|
1718
1526
|
// Generation-safe: a stale release after another run acquired the
|
|
1719
1527
|
// lease is a no-op instead of clobbering the newer cap (§8.1).
|
|
@@ -1734,15 +1542,15 @@ export class AgentSession {
|
|
|
1734
1542
|
*/
|
|
1735
1543
|
_emitPromptSettledIfReady(input) {
|
|
1736
1544
|
try {
|
|
1737
|
-
let state = createPromptSettlementState(input.promptRunId, input.startedAtEpochMs);
|
|
1738
|
-
state = reducePromptSettlement(state, { kind: "terminal", outcome: input.outcome });
|
|
1545
|
+
let state = promptSettlement.createPromptSettlementState(input.promptRunId, input.startedAtEpochMs);
|
|
1546
|
+
state = promptSettlement.reducePromptSettlement(state, { kind: "terminal", outcome: input.outcome });
|
|
1739
1547
|
if (this.isStreaming) {
|
|
1740
|
-
state = reducePromptSettlement(state, { kind: "tool", delta: 1 });
|
|
1548
|
+
state = promptSettlement.reducePromptSettlement(state, { kind: "tool", delta: 1 });
|
|
1741
1549
|
}
|
|
1742
1550
|
if (this.agent.hasQueuedMessages()) {
|
|
1743
|
-
state = reducePromptSettlement(state, { kind: "continuation", delta: 1 });
|
|
1551
|
+
state = promptSettlement.reducePromptSettlement(state, { kind: "continuation", delta: 1 });
|
|
1744
1552
|
}
|
|
1745
|
-
const settled = settlePromptIfReady(state, Date.now());
|
|
1553
|
+
const settled = promptSettlement.settlePromptIfReady(state, Date.now());
|
|
1746
1554
|
if (settled.event !== null) {
|
|
1747
1555
|
input.resourceObservations?.record("prompt_settled_v1", settledObservationFacts(settled.event));
|
|
1748
1556
|
this._emit(settled.event);
|
|
@@ -2031,7 +1839,7 @@ export class AgentSession {
|
|
|
2031
1839
|
// Emit input event for extension interception (before skill/template expansion)
|
|
2032
1840
|
let currentImages = options?.images;
|
|
2033
1841
|
if (this._extensionRunner.hasHandlers("input")) {
|
|
2034
|
-
const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1842
|
+
const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive", this.isStreaming || this.isRetrying ? options?.streamingBehavior : undefined);
|
|
2035
1843
|
if (inputResult.action === "handled") {
|
|
2036
1844
|
preflightResult?.(true);
|
|
2037
1845
|
return;
|
|
@@ -2048,8 +1856,8 @@ export class AgentSession {
|
|
|
2048
1856
|
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
2049
1857
|
}
|
|
2050
1858
|
expandedText = redactSensitiveText(expandedText);
|
|
2051
|
-
//
|
|
2052
|
-
if (this.isStreaming) {
|
|
1859
|
+
// While a run or its retry backoff owns the session, queue instead of starting a competing top-level prompt.
|
|
1860
|
+
if (this.isStreaming || this.isRetrying) {
|
|
2053
1861
|
if (!options?.streamingBehavior) {
|
|
2054
1862
|
throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
|
|
2055
1863
|
}
|
|
@@ -2157,14 +1965,14 @@ export class AgentSession {
|
|
|
2157
1965
|
catch (error) {
|
|
2158
1966
|
preflightResult?.(false);
|
|
2159
1967
|
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
2160
|
-
const cause = this.
|
|
1968
|
+
const cause = preflightFailureCause(rawMessage, Boolean(this.model));
|
|
2161
1969
|
const timestamp = new Date().toISOString();
|
|
2162
1970
|
this._publishTermination(classifySessionTermination({
|
|
2163
1971
|
sessionId: this.sessionId,
|
|
2164
1972
|
runId: `preflight-${randomUUID()}`,
|
|
2165
1973
|
timestamp,
|
|
2166
1974
|
source: "observed",
|
|
2167
|
-
message:
|
|
1975
|
+
message: terminationMessage(rawMessage, "Prompt preflight failed."),
|
|
2168
1976
|
cause,
|
|
2169
1977
|
sideEffects: "none",
|
|
2170
1978
|
...(this.model ? { provider: this.model.provider, model: this.model.id } : {}),
|
|
@@ -2546,7 +2354,7 @@ export class AgentSession {
|
|
|
2546
2354
|
}
|
|
2547
2355
|
async _cycleAvailableModel(direction) {
|
|
2548
2356
|
const resilience = resolveProviderResilience(this.settingsManager.getProviderResilienceSettings());
|
|
2549
|
-
const raw =
|
|
2357
|
+
const raw = this._modelRegistry.getAvailable();
|
|
2550
2358
|
// Hard-kill sticky safety models from the cycle list (Fable must not re-enter via hotkey).
|
|
2551
2359
|
const availableModels = resilience.blockStickySafetyModels
|
|
2552
2360
|
? raw.filter((m) => !isStickySafetyModel(m.id, m.provider))
|
|
@@ -2750,8 +2558,8 @@ export class AgentSession {
|
|
|
2750
2558
|
/**
|
|
2751
2559
|
* Context-pressure band 0..3 from the projected token estimate over the
|
|
2752
2560
|
* model context window (reuses estimateProjectedContextTokens). 0..<0.5,
|
|
2753
|
-
* 1..<0.75, 2..<0.9, 3..>=0.9.
|
|
2754
|
-
*
|
|
2561
|
+
* 1..<0.75, 2..<0.9, 3..>=0.9. The released default pressure coefficient
|
|
2562
|
+
* is 1 and participates only after the classifier has prompt evidence.
|
|
2755
2563
|
*/
|
|
2756
2564
|
_computePressureBucket() {
|
|
2757
2565
|
const contextWindow = this.model?.contextWindow ?? 0;
|
|
@@ -3130,7 +2938,7 @@ export class AgentSession {
|
|
|
3130
2938
|
runId: `compaction-${randomUUID()}`,
|
|
3131
2939
|
timestamp,
|
|
3132
2940
|
source: "observed",
|
|
3133
|
-
message:
|
|
2941
|
+
message: terminationMessage(message, "Manual compaction failed."),
|
|
3134
2942
|
cause: { area: "compaction", code: compactionCode },
|
|
3135
2943
|
sideEffects: committedCompaction ? "confirmed" : "none",
|
|
3136
2944
|
...(this.model ? { provider: this.model.provider, model: this.model.id } : {}),
|
|
@@ -3340,7 +3148,7 @@ export class AgentSession {
|
|
|
3340
3148
|
const compactionModel = this._resolveCompactionModel(this.model);
|
|
3341
3149
|
let apiKey;
|
|
3342
3150
|
let headers;
|
|
3343
|
-
if (this.agent.streamFn
|
|
3151
|
+
if (isBuiltinStreamFn(this.agent.streamFn)) {
|
|
3344
3152
|
const authResult = await this._modelRegistry.getApiKeyAndHeaders(compactionModel);
|
|
3345
3153
|
if (!authResult.ok || !authResult.apiKey) {
|
|
3346
3154
|
const providerLabel = compactionModel.provider;
|