feat(categories): add disable field to CategoryConfigSchema

Allow individual categories to be disabled via `disable: true` in
config. Introduce shared `mergeCategories()` utility to centralize
category merging and disabled filtering across all 7 consumption sites.
This commit is contained in:
YeonGyu-Kim
2026-02-11 13:52:06 +09:00
parent 67b4665c28
commit bfe1730e9f
11 changed files with 131 additions and 29 deletions
+2 -4
View File
@@ -2,7 +2,7 @@ import type { AgentConfig } from "@opencode-ai/sdk"
import type { AgentFactory } from "./types"
import type { CategoriesConfig, CategoryConfig, GitMasterConfig } from "../config/schema"
import type { BrowserAutomationProvider } from "../config/schema"
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants"
import { mergeCategories } from "../shared/merge-categories"
import { resolveMultipleSkills } from "../features/opencode-skill-loader/skill-content"
export type AgentSource = AgentFactory | AgentConfig
@@ -20,9 +20,7 @@ export function buildAgent(
disabledSkills?: Set<string>
): AgentConfig {
const base = isFactory(source) ? source(model) : { ...source }
const categoryConfigs: Record<string, CategoryConfig> = categories
? { ...DEFAULT_CATEGORIES, ...categories }
: DEFAULT_CATEGORIES
const categoryConfigs: Record<string, CategoryConfig> = mergeCategories(categories)
const agentWithCategory = base as AgentConfig & { category?: string; skills?: string[]; variant?: string }
if (agentWithCategory.category) {
+2 -2
View File
@@ -15,7 +15,7 @@ import { isGptModel } from "../types"
import type { AvailableAgent, AvailableSkill, AvailableCategory } from "../dynamic-agent-prompt-builder"
import { buildCategorySkillsDelegationGuide } from "../dynamic-agent-prompt-builder"
import type { CategoryConfig } from "../../config/schema"
import { DEFAULT_CATEGORIES } from "../../tools/delegate-task/constants"
import { mergeCategories } from "../../shared/merge-categories"
import { createAgentToolRestrictions } from "../../shared/permission-compat"
import { getDefaultAtlasPrompt } from "./default"
@@ -70,7 +70,7 @@ function buildDynamicOrchestratorPrompt(ctx?: OrchestratorContext): string {
const userCategories = ctx?.userCategories
const model = ctx?.model
const allCategories = { ...DEFAULT_CATEGORIES, ...userCategories }
const allCategories = mergeCategories(userCategories)
const availableCategories: AvailableCategory[] = Object.entries(allCategories).map(([name]) => ({
name,
description: getCategoryDescription(name, userCategories),
+4 -3
View File
@@ -7,7 +7,8 @@
import type { CategoryConfig } from "../../config/schema"
import { formatCustomSkillsBlock, type AvailableAgent, type AvailableSkill } from "../dynamic-agent-prompt-builder"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants"
import { CATEGORY_DESCRIPTIONS } from "../../tools/delegate-task/constants"
import { mergeCategories } from "../../shared/merge-categories"
import { truncateDescription } from "../../shared/truncate-description"
export const getCategoryDescription = (name: string, userCategories?: Record<string, CategoryConfig>) =>
@@ -33,7 +34,7 @@ ${rows.join("\n")}`
}
export function buildCategorySection(userCategories?: Record<string, CategoryConfig>): string {
const allCategories = { ...DEFAULT_CATEGORIES, ...userCategories }
const allCategories = mergeCategories(userCategories)
const categoryRows = Object.entries(allCategories).map(([name, config]) => {
const temp = config.temperature ?? 0.5
return `| \`${name}\` | ${temp} | ${getCategoryDescription(name, userCategories)} |`
@@ -116,7 +117,7 @@ task(category="[category]", load_skills=["skill-1", "skill-2"], run_in_backgroun
}
export function buildDecisionMatrix(agents: AvailableAgent[], userCategories?: Record<string, CategoryConfig>): string {
const allCategories = { ...DEFAULT_CATEGORIES, ...userCategories }
const allCategories = mergeCategories(userCategories)
const categoryRows = Object.entries(allCategories).map(([name]) =>
`| ${getCategoryDescription(name, userCategories)} | \`category="${name}", load_skills=[...]\` |`
+3 -4
View File
@@ -14,7 +14,8 @@ import { createMomusAgent, momusPromptMetadata } from "./momus"
import { createHephaestusAgent } from "./hephaestus"
import type { AvailableCategory } from "./dynamic-agent-prompt-builder"
import { fetchAvailableModels, readConnectedProvidersCache } from "../shared"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
import { CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
import { mergeCategories } from "../shared/merge-categories"
import { buildAvailableSkills } from "./builtin-agents/available-skills"
import { collectPendingBuiltinAgents } from "./builtin-agents/general-agents"
import { maybeCreateSisyphusConfig } from "./builtin-agents/sisyphus-agent"
@@ -78,9 +79,7 @@ export async function createBuiltinAgents(
const result: Record<string, AgentConfig> = {}
const mergedCategories = categories
? { ...DEFAULT_CATEGORIES, ...categories }
: DEFAULT_CATEGORIES
const mergedCategories = mergeCategories(categories)
const availableCategories: AvailableCategory[] = Object.entries(mergedCategories).map(([name]) => ({
name,