fix(agent): stop the Plan phase demanding target_files for file-less tasks - #74
Merged
Merged
Conversation
…tasks
_generate_spec asked every MEDIUM/HIGH task for "any files you expect to
create or modify" unconditionally. target_files is load-bearing well
past the plan: SpecValidator.verify fails the run when a listed file is
absent from disk, and only writes to a listed file count as progress for
the adaptive step budget. So a task that produces no files at all — a
payment charge, a web search, a plain answer — was pushed to invent
filenames, then failed verification for not creating them, then entered
a VERIFY-CORRECTION round chasing a file it had made up.
Observed in a downstream chat product: "gere uma cobrança PIX" produced
write_file + python_sandbox + read_file + list_directory and an error
reading a nonexistent output/test_results.txt, never calling the
dedicated payment tool.
Both the schema and the instruction now state that target_files is
optional and belongs empty when the task produces no files, and say why
(each entry is verified to exist afterwards).
Also adds AgentConfig.plan_complexity_threshold ("medium" | "high" |
"never", default "medium" = current behavior). IntentParser falls back
to MEDIUM whenever no keyword heuristic matches and no
router.classifier_model is configured, so a general-purpose deployment
plans on effectively every turn; "high" lets it plan only for genuinely
complex work. An unrecognized value falls back to the default rather
than silently disabling the phase.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
_generate_specasked every MEDIUM/HIGH task for "any files you expect to create or modify" — unconditionally, with no notion that many tasks produce no files.target_filesis load-bearing well past the plan itself:SpecValidator.verifyfails the run when a listed file is absent from disk_step_touched_target_file)So a file-less task was pushed to invent filenames, then failed verification for not having created them, then entered a
[VERIFY-CORRECTION]round chasing a file it had made up — and could never earn a step extension.Observed in a downstream general-purpose chat product: "gere uma cobrança PIX" produced
write_file+python_sandbox×3 +read_file+list_directory, errored reading a nonexistentoutput/test_results.txt, and never called the dedicated payment tool.Changes
target_filesis now explicitly optional. Both the JSON schema (field description) and the instruction text state it belongs empty when the task produces no files, and say why — each entry is verified to exist afterwards. This is the actual fix.AgentConfig.plan_complexity_threshold—"medium"(default, current behavior) |"high"|"never".IntentParserfalls back to MEDIUM whenever no keyword heuristic matches and norouter.classifier_modelis set, so a conversational deployment plans on effectively every turn. An unrecognized value falls back to the default rather than silently stripping the phase.Default behavior is unchanged for every existing consumer.
Test plan
uv run pytest --cov— 686 passed, 84.80% coverageuv run ruff check ./ruff format --check .uv run pyright— 0 errors