fix(agents): deny apply_patch for GPT models to prevent verification hangs (#2935)
GPT models (5.3-codex, 5.4, etc.) frequently hang when using apply_patch due to verification loops. This adds: 1. Tool restriction: apply_patch is denied for GPT variants of Hephaestus, Sisyphus-Junior, and Sisyphus agents 2. Prompt guidance: GPT-specific prompts now explicitly instruct using edit/write tools instead of apply_patch 3. Removed the 'Always use apply_patch' instruction from sisyphus-junior/gpt-5-4.ts that contradicted the fix The deny is model-conditional — Claude variants retain apply_patch access since it works reliably there.
This commit is contained in:
@@ -350,6 +350,8 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
|
||||
expect(result.prompt).toContain("Scope Discipline")
|
||||
expect(result.prompt).toContain("<tool_usage_rules>")
|
||||
expect(result.prompt).toContain("Progress Updates")
|
||||
expect(result.prompt).toContain("Do not use `apply_patch`")
|
||||
expect(result.prompt).toContain("`edit` and `write`")
|
||||
})
|
||||
|
||||
test("GPT 5.4 model uses GPT-5.4 specific prompt", () => {
|
||||
@@ -362,6 +364,9 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
|
||||
// then
|
||||
expect(result.prompt).toContain("expert coding agent")
|
||||
expect(result.prompt).toContain("<tool_usage_rules>")
|
||||
expect(result.prompt).toContain("Do not use `apply_patch`")
|
||||
expect(result.prompt).toContain("`edit` and `write`")
|
||||
expect(result.prompt).not.toContain("Always use apply_patch")
|
||||
})
|
||||
|
||||
test("GPT 5.3 Codex model uses GPT-5.3-codex specific prompt", () => {
|
||||
@@ -374,6 +379,28 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
|
||||
// then
|
||||
expect(result.prompt).toContain("Senior Engineer")
|
||||
expect(result.prompt).toContain("<tool_usage_rules>")
|
||||
expect(result.prompt).toContain("Do not use `apply_patch`")
|
||||
expect(result.prompt).toContain("`edit` and `write`")
|
||||
})
|
||||
|
||||
test("GPT variants deny apply_patch while Claude variants do not", () => {
|
||||
// given
|
||||
const gpt54Override = { model: "openai/gpt-5.4" }
|
||||
const gpt53Override = { model: "openai/gpt-5.3-codex" }
|
||||
const gptGenericOverride = { model: "openai/gpt-4o" }
|
||||
const claudeOverride = { model: "anthropic/claude-sonnet-4-6" }
|
||||
|
||||
// when
|
||||
const gpt54Result = createSisyphusJuniorAgentWithOverrides(gpt54Override)
|
||||
const gpt53Result = createSisyphusJuniorAgentWithOverrides(gpt53Override)
|
||||
const gptGenericResult = createSisyphusJuniorAgentWithOverrides(gptGenericOverride)
|
||||
const claudeResult = createSisyphusJuniorAgentWithOverrides(claudeOverride)
|
||||
|
||||
// then
|
||||
expect(gpt54Result.permission ?? {}).toHaveProperty("apply_patch", "deny")
|
||||
expect(gpt53Result.permission ?? {}).toHaveProperty("apply_patch", "deny")
|
||||
expect(gptGenericResult.permission ?? {}).toHaveProperty("apply_patch", "deny")
|
||||
expect(claudeResult.permission ?? {}).not.toHaveProperty("apply_patch")
|
||||
})
|
||||
|
||||
test("prompt_append is added after base prompt", () => {
|
||||
@@ -494,6 +521,7 @@ describe("buildSisyphusJuniorPrompt", () => {
|
||||
expect(prompt).toContain("expert coding agent")
|
||||
expect(prompt).toContain("Scope Discipline")
|
||||
expect(prompt).toContain("<tool_usage_rules>")
|
||||
expect(prompt).toContain("Do not use `apply_patch`")
|
||||
})
|
||||
|
||||
test("GPT 5.3 Codex model uses GPT-5.3-codex prompt", () => {
|
||||
@@ -507,6 +535,7 @@ describe("buildSisyphusJuniorPrompt", () => {
|
||||
expect(prompt).toContain("Senior Engineer")
|
||||
expect(prompt).toContain("Scope Discipline")
|
||||
expect(prompt).toContain("<tool_usage_rules>")
|
||||
expect(prompt).toContain("Do not use `apply_patch`")
|
||||
})
|
||||
|
||||
test("generic GPT model uses generic GPT prompt", () => {
|
||||
@@ -521,6 +550,7 @@ describe("buildSisyphusJuniorPrompt", () => {
|
||||
expect(prompt).toContain("Scope Discipline")
|
||||
expect(prompt).toContain("<tool_usage_rules>")
|
||||
expect(prompt).toContain("Progress Updates")
|
||||
expect(prompt).toContain("Do not use `apply_patch`")
|
||||
})
|
||||
|
||||
test("Claude model prompt contains Claude-specific sections", () => {
|
||||
|
||||
Reference in New Issue
Block a user