Skip to content

feat(agent-core): drop default timeouts for print-mode background tasks - #1737

Merged
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/print-no-background-timeouts
Jul 15, 2026
Merged

feat(agent-core): drop default timeouts for print-mode background tasks#1737
sailist merged 3 commits into
MoonshotAI:mainfrom
sailist:feat/print-no-background-timeouts

Conversation

@sailist

@sailist sailist commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No tracking issue — the problem is explained below (happy to open one for prior discussion if maintainers prefer).

Problem

In print mode (kimi -p), background work was still bounded by interactive-era wall-clock timeouts, which breaks long headless runs:

  • Background Bash tasks were killed after a 600s default timeout unless the model remembered to pass timeout/disable_timeout (observed end-to-end: a 30-minute sleep launched in a -p run was killed at 600s).
  • A foreground command that timed out and was auto-moved to the background got re-armed to the same 600s deadline and killed shortly after.
  • Subagents (Agent / AgentSwarm) inherited a 2h cap (72h in print mode) — still a wall-clock kill a headless run cannot reason about.

Meanwhile print mode already defaults to print_background_mode = "steer" with effectively unbounded wait limits (#1722), so the remaining per-task timeouts were the last thing that could cut a -p run's work short.

What changed

Print mode (kimi -p) now never stops background work by wall-clock; only the model itself stops a task. Interactive defaults are unchanged.

  • New [background] bash_task_timeout_s config (seconds; 0 = no timeout). It drives the default deadline for background Bash tasks and the re-arm deadline for foreground commands moved to the background. Explicit per-call timeout is still honored (and capped at 24h).
  • [subagent] timeout_ms now accepts 0 = no timeout; the 0 is threaded through Agent/AgentSwarm task registration, and the swarm batch no longer arms setTimeout for non-positive timeouts (previously 0 would have aborted a task instantly).
  • Print-mode config defaults fill both with 0 (per-key, explicit user config always wins), alongside the existing unbounded max_steps_per_turn.
  • The Bash tool description and JSON-schema parameter text are rewritten when the effective default is "no timeout", so the model is not told tasks die at 600s nor nudged into defensive timeout arguments.

Verification:

  • Unit: new cases for the Bash timeout default (0/configured/explicit override/description), resolveSubagentTimeoutMs 0-semantics, and print-defaults fill/override; full agent-core suite passes (3798 tests).
  • End-to-end (SEA build, pristine config): a 700s background Bash task launched with no timeout arguments runs to completion and its completion steers a new main turn (previously killed at 600s); a 30-minute background task keeps the run alive and is answered; concurrent mixed tasks (3 Bash + 1 subagent) each steer a turn and are all answered; one-shot crons fire and are answered before exit.
  • Docs (config-files, tools, en/zh) updated for the new key and corrected defaults; changeset included (minor).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

- add `bash_task_timeout_s` config under [background] (0 = no timeout),
  covering the background Bash default and the re-arm after a foreground
  command is moved to the background on timeout
- allow `[subagent] timeout_ms = 0` (no timeout) and thread it through
  Agent/AgentSwarm task registration and the swarm batch timer
- fill both with 0 in print-mode config defaults so `kimi -p` never kills
  background work by wall-clock and only the model stops a task;
  interactive defaults are unchanged
- sync the Bash tool description/parameter text with the effective
  default and update user docs (en/zh) plus changeset
@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 30abb48

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 15, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@30abb48
npx https://pkg.pr.new/@moonshot-ai/kimi-code@30abb48

commit: 30abb48

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ae22da948

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// give it the background default so it is not still bounded by the
// shorter foreground deadline (`undefined` = no timer when the
// config disables the background timeout).
detachTimeoutMs: this.backgroundTimeoutMs,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the foreground timer on no-timeout detach

When background.bash_task_timeout_s=0 and a foreground Bash command is manually detached (Ctrl+B/RPC) before its foreground timeout, this passes undefined as detachTimeoutMs. BackgroundManager.detach only resets the timer when detachTimeoutMs !== undefined, so the original foreground deadline remains armed and the now-background task is still killed at the foreground timeout, contrary to the no-timeout default. Pass a value that clears the timer, such as 0, or update the manager to clear on no-timeout detach.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 30abb48. detachTimeoutMs is now 0 (clear-on-detach) instead of undefined when the background timeout is disabled, so a manually detached foreground command no longer keeps its armed foreground deadline. Added a regression test that drives a manual detach before the foreground timeout and asserts the task stays running.

sailist added 2 commits July 15, 2026 14:20
…kground timeout is disabled

`detach()` only re-arms when `detachTimeoutMs` is defined, so passing
`undefined` with `bash_task_timeout_s = 0` kept the armed foreground
deadline and a manually detached command was still killed at its
foreground timeout. Pass `0` instead so the reset clears the timer.
Caught by Codex review on MoonshotAI#1737.
@sailist
sailist merged commit 5d6ff02 into MoonshotAI:main Jul 15, 2026
14 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 15, 2026
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.

1 participant