fix: resolve 3 community-reported bugs (#2915, #2917, #2918)

- background_output: snapshot read cursor before consuming, restore on
  /undo message removal so re-reads return data (fixes #2915)
- MCP loader: preserve oauth field in transformMcpServer, add scope/
  projectPath filtering so local-scoped MCPs only load in matching
  directories (fixes #2917)
- runtime-fallback: add 'reached your usage limit' to retryable error
  patterns so quota exhaustion triggers model fallback (fixes #2918)

Verified: bun test (4606 pass / 0 fail), tsc --noEmit clean
This commit is contained in:
YeonGyu-Kim
2026-03-29 04:53:36 +09:00
parent 9fc56ab544
commit b2497f1327
16 changed files with 575 additions and 6 deletions
+13
View File
@@ -17,6 +17,11 @@ import {
setPendingModelFallback,
} from "../hooks/model-fallback/hook";
import { getRawFallbackModels } from "../hooks/runtime-fallback/fallback-models";
import {
clearBackgroundOutputConsumptionsForParentSession,
clearBackgroundOutputConsumptionsForTaskSession,
restoreBackgroundOutputConsumption,
} from "../shared/background-output-consumption";
import { resetMessageCursor } from "../shared";
import { getAgentConfigKey } from "../shared/agent-display-names";
import { readConnectedProvidersCache } from "../shared/connected-providers-cache";
@@ -366,6 +371,8 @@ export function createEventHandler(args: {
clearPendingModelFallback(sessionInfo.id);
clearSessionFallbackChain(sessionInfo.id);
resetMessageCursor(sessionInfo.id);
clearBackgroundOutputConsumptionsForParentSession(sessionInfo.id);
clearBackgroundOutputConsumptionsForTaskSession(sessionInfo.id);
firstMessageVariantGate.clear(sessionInfo.id);
clearSessionModel(sessionInfo.id);
clearSessionPromptParams(sessionInfo.id);
@@ -382,6 +389,12 @@ export function createEventHandler(args: {
}
}
if (event.type === "message.removed") {
const messageID = props?.messageID as string | undefined;
const sessionID = props?.sessionID as string | undefined;
restoreBackgroundOutputConsumption(sessionID, messageID);
}
if (event.type === "message.updated") {
const info = props?.info as Record<string, unknown> | undefined;
const sessionID = info?.sessionID as string | undefined;