open-multi-agent-kit 0.98.4 → 0.98.5
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 +12 -0
- package/README.md +3 -2
- package/dist/commands/run-command.d.ts +2 -1
- package/dist/commands/run-command.d.ts.map +1 -1
- package/dist/commands/run-command.js +9 -1
- package/dist/commands/run-command.js.map +1 -1
- package/dist/commands/verified-run-cli.d.ts +6 -0
- package/dist/commands/verified-run-cli.d.ts.map +1 -0
- package/dist/commands/verified-run-cli.js +190 -0
- package/dist/commands/verified-run-cli.js.map +1 -0
- package/dist/core/agent-session-services.d.ts +8 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +41 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +7 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +61 -41
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/prompt-settlement.d.ts +4 -3
- package/dist/core/prompt-settlement.d.ts.map +1 -1
- package/dist/core/prompt-settlement.js.map +1 -1
- package/dist/core/run-budget-policy.d.ts +18 -0
- package/dist/core/run-budget-policy.d.ts.map +1 -0
- package/dist/core/run-budget-policy.js +52 -0
- package/dist/core/run-budget-policy.js.map +1 -0
- package/dist/core/run-budget.d.ts +33 -0
- package/dist/core/run-budget.d.ts.map +1 -0
- package/dist/core/run-budget.js +89 -0
- package/dist/core/run-budget.js.map +1 -0
- package/dist/core/run-execution-api.d.ts +15 -0
- package/dist/core/run-execution-api.d.ts.map +1 -0
- package/dist/core/run-execution-api.js +7 -0
- package/dist/core/run-execution-api.js.map +1 -0
- package/dist/core/run-journal.d.ts.map +1 -1
- package/dist/core/run-journal.js +30 -208
- package/dist/core/run-journal.js.map +1 -1
- package/dist/core/session-bash-service.d.ts +2 -2
- package/dist/core/session-bash-service.d.ts.map +1 -1
- package/dist/core/session-bash-service.js +21 -9
- package/dist/core/session-bash-service.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts.map +1 -1
- package/dist/core/session-failure-cause.js +5 -0
- package/dist/core/session-failure-cause.js.map +1 -1
- package/dist/core/session-prompt-lifecycle.d.ts +25 -0
- package/dist/core/session-prompt-lifecycle.d.ts.map +1 -0
- package/dist/core/session-prompt-lifecycle.js +87 -0
- package/dist/core/session-prompt-lifecycle.js.map +1 -0
- package/dist/core/session-run-budget.d.ts +28 -0
- package/dist/core/session-run-budget.d.ts.map +1 -0
- package/dist/core/session-run-budget.js +127 -0
- package/dist/core/session-run-budget.js.map +1 -0
- package/dist/core/session-run-termination.d.ts.map +1 -1
- package/dist/core/session-run-termination.js +14 -3
- package/dist/core/session-run-termination.js.map +1 -1
- package/dist/core/session-termination-types.d.ts +97 -0
- package/dist/core/session-termination-types.d.ts.map +1 -0
- package/dist/core/session-termination-types.js +26 -0
- package/dist/core/session-termination-types.js.map +1 -0
- package/dist/core/session-termination.d.ts +3 -97
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +24 -28
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagent-lane-launcher.d.ts +3 -2
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
- package/dist/core/subagent-lane-launcher.js +24 -13
- package/dist/core/subagent-lane-launcher.js.map +1 -1
- package/dist/core/verified-run/broker.d.ts +26 -0
- package/dist/core/verified-run/broker.d.ts.map +1 -0
- package/dist/core/verified-run/broker.js +210 -0
- package/dist/core/verified-run/broker.js.map +1 -0
- package/dist/core/verified-run/candidate.d.ts +24 -0
- package/dist/core/verified-run/candidate.d.ts.map +1 -0
- package/dist/core/verified-run/candidate.js +167 -0
- package/dist/core/verified-run/candidate.js.map +1 -0
- package/dist/core/verified-run/check-receipt.d.ts +18 -0
- package/dist/core/verified-run/check-receipt.d.ts.map +1 -0
- package/dist/core/verified-run/check-receipt.js +92 -0
- package/dist/core/verified-run/check-receipt.js.map +1 -0
- package/dist/core/verified-run/coordinator.d.ts +39 -0
- package/dist/core/verified-run/coordinator.d.ts.map +1 -0
- package/dist/core/verified-run/coordinator.js +190 -0
- package/dist/core/verified-run/coordinator.js.map +1 -0
- package/dist/core/verified-run/dag-candidates.d.ts +8 -0
- package/dist/core/verified-run/dag-candidates.d.ts.map +1 -0
- package/dist/core/verified-run/dag-candidates.js +65 -0
- package/dist/core/verified-run/dag-candidates.js.map +1 -0
- package/dist/core/verified-run/dag-phase.d.ts +7 -0
- package/dist/core/verified-run/dag-phase.d.ts.map +1 -0
- package/dist/core/verified-run/dag-phase.js +92 -0
- package/dist/core/verified-run/dag-phase.js.map +1 -0
- package/dist/core/verified-run/dag-projection.d.ts +7 -0
- package/dist/core/verified-run/dag-projection.d.ts.map +1 -0
- package/dist/core/verified-run/dag-projection.js +90 -0
- package/dist/core/verified-run/dag-projection.js.map +1 -0
- package/dist/core/verified-run/dag-recovery.d.ts +13 -0
- package/dist/core/verified-run/dag-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/dag-recovery.js +98 -0
- package/dist/core/verified-run/dag-recovery.js.map +1 -0
- package/dist/core/verified-run/dag-retry-projection.d.ts +9 -0
- package/dist/core/verified-run/dag-retry-projection.d.ts.map +1 -0
- package/dist/core/verified-run/dag-retry-projection.js +43 -0
- package/dist/core/verified-run/dag-retry-projection.js.map +1 -0
- package/dist/core/verified-run/dag-types.d.ts +47 -0
- package/dist/core/verified-run/dag-types.d.ts.map +1 -0
- package/dist/core/verified-run/dag-types.js +2 -0
- package/dist/core/verified-run/dag-types.js.map +1 -0
- package/dist/core/verified-run/event-parser.d.ts +3 -0
- package/dist/core/verified-run/event-parser.d.ts.map +1 -0
- package/dist/core/verified-run/event-parser.js +153 -0
- package/dist/core/verified-run/event-parser.js.map +1 -0
- package/dist/core/verified-run/events.d.ts +4 -0
- package/dist/core/verified-run/events.d.ts.map +1 -0
- package/dist/core/verified-run/events.js +3 -0
- package/dist/core/verified-run/events.js.map +1 -0
- package/dist/core/verified-run/evidence-binding.d.ts +18 -0
- package/dist/core/verified-run/evidence-binding.d.ts.map +1 -0
- package/dist/core/verified-run/evidence-binding.js +81 -0
- package/dist/core/verified-run/evidence-binding.js.map +1 -0
- package/dist/core/verified-run/evidence.d.ts +27 -0
- package/dist/core/verified-run/evidence.d.ts.map +1 -0
- package/dist/core/verified-run/evidence.js +100 -0
- package/dist/core/verified-run/evidence.js.map +1 -0
- package/dist/core/verified-run/journal.d.ts +32 -0
- package/dist/core/verified-run/journal.d.ts.map +1 -0
- package/dist/core/verified-run/journal.js +103 -0
- package/dist/core/verified-run/journal.js.map +1 -0
- package/dist/core/verified-run/namespace-identity.d.ts +11 -0
- package/dist/core/verified-run/namespace-identity.d.ts.map +1 -0
- package/dist/core/verified-run/namespace-identity.js +77 -0
- package/dist/core/verified-run/namespace-identity.js.map +1 -0
- package/dist/core/verified-run/owned-execution.d.ts +21 -0
- package/dist/core/verified-run/owned-execution.d.ts.map +1 -0
- package/dist/core/verified-run/owned-execution.js +43 -0
- package/dist/core/verified-run/owned-execution.js.map +1 -0
- package/dist/core/verified-run/phase-context.d.ts +9 -0
- package/dist/core/verified-run/phase-context.d.ts.map +1 -0
- package/dist/core/verified-run/phase-context.js +2 -0
- package/dist/core/verified-run/phase-context.js.map +1 -0
- package/dist/core/verified-run/process-gate.d.ts +5 -0
- package/dist/core/verified-run/process-gate.d.ts.map +1 -0
- package/dist/core/verified-run/process-gate.js +31 -0
- package/dist/core/verified-run/process-gate.js.map +1 -0
- package/dist/core/verified-run/projection.d.ts +4 -0
- package/dist/core/verified-run/projection.d.ts.map +1 -0
- package/dist/core/verified-run/projection.js +219 -0
- package/dist/core/verified-run/projection.js.map +1 -0
- package/dist/core/verified-run/recovery-clock.d.ts +19 -0
- package/dist/core/verified-run/recovery-clock.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-clock.js +69 -0
- package/dist/core/verified-run/recovery-clock.js.map +1 -0
- package/dist/core/verified-run/recovery-command.d.ts +11 -0
- package/dist/core/verified-run/recovery-command.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-command.js +73 -0
- package/dist/core/verified-run/recovery-command.js.map +1 -0
- package/dist/core/verified-run/recovery-projection.d.ts +12 -0
- package/dist/core/verified-run/recovery-projection.d.ts.map +1 -0
- package/dist/core/verified-run/recovery-projection.js +88 -0
- package/dist/core/verified-run/recovery-projection.js.map +1 -0
- package/dist/core/verified-run/recovery.d.ts +12 -0
- package/dist/core/verified-run/recovery.d.ts.map +1 -0
- package/dist/core/verified-run/recovery.js +115 -0
- package/dist/core/verified-run/recovery.js.map +1 -0
- package/dist/core/verified-run/run-types.d.ts +103 -0
- package/dist/core/verified-run/run-types.d.ts.map +1 -0
- package/dist/core/verified-run/run-types.js +2 -0
- package/dist/core/verified-run/run-types.js.map +1 -0
- package/dist/core/verified-run/scripted-writer.d.ts +15 -0
- package/dist/core/verified-run/scripted-writer.d.ts.map +1 -0
- package/dist/core/verified-run/scripted-writer.js +94 -0
- package/dist/core/verified-run/scripted-writer.js.map +1 -0
- package/dist/core/verified-run/session-port.d.ts +27 -0
- package/dist/core/verified-run/session-port.d.ts.map +1 -0
- package/dist/core/verified-run/session-port.js +2 -0
- package/dist/core/verified-run/session-port.js.map +1 -0
- package/dist/core/verified-run/storage.d.ts +15 -0
- package/dist/core/verified-run/storage.d.ts.map +1 -0
- package/dist/core/verified-run/storage.js +96 -0
- package/dist/core/verified-run/storage.js.map +1 -0
- package/dist/core/verified-run/verification-phase.d.ts +5 -0
- package/dist/core/verified-run/verification-phase.d.ts.map +1 -0
- package/dist/core/verified-run/verification-phase.js +56 -0
- package/dist/core/verified-run/verification-phase.js.map +1 -0
- package/dist/core/verified-run/work-recovery.d.ts +8 -0
- package/dist/core/verified-run/work-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/work-recovery.js +44 -0
- package/dist/core/verified-run/work-recovery.js.map +1 -0
- package/dist/core/verified-run/writer-completion.d.ts +4 -0
- package/dist/core/verified-run/writer-completion.d.ts.map +1 -0
- package/dist/core/verified-run/writer-completion.js +27 -0
- package/dist/core/verified-run/writer-completion.js.map +1 -0
- package/dist/core/verified-run/writer-phase.d.ts +8 -0
- package/dist/core/verified-run/writer-phase.d.ts.map +1 -0
- package/dist/core/verified-run/writer-phase.js +76 -0
- package/dist/core/verified-run/writer-phase.js.map +1 -0
- package/dist/core/verified-run/writer-projection.d.ts +11 -0
- package/dist/core/verified-run/writer-projection.d.ts.map +1 -0
- package/dist/core/verified-run/writer-projection.js +70 -0
- package/dist/core/verified-run/writer-projection.js.map +1 -0
- package/dist/core/verified-run/writer-recovery.d.ts +16 -0
- package/dist/core/verified-run/writer-recovery.d.ts.map +1 -0
- package/dist/core/verified-run/writer-recovery.js +107 -0
- package/dist/core/verified-run/writer-recovery.js.map +1 -0
- package/dist/core/workload-permit-pool.d.ts +1 -3
- package/dist/core/workload-permit-pool.d.ts.map +1 -1
- package/dist/core/workload-permit-pool.js +11 -11
- package/dist/core/workload-permit-pool.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -8
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/session-failure.d.ts +13 -0
- package/dist/modes/interactive/components/session-failure.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-failure.js +81 -0
- package/dist/modes/interactive/components/session-failure.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +45 -31
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tui-diagnostics.d.ts +36 -0
- package/dist/modes/interactive/tui-diagnostics.d.ts.map +1 -0
- package/dist/modes/interactive/tui-diagnostics.js +105 -0
- package/dist/modes/interactive/tui-diagnostics.js.map +1 -0
- package/dist/modes/interactive/tui-runtime-info.d.ts +20 -0
- package/dist/modes/interactive/tui-runtime-info.d.ts.map +1 -0
- package/dist/modes/interactive/tui-runtime-info.js +76 -0
- package/dist/modes/interactive/tui-runtime-info.js.map +1 -0
- package/docs/development.md +10 -0
- package/docs/keybindings.md +1 -1
- package/docs/release-audit-0.98.5.md +84 -0
- package/docs/run-protocol.md +33 -1
- package/docs/runtime-algorithms.md +26 -0
- package/docs/sdk.md +193 -0
- package/docs/usage.md +54 -0
- package/docs/verified-run-testing.md +417 -0
- package/docs/verified-run.md +388 -0
- 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
|
@@ -103,6 +103,7 @@ import { resolveResourceGovernorSettings } from "./resource-governor-settings.js
|
|
|
103
103
|
import { admissionObservationFacts, classificationObservationFacts, ResourceObservationJournal, settledObservationFacts, snapshotObservationFacts, soundObservationFacts, } from "./resource-observation-journal.js";
|
|
104
104
|
import { decideResourceSafetyGate, RESOURCE_PRESSURE_REQUIRED_ACTION } from "./resource-safety-gate.js";
|
|
105
105
|
import { appendRouterFeedbackRecord, ROUTER_FEEDBACK_LEVELS, } from "./router-feedback-collector.js";
|
|
106
|
+
import { RunBudgetExceededError, RunBudgetPolicyError } from "./run-budget-policy.js";
|
|
106
107
|
import { RunJournalStore } from "./run-journal-store.js";
|
|
107
108
|
import { RunResourceLeaseController } from "./run-resource-lease.js";
|
|
108
109
|
import { SessionBashRuntime } from "./session-bash-runtime.js";
|
|
@@ -111,6 +112,8 @@ import { SessionCompactionService } from "./session-compaction-service.js";
|
|
|
111
112
|
import { preflightFailureCause, runtimeFailureCause, terminationMessage } from "./session-failure-cause.js";
|
|
112
113
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
113
114
|
import { acquireSessionOwnerLeaseSync } from "./session-owner-lease.js";
|
|
115
|
+
import { PromptExecutionBusyError, SessionPromptLifecycle } from "./session-prompt-lifecycle.js";
|
|
116
|
+
import { SessionRunBudget } from "./session-run-budget.js";
|
|
114
117
|
import { classifyRunTermination } from "./session-run-termination.js";
|
|
115
118
|
import { assembleSessionSystemPrompt } from "./session-system-prompt.js";
|
|
116
119
|
import { classifySessionTermination, } from "./session-termination.js";
|
|
@@ -217,6 +220,11 @@ export class AgentSession {
|
|
|
217
220
|
// Event subscription state
|
|
218
221
|
_unsubscribeAgent;
|
|
219
222
|
_eventListeners = [];
|
|
223
|
+
_runBudget;
|
|
224
|
+
_promptLifecycle = new SessionPromptLifecycle({
|
|
225
|
+
canSettle: () => !this.isStreaming && !this.agent.hasQueuedMessages(),
|
|
226
|
+
auditsLateSettlement: () => this.agent.toolExecutionPolicy?.lateSettlement !== "ignore",
|
|
227
|
+
});
|
|
220
228
|
_messageEndReplacements = new WeakMap();
|
|
221
229
|
/** Tracks pending steering messages for UI display. Removed when delivered. */
|
|
222
230
|
_steeringMessages = [];
|
|
@@ -313,6 +321,21 @@ export class AgentSession {
|
|
|
313
321
|
_promptCacheLastBreakReason;
|
|
314
322
|
constructor(config) {
|
|
315
323
|
this.agent = config.agent;
|
|
324
|
+
this._runBudget = new SessionRunBudget(this.agent, {
|
|
325
|
+
assertIdle: () => {
|
|
326
|
+
this._promptLifecycle.assertIdle();
|
|
327
|
+
if (this.isRetrying || this.isCompacting || this._branchSummaryAbortController)
|
|
328
|
+
throw new PromptExecutionBusyError();
|
|
329
|
+
},
|
|
330
|
+
stop: (error) => {
|
|
331
|
+
this._pendingRuntimeTerminationCause = { area: "budget", code: error.code };
|
|
332
|
+
this.agent.abort();
|
|
333
|
+
this.abortRetry();
|
|
334
|
+
this.abortCompaction();
|
|
335
|
+
this.abortBranchSummary();
|
|
336
|
+
},
|
|
337
|
+
reject: (error) => this._publishRuntimeFailure(error),
|
|
338
|
+
});
|
|
316
339
|
this.sessionManager = config.sessionManager;
|
|
317
340
|
this.settingsManager = config.settingsManager;
|
|
318
341
|
this._scopedModels = config.scopedModels ?? [];
|
|
@@ -688,6 +711,7 @@ export class AgentSession {
|
|
|
688
711
|
throw new Error(formatNoApiKeyFoundMessage(model.provider));
|
|
689
712
|
}
|
|
690
713
|
async _getCompactionRequestAuth(model) {
|
|
714
|
+
this._runBudget.assertAdmission();
|
|
691
715
|
const options = { minRemainingMs: COMPACTION_MIN_TOKEN_VALIDITY_MS };
|
|
692
716
|
if (isBuiltinStreamFn(this.agent.streamFn)) {
|
|
693
717
|
return this._getRequiredRequestAuth(model, options);
|
|
@@ -842,6 +866,8 @@ export class AgentSession {
|
|
|
842
866
|
}
|
|
843
867
|
}
|
|
844
868
|
}
|
|
869
|
+
if (event.type === "tool_execution_late_settlement")
|
|
870
|
+
this._promptLifecycle.flush();
|
|
845
871
|
};
|
|
846
872
|
_willRetryAfterAgentEnd(event) {
|
|
847
873
|
const settings = this.settingsManager.getRetrySettings();
|
|
@@ -1109,6 +1135,8 @@ export class AgentSession {
|
|
|
1109
1135
|
* Call this when completely done with the session.
|
|
1110
1136
|
*/
|
|
1111
1137
|
dispose() {
|
|
1138
|
+
this._promptLifecycle.dispose();
|
|
1139
|
+
this._runBudget.close();
|
|
1112
1140
|
try {
|
|
1113
1141
|
try {
|
|
1114
1142
|
this.abortRetry();
|
|
@@ -1235,7 +1263,7 @@ export class AgentSession {
|
|
|
1235
1263
|
for (const name of desiredToolNames) {
|
|
1236
1264
|
const tool = this._toolRegistry.get(name);
|
|
1237
1265
|
if (tool) {
|
|
1238
|
-
tools.push(tool);
|
|
1266
|
+
tools.push(this._promptLifecycle.wrapTool(tool));
|
|
1239
1267
|
validToolNames.push(name);
|
|
1240
1268
|
}
|
|
1241
1269
|
else if (lockedToolNames?.includes(name)) {
|
|
@@ -1460,13 +1488,14 @@ export class AgentSession {
|
|
|
1460
1488
|
// One identity per top-level run (§16.2): internal retries and
|
|
1461
1489
|
// continuations inside this call share it, as does the resource lease.
|
|
1462
1490
|
const promptRunId = `prompt-run-${randomUUID()}`;
|
|
1463
|
-
const
|
|
1491
|
+
const ownedRun = this._promptLifecycle.begin(promptRunId);
|
|
1464
1492
|
// Roadmap M2: the lease spans the whole run including internal retries
|
|
1465
1493
|
// and continuations, so they share one admission decision (§8.3).
|
|
1466
1494
|
const resourceLease = await this._beginResourceGovernedRun(promptRunId);
|
|
1467
1495
|
const resourceObservations = this._resourceObservationJournals.get(promptRunId) ?? null;
|
|
1468
1496
|
let outcome = "completed";
|
|
1469
1497
|
try {
|
|
1498
|
+
this._runBudget.assertActive();
|
|
1470
1499
|
await this.agent.prompt(messages);
|
|
1471
1500
|
while (await this._handlePostAgentRun()) {
|
|
1472
1501
|
await this.agent.continue();
|
|
@@ -1478,43 +1507,18 @@ export class AgentSession {
|
|
|
1478
1507
|
throw error;
|
|
1479
1508
|
}
|
|
1480
1509
|
finally {
|
|
1510
|
+
if (this._runBudget.failure && this._lastTermination?.kind !== "budget_exhausted")
|
|
1511
|
+
this._publishRuntimeFailure(this._runBudget.failure);
|
|
1481
1512
|
outcome = promptSettlement.resolvePromptSettlementOutcome(outcome, this._lastTermination?.kind);
|
|
1482
|
-
if (resourceLease !== null) {
|
|
1483
|
-
// Generation-safe: a stale release after another run acquired the
|
|
1484
|
-
// lease is a no-op instead of clobbering the newer cap (§8.1).
|
|
1485
|
-
this._resourceLeaseController?.release(resourceLease);
|
|
1486
|
-
resourceObservations?.record("resource_lease_released_v1", { promptRunId });
|
|
1487
|
-
}
|
|
1488
1513
|
this._flushPendingBashMessages();
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
* conservatively — the continuation run settles under its own id.
|
|
1498
|
-
* Settlement is a UX signal only and must never affect the run (§16.1).
|
|
1499
|
-
*/
|
|
1500
|
-
_emitPromptSettledIfReady(input) {
|
|
1501
|
-
try {
|
|
1502
|
-
let state = promptSettlement.createPromptSettlementState(input.promptRunId, input.startedAtEpochMs);
|
|
1503
|
-
state = promptSettlement.reducePromptSettlement(state, { kind: "terminal", outcome: input.outcome });
|
|
1504
|
-
if (this.isStreaming) {
|
|
1505
|
-
state = promptSettlement.reducePromptSettlement(state, { kind: "tool", delta: 1 });
|
|
1506
|
-
}
|
|
1507
|
-
if (this.agent.hasQueuedMessages()) {
|
|
1508
|
-
state = promptSettlement.reducePromptSettlement(state, { kind: "continuation", delta: 1 });
|
|
1509
|
-
}
|
|
1510
|
-
const settled = promptSettlement.settlePromptIfReady(state, Date.now());
|
|
1511
|
-
if (settled.event !== null) {
|
|
1512
|
-
input.resourceObservations?.record("prompt_settled_v1", settledObservationFacts(settled.event));
|
|
1513
|
-
this._emit(settled.event);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
catch {
|
|
1517
|
-
// Never let settlement bookkeeping break a run.
|
|
1514
|
+
ownedRun.finish(outcome, (event) => {
|
|
1515
|
+
if (resourceLease !== null) {
|
|
1516
|
+
this._resourceLeaseController?.release(resourceLease);
|
|
1517
|
+
resourceObservations?.record("resource_lease_released_v1", { promptRunId });
|
|
1518
|
+
}
|
|
1519
|
+
resourceObservations?.record("prompt_settled_v1", settledObservationFacts(event));
|
|
1520
|
+
this._emit(event);
|
|
1521
|
+
});
|
|
1518
1522
|
}
|
|
1519
1523
|
}
|
|
1520
1524
|
/**
|
|
@@ -1526,7 +1530,7 @@ export class AgentSession {
|
|
|
1526
1530
|
* delayed. The pending probe is bounded (~cpuSampleMs) and never rejects.
|
|
1527
1531
|
* - `adaptive`/`strict`: bounded blocking probe (default 300 ms deadline),
|
|
1528
1532
|
* then a generation-safe lease applies the effective tool cap for this
|
|
1529
|
-
* run.
|
|
1533
|
+
* run. Prompt settlement releases it after owned tool promises terminate.
|
|
1530
1534
|
*
|
|
1531
1535
|
* Never throws: any probe or policy failure leaves this run ungoverned
|
|
1532
1536
|
* (§2.1: probe failure must not crash or block the prompt).
|
|
@@ -1721,6 +1725,7 @@ export class AgentSession {
|
|
|
1721
1725
|
}
|
|
1722
1726
|
}
|
|
1723
1727
|
async _handlePostAgentRun() {
|
|
1728
|
+
this._runBudget.assertActive();
|
|
1724
1729
|
const msg = this._lastAssistantMessage;
|
|
1725
1730
|
this._lastAssistantMessage = undefined;
|
|
1726
1731
|
if (!msg) {
|
|
@@ -1755,7 +1760,15 @@ export class AgentSession {
|
|
|
1755
1760
|
* @throws Error if streaming and no streamingBehavior specified
|
|
1756
1761
|
* @throws Error if no model selected or no API key available (when not streaming)
|
|
1757
1762
|
*/
|
|
1758
|
-
|
|
1763
|
+
prompt(text, options) {
|
|
1764
|
+
if (options?.runBudget === undefined && (this.isStreaming || this.isRetrying))
|
|
1765
|
+
return this._prompt(text, options);
|
|
1766
|
+
return this._runBudget.execute(options?.runBudget, () => this._prompt(text, options), options?.preflightResult);
|
|
1767
|
+
}
|
|
1768
|
+
getRunBudgetSnapshot() {
|
|
1769
|
+
return this._runBudget.snapshot();
|
|
1770
|
+
}
|
|
1771
|
+
async _prompt(text, options) {
|
|
1759
1772
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1760
1773
|
const preflightResult = options?.preflightResult;
|
|
1761
1774
|
let currentText = redactSensitiveText(text);
|
|
@@ -1820,6 +1833,7 @@ export class AgentSession {
|
|
|
1820
1833
|
preflightResult?.(true);
|
|
1821
1834
|
return;
|
|
1822
1835
|
}
|
|
1836
|
+
this._promptLifecycle.assertIdle();
|
|
1823
1837
|
// Flush any pending bash messages before the new prompt
|
|
1824
1838
|
this._flushPendingBashMessages();
|
|
1825
1839
|
// Validate model
|
|
@@ -1918,11 +1932,16 @@ export class AgentSession {
|
|
|
1918
1932
|
}
|
|
1919
1933
|
this._recordPromptCachePlan(result?.systemPrompt ? "extension-override" : "turn-plan");
|
|
1920
1934
|
await this._checkProjectedCompaction(messages);
|
|
1935
|
+
this._runBudget.assertActive();
|
|
1921
1936
|
}
|
|
1922
1937
|
catch (error) {
|
|
1923
1938
|
preflightResult?.(false);
|
|
1924
1939
|
const rawMessage = error instanceof Error ? error.message : String(error);
|
|
1925
|
-
const cause =
|
|
1940
|
+
const cause = error instanceof RunBudgetExceededError
|
|
1941
|
+
? { area: "budget", code: error.code }
|
|
1942
|
+
: error instanceof RunBudgetPolicyError
|
|
1943
|
+
? { area: "configuration", code: "invalid" }
|
|
1944
|
+
: preflightFailureCause(rawMessage, Boolean(this.model));
|
|
1926
1945
|
const timestamp = new Date().toISOString();
|
|
1927
1946
|
this._publishTermination(classifySessionTermination({
|
|
1928
1947
|
sessionId: this.sessionId,
|
|
@@ -2172,6 +2191,7 @@ export class AgentSession {
|
|
|
2172
2191
|
this._followUpMessages = [];
|
|
2173
2192
|
this.agent.clearAllQueues();
|
|
2174
2193
|
this._emitQueueUpdate();
|
|
2194
|
+
this._promptLifecycle.flush();
|
|
2175
2195
|
return { steering, followUp };
|
|
2176
2196
|
}
|
|
2177
2197
|
/** Number of pending messages (includes both steering and follow-up) */
|
|
@@ -3938,7 +3958,7 @@ export class AgentSession {
|
|
|
3938
3958
|
const failoverTo = await this._maybeFailoverFromSafetyStop(message);
|
|
3939
3959
|
const switchedVia = failoverTo ? `failover ${failoverTo}` : rotatedTo ? `route ${rotatedTo}` : undefined;
|
|
3940
3960
|
// Safety stops are usually immediate false positives — short delay after failover, full backoff otherwise.
|
|
3941
|
-
const delayMs = computeRetryDelayMs(settings.baseDelayMs, attempt, switchedVia !== undefined);
|
|
3961
|
+
const delayMs = Math.min(computeRetryDelayMs(settings.baseDelayMs, attempt, switchedVia !== undefined), this._runBudget.remainingMs ?? Infinity);
|
|
3942
3962
|
const errorMessage = switchedVia
|
|
3943
3963
|
? `${message.errorMessage || "content/safety stop"} → ${switchedVia}`
|
|
3944
3964
|
: message.errorMessage || "Unknown error";
|