@code-yeongyu/senpi 2026.9.5 → 2026.9.7
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 +67 -0
- package/dist/core/agent-session.d.ts +21 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +144 -56
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +6 -2
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +4 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/stuck-overflow.d.ts +11 -0
- package/dist/core/compaction/stuck-overflow.d.ts.map +1 -0
- package/dist/core/compaction/stuck-overflow.js +17 -0
- package/dist/core/compaction/stuck-overflow.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/prompt-bridge.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js +15 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry-pump.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-claim.d.ts +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-claim.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-claim.js +2 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-claim.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +4 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +16 -19
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +9 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/lane-policy.js +5 -0
- package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote-convert.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote-convert.js +2 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-convert.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js +14 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation-recovery.js +2 -0
- package/dist/core/extensions/builtin/goal/continuation-recovery.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +4 -0
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +3 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +14 -3
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +2 -1
- package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.js +42 -13
- package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +2 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +8 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/messages.d.ts +7 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +2 -0
- package/dist/core/messages.js.map +1 -1
- package/dist/core/package-identity.d.ts +12 -0
- package/dist/core/package-identity.d.ts.map +1 -0
- package/dist/core/package-identity.js +57 -0
- package/dist/core/package-identity.js.map +1 -0
- package/dist/core/resource-loader.d.ts +0 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +8 -60
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +5 -4
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +12 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +29 -3
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +4 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +5 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +3 -7
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +3 -13
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -2
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +0 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +1 -4
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +0 -15
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/docs/compaction-guide.md +2 -2
- package/docs/compaction.md +2 -2
- package/docs/rpc.md +6 -7
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +57 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +20 -4
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/reserved.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/context-manager.ts +73 -129
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/inline-worker.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/interrupt-bounds.ts +66 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/run-queue.ts +18 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +30 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-runtime.js +16 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +9 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +32 -6
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-slot.ts +106 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +69 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/runtime-asset.ts +40 -14
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +10 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-execution.ts +9 -11
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-contract.ts +45 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +43 -71
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-notification.ts +4 -5
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-status.ts +30 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +1 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-notification-queue.ts +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/interrupt-note.ts +29 -15
- package/node_modules/@code-yeongyu/senpi-codemode/src/tool/types.ts +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +3 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +17 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/reducer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/reducer.js +6 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/reducer.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/context.d.ts +2 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/context.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/context.js +5 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/context.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/jsonl/codec.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts +7 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +2 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/mistral-conversations.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +15 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +4 -4
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cerebras.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +8 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/estimate.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -35,6 +35,7 @@ import { executeBashWithOperations } from "./bash-executor.js";
|
|
|
35
35
|
import { envValue } from "./brand.js";
|
|
36
36
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, resolveThresholdContextTokens, shouldCompact, } from "./compaction/index.js";
|
|
37
37
|
import { CompactionLifecycleCoordinator } from "./compaction/lifecycle.js";
|
|
38
|
+
import { isTurnStuckOnContextOverflow } from "./compaction/stuck-overflow.js";
|
|
38
39
|
import { isWarmSummaryAnchorValid } from "./compaction/warm-anchor.js";
|
|
39
40
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
40
41
|
import { buildDynamicSystemPrompt } from "./dynamic-prompt/index.js";
|
|
@@ -208,6 +209,8 @@ function removeSkillInvocationTokens(text, tokens) {
|
|
|
208
209
|
let result = "";
|
|
209
210
|
for (const token of tokens) {
|
|
210
211
|
result += text.slice(cursor, token.start);
|
|
212
|
+
if (token.position === "inline")
|
|
213
|
+
result += `[skill: ${token.name}]`;
|
|
211
214
|
cursor = token.end;
|
|
212
215
|
if (token.position === "inline" &&
|
|
213
216
|
(result.endsWith(" ") || result.endsWith("\t")) &&
|
|
@@ -755,6 +758,25 @@ export class AgentSession {
|
|
|
755
758
|
return { model };
|
|
756
759
|
}
|
|
757
760
|
}
|
|
761
|
+
/**
|
|
762
|
+
* Resolve the model used for compaction summarization. When the user sets a
|
|
763
|
+
* `compaction.model` override ("provider/model"), that model is used for the
|
|
764
|
+
* summarization call instead of the session model — this is what lets an
|
|
765
|
+
* SDK-owned lane (claude-sdk-oauth) compact on a cheaper/different model.
|
|
766
|
+
* Any resolution failure (unset, malformed, unknown model) falls back to the
|
|
767
|
+
* session model so compaction never silently breaks.
|
|
768
|
+
*/
|
|
769
|
+
_resolveCompactionModel(sessionModel) {
|
|
770
|
+
const override = this._getCompactionSettings().model;
|
|
771
|
+
if (!override)
|
|
772
|
+
return sessionModel;
|
|
773
|
+
const slash = override.indexOf("/");
|
|
774
|
+
if (slash <= 0 || slash === override.length - 1)
|
|
775
|
+
return sessionModel;
|
|
776
|
+
const provider = override.slice(0, slash);
|
|
777
|
+
const modelId = override.slice(slash + 1);
|
|
778
|
+
return this._modelRuntime.getModel(provider, modelId) ?? sessionModel;
|
|
779
|
+
}
|
|
758
780
|
async _getCompactionRequestAuth(model) {
|
|
759
781
|
const auth = await this._getSummarizationRequestAuth(model);
|
|
760
782
|
return {
|
|
@@ -1163,7 +1185,7 @@ export class AgentSession {
|
|
|
1163
1185
|
systemPrompt: this.agent.state.systemPrompt,
|
|
1164
1186
|
tools: this.agent.state.tools,
|
|
1165
1187
|
liveContextTokens: this._getDownswitchLiveContextTokens(model),
|
|
1166
|
-
compaction: this.
|
|
1188
|
+
compaction: this._getCompactionSettings(),
|
|
1167
1189
|
});
|
|
1168
1190
|
return projection.usable ? undefined : projection;
|
|
1169
1191
|
}
|
|
@@ -1353,9 +1375,14 @@ export class AgentSession {
|
|
|
1353
1375
|
const messages = filterContextExcludedMessages(this.agent.state.messages);
|
|
1354
1376
|
return resolveThresholdContextTokens(directContextTokens, estimateMessagesTokens(messages));
|
|
1355
1377
|
}
|
|
1378
|
+
/**
|
|
1379
|
+
* `compaction.enabled=false` disables proactive (threshold) compaction only.
|
|
1380
|
+
* A provider-confirmed overflow is an error the session cannot progress past
|
|
1381
|
+
* by any other route, so overflow recovery stays armed regardless (#1422).
|
|
1382
|
+
*/
|
|
1356
1383
|
_getAutoCompactionReason(message) {
|
|
1357
|
-
const settings = this.
|
|
1358
|
-
if (
|
|
1384
|
+
const settings = this._getCompactionSettings();
|
|
1385
|
+
if (message.stopReason === "aborted") {
|
|
1359
1386
|
return undefined;
|
|
1360
1387
|
}
|
|
1361
1388
|
const model = this.model;
|
|
@@ -1367,11 +1394,15 @@ export class AgentSession {
|
|
|
1367
1394
|
const currentContextNeedsCompaction = contextUsage !== undefined &&
|
|
1368
1395
|
contextUsage.tokens !== null &&
|
|
1369
1396
|
shouldCompact(contextUsage.tokens, contextUsage.contextWindow, settings);
|
|
1370
|
-
|
|
1371
|
-
|
|
1397
|
+
const isOverflow = (isContextOverflow(message, model.contextWindow) && (sameModel || currentContextNeedsCompaction)) ||
|
|
1398
|
+
this._isCursorPayloadOverflow(message);
|
|
1399
|
+
if (isOverflow) {
|
|
1400
|
+
if (settings.enabled || isTurnStuckOnContextOverflow(message, model.contextWindow))
|
|
1401
|
+
return "overflow";
|
|
1402
|
+
return undefined;
|
|
1372
1403
|
}
|
|
1373
|
-
if (
|
|
1374
|
-
return
|
|
1404
|
+
if (!settings.enabled) {
|
|
1405
|
+
return undefined;
|
|
1375
1406
|
}
|
|
1376
1407
|
let contextTokens;
|
|
1377
1408
|
const directContextTokens = message.usage ? calculateContextTokens(message.usage) : 0;
|
|
@@ -3621,7 +3652,7 @@ export class AgentSession {
|
|
|
3621
3652
|
systemPrompt: this.agent.state.systemPrompt,
|
|
3622
3653
|
tools: this.agent.state.tools,
|
|
3623
3654
|
liveContextTokens,
|
|
3624
|
-
compaction: this.
|
|
3655
|
+
compaction: this._getCompactionSettings(),
|
|
3625
3656
|
includeSpeculationLead: options?.includeSpeculationLead,
|
|
3626
3657
|
admission: options?.admission,
|
|
3627
3658
|
});
|
|
@@ -3632,7 +3663,7 @@ export class AgentSession {
|
|
|
3632
3663
|
const currentModel = this.model;
|
|
3633
3664
|
if (!currentModel)
|
|
3634
3665
|
return 0;
|
|
3635
|
-
const compaction = this.
|
|
3666
|
+
const compaction = this._getCompactionSettings();
|
|
3636
3667
|
const currentBudget = projectModelUsabilityBudget({
|
|
3637
3668
|
model: currentModel,
|
|
3638
3669
|
systemPrompt: this.agent.state.systemPrompt,
|
|
@@ -3711,17 +3742,18 @@ export class AgentSession {
|
|
|
3711
3742
|
const thinking = this._getThinkingForModelSwitch(model, opts.ephemeralThinkingLevel);
|
|
3712
3743
|
const liveContextTokens = this._getDownswitchLiveContextTokens(model);
|
|
3713
3744
|
this.agent.state.model = model;
|
|
3714
|
-
|
|
3715
|
-
this.
|
|
3716
|
-
if (opts.appendSessionEntry) {
|
|
3717
|
-
this.sessionManager.appendModelChange(model.provider, model.id, opts.entryReason, previousModel?.provider, previousModel?.id);
|
|
3718
|
-
}
|
|
3719
|
-
if (opts.persistDefault) {
|
|
3720
|
-
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
3745
|
+
if (!(model.id === "gpt-6-astra" && (model.provider === "openai" || model.provider === "openai-codex"))) {
|
|
3746
|
+
this.agent.state.reasoningBaseline = undefined;
|
|
3721
3747
|
}
|
|
3722
3748
|
const scopedMatch = this._scopedModels.find((sm) => modelsAreEqual(sm.model, model));
|
|
3723
3749
|
const previousTier = this._currentServiceTier;
|
|
3724
3750
|
const previousFastMode = this.isFastModeActive();
|
|
3751
|
+
const previousThinkingLevel = this.agent.state.thinkingLevel;
|
|
3752
|
+
const previousThinkingSelection = this.agent.state.thinkingSelection;
|
|
3753
|
+
const previousReasoningBaseline = this.agent.state.reasoningBaseline;
|
|
3754
|
+
const previousAbortServerSideFallback = this.agent.abortServerSideFallback;
|
|
3755
|
+
this.agent.abortServerSideFallback =
|
|
3756
|
+
this.settingsManager.getAbortServerSideFallback() && this._retryFallback.hasConfiguredChain();
|
|
3725
3757
|
this._currentServiceTier = this._resolveServiceTier(model, scopedMatch?.serviceTier);
|
|
3726
3758
|
if (opts.ephemeralThinkingLevel !== undefined) {
|
|
3727
3759
|
this._applyEphemeralThinkingLevel(thinking.level);
|
|
@@ -3730,21 +3762,25 @@ export class AgentSession {
|
|
|
3730
3762
|
this._setThinkingLevel(thinking.level, false, thinking.selection);
|
|
3731
3763
|
}
|
|
3732
3764
|
this._emitHighReasoningWarningIfNeeded();
|
|
3733
|
-
// Post-switch: the level reported here is the one actually in force (clamped, or restored
|
|
3734
|
-
// from this model's memory), not the level requested for the previous model.
|
|
3735
|
-
this._emit({
|
|
3736
|
-
type: "model_changed",
|
|
3737
|
-
model,
|
|
3738
|
-
thinkingLevel: this.thinkingLevel,
|
|
3739
|
-
source: opts.modelSelectSource,
|
|
3740
|
-
});
|
|
3741
|
-
this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
|
|
3742
|
-
if (!opts.emitModelSelect)
|
|
3743
|
-
return undefined;
|
|
3744
3765
|
const previousSystemPrompt = this.agent.state.systemPrompt;
|
|
3745
3766
|
try {
|
|
3746
|
-
const systemPromptChange =
|
|
3767
|
+
const systemPromptChange = opts.emitModelSelect
|
|
3768
|
+
? await this._emitModelSelect(model, previousModel, opts.modelSelectSource)
|
|
3769
|
+
: undefined;
|
|
3747
3770
|
this.assertModelUsable(model, liveContextTokens);
|
|
3771
|
+
if (opts.appendSessionEntry) {
|
|
3772
|
+
this.sessionManager.appendModelChange(model.provider, model.id, opts.entryReason, previousModel?.provider, previousModel?.id);
|
|
3773
|
+
}
|
|
3774
|
+
if (opts.persistDefault)
|
|
3775
|
+
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
3776
|
+
// Emit only after all admission hooks have accepted the candidate.
|
|
3777
|
+
this._emit({
|
|
3778
|
+
type: "model_changed",
|
|
3779
|
+
model,
|
|
3780
|
+
thinkingLevel: this.thinkingLevel,
|
|
3781
|
+
source: opts.modelSelectSource,
|
|
3782
|
+
});
|
|
3783
|
+
this._emitServiceTierChangeIfNeeded(previousTier, previousFastMode);
|
|
3748
3784
|
return systemPromptChange;
|
|
3749
3785
|
}
|
|
3750
3786
|
catch (error) {
|
|
@@ -3753,6 +3789,11 @@ export class AgentSession {
|
|
|
3753
3789
|
else
|
|
3754
3790
|
delete this.agent.state.model;
|
|
3755
3791
|
this.agent.state.systemPrompt = previousSystemPrompt;
|
|
3792
|
+
this.agent.state.thinkingLevel = previousThinkingLevel;
|
|
3793
|
+
this.agent.state.thinkingSelection = previousThinkingSelection;
|
|
3794
|
+
this.agent.state.reasoningBaseline = previousReasoningBaseline;
|
|
3795
|
+
this.agent.abortServerSideFallback = previousAbortServerSideFallback;
|
|
3796
|
+
this._currentServiceTier = previousTier;
|
|
3756
3797
|
throw error;
|
|
3757
3798
|
}
|
|
3758
3799
|
}
|
|
@@ -3929,6 +3970,14 @@ export class AgentSession {
|
|
|
3929
3970
|
}
|
|
3930
3971
|
if (isChanging || selectionChanged) {
|
|
3931
3972
|
this.sessionManager.appendThinkingLevelChange(effectiveLevel, effectiveSelection);
|
|
3973
|
+
const model = this.model;
|
|
3974
|
+
if (isChanging &&
|
|
3975
|
+
model?.id === "gpt-6-astra" &&
|
|
3976
|
+
(model.provider === "openai" || model.provider === "openai-codex")) {
|
|
3977
|
+
this.agent.state.reasoningBaseline ??= previousLevel;
|
|
3978
|
+
this.sessionManager.appendConfigurationUpdate(effectiveLevel);
|
|
3979
|
+
this.agent.state.messages = this.sessionManager.buildSessionContext().messages;
|
|
3980
|
+
}
|
|
3932
3981
|
if (updateGlobalDefault && (this.supportsThinking() || effectiveLevel !== "off")) {
|
|
3933
3982
|
this.settingsManager.setDefaultThinkingLevel(effectiveLevel);
|
|
3934
3983
|
}
|
|
@@ -4237,7 +4286,7 @@ export class AgentSession {
|
|
|
4237
4286
|
if (!model)
|
|
4238
4287
|
throw new Error(formatNoModelSelectedMessage());
|
|
4239
4288
|
const pathEntries = this.sessionManager.getBranch();
|
|
4240
|
-
const settings = cursorOverflowCompactionSettings(this.
|
|
4289
|
+
const settings = cursorOverflowCompactionSettings(this._getCompactionSettings(), model.provider, "manual");
|
|
4241
4290
|
if (!prepareCompaction(pathEntries, settings)) {
|
|
4242
4291
|
const requestId = randomUUID();
|
|
4243
4292
|
const lastEntry = pathEntries[pathEntries.length - 1];
|
|
@@ -4477,7 +4526,7 @@ export class AgentSession {
|
|
|
4477
4526
|
throw new CompactionCancelledError();
|
|
4478
4527
|
}
|
|
4479
4528
|
const pathEntries = this.sessionManager.getBranch();
|
|
4480
|
-
const settings = cursorOverflowCompactionSettings(this.
|
|
4529
|
+
const settings = cursorOverflowCompactionSettings(this._getCompactionSettings(), this.model?.provider, request.reason);
|
|
4481
4530
|
let compactionResult = request.precomputed;
|
|
4482
4531
|
let fromExtension = request.precomputed !== undefined;
|
|
4483
4532
|
if (!compactionResult) {
|
|
@@ -4519,7 +4568,13 @@ export class AgentSession {
|
|
|
4519
4568
|
}
|
|
4520
4569
|
}
|
|
4521
4570
|
if (!compactionResult) {
|
|
4522
|
-
|
|
4571
|
+
// A configured compaction.model override redirects only the
|
|
4572
|
+
// summarization call to that model; every other part of the session
|
|
4573
|
+
// (lifecycle record, preparation, branch) still tracks the session
|
|
4574
|
+
// model. Falls back to the session model when the override is unset
|
|
4575
|
+
// or cannot be resolved.
|
|
4576
|
+
const compactionModel = this._resolveCompactionModel(model);
|
|
4577
|
+
const { model: requestModel, apiKey, headers, extraBody, env, } = await this._getCompactionRequestAuth(compactionModel);
|
|
4523
4578
|
compactionResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, extraBody, request.customInstructions, signal, env, request.reason);
|
|
4524
4579
|
}
|
|
4525
4580
|
}
|
|
@@ -4550,11 +4605,20 @@ export class AgentSession {
|
|
|
4550
4605
|
if (await this._wouldCompactionOverflow(pathEntries, compactionResult, fromExtension, model)) {
|
|
4551
4606
|
return await this._rejectCompaction(request, requestId, operationId, "would-overflow", false);
|
|
4552
4607
|
}
|
|
4608
|
+
const latestConfigurationEffort = this.sessionManager
|
|
4609
|
+
.getBranch()
|
|
4610
|
+
.findLast((entry) => entry.type === "configuration_update")?.reasoning.effort;
|
|
4553
4611
|
const compactionEntryId = this.sessionManager.appendCompaction(compactionResult.summary, compactionResult.firstKeptEntryId, compactionResult.tokensBefore, compactionResult.details, fromExtension, compactionResult.usage);
|
|
4554
4612
|
const savedEntry = this.sessionManager.getEntry(compactionEntryId);
|
|
4555
4613
|
if (savedEntry?.type !== "compaction") {
|
|
4556
4614
|
throw new Error("Compaction entry was not saved");
|
|
4557
4615
|
}
|
|
4616
|
+
const modelAfterCompaction = this.model;
|
|
4617
|
+
if (latestConfigurationEffort !== undefined &&
|
|
4618
|
+
modelAfterCompaction?.id === "gpt-6-astra" &&
|
|
4619
|
+
(modelAfterCompaction.provider === "openai" || modelAfterCompaction.provider === "openai-codex")) {
|
|
4620
|
+
this.sessionManager.appendConfigurationUpdate(latestConfigurationEffort);
|
|
4621
|
+
}
|
|
4558
4622
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
4559
4623
|
const currentAgentMessages = this.agent.state.messages;
|
|
4560
4624
|
const hasUnchangedPrefix = agentMessagesAtStart.every((message, index) => currentAgentMessages[index] === message);
|
|
@@ -4665,7 +4729,7 @@ export class AgentSession {
|
|
|
4665
4729
|
simulatedMessages = truncateToolResultBodies(simulatedMessages).messages ?? simulatedMessages;
|
|
4666
4730
|
}
|
|
4667
4731
|
const contextTokens = estimateMessagesTokens(filterContextExcludedMessages(simulatedMessages));
|
|
4668
|
-
const settings = this.
|
|
4732
|
+
const settings = this._getCompactionSettings();
|
|
4669
4733
|
const reserveTokens = settings.reserveScalingEnabled === false
|
|
4670
4734
|
? settings.reserveTokens
|
|
4671
4735
|
: resolveReserveTokens(model.contextWindow, settings.reserveTokens);
|
|
@@ -4784,7 +4848,7 @@ export class AgentSession {
|
|
|
4784
4848
|
blockedAdmission.revision === this._messageRevision) {
|
|
4785
4849
|
throw new RequiredCompactionError();
|
|
4786
4850
|
}
|
|
4787
|
-
const settings = this.
|
|
4851
|
+
const settings = this._getCompactionSettings();
|
|
4788
4852
|
const model = this.model;
|
|
4789
4853
|
const contextTokens = estimateContextTokens(filterContextExcludedMessages(this.sessionManager.buildSessionContext().messages)).tokens;
|
|
4790
4854
|
const compacted = assistantMessage
|
|
@@ -4832,7 +4896,7 @@ export class AgentSession {
|
|
|
4832
4896
|
const model = this.model;
|
|
4833
4897
|
if (!model)
|
|
4834
4898
|
return;
|
|
4835
|
-
const settings = this.
|
|
4899
|
+
const settings = this._getCompactionSettings();
|
|
4836
4900
|
const reserveTokens = settings.reserveScalingEnabled === false
|
|
4837
4901
|
? settings.reserveTokens
|
|
4838
4902
|
: resolveReserveTokens(model.contextWindow, settings.reserveTokens);
|
|
@@ -4866,9 +4930,7 @@ export class AgentSession {
|
|
|
4866
4930
|
}
|
|
4867
4931
|
}
|
|
4868
4932
|
async _checkCompaction(assistantMessage, skipAbortedCheck = true, inlineReason, retryAfterCompaction = false) {
|
|
4869
|
-
const settings = this.
|
|
4870
|
-
if (!settings.enabled)
|
|
4871
|
-
return false;
|
|
4933
|
+
const settings = this._getCompactionSettings();
|
|
4872
4934
|
// Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
|
|
4873
4935
|
if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
|
|
4874
4936
|
return false;
|
|
@@ -4897,6 +4959,9 @@ export class AgentSession {
|
|
|
4897
4959
|
const isOverflow = (isContextOverflow(assistantMessage, contextWindow) && (sameModel || currentContextNeedsCompaction)) ||
|
|
4898
4960
|
recoverableLength ||
|
|
4899
4961
|
this._isCursorPayloadOverflow(assistantMessage);
|
|
4962
|
+
if (isOverflow && !settings.enabled && !isTurnStuckOnContextOverflow(assistantMessage, contextWindow)) {
|
|
4963
|
+
return false;
|
|
4964
|
+
}
|
|
4900
4965
|
if (isOverflow &&
|
|
4901
4966
|
assistantMessage.stopReason === "stop" &&
|
|
4902
4967
|
this._consumePostCompactionUsageExemption(assistantMessage)) {
|
|
@@ -4967,6 +5032,10 @@ export class AgentSession {
|
|
|
4967
5032
|
}
|
|
4968
5033
|
return compacted;
|
|
4969
5034
|
}
|
|
5035
|
+
// Stuck-overflow recovery above runs regardless of the flag; threshold
|
|
5036
|
+
// compaction below is the proactive path the user switched off (#1422).
|
|
5037
|
+
if (!settings.enabled)
|
|
5038
|
+
return false;
|
|
4970
5039
|
// The first ordinary response can carry provider usage calculated before
|
|
4971
5040
|
// compaction. Consume that exemption only after proving this is not an
|
|
4972
5041
|
// overflow, then retain the decision for later admission re-sampling.
|
|
@@ -5099,7 +5168,7 @@ export class AgentSession {
|
|
|
5099
5168
|
}
|
|
5100
5169
|
async _revalidateScheduledContinuationAdmission() {
|
|
5101
5170
|
const model = this.model;
|
|
5102
|
-
const settings = this.
|
|
5171
|
+
const settings = this._getCompactionSettings();
|
|
5103
5172
|
if (!model || !settings.enabled)
|
|
5104
5173
|
return;
|
|
5105
5174
|
const canonicalMessages = filterContextExcludedMessages(this.sessionManager.buildSessionContext().messages);
|
|
@@ -5279,7 +5348,7 @@ export class AgentSession {
|
|
|
5279
5348
|
}
|
|
5280
5349
|
if (!this._ownsCompactionController(autoCompactionController, "auto"))
|
|
5281
5350
|
return false;
|
|
5282
|
-
const preparation = prepareCompaction(this.sessionManager.getBranch(), cursorOverflowCompactionSettings(this.
|
|
5351
|
+
const preparation = prepareCompaction(this.sessionManager.getBranch(), cursorOverflowCompactionSettings(this._getCompactionSettings(), this.model?.provider, reason), reason === "overflow");
|
|
5283
5352
|
if (!preparation) {
|
|
5284
5353
|
return endBeforeExecution();
|
|
5285
5354
|
}
|
|
@@ -5363,12 +5432,21 @@ export class AgentSession {
|
|
|
5363
5432
|
}
|
|
5364
5433
|
}
|
|
5365
5434
|
/**
|
|
5366
|
-
* Toggle auto-compaction
|
|
5435
|
+
* Toggle auto-compaction for this session only. Persisting the flag is a
|
|
5436
|
+
* settings-editor concern; a session-level command (RPC `set_auto_compaction`,
|
|
5437
|
+
* one thread of a multi-session host) must never rewrite the global setting
|
|
5438
|
+
* for every other session on the machine (#1422).
|
|
5367
5439
|
*/
|
|
5368
5440
|
setAutoCompactionEnabled(enabled) {
|
|
5369
|
-
this.
|
|
5441
|
+
this._autoCompactionSessionOverride = enabled;
|
|
5370
5442
|
this._emitSessionSettingsChanged();
|
|
5371
5443
|
}
|
|
5444
|
+
_getCompactionSettings() {
|
|
5445
|
+
const settings = this.settingsManager.getCompactionSettings();
|
|
5446
|
+
if (this._autoCompactionSessionOverride === undefined)
|
|
5447
|
+
return settings;
|
|
5448
|
+
return { ...settings, enabled: this._autoCompactionSessionOverride };
|
|
5449
|
+
}
|
|
5372
5450
|
_emitSessionSettingsChanged() {
|
|
5373
5451
|
this._emit({
|
|
5374
5452
|
type: "session_settings_changed",
|
|
@@ -5377,9 +5455,9 @@ export class AgentSession {
|
|
|
5377
5455
|
autoCompactionEnabled: this.autoCompactionEnabled,
|
|
5378
5456
|
});
|
|
5379
5457
|
}
|
|
5380
|
-
/** Whether auto-compaction is enabled */
|
|
5458
|
+
/** Whether auto-compaction is enabled for this session */
|
|
5381
5459
|
get autoCompactionEnabled() {
|
|
5382
|
-
return this.settingsManager.getCompactionEnabled();
|
|
5460
|
+
return this._autoCompactionSessionOverride ?? this.settingsManager.getCompactionEnabled();
|
|
5383
5461
|
}
|
|
5384
5462
|
async bindExtensions(bindings) {
|
|
5385
5463
|
const finishBindingWork = this._sessionWorkBarrier.begin();
|
|
@@ -5616,7 +5694,7 @@ export class AgentSession {
|
|
|
5616
5694
|
this._extensionShutdownHandler?.();
|
|
5617
5695
|
},
|
|
5618
5696
|
getContextUsage: () => this.getContextUsage(),
|
|
5619
|
-
getCompactionSettings: () => this.
|
|
5697
|
+
getCompactionSettings: () => this._getCompactionSettings(),
|
|
5620
5698
|
getPromptCacheSafeWaitSeconds: () => this.resolvePromptCacheSafeWaitSeconds(),
|
|
5621
5699
|
getPromptCacheGoalBackstopMaxSeconds: () => this.settingsManager.getPromptCacheGoalBackstopMaxSeconds(),
|
|
5622
5700
|
getPromptCacheKeepAliveSettings: () => this.settingsManager.getPromptCacheKeepAliveSettings(),
|
|
@@ -6214,6 +6292,18 @@ export class AgentSession {
|
|
|
6214
6292
|
let switchedFallback = false;
|
|
6215
6293
|
let is429TierRouted = false;
|
|
6216
6294
|
let hintTierDelayMs;
|
|
6295
|
+
const tryFallback = async (reason, failure) => {
|
|
6296
|
+
try {
|
|
6297
|
+
return await this._retryFallback.tryFallback(reason, failure);
|
|
6298
|
+
}
|
|
6299
|
+
catch (error) {
|
|
6300
|
+
if (error instanceof ModelUsabilityBudgetError) {
|
|
6301
|
+
this._resolveRetry();
|
|
6302
|
+
return false;
|
|
6303
|
+
}
|
|
6304
|
+
throw error;
|
|
6305
|
+
}
|
|
6306
|
+
};
|
|
6217
6307
|
if (sameModelRemint) {
|
|
6218
6308
|
this._retryAttempt++;
|
|
6219
6309
|
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
@@ -6236,9 +6326,7 @@ export class AgentSession {
|
|
|
6236
6326
|
// Billing-class failures never recover on this account, so the fallback
|
|
6237
6327
|
// switch pins as the session model instead of reverting after the cooldown.
|
|
6238
6328
|
const reason = isBillingErrorMessage(errorMessage) ? "billing" : "hard-error";
|
|
6239
|
-
switchedFallback = await
|
|
6240
|
-
errorMessage,
|
|
6241
|
-
});
|
|
6329
|
+
switchedFallback = await tryFallback(reason, { errorMessage });
|
|
6242
6330
|
if (!switchedFallback) {
|
|
6243
6331
|
const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
|
|
6244
6332
|
if (exhaustedChainKey) {
|
|
@@ -6271,7 +6359,7 @@ export class AgentSession {
|
|
|
6271
6359
|
this._resolveRetry();
|
|
6272
6360
|
return "not-handled";
|
|
6273
6361
|
}
|
|
6274
|
-
switchedFallback = await
|
|
6362
|
+
switchedFallback = await tryFallback("refusal", {});
|
|
6275
6363
|
if (!switchedFallback) {
|
|
6276
6364
|
const exhaustedChainKey = this._retryFallback.exhaustedChainKey;
|
|
6277
6365
|
if (exhaustedChainKey) {
|
|
@@ -6317,7 +6405,7 @@ export class AgentSession {
|
|
|
6317
6405
|
is429TierRouted = true;
|
|
6318
6406
|
this._retryAttempt++;
|
|
6319
6407
|
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
6320
|
-
switchedFallback = await
|
|
6408
|
+
switchedFallback = await tryFallback("transient", {
|
|
6321
6409
|
errorMessage,
|
|
6322
6410
|
retryAfterMs: this._getProviderRetryDelayMs(errorMessage),
|
|
6323
6411
|
});
|
|
@@ -6354,7 +6442,7 @@ export class AgentSession {
|
|
|
6354
6442
|
if (tier === "no-hint-fast-fallback") {
|
|
6355
6443
|
// Fall back immediately when a candidate exists; otherwise degrade
|
|
6356
6444
|
// to same-model in-turn retries instead of failing the turn.
|
|
6357
|
-
switchedFallback = await
|
|
6445
|
+
switchedFallback = await tryFallback("transient", { errorMessage });
|
|
6358
6446
|
if (switchedFallback) {
|
|
6359
6447
|
this._retryAttempt = 1;
|
|
6360
6448
|
}
|
|
@@ -6369,7 +6457,7 @@ export class AgentSession {
|
|
|
6369
6457
|
this._retryAttempt++;
|
|
6370
6458
|
if (this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
6371
6459
|
// Budget exhausted within tier1; fall back.
|
|
6372
|
-
switchedFallback = await
|
|
6460
|
+
switchedFallback = await tryFallback("transient", {
|
|
6373
6461
|
errorMessage,
|
|
6374
6462
|
retryAfterMs: this._getProviderRetryDelayMs(errorMessage),
|
|
6375
6463
|
});
|
|
@@ -6410,7 +6498,7 @@ export class AgentSession {
|
|
|
6410
6498
|
if (inTurnResult.demoteToProbeBack) {
|
|
6411
6499
|
// Cumulative hinted wait exceeded cap; demote to tier2 fallback path.
|
|
6412
6500
|
const remainingHintMs = Math.max(0, (this._hintDeadlineMs ?? Date.now()) - Date.now());
|
|
6413
|
-
switchedFallback = await
|
|
6501
|
+
switchedFallback = await tryFallback("transient", {
|
|
6414
6502
|
errorMessage,
|
|
6415
6503
|
retryAfterMs: remainingHintMs,
|
|
6416
6504
|
});
|
|
@@ -6446,7 +6534,7 @@ export class AgentSession {
|
|
|
6446
6534
|
else {
|
|
6447
6535
|
// tier2-fallback-probe-back or tier3-fallback-only: immediate fallback.
|
|
6448
6536
|
const remainingHintMs = hintMs ?? 0;
|
|
6449
|
-
switchedFallback = await
|
|
6537
|
+
switchedFallback = await tryFallback("transient", {
|
|
6450
6538
|
errorMessage,
|
|
6451
6539
|
retryAfterMs: remainingHintMs,
|
|
6452
6540
|
});
|
|
@@ -6469,7 +6557,7 @@ export class AgentSession {
|
|
|
6469
6557
|
this._retryAttempt++;
|
|
6470
6558
|
}
|
|
6471
6559
|
if (!is429TierRouted && this._retryAttempt > retryProfile.turn.maxRetries) {
|
|
6472
|
-
switchedFallback = await
|
|
6560
|
+
switchedFallback = await tryFallback("transient", {
|
|
6473
6561
|
errorMessage,
|
|
6474
6562
|
retryAfterMs: this._getProviderRetryDelayMs(errorMessage),
|
|
6475
6563
|
});
|
|
@@ -6513,7 +6601,7 @@ export class AgentSession {
|
|
|
6513
6601
|
// branch above may have already switched on this same error, and hopping again
|
|
6514
6602
|
// here would skip that candidate's own retry budget.
|
|
6515
6603
|
if (!switchedFallback) {
|
|
6516
|
-
switchedFallback = await
|
|
6604
|
+
switchedFallback = await tryFallback("transient", {
|
|
6517
6605
|
errorMessage,
|
|
6518
6606
|
retryAfterMs: providerDelayMs,
|
|
6519
6607
|
});
|
|
@@ -6595,7 +6683,7 @@ export class AgentSession {
|
|
|
6595
6683
|
// the prior retry checks. Revalidate canonical session context immediately
|
|
6596
6684
|
// before the continuation so a rejected compaction never admits that model.
|
|
6597
6685
|
const model = this.model;
|
|
6598
|
-
const compactionSettings = this.
|
|
6686
|
+
const compactionSettings = this._getCompactionSettings();
|
|
6599
6687
|
const contextTokens = estimateContextTokens(filterContextExcludedMessages(this.sessionManager.buildSessionContext().messages)).tokens;
|
|
6600
6688
|
if (compactionSettings.enabled &&
|
|
6601
6689
|
model &&
|