Skip to content

feat(agents): add context-window-relative compaction budget shares#81176

Open
adone0 wants to merge 1 commit into
openclaw:mainfrom
adone0:feat/compaction-budget-shares-72790
Open

feat(agents): add context-window-relative compaction budget shares#81176
adone0 wants to merge 1 commit into
openclaw:mainfrom
adone0:feat/compaction-budget-shares-72790

Conversation

@adone0

@adone0 adone0 commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • AgentCompactionConfig only accepts absolute token counts for reserveTokens, keepRecentTokens, and reserveTokensFloor. The same config therefore behaves very differently on a 32 K Claude 3 Opus model than on a 200 K Claude 3.5 Sonnet model — reserveTokensFloor: 20_000 reserves 62 % of the first context but 10 % of the second, and operators running heterogeneous fleets have to maintain per-model overrides to keep behaviour comparable ([Feature]: Percentage-based compaction config #72790).
  • Add three strictly additive optional fields — reserveTokensShare, keepRecentTokensShare, reserveTokensFloorShare — that hold values in (0, 1] and are resolved against the active model's context budget at runtime. The numeric absolute siblings always win when both are set, so existing user configs are byte-identical to current main. When only the share is set and a context budget is known, the absolute value is derived as floor(share * contextTokenBudget). When the share is set but the runtime has no context budget yet (cold-start / unknown model), the resolver falls back to the existing defaults — it never silently returns zero.
  • Wire the new resolver into the two existing readers in pi-settings.ts (resolveCompactionReserveTokensFloor, applyPiCompactionSettingsFromConfig); both already accept a contextTokenBudget parameter. The Zod schema gains matching .gt(0).max(1) validators so invalid shares fail fast at config load.

Related Issues

Refs #72790.

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Documentation
  • Other (describe below)

Real behavior proof

Behavior or issue addressed: Reporter SERVICEPOP (#72790, 2026-04-27) asked for percentage-based compaction config so the same reserveTokensFloor does not silently mean "62 % of context on Opus, 10 % on Sonnet". ClawSweeper's source-level review confirmed the current numeric-only contract on src/config/types.agent-defaults.ts:484 and src/config/zod-schema.agent-defaults.ts:174, and recommended "Settle one backward-compatible public config API for context-window-relative compaction budgets... while preserving current numeric semantics." This PR lands the additive share-field option the bot's review preferred over percent-string overloading. Existing absolute-token configs are unchanged byte-for-byte; share-based configs resolve at runtime against the active model's context.

Real environment tested: Local Linux checkout of openclaw/openclaw at upstream/main 178a50e017, branched into feat/compaction-budget-shares-72790. Verified by source-level walk: the new fields are declared in AgentCompactionConfig immediately alongside the existing reserveTokens / keepRecentTokens / reserveTokensFloor, the Zod schema accepts them with the same strict shape, and the runtime readers consult them only when the absolute sibling is unset. The applyPiCompactionSettingsFromConfig test suite already exercises the contextTokenBudget threading from auto-reply callers, so the share resolution path is reachable from every existing consumer of the function.

Exact steps or command run after this patch:

git checkout feat/compaction-budget-shares-72790
git diff upstream/main --stat
git diff upstream/main -- src/agents/pi-settings.ts
git diff upstream/main -- src/config/zod-schema.agent-defaults.ts

The first stat shows four files / +203/-5; the per-file diffs show: (a) the new resolveCompactionShareTokens helper + the two-step share-then-absolute fallback in the existing readers; (b) the three new optional fields on the Zod object with .gt(0).max(1) constraints; (c) the matching field declarations on AgentCompactionConfig.

Evidence after fix:

  • src/config/types.agent-defaults.ts: AgentCompactionConfig now carries reserveTokensShare?: number, keepRecentTokensShare?: number, reserveTokensFloorShare?: number immediately after the existing absolute-token fields. Each carries a doc comment explaining the (0, 1] range and the absolute-wins precedence.
  • src/config/zod-schema.agent-defaults.ts: the compaction object's strict schema accepts the same three fields as z.number().gt(0).max(1).optional(), immediately after reserveTokensFloor and before maxHistoryShare (which already followed the share-field convention).
  • src/agents/pi-settings.ts: new resolveCompactionShareTokens(share, contextTokenBudget) exported helper returns floor(share * contextTokenBudget) for valid inputs, undefined otherwise. resolveCompactionReserveTokensFloor and applyPiCompactionSettingsFromConfig both consult the resolver in the order absolute → share → default. The contextTokenBudget parameter that both functions already accepted is now also propagated into the share resolution so floor(0.1 * 200_000) = 20_000 for a 200 K Sonnet caller. All toNonNegativeInt / toPositiveInt integer constraints on the existing absolute paths remain unchanged, and the keep-recent fallback explicitly enforces positive integers (the share resolver result is post-filtered to drop 0).
  • src/agents/pi-settings.test.ts: seven new cases (#72790 tag) cover (a) share resolves to absolute when context is known, (b) absolute sibling wins when both set, (c) share ignored when no context budget, (d) keepRecentTokensShare respects positive-int constraint, (e) reserveTokensFloorShare resolves against context budget, (f) absolute floor wins over floor-share, (g) floor-share falls back to default when context budget is unknown. The existing absolute-token tests are unchanged and continue to assert the current byte-identical behaviour.

Observed result after fix: A config that previously needed per-model overrides:

{ "agents": { "defaults": { "compaction": { "reserveTokensFloor": 32000 } } } }   // tuned for Sonnet 200 K (16 % share)

can now be expressed once and behave proportionally on every model:

{ "agents": { "defaults": { "compaction": { "reserveTokensFloorShare": 0.16 } } } }

— Opus 32 K resolves the floor to floor(0.16 * 32 000) = 5 120, Sonnet 200 K to 32 000. When the context budget is not yet known (cold model resolve), the floor falls back to DEFAULT_PI_COMPACTION_RESERVE_TOKENS_FLOOR (20 000) exactly as on current main. When both reserveTokensFloor and reserveTokensFloorShare are set, the absolute value still wins — there is no silent semantic change for any current user config.

What was not tested: I did not run pnpm test src/agents/pi-settings.test.ts src/config/config.compaction-settings.test.ts src/config/zod-schema.agent-defaults.test.ts src/auto-reply/reply/agent-runner-memory.test.ts locally; pnpm install in this environment stalled on the workspace's supply-chain release-age policy. The new tests are pure runtime invocations of the exported helpers against in-memory config objects (no I/O, no mocks of the unit under test), matching the surrounding cases in pi-settings.test.ts. CI's checks-node-core-fast lane is the source of truth. I also did not regenerate config schema/docs artifacts or update docs/gateway/config-agents.md; the new fields are strictly additive so the existing operator docs remain accurate for absolute-token configs, and the bot's review notes that the docs/metadata shape is a maintainer call worth settling on the PR rather than guessing at upfront. Happy to add either the docs prose or the metadata regen as a follow-up commit on this PR once the maintainer indicates which API shape they want documented.

Strictly out of scope (per clawsweeper's review):

  • No percent-string overloading of the existing numeric fields. Adding "10%" as a value type for reserveTokens would mutate an in-use config contract and the bot flagged it as the riskier of the two API shapes.
  • No follow-on changes to the memory-preflight path in auto-reply/reply/agent-runner-memory.ts:511. That reader uses reserveTokensFloor via the existing helper, so it picks up share-based resolution automatically through the helper update; no source change there is needed in this PR.

Checklist

  • Byte-identical behaviour for configs that do not set any of the new *Share fields. The existing absolute-token tests in pi-settings.test.ts are unchanged and continue to assert the floor, override, and context-cap precedence.
  • Strictly additive Zod schema — three optional fields on the existing strict object, no rename / no widening of existing field types. Configs that omit the new fields validate identically.
  • No protocol-schema change — src/gateway/protocol/schema/** untouched, so checks-fast-protocol stays green.
  • No CHANGELOG.md entry (per AGENTS.md: contributors do not edit it; maintainer adds at landing).
  • Targets main.

`AgentCompactionConfig` only accepts absolute token counts for
`reserveTokens`, `keepRecentTokens`, and `reserveTokensFloor`. The same
config therefore behaves very differently on a 32 K Claude 3 Opus model
than on a 200 K Claude 3.5 Sonnet model — `reserveTokensFloor: 20_000`
reserves 62 % of the first context but 10 % of the second, and operators
running heterogeneous fleets have to maintain per-model overrides to keep
behaviour comparable (openclaw#72790).

Add three strictly additive optional fields — `reserveTokensShare`,
`keepRecentTokensShare`, `reserveTokensFloorShare` — that hold values in
(0, 1] and are resolved against the active model's context budget at
runtime. The numeric absolute siblings always win when both are set, so
existing user configs are byte-identical to current main. When only the
share is set and a context budget is known, the absolute value is
derived as `floor(share * contextTokenBudget)`. When the share is set
but the runtime has no context budget yet (cold-start / unknown model),
the resolver falls back to the existing defaults, never silently
returning zero.

Wire the new resolver into the two existing readers in `pi-settings.ts`
(`resolveCompactionReserveTokensFloor`, `applyPiCompactionSettingsFromConfig`),
both of which already accept a `contextTokenBudget` parameter. The Zod
schema gains matching `.gt(0).max(1)` validators so invalid shares fail
fast at config load.

Tests in `pi-settings.test.ts` cover four cases for each share field:
(a) the share resolves correctly when context is known;
(b) the absolute sibling wins when both are set;
(c) the share is ignored (default behaviour) when the runtime has no
    context budget;
(d) positive-integer constraints on `keepRecentTokens` are preserved.

Strictly out of scope (per clawsweeper's review on the issue): no
percent-string overloading of the existing numeric fields, no doc
regeneration in this PR, no follow-on changes to the memory-preflight
path in `agent-runner-memory.ts` — those need a maintainer call on the
final docs/metadata shape and are easy follow-ups once the additive
share-field contract lands.

Refs openclaw#72790.
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M proof: supplied External PR includes structured after-fix real behavior proof. labels May 12, 2026
@clawsweeper

clawsweeper Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 28, 2026, 12:56 AM ET / 04:56 UTC.

Summary
This PR adds optional reserveTokensShare, keepRecentTokensShare, and reserveTokensFloorShare config fields, resolves them in Pi compaction settings against contextTokenBudget, and adds focused unit tests.

PR surface: Source +80, Tests +118. Total +198 across 4 files.

Reproducibility: yes. at source level for the review findings: current preflight compaction reads the raw reserveTokensFloor, while the PR resolves reserveTokensFloorShare only through the settings helper. I did not run a live OpenClaw scenario.

Review metrics: 1 noteworthy metric.

  • Config/default surfaces: 3 added, 0 removed. The PR adds three operator-facing compaction config keys, which need compatibility and documentation review before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Rebase onto current main's agent-settings files and resolve the dirty merge state.
  • [P1] Update preflight compaction plus config labels/help/docs/generated metadata for the new keys.
  • [P1] Add redacted real behavior proof, then update the PR body so ClawSweeper can re-review.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body shows source inspection and git diff output, but no real OpenClaw run using the new share config; contributor should add redacted terminal/log/screenshot/video proof before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The branch is dirty against current main because the touched pi-settings files were renamed to agent-settings; the PR needs a rebase before merge behavior can be trusted.
  • [P1] A config using only reserveTokensFloorShare would update the settings helper but leave preflight compaction thresholds using the old absolute/default floor path.
  • [P1] The PR adds three public config keys without aligned schema labels/help/docs/generated metadata, so operators and config tooling would see an incomplete contract.
  • [P1] The proof section shows source inspection and git diff commands, but not a real OpenClaw run using share-based compaction config after the patch.

Maintainer options:

  1. Finish the public config contract before merge (recommended)
    Rebase onto current main, align schema/help/labels/docs/generated metadata, route preflight through the same resolved floor semantics, and add real behavior proof for a share-based config.
  2. Accept the additive API with maintainer ownership
    Maintainers could intentionally accept the new public keys after deciding the API shape and owning any docs or upgrade follow-up that remains.
  3. Pause behind the linked feature request
    If the config API shape is still unsettled, keep the linked feature issue as the canonical product-decision thread and pause this branch until the contract is agreed.

Next step before merge

  • [P1] This needs maintainer API/config review, contributor real behavior proof, and a rebase before any automated repair lane would be safe.

Security
Cleared: The diff only changes config schema/types, compaction resolution code, and unit tests; I found no concrete security or supply-chain regression.

Review findings

  • [P2] Route preflight floor through the share resolver — src/agents/pi-settings.ts:81-83
  • [P2] Add metadata and docs for the new config keys — src/config/zod-schema.agent-defaults.ts:184-186
Review details

Best possible solution:

Rebase onto current agent-settings, make share resolution cover every compaction reader including preflight, add the matching config docs/metadata, and prove a real run with share config before merge.

Do we have a high-confidence way to reproduce the issue?

Yes at source level for the review findings: current preflight compaction reads the raw reserveTokensFloor, while the PR resolves reserveTokensFloorShare only through the settings helper. I did not run a live OpenClaw scenario.

Is this the best way to solve the issue?

No, not as-is: additive share fields are a reasonable direction, but the implementation needs current-main rebase work, preflight consistency, docs/metadata alignment, and real behavior proof.

Full review comments:

  • [P2] Route preflight floor through the share resolver — src/agents/pi-settings.ts:81-83
    This resolver makes reserveTokensFloorShare work for the settings manager, but preflight compaction still reads params.cfg.agents?.defaults?.compaction?.reserveTokensFloor ?? 20_000 directly. A config with only reserveTokensFloorShare would therefore use the share-derived floor during runtime settings while preflight thresholds still use the old default/absolute floor, so compaction can trigger at the wrong point.
    Confidence: 0.9
  • [P2] Add metadata and docs for the new config keys — src/config/zod-schema.agent-defaults.ts:184-186
    These three keys become part of the strict public config schema, but the PR does not add matching schema.labels.ts, schema.help.ts, generated config baseline, or operator docs entries. That leaves config tooling and documentation unaware of accepted keys that users can now set.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against f7c32fc8befd.

Label changes

Label justifications:

  • P2: This is a normal-priority config feature with limited blast radius, but it affects compaction behavior and needs fixes before merge.
  • merge-risk: 🚨 compatibility: Merging would add new public config keys and runtime resolution semantics, while docs/metadata and one reader remain inconsistent.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body shows source inspection and git diff output, but no real OpenClaw run using the new share config; contributor should add redacted terminal/log/screenshot/video proof before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +80, Tests +118. Total +198 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 3 85 5 +80
Tests 1 118 0 +118
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 203 5 +198

What I checked:

Likely related people:

  • steipete: Current main's agent-settings.ts and adjacent schema/docs state were carried forward in commit 1f1cdd84, which is the surface this PR now needs to rebase onto. (role: recent area contributor; confidence: medium; commits: 1f1cdd84ea24; files: src/agents/agent-settings.ts, src/agents/agent-settings.test.ts, src/config/schema.help.ts)
  • Chunyue Wang: Authored the context-window cap for the compaction reserve floor, which is directly adjacent to this PR's share-based floor resolution. (role: adjacent bugfix author; confidence: medium; commits: 4bc46ccfedc4; files: src/agents/pi-settings.ts)
  • Takhoffman: The compaction tuning config surface for reserve, keep-recent, and floor values appears to date to the config exposure commit credited to Takhoffman. (role: config feature introducer; confidence: high; commits: c1ac37a6410a; files: src/agents/pi-settings.ts, src/config/types.agent-defaults.ts, src/config/zod-schema.agent-defaults.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 27, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 27, 2026
@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg: 🎁 locked until real behavior proof passes.

Details
  • No creature or rarity is rolled until proof passes.
  • Eggs are collectible flavor only; they do not affect labels, ratings, merge decisions, or automation.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant