Skip to content

fix(cli): let the config file set max_steps for the interactive command - #492

Open
sxh313 wants to merge 1 commit into
bytedance:mainfrom
sxh313:fix/interactive-max-steps-default
Open

sxh313 wants to merge 1 commit into
bytedance:mainfrom
sxh313:fix/interactive-max-steps-default

Conversation

@sxh313

@sxh313 sxh313 commented Sep 26, 2026

Copy link
Copy Markdown

Description

trae-cli interactive silently ignored max_steps from the config file: its --max-steps click
option was declared with default=20, so interactive() always handed 20 to
Config.create(...).resolve_config_values(max_steps=...) as the CLI value. Since
resolve_config_value is documented as "CLI > ENV > Config > Default", a filled-in default always
beat the config file, and agents.trae_agent.max_steps was never consulted in interactive mode.

The other two commands that resolve the same config (run, show-config) declare the option
without a default and therefore do honour the config file. This PR removes the inconsistent default
so all three commands share one precedence rule, and adds a regression test that pins the
behaviour in both directions (flag absent -> config value, flag present -> CLI value).

Reported in #491.

More Information

The single production change is in trae_agent/cli.py (line 425, the interactive command):

-@click.option("--max-steps", help="Maximum number of execution steps", type=int, default=20)
+@click.option("--max-steps", help="Maximum number of execution steps", type=int)

Why removing the default cannot leave the value undefined:

  • interactive() already annotates the parameter as max_steps: int | None = None
    (trae_agent/cli.py:437), so "flag not given = None" is the shape the function expects - the
    same shape run() and show_config() use.
  • max_steps is a required field of the agent config: Config.create() builds
    TraeAgentConfig(**agent_config, ...), and a config file without max_steps fails outright with
    TypeError: TraeAgentConfig.__init__() missing 1 required positional argument: 'max_steps'.
    resolve_config_values therefore always yields an int; there is no path where the removed
    default was the only thing keeping the value non-None.
  • Nothing in the repo documents a CLI default of 20 for interactive (the 20 values in
    docs/legacy_config.md and docs/TRAJECTORY_RECORDING.md are config file examples, and
    README.md demonstrates max_steps: 200).

Impact: interactive sessions now respect the configured step budget. Users who relied on the
implicit 20 can pass --max-steps 20, and their config file value keeps working - which is the
behaviour the config schema and the other two commands already promise.

The new test tests/test_cli_max_steps.py drives the real commands through click.testing.CliRunner
with a temp config file (max_steps: 50) and asserts the value that reaches the agent config, for
both interactive and run, with and without the flag. It lives in its own file to avoid touching
tests/test_cli.py, which several open PRs are editing.

Validation

All commands were run locally on Windows 11 / Python 3.12.13, uv environment of the repo
(--all-extras), against main = e839e559ac61bdd0e057c375dd1dee391fee797d.

  1. Red first - the new test on unmodified main (the test file added, trae_agent/cli.py reverted
    to e839e55):

    $ SKIP_OLLAMA_TEST=true SKIP_OPENROUTER_TEST=true SKIP_GOOGLE_TEST=true \
        python -m pytest tests/test_cli_max_steps.py --tb=short
    .F..                                                                     [100%]
    E   AssertionError: 20 != 50
    1 failed, 3 passed
    

    The failing case is test_interactive_without_flag_keeps_config_max_steps; the three others
    (run without the flag, and both commands with --max-steps 70) already passed, which is what
    makes the failure specific to interactive.

  2. Same test after removing default=20:

    $ SKIP_OLLAMA_TEST=true SKIP_OPENROUTER_TEST=true SKIP_GOOGLE_TEST=true \
        python -m pytest tests/test_cli_max_steps.py tests/test_cli.py --tb=short
    ...........                                                              [100%]
    11 passed in 3.13s
    
  3. Full suite on the branch, with the clean main clone as control (same machine, same
    environment):

    # branch fix/interactive-max-steps-default
    $ SKIP_OLLAMA_TEST=true SKIP_OPENROUTER_TEST=true SKIP_GOOGLE_TEST=true \
        python -m pytest tests/ --tb=short --continue-on-collection-errors
    3 failed, 63 passed, 17 skipped in 24.13s
    
    # control: main @ e839e55
    3 failed, 59 passed, 17 skipped in 15.11s
    

    63 = 59 + the 4 new tests, and the skipped count is unchanged. The 3 failures are identical in
    both runs and are pre-existing, Windows-only baseline failures, not caused by this PR:
    tests/tools/test_bash_tool.py::TestBashTool::test_command_error_handling,
    ::test_session_restart, ::test_successful_command_execution (they depend on pexpect/POSIX
    bash session behaviour, so they fail on a Windows checkout of main and pass on the Linux CI
    runners).

  4. Static checks on the changed files only:

    $ pre-commit run --files trae_agent/cli.py tests/test_cli_max_steps.py
    trailing whitespace / end-of-file / check-added-large-files / detect-private-key: Passed
    ruff / ruff-format / codespell: Passed
    mypy: Failed - trae_agent\tools\bash_tool.py:49: error: Module has no attribute "setsid"
    

    The mypy finding is in trae_agent/tools/bash_tool.py, a file this PR does not touch: os.setsid
    is POSIX-only, so mypy on Windows reports it for any checkout of main. No mypy error is
    reported for the two changed files.

  5. Conflict screen against the open PRs that edit the same files. trae_agent/cli.py is touched by
    15 open PRs, but none of their diff hunks cover the interactive option line (base lines
    423-427), and a three-way merge of this branch against the nearest seven heads
    (#412 #423 #434 #435 #436 #437 #438) is clean:

    $ git merge-tree --write-tree fix/interactive-max-steps-default cm434   # ... repeated per head
    (no CONFLICT output, exit 0 for all seven)
    

Linked Issues

Resolves #491

The interactive command declared `default=20` for --max-steps, while run and
show-config left it unset. click then always passed 20 as the CLI value, which
outranks the config file in resolve_config_value, so agents.trae_agent.max_steps
was silently ignored in interactive mode.
@sxh313

sxh313 commented Sep 26, 2026

Copy link
Copy Markdown
Author

Closing this PR on the same three measurements documented on #490, re-taken at 2026-09-26T00:39Z. The reason is the state of the repository, not the change.

  1. Merged pull requests in the last 30 days: 0. GET /search/issues?q=repo:bytedance/trae-agent is:pr is:merged merged:>=2026-08-28 → total_count = 0. Newest merged PR anywhere: fix(openai): persist tool outputs in message history #369, merged_at = 2026-02-05T11:21:00Z.
  2. main has one commit in the last twelve months. GET /repos/bytedance/trae-agent/commits?sha=main&since=2025-09-27 → 1 commit, e839e559a (2026-02-05). This PR's base.sha is that same commit, so nothing upstream has touched the case it covers — the interactive command not honouring a configured max_steps.
  3. Nothing here has ever been machine-validated. GET /commits/e5a544b67b045784d42c04a8e184e68fbb78aba1/check-runs → total_count = 0; the two runs created for this head, Unit Tests 36205149933 and Pre-commit 36205150000 (created 2026-09-26T00:31:10Z), are completed / action_required with jobs total_count = 0 each — no job, no step, no log. A fork PR's first run needs a maintainer's approval to start; that approval has not been given to anything in this repository since February.

Expect the red ✗ on those two runs within a second or two of this close: it happened on all three earlier batches today (closes at 18:22Z, 22:32Z, 00:31Z), the flip lands 1–2 s after closed_at and the job count stays 0. That is the close reported against runs that never started, not a test result.

One thing to say plainly, because both sides of this are the same GitHub account: the PR above and this close come from sxh313 driven by two different automations. The filing side keeps producing one PR per cycle on this repository (#476 #478 #480 #482 #484 #486 #488 #490 #492 — nine in six hours, and this one was opened fourteen seconds before the previous was closed); the triage side closes them on the three numbers above. No human is being overruled here, and no contributor's work is being judged — it is a recorded disagreement between two jobs, and the visible symptom is this pile. The durable fix is to stop filing against a repository whose last merge was 2026-02-05, which is a configuration change on the filing side rather than something a close can accomplish.

The branch sxh313/trae-agent:fix/interactive-max-steps-default stays and gh pr reopen restores this thread. If the project revives, rebase onto a live main — this is worth a second look rather than a rewrite.

@sxh313 sxh313 closed this Sep 26, 2026
@sxh313 sxh313 reopened this Sep 26, 2026
@sxh313

sxh313 commented Sep 26, 2026

Copy link
Copy Markdown
Author

Reopening at the lane owner's instruction, 2026-09-26.

Re-checked against bytedance/trae-agent at main = e839e559a (the commit this PR is based on; main has not moved since): the defect in #491 is still present and nothing upstream addresses it. The branch fix/interactive-max-steps-default is unchanged, still applies cleanly, and carries the regression test described above.

My closing comment recorded why the thread was parked - this repository has accepted no pull requests since 2026-02-05, so fork CI runs here stay at action_required and nothing about this change can be machine-validated - not that the change was wrong or the report was unfounded. Leaving the fix linked to the open report is the more useful state for anyone who picks either of them up. Nothing is requested of maintainers by this reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: trae-cli interactive ignores max_steps from the config file

1 participant