Merge pull request #1974 from ControlNet/dev
This commit is contained in:
commit
e758623a2e
@ -1133,6 +1133,7 @@ Opt-in experimental features that may change or be removed in future versions. U
|
|||||||
"truncate_all_tool_outputs": true,
|
"truncate_all_tool_outputs": true,
|
||||||
"aggressive_truncation": true,
|
"aggressive_truncation": true,
|
||||||
"auto_resume": true,
|
"auto_resume": true,
|
||||||
|
"disable_omo_env": false,
|
||||||
"dynamic_context_pruning": {
|
"dynamic_context_pruning": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"notification": "detailed",
|
"notification": "detailed",
|
||||||
@ -1164,6 +1165,7 @@ Opt-in experimental features that may change or be removed in future versions. U
|
|||||||
| `truncate_all_tool_outputs` | `false` | Truncates ALL tool outputs instead of just whitelisted tools (Grep, Glob, LSP, AST-grep). Tool output truncator is enabled by default - disable via `disabled_hooks`. |
|
| `truncate_all_tool_outputs` | `false` | Truncates ALL tool outputs instead of just whitelisted tools (Grep, Glob, LSP, AST-grep). Tool output truncator is enabled by default - disable via `disabled_hooks`. |
|
||||||
| `aggressive_truncation` | `false` | When token limit is exceeded, aggressively truncates tool outputs to fit within limits. More aggressive than the default truncation behavior. Falls back to summarize/revert if insufficient. |
|
| `aggressive_truncation` | `false` | When token limit is exceeded, aggressively truncates tool outputs to fit within limits. More aggressive than the default truncation behavior. Falls back to summarize/revert if insufficient. |
|
||||||
| `auto_resume` | `false` | Automatically resumes session after successful recovery from thinking block errors or thinking disabled violations. Extracts last user message and continues. |
|
| `auto_resume` | `false` | Automatically resumes session after successful recovery from thinking block errors or thinking disabled violations. Extracts last user message and continues. |
|
||||||
|
| `disable_omo_env` | `false` | When `true`, disables auto-injected `<omo-env>` block generation (date, time, timezone, locale). When unset or `false`, current behavior is preserved. Setting this to `true` will improve the cache hit rate and reduce the API cost. |
|
||||||
| `dynamic_context_pruning` | See below | Dynamic context pruning configuration for managing context window usage automatically. See [Dynamic Context Pruning](#dynamic-context-pruning) below. |
|
| `dynamic_context_pruning` | See below | Dynamic context pruning configuration for managing context window usage automatically. See [Dynamic Context Pruning](#dynamic-context-pruning) below. |
|
||||||
|
|
||||||
### Dynamic Context Pruning
|
### Dynamic Context Pruning
|
||||||
|
|||||||
@ -69,8 +69,10 @@ export async function createBuiltinAgents(
|
|||||||
browserProvider?: BrowserAutomationProvider,
|
browserProvider?: BrowserAutomationProvider,
|
||||||
uiSelectedModel?: string,
|
uiSelectedModel?: string,
|
||||||
disabledSkills?: Set<string>,
|
disabledSkills?: Set<string>,
|
||||||
useTaskSystem = false
|
useTaskSystem = false,
|
||||||
|
disableOmoEnv = false
|
||||||
): Promise<Record<string, AgentConfig>> {
|
): Promise<Record<string, AgentConfig>> {
|
||||||
|
|
||||||
const connectedProviders = readConnectedProvidersCache()
|
const connectedProviders = readConnectedProvidersCache()
|
||||||
const providerModelsConnected = connectedProviders
|
const providerModelsConnected = connectedProviders
|
||||||
? (readProviderModelsCache()?.connected ?? [])
|
? (readProviderModelsCache()?.connected ?? [])
|
||||||
@ -112,6 +114,7 @@ export async function createBuiltinAgents(
|
|||||||
uiSelectedModel,
|
uiSelectedModel,
|
||||||
availableModels,
|
availableModels,
|
||||||
disabledSkills,
|
disabledSkills,
|
||||||
|
disableOmoEnv,
|
||||||
})
|
})
|
||||||
|
|
||||||
const registeredAgents = parseRegisteredAgentSummaries(customAgentSummaries)
|
const registeredAgents = parseRegisteredAgentSummaries(customAgentSummaries)
|
||||||
@ -145,6 +148,7 @@ export async function createBuiltinAgents(
|
|||||||
directory,
|
directory,
|
||||||
userCategories: categories,
|
userCategories: categories,
|
||||||
useTaskSystem,
|
useTaskSystem,
|
||||||
|
disableOmoEnv,
|
||||||
})
|
})
|
||||||
if (sisyphusConfig) {
|
if (sisyphusConfig) {
|
||||||
result["sisyphus"] = sisyphusConfig
|
result["sisyphus"] = sisyphusConfig
|
||||||
@ -162,6 +166,7 @@ export async function createBuiltinAgents(
|
|||||||
mergedCategories,
|
mergedCategories,
|
||||||
directory,
|
directory,
|
||||||
useTaskSystem,
|
useTaskSystem,
|
||||||
|
disableOmoEnv,
|
||||||
})
|
})
|
||||||
if (hephaestusConfig) {
|
if (hephaestusConfig) {
|
||||||
result["hephaestus"] = hephaestusConfig
|
result["hephaestus"] = hephaestusConfig
|
||||||
|
|||||||
@ -1,8 +1,16 @@
|
|||||||
import type { AgentConfig } from "@opencode-ai/sdk"
|
import type { AgentConfig } from "@opencode-ai/sdk"
|
||||||
import { createEnvContext } from "../env-context"
|
import { createEnvContext } from "../env-context"
|
||||||
|
|
||||||
export function applyEnvironmentContext(config: AgentConfig, directory?: string): AgentConfig {
|
type ApplyEnvironmentContextOptions = {
|
||||||
if (!directory || !config.prompt) return config
|
disableOmoEnv?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function applyEnvironmentContext(
|
||||||
|
config: AgentConfig,
|
||||||
|
directory?: string,
|
||||||
|
options: ApplyEnvironmentContextOptions = {}
|
||||||
|
): AgentConfig {
|
||||||
|
if (options.disableOmoEnv || !directory || !config.prompt) return config
|
||||||
const envContext = createEnvContext()
|
const envContext = createEnvContext()
|
||||||
return { ...config, prompt: config.prompt + envContext }
|
return { ...config, prompt: config.prompt + envContext }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ export function collectPendingBuiltinAgents(input: {
|
|||||||
availableModels: Set<string>
|
availableModels: Set<string>
|
||||||
disabledSkills?: Set<string>
|
disabledSkills?: Set<string>
|
||||||
useTaskSystem?: boolean
|
useTaskSystem?: boolean
|
||||||
|
disableOmoEnv?: boolean
|
||||||
}): { pendingAgentConfigs: Map<string, AgentConfig>; availableAgents: AvailableAgent[] } {
|
}): { pendingAgentConfigs: Map<string, AgentConfig>; availableAgents: AvailableAgent[] } {
|
||||||
const {
|
const {
|
||||||
agentSources,
|
agentSources,
|
||||||
@ -37,6 +38,7 @@ export function collectPendingBuiltinAgents(input: {
|
|||||||
uiSelectedModel,
|
uiSelectedModel,
|
||||||
availableModels,
|
availableModels,
|
||||||
disabledSkills,
|
disabledSkills,
|
||||||
|
disableOmoEnv = false,
|
||||||
} = input
|
} = input
|
||||||
|
|
||||||
const availableAgents: AvailableAgent[] = []
|
const availableAgents: AvailableAgent[] = []
|
||||||
@ -81,7 +83,7 @@ export function collectPendingBuiltinAgents(input: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (agentName === "librarian") {
|
if (agentName === "librarian") {
|
||||||
config = applyEnvironmentContext(config, directory)
|
config = applyEnvironmentContext(config, directory, { disableOmoEnv })
|
||||||
}
|
}
|
||||||
|
|
||||||
config = applyOverrides(config, override, mergedCategories, directory)
|
config = applyOverrides(config, override, mergedCategories, directory)
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import type { CategoryConfig } from "../../config/schema"
|
|||||||
import type { AvailableAgent, AvailableCategory, AvailableSkill } from "../dynamic-agent-prompt-builder"
|
import type { AvailableAgent, AvailableCategory, AvailableSkill } from "../dynamic-agent-prompt-builder"
|
||||||
import { AGENT_MODEL_REQUIREMENTS, isAnyProviderConnected } from "../../shared"
|
import { AGENT_MODEL_REQUIREMENTS, isAnyProviderConnected } from "../../shared"
|
||||||
import { createHephaestusAgent } from "../hephaestus"
|
import { createHephaestusAgent } from "../hephaestus"
|
||||||
import { createEnvContext } from "../env-context"
|
import { applyEnvironmentContext } from "./environment-context"
|
||||||
import { applyCategoryOverride, mergeAgentConfig } from "./agent-overrides"
|
import { applyCategoryOverride, mergeAgentConfig } from "./agent-overrides"
|
||||||
import { applyModelResolution, getFirstFallbackModel } from "./model-resolution"
|
import { applyModelResolution, getFirstFallbackModel } from "./model-resolution"
|
||||||
|
|
||||||
@ -20,6 +20,7 @@ export function maybeCreateHephaestusConfig(input: {
|
|||||||
mergedCategories: Record<string, CategoryConfig>
|
mergedCategories: Record<string, CategoryConfig>
|
||||||
directory?: string
|
directory?: string
|
||||||
useTaskSystem: boolean
|
useTaskSystem: boolean
|
||||||
|
disableOmoEnv?: boolean
|
||||||
}): AgentConfig | undefined {
|
}): AgentConfig | undefined {
|
||||||
const {
|
const {
|
||||||
disabledAgents,
|
disabledAgents,
|
||||||
@ -33,6 +34,7 @@ export function maybeCreateHephaestusConfig(input: {
|
|||||||
mergedCategories,
|
mergedCategories,
|
||||||
directory,
|
directory,
|
||||||
useTaskSystem,
|
useTaskSystem,
|
||||||
|
disableOmoEnv = false,
|
||||||
} = input
|
} = input
|
||||||
|
|
||||||
if (disabledAgents.includes("hephaestus")) return undefined
|
if (disabledAgents.includes("hephaestus")) return undefined
|
||||||
@ -79,10 +81,7 @@ export function maybeCreateHephaestusConfig(input: {
|
|||||||
hephaestusConfig = applyCategoryOverride(hephaestusConfig, hepOverrideCategory, mergedCategories)
|
hephaestusConfig = applyCategoryOverride(hephaestusConfig, hepOverrideCategory, mergedCategories)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (directory && hephaestusConfig.prompt) {
|
hephaestusConfig = applyEnvironmentContext(hephaestusConfig, directory, { disableOmoEnv })
|
||||||
const envContext = createEnvContext()
|
|
||||||
hephaestusConfig = { ...hephaestusConfig, prompt: hephaestusConfig.prompt + envContext }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hephaestusOverride) {
|
if (hephaestusOverride) {
|
||||||
hephaestusConfig = mergeAgentConfig(hephaestusConfig, hephaestusOverride, directory)
|
hephaestusConfig = mergeAgentConfig(hephaestusConfig, hephaestusOverride, directory)
|
||||||
|
|||||||
@ -22,6 +22,7 @@ export function maybeCreateSisyphusConfig(input: {
|
|||||||
directory?: string
|
directory?: string
|
||||||
userCategories?: CategoriesConfig
|
userCategories?: CategoriesConfig
|
||||||
useTaskSystem: boolean
|
useTaskSystem: boolean
|
||||||
|
disableOmoEnv?: boolean
|
||||||
}): AgentConfig | undefined {
|
}): AgentConfig | undefined {
|
||||||
const {
|
const {
|
||||||
disabledAgents,
|
disabledAgents,
|
||||||
@ -36,6 +37,7 @@ export function maybeCreateSisyphusConfig(input: {
|
|||||||
mergedCategories,
|
mergedCategories,
|
||||||
directory,
|
directory,
|
||||||
useTaskSystem,
|
useTaskSystem,
|
||||||
|
disableOmoEnv = false,
|
||||||
} = input
|
} = input
|
||||||
|
|
||||||
const sisyphusOverride = agentOverrides["sisyphus"]
|
const sisyphusOverride = agentOverrides["sisyphus"]
|
||||||
@ -78,7 +80,9 @@ export function maybeCreateSisyphusConfig(input: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sisyphusConfig = applyOverrides(sisyphusConfig, sisyphusOverride, mergedCategories, directory)
|
sisyphusConfig = applyOverrides(sisyphusConfig, sisyphusOverride, mergedCategories, directory)
|
||||||
sisyphusConfig = applyEnvironmentContext(sisyphusConfig, directory)
|
sisyphusConfig = applyEnvironmentContext(sisyphusConfig, directory, {
|
||||||
|
disableOmoEnv,
|
||||||
|
})
|
||||||
|
|
||||||
return sisyphusConfig
|
return sisyphusConfig
|
||||||
}
|
}
|
||||||
|
|||||||
@ -662,6 +662,178 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("Hephaestus environment context toggle", () => {
|
||||||
|
let fetchSpy: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||||
|
new Set(["openai/gpt-5.3-codex"])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchSpy.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function buildAgents(disableFlag?: boolean) {
|
||||||
|
return createBuiltinAgents(
|
||||||
|
[],
|
||||||
|
{},
|
||||||
|
"/tmp/work",
|
||||||
|
TEST_DEFAULT_MODEL,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
disableFlag
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test("includes <omo-env> tag when disable flag is unset", async () => {
|
||||||
|
// #when
|
||||||
|
const agents = await buildAgents(undefined)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(agents.hephaestus).toBeDefined()
|
||||||
|
expect(agents.hephaestus.prompt).toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("includes <omo-env> tag when disable flag is false", async () => {
|
||||||
|
// #when
|
||||||
|
const agents = await buildAgents(false)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(agents.hephaestus).toBeDefined()
|
||||||
|
expect(agents.hephaestus.prompt).toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("omits <omo-env> tag when disable flag is true", async () => {
|
||||||
|
// #when
|
||||||
|
const agents = await buildAgents(true)
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(agents.hephaestus).toBeDefined()
|
||||||
|
expect(agents.hephaestus.prompt).not.toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Sisyphus and Librarian environment context toggle", () => {
|
||||||
|
let fetchSpy: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||||
|
new Set(["anthropic/claude-opus-4-6", "google/gemini-3-flash"])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchSpy.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function buildAgents(disableFlag?: boolean) {
|
||||||
|
return createBuiltinAgents(
|
||||||
|
[],
|
||||||
|
{},
|
||||||
|
"/tmp/work",
|
||||||
|
TEST_DEFAULT_MODEL,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
disableFlag
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test("includes <omo-env> for sisyphus and librarian when disable flag is unset", async () => {
|
||||||
|
const agents = await buildAgents(undefined)
|
||||||
|
|
||||||
|
expect(agents.sisyphus).toBeDefined()
|
||||||
|
expect(agents.librarian).toBeDefined()
|
||||||
|
expect(agents.sisyphus.prompt).toContain("<omo-env>")
|
||||||
|
expect(agents.librarian.prompt).toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("includes <omo-env> for sisyphus and librarian when disable flag is false", async () => {
|
||||||
|
const agents = await buildAgents(false)
|
||||||
|
|
||||||
|
expect(agents.sisyphus).toBeDefined()
|
||||||
|
expect(agents.librarian).toBeDefined()
|
||||||
|
expect(agents.sisyphus.prompt).toContain("<omo-env>")
|
||||||
|
expect(agents.librarian.prompt).toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("omits <omo-env> for sisyphus and librarian when disable flag is true", async () => {
|
||||||
|
const agents = await buildAgents(true)
|
||||||
|
|
||||||
|
expect(agents.sisyphus).toBeDefined()
|
||||||
|
expect(agents.librarian).toBeDefined()
|
||||||
|
expect(agents.sisyphus.prompt).not.toContain("<omo-env>")
|
||||||
|
expect(agents.librarian.prompt).not.toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("Atlas is unaffected by environment context toggle", () => {
|
||||||
|
let fetchSpy: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||||
|
new Set(["anthropic/claude-opus-4-6", "openai/gpt-5.2"])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fetchSpy.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("atlas prompt is unchanged and never contains <omo-env>", async () => {
|
||||||
|
const agentsDefault = await createBuiltinAgents(
|
||||||
|
[],
|
||||||
|
{},
|
||||||
|
"/tmp/work",
|
||||||
|
TEST_DEFAULT_MODEL,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
const agentsDisabled = await createBuiltinAgents(
|
||||||
|
[],
|
||||||
|
{},
|
||||||
|
"/tmp/work",
|
||||||
|
TEST_DEFAULT_MODEL,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(agentsDefault.atlas).toBeDefined()
|
||||||
|
expect(agentsDisabled.atlas).toBeDefined()
|
||||||
|
expect(agentsDefault.atlas.prompt).not.toContain("<omo-env>")
|
||||||
|
expect(agentsDisabled.atlas.prompt).not.toContain("<omo-env>")
|
||||||
|
expect(agentsDisabled.atlas.prompt).toBe(agentsDefault.atlas.prompt)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("createBuiltinAgents with requiresAnyModel gating (sisyphus)", () => {
|
describe("createBuiltinAgents with requiresAnyModel gating (sisyphus)", () => {
|
||||||
test("sisyphus is created when at least one fallback model is available", async () => {
|
test("sisyphus is created when at least one fallback model is available", async () => {
|
||||||
// #given
|
// #given
|
||||||
|
|||||||
@ -741,6 +741,59 @@ describe("ExperimentalConfigSchema feature flags", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("accepts disable_omo_env as true", () => {
|
||||||
|
//#given
|
||||||
|
const config = { disable_omo_env: true }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = ExperimentalConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.disable_omo_env).toBe(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("accepts disable_omo_env as false", () => {
|
||||||
|
//#given
|
||||||
|
const config = { disable_omo_env: false }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = ExperimentalConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.disable_omo_env).toBe(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("disable_omo_env is optional", () => {
|
||||||
|
//#given
|
||||||
|
const config = { safe_hook_creation: true }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = ExperimentalConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.data.disable_omo_env).toBeUndefined()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test("rejects non-boolean disable_omo_env", () => {
|
||||||
|
//#given
|
||||||
|
const config = { disable_omo_env: "true" }
|
||||||
|
|
||||||
|
//#when
|
||||||
|
const result = ExperimentalConfigSchema.safeParse(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(result.success).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
test("rejects non-boolean hashline_edit", () => {
|
test("rejects non-boolean hashline_edit", () => {
|
||||||
//#given
|
//#given
|
||||||
const config = { hashline_edit: "true" }
|
const config = { hashline_edit: "true" }
|
||||||
|
|||||||
@ -15,6 +15,8 @@ export const ExperimentalConfigSchema = z.object({
|
|||||||
plugin_load_timeout_ms: z.number().min(1000).optional(),
|
plugin_load_timeout_ms: z.number().min(1000).optional(),
|
||||||
/** Wrap hook creation in try/catch to prevent one failing hook from crashing the plugin (default: true at call site) */
|
/** Wrap hook creation in try/catch to prevent one failing hook from crashing the plugin (default: true at call site) */
|
||||||
safe_hook_creation: z.boolean().optional(),
|
safe_hook_creation: z.boolean().optional(),
|
||||||
|
/** Disable auto-injected <omo-env> context in prompts (experimental) */
|
||||||
|
disable_omo_env: z.boolean().optional(),
|
||||||
/** Enable hashline_edit tool for improved file editing with hash-based line anchors */
|
/** Enable hashline_edit tool for improved file editing with hash-based line anchors */
|
||||||
hashline_edit: z.boolean().optional(),
|
hashline_edit: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
|
|||||||
@ -76,6 +76,7 @@ export async function applyAgentConfig(params: {
|
|||||||
const currentModel = params.config.model as string | undefined;
|
const currentModel = params.config.model as string | undefined;
|
||||||
const disabledSkills = new Set<string>(params.pluginConfig.disabled_skills ?? []);
|
const disabledSkills = new Set<string>(params.pluginConfig.disabled_skills ?? []);
|
||||||
const useTaskSystem = params.pluginConfig.experimental?.task_system ?? false;
|
const useTaskSystem = params.pluginConfig.experimental?.task_system ?? false;
|
||||||
|
const disableOmoEnv = params.pluginConfig.experimental?.disable_omo_env ?? false;
|
||||||
|
|
||||||
const builtinAgents = await createBuiltinAgents(
|
const builtinAgents = await createBuiltinAgents(
|
||||||
migratedDisabledAgents,
|
migratedDisabledAgents,
|
||||||
@ -90,6 +91,7 @@ export async function applyAgentConfig(params: {
|
|||||||
currentModel,
|
currentModel,
|
||||||
disabledSkills,
|
disabledSkills,
|
||||||
useTaskSystem,
|
useTaskSystem,
|
||||||
|
disableOmoEnv,
|
||||||
);
|
);
|
||||||
|
|
||||||
const includeClaudeAgents = params.pluginConfig.claude_code?.agents ?? true;
|
const includeClaudeAgents = params.pluginConfig.claude_code?.agents ?? true;
|
||||||
|
|||||||
@ -1275,3 +1275,69 @@ describe("per-agent todowrite/todoread deny when task_system enabled", () => {
|
|||||||
expect(agentResult[getAgentDisplayName("sisyphus")]?.permission?.todoread).toBeUndefined()
|
expect(agentResult[getAgentDisplayName("sisyphus")]?.permission?.todoread).toBeUndefined()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("disable_omo_env pass-through", () => {
|
||||||
|
test("omits <omo-env> in generated sisyphus prompt when disable_omo_env is true", async () => {
|
||||||
|
//#given
|
||||||
|
;(agents.createBuiltinAgents as any)?.mockRestore?.()
|
||||||
|
;(shared.fetchAvailableModels as any).mockResolvedValue(
|
||||||
|
new Set(["anthropic/claude-opus-4-6", "google/gemini-3-flash"])
|
||||||
|
)
|
||||||
|
|
||||||
|
const pluginConfig: OhMyOpenCodeConfig = {
|
||||||
|
experimental: { disable_omo_env: true },
|
||||||
|
}
|
||||||
|
const config: Record<string, unknown> = {
|
||||||
|
model: "anthropic/claude-opus-4-6",
|
||||||
|
agent: {},
|
||||||
|
}
|
||||||
|
const handler = createConfigHandler({
|
||||||
|
ctx: { directory: "/tmp" },
|
||||||
|
pluginConfig,
|
||||||
|
modelCacheState: {
|
||||||
|
anthropicContext1MEnabled: false,
|
||||||
|
modelContextLimitsCache: new Map(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await handler(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const agentResult = config.agent as Record<string, { prompt?: string }>
|
||||||
|
const sisyphusPrompt = agentResult[getAgentDisplayName("sisyphus")]?.prompt
|
||||||
|
expect(sisyphusPrompt).toBeDefined()
|
||||||
|
expect(sisyphusPrompt).not.toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("keeps <omo-env> in generated sisyphus prompt when disable_omo_env is omitted", async () => {
|
||||||
|
//#given
|
||||||
|
;(agents.createBuiltinAgents as any)?.mockRestore?.()
|
||||||
|
;(shared.fetchAvailableModels as any).mockResolvedValue(
|
||||||
|
new Set(["anthropic/claude-opus-4-6", "google/gemini-3-flash"])
|
||||||
|
)
|
||||||
|
|
||||||
|
const pluginConfig: OhMyOpenCodeConfig = {}
|
||||||
|
const config: Record<string, unknown> = {
|
||||||
|
model: "anthropic/claude-opus-4-6",
|
||||||
|
agent: {},
|
||||||
|
}
|
||||||
|
const handler = createConfigHandler({
|
||||||
|
ctx: { directory: "/tmp" },
|
||||||
|
pluginConfig,
|
||||||
|
modelCacheState: {
|
||||||
|
anthropicContext1MEnabled: false,
|
||||||
|
modelContextLimitsCache: new Map(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await handler(config)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
const agentResult = config.agent as Record<string, { prompt?: string }>
|
||||||
|
const sisyphusPrompt = agentResult[getAgentDisplayName("sisyphus")]?.prompt
|
||||||
|
expect(sisyphusPrompt).toBeDefined()
|
||||||
|
expect(sisyphusPrompt).toContain("<omo-env>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user