fix(config): allow Sisyphus-Junior agent customization via oh-my-opencode.json (#648)
* fix(config): allow Sisyphus-Junior agent customization via oh-my-opencode.json Allow users to configure Sisyphus-Junior agent via agents["Sisyphus-Junior"] in oh-my-opencode.json, removing hardcoded defaults while preserving safety constraints. Closes #623 Changes: - Add "Sisyphus-Junior" to AgentOverridesSchema and OverridableAgentNameSchema - Create createSisyphusJuniorAgentWithOverrides() helper with guardrails - Update config-handler to use override helper instead of hardcoded values - Fix README category wording (runtime presets, not separate agents) Honored override fields: - model, temperature, top_p, tools, permission, description, color, prompt_append Safety guardrails enforced post-merge: - mode forced to "subagent" (cannot change) - prompt is append-only (base discipline text preserved) - blocked tools (task, sisyphus_task, call_omo_agent) always denied - disable: true ignores override block, uses defaults Category interaction: - sisyphus_task(category=...) runs use the base Sisyphus-Junior agent config - Category model/temperature overrides take precedence at request time - To change model for a category, set categories.<cat>.model (not agent override) - Categories are runtime presets applied to Sisyphus-Junior, not separate agents Tests: 15 new tests in sisyphus-junior.test.ts, 3 new schema tests Co-Authored-By: Sisyphus <sisyphus@mengmota.com> * test(sisyphus-junior): add guard assertion for prompt anchor text Add validation that baseEndIndex is not -1 before using it for ordering assertion. Previously, if "Dense > verbose." text changed in the base prompt, indexOf would return -1 and any positive appendIndex would pass. Co-Authored-By: Sisyphus <sisyphus@mengmota.com> --------- Co-authored-by: Sisyphus <sisyphus@mengmota.com>
This commit is contained in:
parent
c79235744b
commit
0fada4d0fc
@ -1058,7 +1058,7 @@ Configure concurrency limits for background agent tasks. This controls how many
|
|||||||
|
|
||||||
### Categories
|
### Categories
|
||||||
|
|
||||||
Categories enable domain-specific task delegation via the `sisyphus_task` tool. Each category pre-configures a specialized `Sisyphus-Junior-{category}` agent with optimized model settings and prompts.
|
Categories enable domain-specific task delegation via the `sisyphus_task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent.
|
||||||
|
|
||||||
**Default Categories:**
|
**Default Categories:**
|
||||||
|
|
||||||
|
|||||||
@ -465,6 +465,129 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Sisyphus-Junior": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"model": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"skills": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 2
|
||||||
|
},
|
||||||
|
"top_p": {
|
||||||
|
"type": "number",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 1
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"prompt_append": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"type": "object",
|
||||||
|
"propertyNames": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"disable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"subagent",
|
||||||
|
"primary",
|
||||||
|
"all"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^#[0-9A-Fa-f]{6}$"
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"edit": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bash": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"propertyNames": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"webfetch": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"doom_loop": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"external_directory": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"ask",
|
||||||
|
"allow",
|
||||||
|
"deny"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"OpenCode-Builder": {
|
"OpenCode-Builder": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
230
src/agents/sisyphus-junior.test.ts
Normal file
230
src/agents/sisyphus-junior.test.ts
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import { describe, expect, test } from "bun:test"
|
||||||
|
import { createSisyphusJuniorAgentWithOverrides, SISYPHUS_JUNIOR_DEFAULTS } from "./sisyphus-junior"
|
||||||
|
|
||||||
|
describe("createSisyphusJuniorAgentWithOverrides", () => {
|
||||||
|
describe("honored fields", () => {
|
||||||
|
test("applies model override", () => {
|
||||||
|
// #given
|
||||||
|
const override = { model: "openai/gpt-5.2" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.model).toBe("openai/gpt-5.2")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("applies temperature override", () => {
|
||||||
|
// #given
|
||||||
|
const override = { temperature: 0.5 }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.temperature).toBe(0.5)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("applies top_p override", () => {
|
||||||
|
// #given
|
||||||
|
const override = { top_p: 0.9 }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.top_p).toBe(0.9)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("applies description override", () => {
|
||||||
|
// #given
|
||||||
|
const override = { description: "Custom description" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.description).toBe("Custom description")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("applies color override", () => {
|
||||||
|
// #given
|
||||||
|
const override = { color: "#FF0000" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.color).toBe("#FF0000")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("appends prompt_append to base prompt", () => {
|
||||||
|
// #given
|
||||||
|
const override = { prompt_append: "Extra instructions here" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.prompt).toContain("You work ALONE")
|
||||||
|
expect(result.prompt).toContain("Extra instructions here")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("defaults", () => {
|
||||||
|
test("uses default model when no override", () => {
|
||||||
|
// #given
|
||||||
|
const override = {}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.model).toBe(SISYPHUS_JUNIOR_DEFAULTS.model)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("uses default temperature when no override", () => {
|
||||||
|
// #given
|
||||||
|
const override = {}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.temperature).toBe(SISYPHUS_JUNIOR_DEFAULTS.temperature)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("disable semantics", () => {
|
||||||
|
test("disable: true causes override block to be ignored", () => {
|
||||||
|
// #given
|
||||||
|
const override = {
|
||||||
|
disable: true,
|
||||||
|
model: "openai/gpt-5.2",
|
||||||
|
temperature: 0.9,
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then - defaults should be used, not the overrides
|
||||||
|
expect(result.model).toBe(SISYPHUS_JUNIOR_DEFAULTS.model)
|
||||||
|
expect(result.temperature).toBe(SISYPHUS_JUNIOR_DEFAULTS.temperature)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("constrained fields", () => {
|
||||||
|
test("mode is forced to subagent", () => {
|
||||||
|
// #given
|
||||||
|
const override = { mode: "primary" as const }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.mode).toBe("subagent")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("prompt override is ignored (discipline text preserved)", () => {
|
||||||
|
// #given
|
||||||
|
const override = { prompt: "Completely new prompt that replaces everything" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.prompt).toContain("You work ALONE")
|
||||||
|
expect(result.prompt).not.toBe("Completely new prompt that replaces everything")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("tool safety (blocked tools enforcement)", () => {
|
||||||
|
test("blocked tools remain blocked even if override tries to enable them via tools format", () => {
|
||||||
|
// #given
|
||||||
|
const override = {
|
||||||
|
tools: {
|
||||||
|
task: true,
|
||||||
|
sisyphus_task: true,
|
||||||
|
call_omo_agent: true,
|
||||||
|
read: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
const tools = result.tools as Record<string, boolean> | undefined
|
||||||
|
const permission = result.permission as Record<string, string> | undefined
|
||||||
|
if (tools) {
|
||||||
|
expect(tools.task).toBe(false)
|
||||||
|
expect(tools.sisyphus_task).toBe(false)
|
||||||
|
expect(tools.call_omo_agent).toBe(false)
|
||||||
|
expect(tools.read).toBe(true)
|
||||||
|
}
|
||||||
|
if (permission) {
|
||||||
|
expect(permission.task).toBe("deny")
|
||||||
|
expect(permission.sisyphus_task).toBe("deny")
|
||||||
|
expect(permission.call_omo_agent).toBe("deny")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("blocked tools remain blocked when using permission format override", () => {
|
||||||
|
// #given
|
||||||
|
const override = {
|
||||||
|
permission: {
|
||||||
|
task: "allow",
|
||||||
|
sisyphus_task: "allow",
|
||||||
|
call_omo_agent: "allow",
|
||||||
|
read: "allow",
|
||||||
|
},
|
||||||
|
} as { permission: Record<string, string> }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override as Parameters<typeof createSisyphusJuniorAgentWithOverrides>[0])
|
||||||
|
|
||||||
|
// #then - blocked tools should be denied regardless
|
||||||
|
const tools = result.tools as Record<string, boolean> | undefined
|
||||||
|
const permission = result.permission as Record<string, string> | undefined
|
||||||
|
if (tools) {
|
||||||
|
expect(tools.task).toBe(false)
|
||||||
|
expect(tools.sisyphus_task).toBe(false)
|
||||||
|
expect(tools.call_omo_agent).toBe(false)
|
||||||
|
}
|
||||||
|
if (permission) {
|
||||||
|
expect(permission.task).toBe("deny")
|
||||||
|
expect(permission.sisyphus_task).toBe("deny")
|
||||||
|
expect(permission.call_omo_agent).toBe("deny")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("prompt composition", () => {
|
||||||
|
test("base prompt contains discipline constraints", () => {
|
||||||
|
// #given
|
||||||
|
const override = {}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.prompt).toContain("Sisyphus-Junior")
|
||||||
|
expect(result.prompt).toContain("You work ALONE")
|
||||||
|
expect(result.prompt).toContain("BLOCKED ACTIONS")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("prompt_append is added after base prompt", () => {
|
||||||
|
// #given
|
||||||
|
const override = { prompt_append: "CUSTOM_MARKER_FOR_TEST" }
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = createSisyphusJuniorAgentWithOverrides(override)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
const baseEndIndex = result.prompt!.indexOf("Dense > verbose.")
|
||||||
|
const appendIndex = result.prompt!.indexOf("CUSTOM_MARKER_FOR_TEST")
|
||||||
|
expect(baseEndIndex).not.toBe(-1) // Guard: anchor text must exist in base prompt
|
||||||
|
expect(appendIndex).toBeGreaterThan(baseEndIndex)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -1,9 +1,10 @@
|
|||||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||||
import { isGptModel } from "./types"
|
import { isGptModel } from "./types"
|
||||||
import type { CategoryConfig } from "../config/schema"
|
import type { AgentOverrideConfig, CategoryConfig } from "../config/schema"
|
||||||
import {
|
import {
|
||||||
createAgentToolRestrictions,
|
createAgentToolRestrictions,
|
||||||
migrateAgentConfig,
|
migrateAgentConfig,
|
||||||
|
supportsNewPermissionSystem,
|
||||||
} from "../shared/permission-compat"
|
} from "../shared/permission-compat"
|
||||||
|
|
||||||
const SISYPHUS_JUNIOR_PROMPT = `<Role>
|
const SISYPHUS_JUNIOR_PROMPT = `<Role>
|
||||||
@ -77,6 +78,71 @@ function buildSisyphusJuniorPrompt(promptAppend?: string): string {
|
|||||||
// Core tools that Sisyphus-Junior must NEVER have access to
|
// Core tools that Sisyphus-Junior must NEVER have access to
|
||||||
const BLOCKED_TOOLS = ["task", "sisyphus_task", "call_omo_agent"]
|
const BLOCKED_TOOLS = ["task", "sisyphus_task", "call_omo_agent"]
|
||||||
|
|
||||||
|
export const SISYPHUS_JUNIOR_DEFAULTS = {
|
||||||
|
model: "anthropic/claude-sonnet-4-5",
|
||||||
|
temperature: 0.1,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export function createSisyphusJuniorAgentWithOverrides(
|
||||||
|
override: AgentOverrideConfig | undefined
|
||||||
|
): AgentConfig {
|
||||||
|
if (override?.disable) {
|
||||||
|
override = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const model = override?.model ?? SISYPHUS_JUNIOR_DEFAULTS.model
|
||||||
|
const temperature = override?.temperature ?? SISYPHUS_JUNIOR_DEFAULTS.temperature
|
||||||
|
|
||||||
|
const promptAppend = override?.prompt_append
|
||||||
|
const prompt = buildSisyphusJuniorPrompt(promptAppend)
|
||||||
|
|
||||||
|
const baseRestrictions = createAgentToolRestrictions(BLOCKED_TOOLS)
|
||||||
|
|
||||||
|
let toolsConfig: Record<string, unknown> = {}
|
||||||
|
if (supportsNewPermissionSystem()) {
|
||||||
|
const userPermission = (override?.permission ?? {}) as Record<string, string>
|
||||||
|
const basePermission = (baseRestrictions as { permission: Record<string, string> }).permission
|
||||||
|
const merged: Record<string, string> = { ...userPermission }
|
||||||
|
for (const tool of BLOCKED_TOOLS) {
|
||||||
|
merged[tool] = "deny"
|
||||||
|
}
|
||||||
|
toolsConfig = { permission: { ...merged, ...basePermission } }
|
||||||
|
} else {
|
||||||
|
const userTools = override?.tools ?? {}
|
||||||
|
const baseTools = (baseRestrictions as { tools: Record<string, boolean> }).tools
|
||||||
|
const merged: Record<string, boolean> = { ...userTools }
|
||||||
|
for (const tool of BLOCKED_TOOLS) {
|
||||||
|
merged[tool] = false
|
||||||
|
}
|
||||||
|
toolsConfig = { tools: { ...merged, ...baseTools } }
|
||||||
|
}
|
||||||
|
|
||||||
|
const base: AgentConfig = {
|
||||||
|
description: override?.description ??
|
||||||
|
"Sisyphus-Junior - Focused task executor. Same discipline, no delegation.",
|
||||||
|
mode: "subagent" as const,
|
||||||
|
model,
|
||||||
|
temperature,
|
||||||
|
maxTokens: 64000,
|
||||||
|
prompt,
|
||||||
|
color: override?.color ?? "#20B2AA",
|
||||||
|
...toolsConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (override?.top_p !== undefined) {
|
||||||
|
base.top_p = override.top_p
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isGptModel(model)) {
|
||||||
|
return { ...base, reasoningEffort: "medium" } as AgentConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...base,
|
||||||
|
thinking: { type: "enabled", budgetTokens: 32000 },
|
||||||
|
} as AgentConfig
|
||||||
|
}
|
||||||
|
|
||||||
export function createSisyphusJuniorAgent(
|
export function createSisyphusJuniorAgent(
|
||||||
categoryConfig: CategoryConfig,
|
categoryConfig: CategoryConfig,
|
||||||
promptAppend?: string
|
promptAppend?: string
|
||||||
|
|||||||
@ -315,3 +315,76 @@ describe("BuiltinCategoryNameSchema", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Sisyphus-Junior agent override", () => {
|
||||||
|
test("schema accepts agents['Sisyphus-Junior'] and retains the key after parsing", () => {
|
||||||
|
// #given
|
||||||
|
const config = {
|
||||||
|
agents: {
|
||||||
|
"Sisyphus-Junior": {
|
||||||
|
model: "openai/gpt-5.2",
|
||||||
|
temperature: 0.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = OhMyOpenCodeConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.agents?.["Sisyphus-Junior"]).toBeDefined()
|
||||||
|
expect(result.data.agents?.["Sisyphus-Junior"]?.model).toBe("openai/gpt-5.2")
|
||||||
|
expect(result.data.agents?.["Sisyphus-Junior"]?.temperature).toBe(0.2)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("schema accepts Sisyphus-Junior with prompt_append", () => {
|
||||||
|
// #given
|
||||||
|
const config = {
|
||||||
|
agents: {
|
||||||
|
"Sisyphus-Junior": {
|
||||||
|
prompt_append: "Additional instructions for Sisyphus-Junior",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = OhMyOpenCodeConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.agents?.["Sisyphus-Junior"]?.prompt_append).toBe(
|
||||||
|
"Additional instructions for Sisyphus-Junior"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("schema accepts Sisyphus-Junior with tools override", () => {
|
||||||
|
// #given
|
||||||
|
const config = {
|
||||||
|
agents: {
|
||||||
|
"Sisyphus-Junior": {
|
||||||
|
tools: {
|
||||||
|
read: true,
|
||||||
|
write: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = OhMyOpenCodeConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.agents?.["Sisyphus-Junior"]?.tools).toEqual({
|
||||||
|
read: true,
|
||||||
|
write: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -39,6 +39,7 @@ export const OverridableAgentNameSchema = z.enum([
|
|||||||
"build",
|
"build",
|
||||||
"plan",
|
"plan",
|
||||||
"Sisyphus",
|
"Sisyphus",
|
||||||
|
"Sisyphus-Junior",
|
||||||
"OpenCode-Builder",
|
"OpenCode-Builder",
|
||||||
"Prometheus (Planner)",
|
"Prometheus (Planner)",
|
||||||
"Metis (Plan Consultant)",
|
"Metis (Plan Consultant)",
|
||||||
@ -119,6 +120,7 @@ export const AgentOverridesSchema = z.object({
|
|||||||
build: AgentOverrideConfigSchema.optional(),
|
build: AgentOverrideConfigSchema.optional(),
|
||||||
plan: AgentOverrideConfigSchema.optional(),
|
plan: AgentOverrideConfigSchema.optional(),
|
||||||
Sisyphus: AgentOverrideConfigSchema.optional(),
|
Sisyphus: AgentOverrideConfigSchema.optional(),
|
||||||
|
"Sisyphus-Junior": AgentOverrideConfigSchema.optional(),
|
||||||
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
"OpenCode-Builder": AgentOverrideConfigSchema.optional(),
|
||||||
"Prometheus (Planner)": AgentOverrideConfigSchema.optional(),
|
"Prometheus (Planner)": AgentOverrideConfigSchema.optional(),
|
||||||
"Metis (Plan Consultant)": AgentOverrideConfigSchema.optional(),
|
"Metis (Plan Consultant)": AgentOverrideConfigSchema.optional(),
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { createBuiltinAgents } from "../agents";
|
import { createBuiltinAgents } from "../agents";
|
||||||
import { createSisyphusJuniorAgent } from "../agents/sisyphus-junior";
|
import { createSisyphusJuniorAgentWithOverrides } from "../agents/sisyphus-junior";
|
||||||
import {
|
import {
|
||||||
loadUserCommands,
|
loadUserCommands,
|
||||||
loadProjectCommands,
|
loadProjectCommands,
|
||||||
@ -152,10 +152,9 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
|
|||||||
Sisyphus: builtinAgents.Sisyphus,
|
Sisyphus: builtinAgents.Sisyphus,
|
||||||
};
|
};
|
||||||
|
|
||||||
agentConfig["Sisyphus-Junior"] = createSisyphusJuniorAgent({
|
agentConfig["Sisyphus-Junior"] = createSisyphusJuniorAgentWithOverrides(
|
||||||
model: "anthropic/claude-sonnet-4-5",
|
pluginConfig.agents?.["Sisyphus-Junior"]
|
||||||
temperature: 0.1,
|
);
|
||||||
});
|
|
||||||
|
|
||||||
if (builderEnabled) {
|
if (builderEnabled) {
|
||||||
const { name: _buildName, ...buildConfigWithoutName } =
|
const { name: _buildName, ...buildConfigWithoutName } =
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { supportsNewPermissionSystem } from "./opencode-version"
|
import { supportsNewPermissionSystem } from "./opencode-version"
|
||||||
|
|
||||||
|
export { supportsNewPermissionSystem }
|
||||||
|
|
||||||
export type PermissionValue = "ask" | "allow" | "deny"
|
export type PermissionValue = "ask" | "allow" | "deny"
|
||||||
|
|
||||||
export interface LegacyToolsFormat {
|
export interface LegacyToolsFormat {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user