fix(agent): cut a dense screen by the judgment's measured instruction

Merged
OK
14d ago
+37-11

What and why

  • A judgment (agent.assert, agent.waitFor, agent.extract) sized its observation from the system message plus a fixed 4,096-byte reserve (packages/e2e/src/agent/observation-budget.ts). The instruction itself was never measured.
  • An instruction past that reserve, a few thousand characters of extract or the explore planner's record of earlier steps, pushed the request over maxInputTokens and the adapter's pre-flight refused it with STEP_BUDGET_EXHAUSTED before anything was sent. e2e explore then ended aborted with no assessment.
  • The budget now subtracts the instruction's measured bytes; the reserve stays for the request text, markup and a repair section. The act loop passes 0: its instruction opens the history and is not resent with each observation.
flowchart LR
  S[system bytes] --> O[observation budget]
  I[instruction bytes, measured] --> O
  R[reserve: request text, markup, repair] --> O
  O --> C[screen cut to fit maxInputTokens]

Closes #1091

Verified

Ran it locally: yes

  • The issue's dense page (1,753 nodes) under /tmp, e2e run on its agent.extract test and e2e explore on its 1,903-character goal, no API key, default maxInputTokens. Same commands against a main build.
runmainthis branch
extract, 3,388-char instructionSTEP_BUDGET_EXHAUSTED: model input upper bound 64481 exceeds the agent's maxInputTokens 64000, observation 58,817 bytespre-flight passes, fails only on MODEL_PROVIDER_FAILED: OpenAI API key is missing, observation 55,429 bytes
extract, 7,888-char instructionnot run (issue reports 68981 exceeds 64000)pre-flight passes, key missing, observation 50,942 bytes
extract, 1-clause instructionobservation 58,817 bytesobservation 58,722 bytes
explore, 1,903-char goal, --max-steps 3no step ran, STEP_BUDGET_EXHAUSTED ... 64990 exceeds ... 64000, ended: aborted, observation 56,864 bytespre-flight passes, fails only on the missing key, observation 52,956 bytes
# this branch, explore
   no step ran
   ended: the run was cut short
MODEL_PROVIDER_FAILED: model provider failed: OpenAI API key is missing. ...

The short-instruction control loses 95 bytes of observation: the instruction's own size, now measured instead of folded into the reserve.

Checklist

  • Changeset added (pnpm changeset) for any change to a published package, or the change is testbed, docs, or CI only.
  • Breaking change: title carries !, the changeset body names what breaks and what replaces it, and the deprecation warning landed a window earlier (stability policy in CONTRIBUTING.md).
  • Docs updated in the same PR: the docs/**/*.mdx page for the behavior, and skills/e2e/ if the skill describes it. (docs/reference/config.mdx already promises "a dense screen is cut to fit under it"; no change.)
  • Contract change: emitted .d.ts reviewed, tests/types/sdk-types.ts updated; wire change edits the schema and both fixtures.
  • Engine contract change (e2e/engine): changesets for e2e, @e2e-dev/web, and @e2e-dev/mobile.