Files
oh-my-opencode/src/hooks/compaction-context-injector/recovery-prompt-config.ts
T
YeonGyu-Kim 62c60ae9d8 fix: numeric skill names, ultrawork missing run_in_background, ZWSP agent lookups
- #3354: Coerce data.name to String in loadSkillFromPath/loadSkillFromPathAsync
  to prevent crash when YAML parses numeric skill names (e.g., name: 12306)

- #3416: Add required run_in_background parameter to all task() examples in
  ultrawork prompts (default, gpt, gemini, planner) to match tool schema

- #3379/#3417/#3418/#3337/#3335: Strip ZWSP (U+200B) before agent name
  comparisons in agent-tool-restrictions, sync-prompt-sender, tool-execute-after,
  tool-execute-before, oracle-verification-detector, call-omo-agent,
  recovery-prompt-config, and agent-variant to prevent ZWSP-prefixed display
  names from breaking exact-match lookups
2026-04-15 10:46:41 +09:00

78 lines
2.3 KiB
TypeScript

import { stripInvisibleAgentCharacters } from "../../shared/agent-display-names"
import type { CompactionAgentConfigCheckpoint } from "../../shared/compaction-agent-config-checkpoint"
export type RecoveryPromptConfig = CompactionAgentConfigCheckpoint & {
agent: string
}
function isCompactionAgent(agent: string | undefined): boolean {
return agent?.trim().toLowerCase() === "compaction"
}
function matchesExpectedModel(
actualModel: CompactionAgentConfigCheckpoint["model"],
expectedModel: CompactionAgentConfigCheckpoint["model"],
): boolean {
if (!expectedModel) {
return true
}
return (
actualModel?.providerID === expectedModel.providerID &&
actualModel.modelID === expectedModel.modelID
)
}
function matchesExpectedTools(
actualTools: CompactionAgentConfigCheckpoint["tools"],
expectedTools: CompactionAgentConfigCheckpoint["tools"],
): boolean {
if (!expectedTools) {
return true
}
if (!actualTools) {
return false
}
const expectedEntries = Object.entries(expectedTools)
if (expectedEntries.length !== Object.keys(actualTools).length) {
return false
}
return expectedEntries.every(
([toolName, isAllowed]) => actualTools[toolName] === isAllowed,
)
}
export function createExpectedRecoveryPromptConfig(
checkpoint: Pick<RecoveryPromptConfig, "agent"> & CompactionAgentConfigCheckpoint,
currentPromptConfig: CompactionAgentConfigCheckpoint,
): RecoveryPromptConfig {
const model = checkpoint.model ?? currentPromptConfig.model
const tools = checkpoint.tools ?? currentPromptConfig.tools
return {
agent: checkpoint.agent,
...(model ? { model } : {}),
...(tools ? { tools } : {}),
}
}
export function isPromptConfigRecovered(
actualPromptConfig: CompactionAgentConfigCheckpoint,
expectedPromptConfig: RecoveryPromptConfig,
): boolean {
const actualAgent = actualPromptConfig.agent
const agentMatches =
typeof actualAgent === "string" &&
!isCompactionAgent(actualAgent) &&
stripInvisibleAgentCharacters(actualAgent).toLowerCase() === stripInvisibleAgentCharacters(expectedPromptConfig.agent).toLowerCase()
return (
agentMatches &&
matchesExpectedModel(actualPromptConfig.model, expectedPromptConfig.model) &&
matchesExpectedTools(actualPromptConfig.tools, expectedPromptConfig.tools)
)
}