Consolidate duplicate patterns and simplify codebase (#1317)
* refactor(shared): unify binary downloader and session path storage - Create binary-downloader.ts for common download/extract logic - Create session-injected-paths.ts for unified path tracking - Refactor comment-checker, ast-grep, grep downloaders to use shared util - Consolidate directory injector types into shared module * feat(shared): implement unified model resolution pipeline - Create ModelResolutionPipeline for centralized model selection - Refactor model-resolver to use pipeline - Update delegate-task and config-handler to use unified logic - Ensure consistent model resolution across all agent types * refactor(agents): simplify agent utils and metadata management - Extract helper functions for config merging and env context - Register prompt metadata for all agents - Simplify agent variant detection logic * cleanup: inline utilities and remove unused exports - Remove case-insensitive.ts (inline with native JS) - Simplify opencode-version helpers - Remove unused getModelLimit, createCompactionContextInjector exports - Inline transcript entry creation in claude-code-hooks - Update tests accordingly --------- Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||
import type { AgentMode } from "./types"
|
||||
import type { AgentMode, AgentPromptMetadata } from "./types"
|
||||
import { isGptModel } from "./types"
|
||||
|
||||
const MODE: AgentMode = "primary"
|
||||
export const SISYPHUS_PROMPT_METADATA: AgentPromptMetadata = {
|
||||
category: "utility",
|
||||
cost: "EXPENSIVE",
|
||||
promptAlias: "Sisyphus",
|
||||
triggers: [],
|
||||
}
|
||||
import type { AvailableAgent, AvailableTool, AvailableSkill, AvailableCategory } from "./dynamic-agent-prompt-builder"
|
||||
import {
|
||||
buildKeyTriggersSection,
|
||||
|
||||
+61
-40
@@ -6,11 +6,11 @@ import { createOracleAgent, ORACLE_PROMPT_METADATA } from "./oracle"
|
||||
import { createLibrarianAgent, LIBRARIAN_PROMPT_METADATA } from "./librarian"
|
||||
import { createExploreAgent, EXPLORE_PROMPT_METADATA } from "./explore"
|
||||
import { createMultimodalLookerAgent, MULTIMODAL_LOOKER_PROMPT_METADATA } from "./multimodal-looker"
|
||||
import { createMetisAgent } from "./metis"
|
||||
import { createAtlasAgent } from "./atlas"
|
||||
import { createMomusAgent } from "./momus"
|
||||
import { createMetisAgent, metisPromptMetadata } from "./metis"
|
||||
import { createAtlasAgent, atlasPromptMetadata } from "./atlas"
|
||||
import { createMomusAgent, momusPromptMetadata } from "./momus"
|
||||
import type { AvailableAgent, AvailableCategory, AvailableSkill } from "./dynamic-agent-prompt-builder"
|
||||
import { deepMerge, fetchAvailableModels, resolveModelWithFallback, AGENT_MODEL_REQUIREMENTS, findCaseInsensitive, includesCaseInsensitive, readConnectedProvidersCache, isModelAvailable } from "../shared"
|
||||
import { deepMerge, fetchAvailableModels, resolveModelPipeline, AGENT_MODEL_REQUIREMENTS, readConnectedProvidersCache, isModelAvailable } from "../shared"
|
||||
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
|
||||
import { resolveMultipleSkills } from "../features/opencode-skill-loader/skill-content"
|
||||
import { createBuiltinSkills } from "../features/builtin-skills"
|
||||
@@ -41,6 +41,9 @@ const agentMetadata: Partial<Record<BuiltinAgentName, AgentPromptMetadata>> = {
|
||||
librarian: LIBRARIAN_PROMPT_METADATA,
|
||||
explore: EXPLORE_PROMPT_METADATA,
|
||||
"multimodal-looker": MULTIMODAL_LOOKER_PROMPT_METADATA,
|
||||
metis: metisPromptMetadata,
|
||||
momus: momusPromptMetadata,
|
||||
atlas: atlasPromptMetadata,
|
||||
}
|
||||
|
||||
function isFactory(source: AgentSource): source is AgentFactory {
|
||||
@@ -147,6 +150,45 @@ function applyCategoryOverride(
|
||||
return result as AgentConfig
|
||||
}
|
||||
|
||||
function applyModelResolution(input: {
|
||||
uiSelectedModel?: string
|
||||
userModel?: string
|
||||
requirement?: { fallbackChain?: { providers: string[]; model: string; variant?: string }[] }
|
||||
availableModels: Set<string>
|
||||
systemDefaultModel?: string
|
||||
}) {
|
||||
const { uiSelectedModel, userModel, requirement, availableModels, systemDefaultModel } = input
|
||||
return resolveModelPipeline({
|
||||
intent: { uiSelectedModel, userModel },
|
||||
constraints: { availableModels },
|
||||
policy: { fallbackChain: requirement?.fallbackChain, systemDefaultModel },
|
||||
})
|
||||
}
|
||||
|
||||
function applyEnvironmentContext(config: AgentConfig, directory?: string): AgentConfig {
|
||||
if (!directory || !config.prompt) return config
|
||||
const envContext = createEnvContext()
|
||||
return { ...config, prompt: config.prompt + envContext }
|
||||
}
|
||||
|
||||
function applyOverrides(
|
||||
config: AgentConfig,
|
||||
override: AgentOverrideConfig | undefined,
|
||||
mergedCategories: Record<string, CategoryConfig>
|
||||
): AgentConfig {
|
||||
let result = config
|
||||
const overrideCategory = (override as Record<string, unknown> | undefined)?.category as string | undefined
|
||||
if (overrideCategory) {
|
||||
result = applyCategoryOverride(result, overrideCategory, mergedCategories)
|
||||
}
|
||||
|
||||
if (override) {
|
||||
result = mergeAgentConfig(result, override)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function mergeAgentConfig(
|
||||
base: AgentConfig,
|
||||
override: AgentOverrideConfig
|
||||
@@ -223,9 +265,10 @@ export async function createBuiltinAgents(
|
||||
|
||||
if (agentName === "sisyphus") continue
|
||||
if (agentName === "atlas") continue
|
||||
if (includesCaseInsensitive(disabledAgents, agentName)) continue
|
||||
if (disabledAgents.some((name) => name.toLowerCase() === agentName.toLowerCase())) continue
|
||||
|
||||
const override = findCaseInsensitive(agentOverrides, agentName)
|
||||
const override = agentOverrides[agentName]
|
||||
?? Object.entries(agentOverrides).find(([key]) => key.toLowerCase() === agentName.toLowerCase())?.[1]
|
||||
const requirement = AGENT_MODEL_REQUIREMENTS[agentName]
|
||||
|
||||
// Check if agent requires a specific model
|
||||
@@ -237,10 +280,10 @@ export async function createBuiltinAgents(
|
||||
|
||||
const isPrimaryAgent = isFactory(source) && source.mode === "primary"
|
||||
|
||||
const resolution = resolveModelWithFallback({
|
||||
const resolution = applyModelResolution({
|
||||
uiSelectedModel: isPrimaryAgent ? uiSelectedModel : undefined,
|
||||
userModel: override?.model,
|
||||
fallbackChain: requirement?.fallbackChain,
|
||||
requirement,
|
||||
availableModels,
|
||||
systemDefaultModel,
|
||||
})
|
||||
@@ -260,15 +303,11 @@ export async function createBuiltinAgents(
|
||||
config = applyCategoryOverride(config, overrideCategory, mergedCategories)
|
||||
}
|
||||
|
||||
if (agentName === "librarian" && directory && config.prompt) {
|
||||
const envContext = createEnvContext()
|
||||
config = { ...config, prompt: config.prompt + envContext }
|
||||
if (agentName === "librarian") {
|
||||
config = applyEnvironmentContext(config, directory)
|
||||
}
|
||||
|
||||
// Direct override properties take highest priority
|
||||
if (override) {
|
||||
config = mergeAgentConfig(config, override)
|
||||
}
|
||||
config = applyOverrides(config, override, mergedCategories)
|
||||
|
||||
result[name] = config
|
||||
|
||||
@@ -286,10 +325,10 @@ export async function createBuiltinAgents(
|
||||
const sisyphusOverride = agentOverrides["sisyphus"]
|
||||
const sisyphusRequirement = AGENT_MODEL_REQUIREMENTS["sisyphus"]
|
||||
|
||||
const sisyphusResolution = resolveModelWithFallback({
|
||||
const sisyphusResolution = applyModelResolution({
|
||||
uiSelectedModel,
|
||||
userModel: sisyphusOverride?.model,
|
||||
fallbackChain: sisyphusRequirement?.fallbackChain,
|
||||
requirement: sisyphusRequirement,
|
||||
availableModels,
|
||||
systemDefaultModel,
|
||||
})
|
||||
@@ -309,19 +348,8 @@ export async function createBuiltinAgents(
|
||||
sisyphusConfig = { ...sisyphusConfig, variant: sisyphusResolvedVariant }
|
||||
}
|
||||
|
||||
const sisOverrideCategory = (sisyphusOverride as Record<string, unknown> | undefined)?.category as string | undefined
|
||||
if (sisOverrideCategory) {
|
||||
sisyphusConfig = applyCategoryOverride(sisyphusConfig, sisOverrideCategory, mergedCategories)
|
||||
}
|
||||
|
||||
if (directory && sisyphusConfig.prompt) {
|
||||
const envContext = createEnvContext()
|
||||
sisyphusConfig = { ...sisyphusConfig, prompt: sisyphusConfig.prompt + envContext }
|
||||
}
|
||||
|
||||
if (sisyphusOverride) {
|
||||
sisyphusConfig = mergeAgentConfig(sisyphusConfig, sisyphusOverride)
|
||||
}
|
||||
sisyphusConfig = applyOverrides(sisyphusConfig, sisyphusOverride, mergedCategories)
|
||||
sisyphusConfig = applyEnvironmentContext(sisyphusConfig, directory)
|
||||
|
||||
result["sisyphus"] = sisyphusConfig
|
||||
}
|
||||
@@ -331,10 +359,10 @@ export async function createBuiltinAgents(
|
||||
const orchestratorOverride = agentOverrides["atlas"]
|
||||
const atlasRequirement = AGENT_MODEL_REQUIREMENTS["atlas"]
|
||||
|
||||
const atlasResolution = resolveModelWithFallback({
|
||||
const atlasResolution = applyModelResolution({
|
||||
// NOTE: Atlas does NOT use uiSelectedModel - respects its own fallbackChain (k2p5 primary)
|
||||
userModel: orchestratorOverride?.model,
|
||||
fallbackChain: atlasRequirement?.fallbackChain,
|
||||
requirement: atlasRequirement,
|
||||
availableModels,
|
||||
systemDefaultModel,
|
||||
})
|
||||
@@ -353,14 +381,7 @@ export async function createBuiltinAgents(
|
||||
orchestratorConfig = { ...orchestratorConfig, variant: atlasResolvedVariant }
|
||||
}
|
||||
|
||||
const atlasOverrideCategory = (orchestratorOverride as Record<string, unknown> | undefined)?.category as string | undefined
|
||||
if (atlasOverrideCategory) {
|
||||
orchestratorConfig = applyCategoryOverride(orchestratorConfig, atlasOverrideCategory, mergedCategories)
|
||||
}
|
||||
|
||||
if (orchestratorOverride) {
|
||||
orchestratorConfig = mergeAgentConfig(orchestratorConfig, orchestratorOverride)
|
||||
}
|
||||
orchestratorConfig = applyOverrides(orchestratorConfig, orchestratorOverride, mergedCategories)
|
||||
|
||||
result["atlas"] = orchestratorConfig
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user