fix: address systems review findings for agent-not-found fallback
1. [HIGH] Tool restrictions recomputed for fallback agent via buildFallbackBody() — no longer inherits original agent's restrictions. 2. [HIGH] Double-retry race prevented — handleSessionErrorEvent now returns early for agent-not-found errors, since the prompt catch block already handles them with agent fallback. This prevents tryFallbackRetry from racing with a model-level retry on the same error (the "not found" pattern in RETRYABLE_MESSAGE_PATTERNS). 3. [MEDIUM] task.agent updated to FALLBACK_AGENT after successful fallback — notifications, toast, and logging reflect actual agent. 4. [MEDIUM] FALLBACK_AGENT exported from spawner.ts and imported into manager.ts — single source of truth. 5. [LOW] resumeTask fallback now uses promptWithModelSuggestionRetry (consistent with startTask), getting timeout protection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,13 +8,29 @@ import { getTaskToastManager } from "../task-toast-manager"
|
||||
import { isInsideTmux } from "../../shared/tmux"
|
||||
import type { ConcurrencyManager } from "./concurrency"
|
||||
|
||||
const FALLBACK_AGENT = "general"
|
||||
export const FALLBACK_AGENT = "general"
|
||||
|
||||
export function isAgentNotFoundError(error: unknown): boolean {
|
||||
const message = error instanceof Error ? error.message : String(error)
|
||||
return message.includes("Agent not found")
|
||||
}
|
||||
|
||||
export function buildFallbackBody(
|
||||
originalBody: Record<string, unknown>,
|
||||
fallbackAgent: string,
|
||||
): Record<string, unknown> {
|
||||
return {
|
||||
...originalBody,
|
||||
agent: fallbackAgent,
|
||||
tools: {
|
||||
task: false,
|
||||
call_omo_agent: true,
|
||||
question: false,
|
||||
...getAgentToolRestrictions(fallbackAgent),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export interface SpawnerContext {
|
||||
client: OpencodeClient
|
||||
directory: string
|
||||
@@ -172,8 +188,9 @@ export async function startTask(
|
||||
try {
|
||||
await promptWithModelSuggestionRetry(client, {
|
||||
path: { id: sessionID },
|
||||
body: { ...promptBody, agent: FALLBACK_AGENT },
|
||||
body: buildFallbackBody(promptBody, FALLBACK_AGENT),
|
||||
})
|
||||
task.agent = FALLBACK_AGENT
|
||||
return
|
||||
} catch (retryError) {
|
||||
log("[background-agent] Fallback agent also failed:", retryError)
|
||||
@@ -279,10 +296,11 @@ export async function resumeTask(
|
||||
taskId: task.id,
|
||||
})
|
||||
try {
|
||||
await client.session.promptAsync({
|
||||
await promptWithModelSuggestionRetry(client, {
|
||||
path: { id: task.sessionID! },
|
||||
body: { ...resumeBody, agent: FALLBACK_AGENT },
|
||||
body: buildFallbackBody(resumeBody, FALLBACK_AGENT),
|
||||
})
|
||||
task.agent = FALLBACK_AGENT
|
||||
return
|
||||
} catch (retryError) {
|
||||
log("[background-agent] Resume fallback agent also failed:", retryError)
|
||||
|
||||
Reference in New Issue
Block a user