Skip to content

ENG-3444: Apply the tenant's per-task limits to web turns - #577

Draft
alecantu7 wants to merge 3 commits into
stagingfrom
alejandrocantu/eng-3444-web-tasks-ignore-the-users-limit-settings-and-stop-at-10
Draft

alecantu7 wants to merge 3 commits into
stagingfrom
alejandrocantu/eng-3444-web-tasks-ignore-the-users-limit-settings-and-stop-at-10

Conversation

@alecantu7

@alecantu7 alecantu7 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Why

Web turns run on anton's built-in limits (25 steps, 3 auto-continues, 1.25M tokens), whatever the tenant set in Settings, because the pod never receives the tenant's settings (ENG-3444). Desktop doesn't have this problem: cowork-server overlays the settings onto anton for an in-process turn.

What changed

  • TurnRequestV1 reads an optional limits block: max_tool_rounds, max_continuations, max_turn_tokens.
  • build_cloud_chat_session applies each one present in place of anton's default.
  • Each value is checked on its own: a known name, an integer (not a bool), at or above its minimum. A bad value is dropped and that limit keeps its default; the turn doesn't fail. A token limit of 0, which anton reads as "no limit", is refused so a producer bug can't turn the ceiling off.
  • No block (an older controller or cowork-server) keeps today's behaviour.
  • Each dropped limit is logged as a warning with its name, the reason (unknown limit, not an integer, below its minimum) and the conversation id, as an unparsable started_at is. Values are never logged. A block that isn't an object is logged too; an absent block logs nothing.

Validation

  • uv run --group dev pytest tests/ --ignore=tests/e2e: 5,282 passed, 237 skipped on the first commit. On the logging commit, 5,276 passed and 9 subprocess tests failed (test_cloud_turn_process.py, test_chat_scratchpad.py) identically with the change stashed: locally the venv's .pth files carry the macOS hidden flag, which Python 3.12.12 skips, so a child process can't import anton. Environmental; CI on Linux decides.
  • Logging tests: each drop is logged once, by name and reason, with the conversation id and never the value; a non-object block is logged; no block logs nothing. Each was checked to fail with its part reverted, including logging the value.
  • New tests build a real ChatSession from a request line and check its step, auto-continue and token caps; without a block it keeps CoreSettings defaults; one limit replaces only its own default. Contract tests cover a missing or non-object block, unknown names, strings, floats, negatives, bools, a 0 token limit, and 0 auto-continues (a real value).
  • Each of these was checked to fail with the matching line reverted: not applying the block, not parsing it, accepting 0 tokens, accepting bools.
  • The wire test sends 7 / 2 / 4,000,000, unlike both anton's old (25 / 3 / 1.25M) and anton#576's new (250 / 10 / 25M) defaults, so it can't pass by accident once both merge. It fails with the loop that applies the block removed.
  • Rebased onto staging on 2026-10-21: uv run --group dev pytest tests/ --ignore=tests/e2e: 7,749 passed, 267 skipped (run from a checkout outside ~/Documents, where the macOS hidden-.pth problem doesn't occur).

Limitations

  • Reaches web pods automatically: their image is rebuilt from anton on every push to staging and every release. On its own that changes nothing, because nothing sends limits until cowork-server#694.
  • The web time limit and its "Keep going" card are not here; that work comes next under ENG-3444 (scratchpad-controller#73, which it builds on, has merged).

Merge order (ENG-3442)

  1. ENG-3443: Default the turn limits to the safety limits cowork-server#693: the new defaults for desktop and self-hosted.
  2. ENG-3445: Let users opt into task limits; run to the defaults until they do cowork-server#695, then ENG-3445: Add the limits switch to Advanced Settings cowork#1213: the limits switch, server first, then Settings.
  3. Web plumbing, in any order. On their own they change nothing a user sees: ENG-3444: Apply the tenant's per-task limits to web turns #577, mindsdb/scratchpad-controller#89, mindsdb/scratchpad-controller#90, ENG-3444: Pin that controller liveness keeps a quiet web turn alive, and describe it cowork-server#696.
  4. Held until the web 60-minute limit (the rest of ENG-3444) lands:

mindsdb/cowork_evals#35 can merge at any time.

The wire is skew-safe in any order. An older controller drops the block (_build_request is an allowlist) and params accepts any key. An older pod ignores an unknown request key. A pod with no block keeps anton's defaults.

🤖 Generated with Claude Code

@alecantu7
alecantu7 force-pushed the alejandrocantu/eng-3444-web-tasks-ignore-the-users-limit-settings-and-stop-at-10 branch 2 times, most recently from d1d4028 to daf8832 Compare October 21, 2026 16:06
alecantu7 and others added 3 commits October 21, 2026 15:30
… (ENG-3444)

A web turn ran on anton's built-in 25 steps, 3 auto-continues and 1.25M
tokens whatever the tenant set, because the pod never received the
tenant's settings. TurnRequestV1 now reads an optional `limits` block
(max_tool_rounds, max_continuations, max_turn_tokens) and the cloud
session applies each one in place of the default.

Unknown names and unusable values are dropped one by one, so a bad value
leaves that limit at the default rather than failing the turn. A token
limit of 0, which anton reads as no limit, is refused. No block (an older
controller) keeps today's behaviour.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… (ENG-3444)

A limit dropped in silence looked exactly like a controller that sent no
block: the only symptom was a web turn stopping at anton's default. Each
drop is now logged as a warning with the limit's name, the reason (unknown
limit, not an integer, below its minimum) and the conversation id, as an
unparsable started_at is. Values are never logged. A block that is not an
object is logged too; an absent block logs nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The wire test sent 250 / 10 / 25M, the higher defaults anton#576 brings, so
with both merged it would pass even if the session ignored the request.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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