← Back to task

Commit b767491a

commit b767491a8a0ef9b46c198a0584e8d43c2d17d87d
Author: Ben Sima <ben@bensima.com>
Date:   Mon Dec 1 15:56:35 2025

    Scale cost guardrail by task complexity
    
    Cost limits by complexity level:
    - Complexity 1: 50 cents
    - Complexity 2: 100 cents
    - Complexity 3: 200 cents (default)
    - Complexity 4: 400 cents
    - Complexity 5: 600 cents
    
    This prevents low-complexity tasks from burning budget while allowing
    complex tasks more room for iteration.
    
    Task-Id: t-223

diff --git a/Omni/Agent/Worker.hs b/Omni/Agent/Worker.hs
index ea2593e7..d79adaab 100644
--- a/Omni/Agent/Worker.hs
+++ b/Omni/Agent/Worker.hs
@@ -60,6 +60,8 @@ formatGuardrailResult (Engine.GuardrailDuplicateToolCalls tool count) =
   "Duplicate tool calls: " <> tool <> " called " <> tshow count <> " times"
 formatGuardrailResult (Engine.GuardrailTestFailures count) =
   "Test failures: " <> tshow count <> " failures"
+formatGuardrailResult (Engine.GuardrailEditFailures count) =
+  "Edit failures: " <> tshow count <> " 'old_str not found' errors"
 
 runOnce :: Core.Worker -> Maybe Text -> IO ()
 runOnce worker maybeTaskId = do
@@ -312,13 +314,15 @@ runWithEngine worker repo task = do
                   logSystemEvent "Guardrail" contentJson
               }
 
-      -- Build Agent config with guardrails
-      let guardrails =
+      -- Build Agent config with guardrails (scale cost by complexity)
+      let baseCost = selectCostByComplexity (TaskCore.taskComplexity task)
+          guardrails =
             Engine.Guardrails
-              { Engine.guardrailMaxCostCents = 200.0,
+              { Engine.guardrailMaxCostCents = baseCost,
                 Engine.guardrailMaxTokens = 2000000,
                 Engine.guardrailMaxDuplicateToolCalls = 30,
-                Engine.guardrailMaxTestFailures = 3
+                Engine.guardrailMaxTestFailures = 3,
+                Engine.guardrailMaxEditFailures = 5
               }
           agentCfg =
             Engine.AgentConfig
@@ -437,6 +441,17 @@ selectModelByComplexity (Just 4) = "anthropic/claude-sonnet-4.5"
 selectModelByComplexity (Just 5) = "anthropic/claude-opus-4.5"
 selectModelByComplexity (Just _) = "anthropic/claude-sonnet-4.5"
 
+-- | Select cost guardrail based on complexity level (in cents)
+-- Lower complexity = lower budget, higher complexity = more room for iteration
+selectCostByComplexity :: Maybe Int -> Double
+selectCostByComplexity Nothing = 200.0
+selectCostByComplexity (Just 1) = 50.0
+selectCostByComplexity (Just 2) = 100.0
+selectCostByComplexity (Just 3) = 200.0
+selectCostByComplexity (Just 4) = 400.0
+selectCostByComplexity (Just 5) = 600.0
+selectCostByComplexity (Just _) = 200.0
+
 formatTask :: TaskCore.Task -> Text
 formatTask t =
   "Task: "