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:
YeonGyu-Kim
2026-04-07 11:28:48 +09:00
parent 12106ffccc
commit 1140080927
14 changed files with 100 additions and 6 deletions
+33
View File
@@ -192,6 +192,8 @@ describe("createHephaestusAgent", () => {
expect(config.prompt).toContain("You build context by examining");
expect(config.prompt).toContain("Never chain together bash commands");
expect(config.prompt).toContain("<tool_usage_rules>");
expect(config.prompt).toContain("Do not use `apply_patch`");
expect(config.prompt).toContain("`edit` and `write`");
});
test("GPT 5.3-codex model includes GPT-5.3 specific prompt content", () => {
@@ -205,6 +207,8 @@ describe("createHephaestusAgent", () => {
expect(config.prompt).toContain("Senior Staff Engineer");
expect(config.prompt).toContain("Hard Constraints");
expect(config.prompt).toContain("<tool_usage_rules>");
expect(config.prompt).toContain("Do not use `apply_patch`");
expect(config.prompt).toContain("`edit` and `write`");
});
test("includes Hephaestus identity in prompt", () => {
@@ -219,6 +223,35 @@ describe("createHephaestusAgent", () => {
expect(config.prompt).toContain("autonomous deep worker");
});
test("generic GPT model includes apply_patch workaround guidance", () => {
// given
const model = "openai/gpt-4o";
// when
const config = createHephaestusAgent(model);
// then
expect(config.prompt).toContain("Do not use `apply_patch`");
expect(config.prompt).toContain("`edit` and `write`");
});
test("GPT models deny apply_patch while non-GPT models do not", () => {
// given
const gpt54Model = "openai/gpt-5.4";
const gptGenericModel = "openai/gpt-4o";
const claudeModel = "anthropic/claude-opus-4-6";
// when
const gpt54Config = createHephaestusAgent(gpt54Model);
const gptGenericConfig = createHephaestusAgent(gptGenericModel);
const claudeConfig = createHephaestusAgent(claudeModel);
// then
expect(gpt54Config.permission ?? {}).toHaveProperty("apply_patch", "deny");
expect(gptGenericConfig.permission ?? {}).toHaveProperty("apply_patch", "deny");
expect(claudeConfig.permission ?? {}).not.toHaveProperty("apply_patch");
});
test("useTaskSystem=true produces Task Discipline prompt", () => {
// given
const model = "openai/gpt-5.4";