open-multi-agent-kit 0.99.0 → 1.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/CHANGELOG.md +24 -0
- package/README.md +3 -3
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +1 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bundled-coding-agent.d.ts +10 -0
- package/dist/bun/register-bundled-coding-agent.d.ts.map +1 -0
- package/dist/bun/register-bundled-coding-agent.js +12 -0
- package/dist/bun/register-bundled-coding-agent.js.map +1 -0
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/neo-cli.d.ts +9 -0
- package/dist/commands/neo-cli.d.ts.map +1 -0
- package/dist/commands/neo-cli.js +61 -0
- package/dist/commands/neo-cli.js.map +1 -0
- package/dist/core/agent-session.d.ts +29 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +107 -30
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bundled-skills.d.ts +4 -0
- package/dist/core/bundled-skills.d.ts.map +1 -0
- package/dist/core/bundled-skills.js +32 -0
- package/dist/core/bundled-skills.js.map +1 -0
- package/dist/core/cli-diagnostics.d.ts +6 -0
- package/dist/core/cli-diagnostics.d.ts.map +1 -0
- package/dist/core/cli-diagnostics.js +20 -0
- package/dist/core/cli-diagnostics.js.map +1 -0
- package/dist/core/context-budget-headroom.d.ts +12 -0
- package/dist/core/context-budget-headroom.d.ts.map +1 -1
- package/dist/core/context-budget-headroom.js +35 -0
- package/dist/core/context-budget-headroom.js.map +1 -1
- package/dist/core/context-budget-v2-input-validation.d.ts +4 -0
- package/dist/core/context-budget-v2-input-validation.d.ts.map +1 -0
- package/dist/core/context-budget-v2-input-validation.js +79 -0
- package/dist/core/context-budget-v2-input-validation.js.map +1 -0
- package/dist/core/context-budget-v2-observability.d.ts +15 -0
- package/dist/core/context-budget-v2-observability.d.ts.map +1 -0
- package/dist/core/context-budget-v2-observability.js +35 -0
- package/dist/core/context-budget-v2-observability.js.map +1 -0
- package/dist/core/context-budget-v2-planned-items.d.ts +5 -0
- package/dist/core/context-budget-v2-planned-items.d.ts.map +1 -0
- package/dist/core/context-budget-v2-planned-items.js +40 -0
- package/dist/core/context-budget-v2-planned-items.js.map +1 -0
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +57 -38
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +19 -3
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +35 -57
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-tiers.d.ts.map +1 -1
- package/dist/core/context-budget-v2-tiers.js +9 -42
- package/dist/core/context-budget-v2-tiers.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +8 -1
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/extensions/bundled-virtual-modules.d.ts +15 -0
- package/dist/core/extensions/bundled-virtual-modules.d.ts.map +1 -0
- package/dist/core/extensions/bundled-virtual-modules.js +63 -0
- package/dist/core/extensions/bundled-virtual-modules.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -42
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +10 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/loadout-runtime.d.ts +2 -8
- package/dist/core/loadout-runtime.d.ts.map +1 -1
- package/dist/core/loadout-runtime.js.map +1 -1
- package/dist/core/mcp/client.d.ts +27 -6
- package/dist/core/mcp/client.d.ts.map +1 -1
- package/dist/core/mcp/client.js +80 -20
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/manager.d.ts +10 -1
- package/dist/core/mcp/manager.d.ts.map +1 -1
- package/dist/core/mcp/manager.js +68 -9
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/protocol.d.ts +9 -3
- package/dist/core/mcp/protocol.d.ts.map +1 -1
- package/dist/core/mcp/protocol.js +61 -15
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/mcp/stdio-transport.d.ts +12 -1
- package/dist/core/mcp/stdio-transport.d.ts.map +1 -1
- package/dist/core/mcp/stdio-transport.js +30 -2
- package/dist/core/mcp/stdio-transport.js.map +1 -1
- package/dist/core/mcp-descriptor-injection.d.ts +26 -0
- package/dist/core/mcp-descriptor-injection.d.ts.map +1 -0
- package/dist/core/mcp-descriptor-injection.js +25 -0
- package/dist/core/mcp-descriptor-injection.js.map +1 -0
- package/dist/core/mcp-public-presets.d.ts +1 -3
- package/dist/core/mcp-public-presets.d.ts.map +1 -1
- package/dist/core/mcp-public-presets.js +3 -15
- package/dist/core/mcp-public-presets.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +24 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/neo/catalog.d.ts +20 -0
- package/dist/core/neo/catalog.d.ts.map +1 -0
- package/dist/core/neo/catalog.js +50 -0
- package/dist/core/neo/catalog.js.map +1 -0
- package/dist/core/neo/setup.d.ts +3 -0
- package/dist/core/neo/setup.d.ts.map +1 -0
- package/dist/core/neo/setup.js +47 -0
- package/dist/core/neo/setup.js.map +1 -0
- package/dist/core/provider-default-models.d.ts +1 -0
- package/dist/core/provider-default-models.d.ts.map +1 -1
- package/dist/core/provider-default-models.js +1 -0
- package/dist/core/provider-default-models.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/provider-error-classification.d.ts +57 -0
- package/dist/core/provider-error-classification.d.ts.map +1 -0
- package/dist/core/provider-error-classification.js +103 -0
- package/dist/core/provider-error-classification.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +10 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +36 -3
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-usage-commandcode.d.ts +9 -0
- package/dist/core/provider-usage-commandcode.d.ts.map +1 -0
- package/dist/core/provider-usage-commandcode.js +198 -0
- package/dist/core/provider-usage-commandcode.js.map +1 -0
- package/dist/core/provider-usage-devin.d.ts +5 -3
- package/dist/core/provider-usage-devin.d.ts.map +1 -1
- package/dist/core/provider-usage-devin.js +15 -5
- package/dist/core/provider-usage-devin.js.map +1 -1
- package/dist/core/provider-usage-types.d.ts +1 -1
- package/dist/core/provider-usage-types.d.ts.map +1 -1
- package/dist/core/provider-usage-types.js.map +1 -1
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +6 -0
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/resource-admission.d.ts +36 -0
- package/dist/core/resource-admission.d.ts.map +1 -1
- package/dist/core/resource-admission.js +59 -0
- package/dist/core/resource-admission.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +2 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/run-usage-ledger.d.ts +47 -0
- package/dist/core/run-usage-ledger.d.ts.map +1 -0
- package/dist/core/run-usage-ledger.js +162 -0
- package/dist/core/run-usage-ledger.js.map +1 -0
- package/dist/core/run-usage-operation.d.ts +8 -0
- package/dist/core/run-usage-operation.d.ts.map +1 -0
- package/dist/core/run-usage-operation.js +12 -0
- package/dist/core/run-usage-operation.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts.map +1 -1
- package/dist/core/session-failure-cause.js +14 -5
- package/dist/core/session-failure-cause.js.map +1 -1
- package/dist/core/session-prompt-lifecycle.d.ts +6 -0
- package/dist/core/session-prompt-lifecycle.d.ts.map +1 -1
- package/dist/core/session-prompt-lifecycle.js +47 -2
- package/dist/core/session-prompt-lifecycle.js.map +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +4 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/subagent-lane-authority.d.ts +28 -0
- package/dist/core/subagent-lane-authority.d.ts.map +1 -0
- package/dist/core/subagent-lane-authority.js +119 -0
- package/dist/core/subagent-lane-authority.js.map +1 -0
- package/dist/core/subagent-lane-contract.d.ts +114 -0
- package/dist/core/subagent-lane-contract.d.ts.map +1 -0
- package/dist/core/subagent-lane-contract.js +18 -0
- package/dist/core/subagent-lane-contract.js.map +1 -0
- package/dist/core/subagent-lane-launcher.d.ts +3 -6
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
- package/dist/core/subagent-lane-launcher.js +53 -12
- package/dist/core/subagent-lane-launcher.js.map +1 -1
- package/dist/core/subagent-orchestration.d.ts +4 -17
- package/dist/core/subagent-orchestration.d.ts.map +1 -1
- package/dist/core/subagent-orchestration.js.map +1 -1
- package/dist/core/verified-run/broker.d.ts.map +1 -1
- package/dist/core/verified-run/broker.js +4 -1
- package/dist/core/verified-run/broker.js.map +1 -1
- package/dist/core/workload-permit-pool.d.ts +1 -1
- package/dist/core/workload-permit-pool.d.ts.map +1 -1
- package/dist/core/workload-permit-pool.js +3 -0
- package/dist/core/workload-permit-pool.js.map +1 -1
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts +34 -0
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts.map +1 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js +70 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +11 -18
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-agent.d.ts +24 -0
- package/dist/modes/acp/acp-agent.d.ts.map +1 -0
- package/dist/modes/acp/acp-agent.js +133 -0
- package/dist/modes/acp/acp-agent.js.map +1 -0
- package/dist/modes/acp/acp-mode.d.ts +4 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +34 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/acp-session.d.ts +4 -0
- package/dist/modes/acp/acp-session.d.ts.map +1 -0
- package/dist/modes/acp/acp-session.js +76 -0
- package/dist/modes/acp/acp-session.js.map +1 -0
- package/dist/modes/acp/acp-transport.d.ts +5 -0
- package/dist/modes/acp/acp-transport.d.ts.map +1 -0
- package/dist/modes/acp/acp-transport.js +90 -0
- package/dist/modes/acp/acp-transport.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/audit-revalidation-2026-09-17.md +77 -0
- package/docs/devin-harness.md +33 -4
- package/docs/ecraf-normalization.md +83 -0
- package/docs/model-catalog-refresh.md +51 -1
- package/docs/models.md +1 -1
- package/docs/neo.md +134 -0
- package/docs/providers.md +72 -6
- package/docs/run-usage-ledger.md +56 -0
- package/docs/runtime-algorithms.md +44 -0
- package/docs/skills.md +1 -1
- package/docs/usage.md +2 -1
- 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/subagent/adaptive-agent-runtime.ts +14 -1
- package/examples/extensions/subagent/graph-result.ts +48 -0
- package/examples/extensions/subagent/index.ts +246 -111
- package/examples/extensions/subagent/managed-process-tree.ts +42 -0
- package/examples/extensions/subagent/managed-process.test.ts +24 -0
- package/examples/extensions/subagent/managed-process.ts +93 -112
- package/examples/extensions/subagent/subagent-runtime-types.ts +17 -1
- package/examples/extensions/subagent/subagent-stream.ts +161 -0
- package/examples/extensions/terminal-browser/README.md +54 -0
- package/examples/extensions/terminal-browser/bridge-protocol.ts +29 -0
- package/examples/extensions/terminal-browser/bridge.ts +219 -0
- package/examples/extensions/terminal-browser/browser-surface.ts +288 -0
- package/examples/extensions/terminal-browser/index.ts +215 -0
- package/examples/extensions/terminal-browser/placeholders.ts +49 -0
- 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 +8 -7
- package/resources/neo/skills/omk-browser/SKILL.md +32 -0
- package/resources/neo/skills/omk-code-review/SKILL.md +24 -0
- package/resources/neo/skills/omk-computeruse/SKILL.md +34 -0
- package/resources/neo/skills/omk-mcp-setup/SKILL.md +48 -0
- package/resources/neo/skills/omk-research/SKILL.md +24 -0
- package/resources/neo/skills/omk-site/SKILL.md +28 -0
|
@@ -18,7 +18,7 @@ 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
20
|
import { clampThinkingLevel, cleanupSessionResources, deriveContextPromptCacheKey, getSupportedThinkingLevels, isBuiltinStreamFn, modelsAreEqual, resetApiProviders, } from "omk-ai";
|
|
21
|
-
import { APP_NAME, VERSION } from "../config.js";
|
|
21
|
+
import { APP_NAME, getAgentDir, VERSION } from "../config.js";
|
|
22
22
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
23
23
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
24
24
|
import { resolvePath } from "../utils/paths.js";
|
|
@@ -33,6 +33,7 @@ import { getCompactionHeadroomThreshold } from "./compaction/compaction.js";
|
|
|
33
33
|
import { createCompactionHysteresisConfig, createCompactionHysteresisState, stepCompactionHysteresis, } from "./compaction/hysteresis.js";
|
|
34
34
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, generateBranchSummary, prepareCompaction, resolveCompactionModel, } from "./compaction/index.js";
|
|
35
35
|
import { summarizeWithOAuthRecovery } from "./compaction/oauth-recovery.js";
|
|
36
|
+
import { overflowRetryBlocked } from "./compaction/overflow-retry-guard.js";
|
|
36
37
|
import { compactionEmitWillRetry } from "./compaction/resume-policy.js";
|
|
37
38
|
import { isSessionModelOverflow, shouldSkipCompactionCheck } from "./compaction-gate.js";
|
|
38
39
|
import { estimateToolResultReserve, } from "./context-budget-reserved-tokens.js";
|
|
@@ -47,11 +48,14 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
|
47
48
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
48
49
|
import { assertTextChatModelForCompletion, grokHarnessAutoApplyEnabled, isGrokOAuthProvider, selectGrokHarnessSkills, } from "./grok-harness.js";
|
|
49
50
|
import { grokPlaybookAppendForProvider } from "./grok-playbook.js";
|
|
51
|
+
import { loadHookInventory } from "./hook-inventory.js";
|
|
50
52
|
import { captureHostResourceSnapshot } from "./host-resource-snapshot.js";
|
|
51
53
|
import { decideLoadoutAccess } from "./loadout-access-policy.js";
|
|
54
|
+
import { buildCapabilityInventory } from "./loadout-runtime.js";
|
|
52
55
|
import { loadMcpServerConfigs } from "./mcp/config.js";
|
|
53
56
|
import { McpManager } from "./mcp/manager.js";
|
|
54
57
|
import { buildRuntimeProvenance } from "./runtime-provenance.js";
|
|
58
|
+
import { createSubagentLaneAuthority } from "./subagent-lane-authority.js";
|
|
55
59
|
import { TurnMetricsSink } from "./turn-metrics.js";
|
|
56
60
|
/** Values that disable a session-level feature through its environment variable. */
|
|
57
61
|
const DISABLED_ENV_VALUES = new Set(["0", "false", "off", "disable", "disabled"]);
|
|
@@ -94,12 +98,12 @@ import { classifyPromptCacheTransition } from "./prompt-cache.js";
|
|
|
94
98
|
import * as promptSettlement from "./prompt-settlement.js";
|
|
95
99
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
96
100
|
import { isQuotaExhaustionMessage, isStickySafetyModel, isUpstreamUnavailableMessage, pickFailoverCandidate, resolveFailoverCandidates, resolveProviderResilience, sameModelRouteCandidates, shouldEjectStickySafetyModel, shouldHonorSafetyFailover, stickySafetyBlockMessage, } from "./provider-resilience.js";
|
|
97
|
-
import { computeRetryDelayMs, failoverModelKey, isFailoverTriggerError, isRetryableAssistantError, nextRetryAttempt, retryBudgetForAssistantError, } from "./provider-retry.js";
|
|
101
|
+
import { computeRetryDelayMs, failoverModelKey, isEmptyStreamedCompletion, isFailoverTriggerError, isRetryableAssistantError, nextRetryAttempt, retryBudgetForAssistantError, } from "./provider-retry.js";
|
|
98
102
|
import { getBiasStepsForCell, parseRouterBiasSnapshot } from "./reasoning-router-bias.js";
|
|
99
103
|
import { classifyTaskV4, deriveRouterFeedbackFeaturesV4, resolveThinkingLevelV4WithUncertainty, TASK_CLASS_THINKING_LEVELS_V4, } from "./reasoning-router-v4.js";
|
|
100
104
|
import { redactSensitiveText, redactSensitiveTextForced } from "./redaction.js";
|
|
101
105
|
import { getRepositoryRouterLearningPaths } from "./repository-learning-scope.js";
|
|
102
|
-
import { decideResourceAdmission } from "./resource-admission.js";
|
|
106
|
+
import { createResourcePressureStabilizer, decideResourceAdmission, evaluateResourcePressure, rederiveResourceAdmissionForPressure, } from "./resource-admission.js";
|
|
103
107
|
import { resolveResourceGovernorSettings } from "./resource-governor-settings.js";
|
|
104
108
|
import { admissionObservationFacts, classificationObservationFacts, ResourceObservationJournal, settledObservationFacts, snapshotObservationFacts, soundObservationFacts, } from "./resource-observation-journal.js";
|
|
105
109
|
import { decideResourceSafetyGate, RESOURCE_PRESSURE_REQUIRED_ACTION } from "./resource-safety-gate.js";
|
|
@@ -289,6 +293,10 @@ export class AgentSession {
|
|
|
289
293
|
_resourceObservationJournals = new Map();
|
|
290
294
|
_latestResourcePromptRunId = null;
|
|
291
295
|
_lastResourceAdmission = null;
|
|
296
|
+
// Per-session pressure hysteresis (audit §16.1): escalation is immediate,
|
|
297
|
+
// recovery requires consecutive healthier probes so the applied cap does
|
|
298
|
+
// not flap around a threshold between prompts.
|
|
299
|
+
_resourcePressureStabilizer;
|
|
292
300
|
_workloadPermitPool;
|
|
293
301
|
_pendingRuntimeTerminationCause;
|
|
294
302
|
_activeRunToolTermination;
|
|
@@ -861,8 +869,13 @@ export class AgentSession {
|
|
|
861
869
|
this._overflowRecoveryAttempts = 0;
|
|
862
870
|
}
|
|
863
871
|
// Reset retry counter immediately on successful assistant response
|
|
864
|
-
// This prevents accumulation across multiple LLM calls within a turn
|
|
865
|
-
|
|
872
|
+
// This prevents accumulation across multiple LLM calls within a turn.
|
|
873
|
+
// An empty streamed completion wears a success shape (stop=stop, zero
|
|
874
|
+
// usable output) but is a dead stream — counting it as success reset
|
|
875
|
+
// the budget every cycle and retried forever (union-alpha relay loop).
|
|
876
|
+
if (assistantMsg.stopReason !== "error" &&
|
|
877
|
+
!isEmptyStreamedCompletion(assistantMsg) &&
|
|
878
|
+
this._retryAttempt > 0) {
|
|
866
879
|
this._emit({
|
|
867
880
|
type: "auto_retry_end",
|
|
868
881
|
success: true,
|
|
@@ -1371,16 +1384,19 @@ export class AgentSession {
|
|
|
1371
1384
|
* Extract the most recent user query text from conversation messages.
|
|
1372
1385
|
* Returns undefined when no user message exists or content is empty.
|
|
1373
1386
|
* Handles both string content and multimodal (array) content.
|
|
1387
|
+
*
|
|
1388
|
+
* The scan walks the whole transcript backwards and stops at the first user
|
|
1389
|
+
* message. A fixed tail window cannot work here: tool results are their own
|
|
1390
|
+
* messages, so a single turn that calls two tools already leaves
|
|
1391
|
+
* `[user, assistant, toolResult, toolResult]` and buries the task four deep.
|
|
1392
|
+
* Losing it mid-turn collapses every skill to the neutral relevance score and
|
|
1393
|
+
* degrades ranking to catalogue order, precisely while tools are running and
|
|
1394
|
+
* a matching skill matters most.
|
|
1374
1395
|
*/
|
|
1375
1396
|
_extractCurrentQuery() {
|
|
1376
1397
|
const messages = this.messages;
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
}
|
|
1380
|
-
// Scan recent messages (last 3) for the most recent user message
|
|
1381
|
-
const recent = messages.slice(-3);
|
|
1382
|
-
for (let i = recent.length - 1; i >= 0; i--) {
|
|
1383
|
-
const msg = recent[i];
|
|
1398
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1399
|
+
const msg = messages[i];
|
|
1384
1400
|
if (!msg || !("role" in msg) || msg.role !== "user") {
|
|
1385
1401
|
continue;
|
|
1386
1402
|
}
|
|
@@ -1576,8 +1592,12 @@ export class AgentSession {
|
|
|
1576
1592
|
}
|
|
1577
1593
|
const snapshot = await captureHostResourceSnapshot(probeOptions);
|
|
1578
1594
|
const decision = decideResourceAdmission({ snapshot, config: resolved.admission, configuredCaps });
|
|
1595
|
+
const stabilized = this._stabilizeResourcePressure(snapshot, resolved);
|
|
1596
|
+
const appliedDecision = stabilized === decision.pressure
|
|
1597
|
+
? decision
|
|
1598
|
+
: rederiveResourceAdmissionForPressure(decision, resolved.admission.caps, configuredCaps, stabilized);
|
|
1579
1599
|
if (this._latestResourcePromptRunId === promptRunId) {
|
|
1580
|
-
this._lastResourceAdmission =
|
|
1600
|
+
this._lastResourceAdmission = appliedDecision;
|
|
1581
1601
|
}
|
|
1582
1602
|
resourceObservations?.record("resource_snapshot_v1", snapshotObservationFacts(snapshot));
|
|
1583
1603
|
resourceObservations?.record("resource_admission_v1", admissionObservationFacts(decision));
|
|
@@ -1587,7 +1607,7 @@ export class AgentSession {
|
|
|
1587
1607
|
this.agent.maxToolConcurrency = cap;
|
|
1588
1608
|
},
|
|
1589
1609
|
});
|
|
1590
|
-
const lease = this._resourceLeaseController.acquire({ promptRunId, decision });
|
|
1610
|
+
const lease = this._resourceLeaseController.acquire({ promptRunId, decision: appliedDecision });
|
|
1591
1611
|
resourceObservations?.record("resource_lease_acquired_v1", {
|
|
1592
1612
|
decisionId: decision.decisionId,
|
|
1593
1613
|
appliedToolCap: decision.maxToolConcurrency,
|
|
@@ -1598,6 +1618,15 @@ export class AgentSession {
|
|
|
1598
1618
|
return null;
|
|
1599
1619
|
}
|
|
1600
1620
|
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Feed one snapshot's raw pressure through the per-session stabilizer.
|
|
1623
|
+
* Created lazily so sessions that never probe carry no state; the first
|
|
1624
|
+
* observation installs its own level directly (no warmup lag).
|
|
1625
|
+
*/
|
|
1626
|
+
_stabilizeResourcePressure(snapshot, resolved) {
|
|
1627
|
+
this._resourcePressureStabilizer ??= createResourcePressureStabilizer();
|
|
1628
|
+
return this._resourcePressureStabilizer.observe(evaluateResourcePressure(snapshot, resolved.admission.thresholds));
|
|
1629
|
+
}
|
|
1601
1630
|
_openResourceObservations(promptRunId) {
|
|
1602
1631
|
this._latestResourcePromptRunId = promptRunId;
|
|
1603
1632
|
try {
|
|
@@ -1633,6 +1662,30 @@ export class AgentSession {
|
|
|
1633
1662
|
getCurrentResourceAdmission() {
|
|
1634
1663
|
return this._lastResourceAdmission;
|
|
1635
1664
|
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Spec 020 Req1 — canonical subagent lane authority bound to this session.
|
|
1667
|
+
* Rebuilt on each call so it tracks the live admission decision, shared
|
|
1668
|
+
* permit pool, and open prompt run. Extension tool contexts read it through
|
|
1669
|
+
* `ctx.getSubagentLaneAuthority()`.
|
|
1670
|
+
*/
|
|
1671
|
+
_getSubagentLaneAuthority() {
|
|
1672
|
+
const hookInventory = loadHookInventory(getAgentDir());
|
|
1673
|
+
const sessionView = {
|
|
1674
|
+
_baseToolDefinitions: this._baseToolDefinitions,
|
|
1675
|
+
_extensionRunner: this._extensionRunner,
|
|
1676
|
+
_customTools: this._customTools,
|
|
1677
|
+
};
|
|
1678
|
+
const inventory = buildCapabilityInventory(sessionView, this._resourceLoader, this._cwd, hookInventory);
|
|
1679
|
+
return createSubagentLaneAuthority({
|
|
1680
|
+
runId: this._activeRunId ?? `session-${this.sessionManager.getSessionId() ?? "unknown"}`,
|
|
1681
|
+
promptRunId: this._promptLifecycle.activePromptRunId,
|
|
1682
|
+
decision: this._lastResourceAdmission,
|
|
1683
|
+
permitPool: this.workloadPermitPool,
|
|
1684
|
+
inventory,
|
|
1685
|
+
signal: this.agent?.signal,
|
|
1686
|
+
noteDetachedChild: () => this._promptLifecycle.noteDetachedChild(),
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1636
1689
|
/** §19.4 read-only SDK surface: capture a fresh host resource snapshot. */
|
|
1637
1690
|
async getHostResourceSnapshot() {
|
|
1638
1691
|
const resolved = resolveResourceGovernorSettings(this.settingsManager.getResourceGovernorSettings());
|
|
@@ -1741,12 +1794,15 @@ export class AgentSession {
|
|
|
1741
1794
|
if (this._isRetryableError(msg) && (await this._prepareRetry(msg))) {
|
|
1742
1795
|
return true;
|
|
1743
1796
|
}
|
|
1744
|
-
|
|
1797
|
+
// The retry budget is exhausted without a real answer. This covers the
|
|
1798
|
+
// empty-streamed-completion path whose success-shaped stopReason
|
|
1799
|
+
// otherwise left the UI pinned in the retrying state forever.
|
|
1800
|
+
if (this._retryAttempt > 0) {
|
|
1745
1801
|
this._emit({
|
|
1746
1802
|
type: "auto_retry_end",
|
|
1747
1803
|
success: false,
|
|
1748
1804
|
attempt: this._retryAttempt,
|
|
1749
|
-
finalError: msg.errorMessage,
|
|
1805
|
+
finalError: msg.errorMessage ?? "The provider returned an empty response.",
|
|
1750
1806
|
});
|
|
1751
1807
|
this._retryAttempt = 0;
|
|
1752
1808
|
this._refusedModels.clear();
|
|
@@ -3008,8 +3064,13 @@ export class AgentSession {
|
|
|
3008
3064
|
/**
|
|
3009
3065
|
* Effective context window for the upcoming turn.
|
|
3010
3066
|
* Image-bearing turns with a text-only session model are auto-routed to the
|
|
3011
|
-
* vision model (gpt-5.6-luna, 1M)
|
|
3012
|
-
*
|
|
3067
|
+
* vision model (gpt-5.6-luna, 1M), so the request has to fit both windows and
|
|
3068
|
+
* the binding limit is the smaller one. Session windows fall on both sides of
|
|
3069
|
+
* 1M: most catalogued models are smaller (median near 300K) and keep their own
|
|
3070
|
+
* window as the limit, while the larger-than-1M models are the ones the clamp
|
|
3071
|
+
* exists for — without it their threshold is computed against a window the
|
|
3072
|
+
* vision route will not honour, and the request overflows before compaction
|
|
3073
|
+
* fires. Text-only turns keep the session model's window untouched.
|
|
3013
3074
|
*/
|
|
3014
3075
|
_effectiveTurnContextWindow(pendingMessages, sessionWindow) {
|
|
3015
3076
|
// Vision routing keys off the full transcript, not just the pending turn:
|
|
@@ -3288,16 +3349,25 @@ export class AgentSession {
|
|
|
3288
3349
|
// the compaction_end event (so the TUI flushes its queued messages
|
|
3289
3350
|
// correctly) and the return value below.
|
|
3290
3351
|
const resumeMessages = this.agent.state.messages;
|
|
3291
|
-
|
|
3292
|
-
for (let i = resumeMessages.length - 1; i >= 0; i--) {
|
|
3293
|
-
const candidate = resumeMessages[i];
|
|
3294
|
-
if (candidate.role === "assistant") {
|
|
3295
|
-
lastAssistantMsg = candidate;
|
|
3296
|
-
break;
|
|
3297
|
-
}
|
|
3298
|
-
}
|
|
3352
|
+
const lastAssistantMsg = this._findLastAssistantMessage();
|
|
3299
3353
|
const endedCleanly = lastAssistantMsg?.stopReason === "stop";
|
|
3300
3354
|
const willResume = this.agent.hasQueuedMessages() || !endedCleanly;
|
|
3355
|
+
// overflow-retry-guard 배선: 압축 후 재전송 컨텍스트가 창을 확실히 초과하면
|
|
3356
|
+
// 재시도는 프로바이더 왕복만 소모한다 — 정확한 수치 진단과 함께 차단한다.
|
|
3357
|
+
const overflowBlock = willRetry
|
|
3358
|
+
? overflowRetryBlocked(resumeMessages, this.model?.contextWindow ?? 0)
|
|
3359
|
+
: undefined;
|
|
3360
|
+
if (overflowBlock !== undefined) {
|
|
3361
|
+
this._emit({
|
|
3362
|
+
type: "compaction_end",
|
|
3363
|
+
reason,
|
|
3364
|
+
result,
|
|
3365
|
+
aborted: false,
|
|
3366
|
+
willRetry: false,
|
|
3367
|
+
errorMessage: overflowBlock,
|
|
3368
|
+
});
|
|
3369
|
+
return false;
|
|
3370
|
+
}
|
|
3301
3371
|
const emitWillRetry = compactionEmitWillRetry(willRetry, willResume);
|
|
3302
3372
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry: emitWillRetry });
|
|
3303
3373
|
if (willRetry) {
|
|
@@ -3534,6 +3604,10 @@ export class AgentSession {
|
|
|
3534
3604
|
},
|
|
3535
3605
|
getSystemPrompt: () => this.systemPrompt,
|
|
3536
3606
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
3607
|
+
// Spec 020 Req1 — session-bound lane authority for extension tool
|
|
3608
|
+
// contexts (subagent spawn funnel). Rebuilt on demand so it always
|
|
3609
|
+
// sees the live admission decision, permit pool, and prompt run.
|
|
3610
|
+
getSubagentLaneAuthority: () => this._getSubagentLaneAuthority(),
|
|
3537
3611
|
}, {
|
|
3538
3612
|
registerProvider: (name, config) => {
|
|
3539
3613
|
this._modelRegistry.registerProvider(name, config);
|
|
@@ -3965,10 +4039,13 @@ export class AgentSession {
|
|
|
3965
4039
|
if (attempt === undefined)
|
|
3966
4040
|
return false;
|
|
3967
4041
|
this._retryAttempt = attempt;
|
|
3968
|
-
// Upstream-unavailable (gateway 5xx / dropped stream
|
|
3969
|
-
// authenticated route of the SAME model family so the
|
|
3970
|
-
// live endpoint instead of hammering the dead one.
|
|
3971
|
-
|
|
4042
|
+
// Upstream-unavailable (gateway 5xx / dropped stream / dead relay stream):
|
|
4043
|
+
// rotate to another authenticated route of the SAME model family so the
|
|
4044
|
+
// retry lands on a live endpoint instead of hammering the dead one. An
|
|
4045
|
+
// empty streamed completion is the same dead-stream signature wearing a
|
|
4046
|
+
// success stopReason, so it rotates too — otherwise the retry re-hits the
|
|
4047
|
+
// route that just returned nothing.
|
|
4048
|
+
const rotatedTo = isUpstreamUnavailableMessage(message.errorMessage) || isEmptyStreamedCompletion(message)
|
|
3972
4049
|
? await this._maybeRotateModelRoutes()
|
|
3973
4050
|
: undefined;
|
|
3974
4051
|
// Content/safety stop (Fable/Opus/Sonnet): switch model BEFORE delay so retry is not same-model refusal.
|