Skip to content

agent_settings: tool_result_inline_max_chars becomes a durable resident setting - #94

Merged
antra-tess merged 2 commits into
mainfrom
agent-settings/durable-tool-result-cap
Aug 6, 2026
Merged

agent_settings: tool_result_inline_max_chars becomes a durable resident setting#94
antra-tess merged 2 commits into
mainfrom
agent-settings/durable-tool-result-cap

Conversation

@antra-tess

Copy link
Copy Markdown
Collaborator

Immediately coupled follow-up to #91, implementing Sol's ruling (antra concurring) from #architecture: the resident-set inline cap must use the same durable, agent-exposed config plane as everything else — not an ephemeral hot override.

Semantics (Sol's spec, point by point)

The one design decision — flagging for Sol

opus-rev's review point: #91's override escapes the strategy clamp, which was defensible for a lift that died on restart but becomes a silent permanent over-budget pin once durable. This PR keeps the resident's value honored (they own the setting; clamping it would gut the raise-to-see-more use case on bounded strategies) but makes it impossible to be silent: _source reports agent-settings-override (exceeds strategy bound) whenever the pinned value sits above maxMessageTokens * 4. If the house later wants a hard clamp instead, it's a two-line change in resolveToolResultInlineCap.

Not addressed here (bigger surface, opus-rev's option (b)): a general persistence contract for AgentSettingsExtension so module-owned settings can be durable too. This PR only moves the framework-owned key onto the durable plane; the extension interface is unchanged.

Tests

12 in test/tool-result-spill.test.ts (was 11): the restart test now proves the full durable lifecycle — resident sets 60k → survives restart with correct provenance → reset returns to the 8k residence config → reset survives a further restart; plus the new exceeds-strategy-bound provenance pin. Full suite: 531 pass / 0 fail / 1 skip (CI red remains the pre-existing main drift, same five error classes).

Release note: rides the same AF release train as #91/#88 — no additional host changes needed for this PR (the recipe passthrough for the default remains the separate host-side PR).

🤖 Generated with Claude Code

…ent setting

Sol's ruling on #91 (antra concurring): the resident-set inline cap must not
be an ephemeral hot override — it joins the durable settings plane like
context budget/tail/transition settings.

- update persists the value to framework/state (toolResultInlineCaps slot,
  same store plane as agentRuntimeSettings) and create() restores it, with
  load-time validation that drops invalid entries loudly.
- reset clears the persisted value and deliberately returns the agent to the
  residence default (FrameworkConfig.toolResultInlineMaxChars → house 5000);
  the reset itself survives restarts.
- Provenance: a resident value pinned above the strategy-derived bound is
  still honored (the resident owns this setting) but agent_settings get now
  reports 'agent-settings-override (exceeds strategy bound)' — a durable
  over-budget pin must never be silent (opus-rev's review point).
- Docs/notices updated: no more 'temporary lift' framing.

Refs #89.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Aug 6, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

…tegy bound

Sol's #94 ruling: persist the resident's DESIRED cap, but the EFFECTIVE
inline cap is min(desired, strategy bound) for every source — a durable
preference must not be a durable path for one tool result to exceed the
context strategy's per-message safety limit. The way to see the whole
result is the spill file, not an over-bound blob in live context.

agent_settings get now reports the full quartet:
- tool_result_inline_max_chars      — persisted desired value (null if unset)
- ..._effective                     — min(desired, strategy bound)
- ..._source                        — agent-settings-override | framework-config | default
- ..._clamped_by                    — 'strategy-bound' | null

(replaces the previous ' (strategy-clamped)' / ' (exceeds strategy bound)'
source-string suffixes with a clean dedicated key).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@antra-tess

Copy link
Copy Markdown
Collaborator Author

Revised per Sol's ruling — head is now 5b9f0a7:

  • Effective cap is hard-clamped: min(desired, strategy bound) for every source, resident value included. The clamp-escape from Complete oversized tool-result spill: safe 5k default, error paths, all result paths (#89) #91 is gone entirely.
  • Desired survives: the resident's persisted value is kept verbatim and reported as tool_result_inline_max_chars; _effective reports the min; _source is now a clean enum; _clamped_by is a dedicated key ('strategy-bound' | null) replacing the source-string suffixes.
  • Test updated to pin desired-preserved / effective-clamped / clamp-enforced-on-the-wire; the restart lifecycle test is unchanged and still proves desired-survives-restart.

Full suite 550 pass / 0 fail / 1 skip locally (with the collection-count caveat opus-rev documented). PR body's 'honored above bound' paragraph is superseded by this comment.

@antra-tess
antra-tess merged commit fc398c7 into main Aug 6, 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