fix: address Cubic findings for runtime fallback child sessions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -30,7 +30,7 @@ declare function clearTimeout(timeout: TimerHandle): void
|
|||||||
>>>>>>> b6f740ed (fix: enable runtime fallback for delegated child sessions (#2357))
|
>>>>>>> b6f740ed (fix: enable runtime fallback for delegated child sessions (#2357))
|
||||||
|
|
||||||
export function createAutoRetryHelpers(deps: HookDeps) {
|
export function createAutoRetryHelpers(deps: HookDeps) {
|
||||||
const { ctx, config, options, sessionStates, sessionLastAccess, sessionRetryInFlight, sessionAwaitingFallbackResult, sessionFallbackTimeouts, pluginConfig } = deps
|
const { ctx, config, options, sessionStates, sessionLastAccess, sessionRetryInFlight, sessionAwaitingFallbackResult, sessionFallbackTimeouts, pluginConfig, sessionStatusRetryKeys } = deps
|
||||||
|
|
||||||
const abortSessionRequest = async (sessionID: string, source: string): Promise<void> => {
|
const abortSessionRequest = async (sessionID: string, source: string): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
@@ -201,6 +201,7 @@ export function createAutoRetryHelpers(deps: HookDeps) {
|
|||||||
sessionAwaitingFallbackResult.delete(sessionID)
|
sessionAwaitingFallbackResult.delete(sessionID)
|
||||||
clearSessionFallbackTimeout(sessionID)
|
clearSessionFallbackTimeout(sessionID)
|
||||||
SessionCategoryRegistry.remove(sessionID)
|
SessionCategoryRegistry.remove(sessionID)
|
||||||
|
sessionStatusRetryKeys.delete(sessionID)
|
||||||
cleanedCount++
|
cleanedCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
declare const require: (name: string) => any
|
import { describe, expect, test } from "bun:test"
|
||||||
const { describe, expect, test } = require("bun:test")
|
|
||||||
|
|
||||||
import { classifyErrorType, extractAutoRetrySignal, isRetryableError } from "./error-classifier"
|
import { classifyErrorType, extractAutoRetrySignal, isRetryableError } from "./error-classifier"
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import { dispatchFallbackRetry } from "./fallback-retry-dispatcher"
|
|||||||
import { createSessionStatusHandler } from "./session-status-handler"
|
import { createSessionStatusHandler } from "./session-status-handler"
|
||||||
|
|
||||||
export function createEventHandler(deps: HookDeps, helpers: AutoRetryHelpers) {
|
export function createEventHandler(deps: HookDeps, helpers: AutoRetryHelpers) {
|
||||||
const { config, pluginConfig, sessionStates, sessionLastAccess, sessionRetryInFlight, sessionAwaitingFallbackResult, sessionFallbackTimeouts } = deps
|
const { config, pluginConfig, sessionStates, sessionLastAccess, sessionRetryInFlight, sessionAwaitingFallbackResult, sessionFallbackTimeouts, sessionStatusRetryKeys } = deps
|
||||||
const sessionStatusRetryKeys = new Map<string, string>()
|
|
||||||
const sessionStatusHandler = createSessionStatusHandler(deps, helpers, sessionStatusRetryKeys)
|
const sessionStatusHandler = createSessionStatusHandler(deps, helpers, sessionStatusRetryKeys)
|
||||||
|
|
||||||
const handleSessionCreated = (props: Record<string, unknown> | undefined) => {
|
const handleSessionCreated = (props: Record<string, unknown> | undefined) => {
|
||||||
|
|||||||
@@ -32,6 +32,20 @@ export function resolveFallbackBootstrapModel(
|
|||||||
return agentModel
|
return agentModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const agentCategory = typeof agentConfig?.category === "string" ? agentConfig.category : undefined
|
||||||
|
if (agentCategory) {
|
||||||
|
const agentCategoryModel = options.pluginConfig?.categories?.[agentCategory]?.model
|
||||||
|
if (typeof agentCategoryModel === "string" && agentCategoryModel.length > 0) {
|
||||||
|
log(`[${HOOK_NAME}] Derived model from agent category config for ${options.source}`, {
|
||||||
|
sessionID: options.sessionID,
|
||||||
|
agent: options.resolvedAgent,
|
||||||
|
category: agentCategory,
|
||||||
|
model: agentCategoryModel,
|
||||||
|
})
|
||||||
|
return agentCategoryModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sessionCategory = SessionCategoryRegistry.get(options.sessionID)
|
const sessionCategory = SessionCategoryRegistry.get(options.sessionID)
|
||||||
const categoryModel = sessionCategory
|
const categoryModel = sessionCategory
|
||||||
? options.pluginConfig?.categories?.[sessionCategory]?.model
|
? options.pluginConfig?.categories?.[sessionCategory]?.model
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export function createRuntimeFallbackHook(
|
|||||||
sessionRetryInFlight: new Set(),
|
sessionRetryInFlight: new Set(),
|
||||||
sessionAwaitingFallbackResult: new Set(),
|
sessionAwaitingFallbackResult: new Set(),
|
||||||
sessionFallbackTimeouts: new Map(),
|
sessionFallbackTimeouts: new Map(),
|
||||||
|
sessionStatusRetryKeys: new Map(),
|
||||||
}
|
}
|
||||||
|
|
||||||
const helpers = createAutoRetryHelpers(deps)
|
const helpers = createAutoRetryHelpers(deps)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
declare const require: (name: string) => any
|
import { describe, expect, test, beforeEach, afterEach, spyOn } from "bun:test"
|
||||||
const { describe, expect, test, beforeEach, afterEach, spyOn } = require("bun:test")
|
|
||||||
import { createRuntimeFallbackHook } from "./index"
|
import { createRuntimeFallbackHook } from "./index"
|
||||||
import type { RuntimeFallbackConfig, OhMyOpenCodeConfig } from "../../config"
|
import type { RuntimeFallbackConfig, OhMyOpenCodeConfig } from "../../config"
|
||||||
import * as sharedModule from "../../shared"
|
import * as sharedModule from "../../shared"
|
||||||
|
|||||||
@@ -1,14 +1,22 @@
|
|||||||
type SessionMessagesResponse = {
|
type MessageItem = {
|
||||||
data?: Array<{
|
info?: Record<string, unknown>
|
||||||
info?: Record<string, unknown>
|
parts?: Array<{ type?: string; text?: string }>
|
||||||
parts?: Array<{ type?: string; text?: string }>
|
}
|
||||||
}>
|
|
||||||
|
function extractMessages(messagesResponse: unknown): MessageItem[] | undefined {
|
||||||
|
if (messagesResponse == null) return undefined
|
||||||
|
if (Array.isArray(messagesResponse)) return messagesResponse as MessageItem[]
|
||||||
|
if (typeof messagesResponse === "object") {
|
||||||
|
const data = (messagesResponse as Record<string, unknown>).data
|
||||||
|
if (Array.isArray(data)) return data as MessageItem[]
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLastUserRetryParts(
|
export function getLastUserRetryParts(
|
||||||
messagesResponse: unknown,
|
messagesResponse: unknown,
|
||||||
): Array<{ type: "text"; text: string }> {
|
): Array<{ type: "text"; text: string }> {
|
||||||
const messages = (messagesResponse as SessionMessagesResponse).data
|
const messages = extractMessages(messagesResponse)
|
||||||
const lastUserMessage = messages?.filter((message) => message.info?.role === "user").pop()
|
const lastUserMessage = messages?.filter((message) => message.info?.role === "user").pop()
|
||||||
const lastUserParts =
|
const lastUserParts =
|
||||||
lastUserMessage?.parts
|
lastUserMessage?.parts
|
||||||
|
|||||||
@@ -72,11 +72,6 @@ export interface HookDeps {
|
|||||||
sessionLastAccess: Map<string, number>
|
sessionLastAccess: Map<string, number>
|
||||||
sessionRetryInFlight: Set<string>
|
sessionRetryInFlight: Set<string>
|
||||||
sessionAwaitingFallbackResult: Set<string>
|
sessionAwaitingFallbackResult: Set<string>
|
||||||
<<<<<<< HEAD
|
|
||||||
sessionFallbackTimeouts: Map<string, RuntimeFallbackTimeout>
|
sessionFallbackTimeouts: Map<string, RuntimeFallbackTimeout>
|
||||||
||||||| parent of b6f740ed (fix: enable runtime fallback for delegated child sessions (#2357))
|
sessionStatusRetryKeys: Map<string, string>
|
||||||
sessionFallbackTimeouts: Map<string, ReturnType<typeof setTimeout>>
|
|
||||||
=======
|
|
||||||
sessionFallbackTimeouts: Map<string, TimerHandle>
|
|
||||||
>>>>>>> b6f740ed (fix: enable runtime fallback for delegated child sessions (#2357))
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user