Skip to content

feat(context-ts): add context strategy presets + rewire defaults to use class - #4256

Merged
lizradway merged 10 commits into
strands-agents:mainfrom
lizradway:cm-presets-and-rewire
Sep 11, 2026
Merged

lizradway merged 10 commits into
strands-agents:mainfrom
lizradway:cm-presets-and-rewire

Conversation

@lizradway

@lizradway lizradway commented Sep 9, 2026

Copy link
Copy Markdown
Member

Summary

Adds strategy presets to ContextManager and rewires the 'auto' and 'agentic' modes to use ContextManager internally instead of SummarizingConversationManager. This makes ContextManager the single owner of context reduction — overflow recovery, proactive compression, and emergency truncation all flow through the strategy pipeline.

What changed

  • Strategy presets: named building blocks ('proactiveSummarization', 'largeToolOffloading', 'overflowProtection', 'staleToolCleanup') that resolve to concrete Offload.* strategies. Usable in the strategies array alongside raw strategies.
  • ContextManager.from() factory: resolves ContextManagerStrategy values ('auto' | 'agentic' | ContextManagerConfig | false) into internal ContextManager instances. Validates unknown preset strings.
  • Agent config simplified: contextManager on AgentConfig accepts a preset string or config object. The agent constructs and registers the manager — no need to instantiate ContextManager directly.
  • ContextManager class removed from barrel: it's an internal implementation detail. Only the config types and Offload builder are public.
  • _removalRatio removed: preserveRecent is now the sole control for message-level removal. Decimal (0 < n < 1) = ratio, integer (>= 1) = absolute count.
  • Overflow recovery: strategies bypass utilization gates when running in response to ContextWindowOverflowError (the estimate undercounts without system prompt/tool specs). Emergency truncate also honors the overflow flag but clears it once strategies bring utilization below 1.0.
  • Pinned message support: BaseOffloadStrategy now filters out pinned messages (and tool-pair partners) in both message-level and per-block paths. Emergency truncate ignores pins as a last resort.

API changes

New exports (all @experimental):

// Config types
export type { ContextManagerStrategy }    // 'auto' | 'agentic' | ContextManagerConfig | false
export type { ContextManagerConfig }       // { strategies?, stash? }
export type { ContextStrategy, ContextState, StashConfig }
export type { StrategyPresetName }         // 'proactiveSummarization' | 'largeToolOffloading' | ...

// Builder
export { Offload }                         // Offload.drop() / .truncate() / .summarize() + .when()
export type { OffloadTarget, OffloadConditions, OffloadStrategyBuilder }
export type { TruncateConfig, SummarizeConfig }

Changed:

  • AgentConfig.contextManager: ContextManagerStrategy (was not previously typed for presets)

Removed from barrel:

  • ContextManager class (internal — use preset strings or ContextManagerConfig instead)

Usage

// Preset (recommended)
const agent = new Agent({ contextManager: 'auto' })
const agent = new Agent({ contextManager: 'agentic' })

// Custom config with strategy presets
const agent = new Agent({
  contextManager: {
    strategies: ['largeToolOffloading', 'proactiveSummarization'],
  }
})

// Custom config with raw strategies
const agent = new Agent({
  contextManager: {
    strategies: [
      Offload.truncate('toolResults', { previewTokens: 500 }).when({ threshold: 2000 }),
      Offload.summarize('*').when({ utilization: 0.8, preserveRecent: 0.7 }),
    ],
    stash: { storage: myStorage },
  }
})

// Disable
const agent = new Agent({ contextManager: false })

Related Issues

#4053

Type of Change

New feature

Testing

  • 205 unit tests passing across context-manager module
  • Tests cover: preset resolution, ContextManager.from() validation, overflow bypass, emergency truncate, pinned message protection, strategy pipeline ordering
  • Verified overflow recovery end-to-end: strategies fire and retry is set when provider throws ContextWindowOverflowError

@github-actions github-actions Bot added enhancement New feature or request area-context Session or context related area-language Related to new language development typescript Pull requests that update typescript code labels Sep 9, 2026
@lizradway
lizradway force-pushed the cm-presets-and-rewire branch from a9150a7 to 3e9923d Compare September 9, 2026 18:33
@lizradway

Copy link
Copy Markdown
Member Author

@strandly-the-agent pls review

@github-actions github-actions Bot added complexity/low Touched functions have low cognitive complexity (<=10) size/m labels Sep 9, 2026
@lizradway
lizradway force-pushed the cm-presets-and-rewire branch from 3e9923d to 90e412e Compare September 9, 2026 18:36
Comment thread strands-ts/src/context-manager/context-manager.ts
Comment thread strands-ts/src/context-manager/context-manager.ts Outdated
Comment thread strands-ts/src/context-manager/context-manager.ts Outdated
Comment thread strands-ts/src/context-manager/strategies/offload/base.ts Outdated
Comment thread strands-ts/src/context-manager/strategies/offload/base.ts Outdated
Comment thread strands-ts/src/context-manager/__tests__/presets.test.ts Outdated
Comment thread strands-ts/src/index.ts
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Review Summary

Assessment: Request Changes

Solid, well-scoped refactor that consolidates context management behind ContextManager + strategy presets. The core direction is good, but there are a couple of blocking items and a few design questions to resolve before merge.

Review Categories
  • CI gates (blocking): format:check fails — Prettier reports style issues in context-manager.ts and offload/base.ts (ternary wrapping + a stray blank line). Run npm run format. Tests (73) and type-check pass locally.
  • API bar-raising (blocking): A significant public surface is newly exported from index.ts, but there's no api/needs-review label and the PR description is the untouched template. Add the label and the required use cases / examples / signatures.
  • Breaking API contract: contextManager no longer accepts a ContextManager instance (now ContextManagerConfig), even though ContextManager is publicly exported — and from() silently degrades an instance to the default pipeline for JS callers. Confirm this is intentional and document the migration.
  • Behavioral change: base _removalRatio 0.3 → 1.0 changes default message-level removal from 30% to 100%; not called out or directly tested.
  • Cleanup / tests: isContextManagerPreset is dead code; the preset "integration" tests only assert toBeDefined(); constructor default pipeline diverges from the 'auto' preset.

Nice consolidation overall — collapsing the SummarizingConversationManager + ContextOffloader wiring into a single ContextManager path meaningfully simplifies the agent construction logic.

@strandly-the-agent strandly-the-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes requested — the presets are a good shape; the collateral changes to the reduction path are what need work.

Three blockers, all on documented entry points (evidence for each in the inline comments):

  • 🔴 _removalRatio 0.3 → 1.0 makes every message-level strategy remove 100% of eligible messages in one pass — for all existing Offload.* users, not just the new presets.
  • 🔴 proactiveSummarization has no preserveRecent, so at 70% utilization it summarizes the pending user turn away before the model sees it.
  • 🔴 Presets now run on NullConversationManager, and the overflow retry re-gates on estimated utilization — a real ContextWindowOverflowError can end with no reduction and no retry (measured: 'auto'/'agentic' → no retry; old SummarizingConversationManager → retry).

Plus 3 🟡 inline (pins evicted under 'agentic', unvalidated preset strings, two storage tests that assert the same thing) and two design questions I'd want answered before merge: the silently-dropped conversationManager, and root barrel vs ./experimental for the new exports. The api/needs-review label + PR description the bot already asked for still apply — the export-surface decision needs an API reviewer, not a solo approve.

Not re-raised: the instance-form narrowing (fixed in d573ca9), dead isContextManagerPreset, {} vs 'auto' divergence, presets.test.ts toBeDefined(), prettier — the bot review covers those.

Details — evidence ledger, questions, reading order, appendix

Verified

  • ✅ Reviewed d573ca940bc334b53dc0da226104d5ab7cfe4408 (delta from 90e412e7 is the 3-line instanceof ContextManager passthrough) against merge-base 545d9ed0.
  • eslint (changed files) exit 0 · ✅ tsc --noEmit (src) exit 0 on both heads · 🔴 prettier --check exit 1 on 4 changed files (context-manager.ts, offload/base.ts, offload-strategy.test.ts, agent.context-manager.test.ts) · ✅ vitest run --project unit-node 32 files / 759 tests passed on 90e412e7.
  • ✅ Probes (scratch vitest files, deleted): real ContextWindowOverflowError at the AfterModelCallEvent hook → from('agentic')/from('auto') retry=undefined, 40 messages untouched; SummarizingConversationManager(0.3) retry=true, 29 left. proactiveSummarization on 10 messages at util 0.7 → [m0, "[Summarized: 9 messages…]"], the question inside the summary. truncate('*').when({utilization:0.5}) on 8 messages → 1 left (pre-PR: 2 removed); 'auto' summarize on 40 → 5 left. Pinned message at index 3 gone after 'agentic' summarize. from('manual') → default pipeline, no throw; strategies: ['typo']TypeError: resolvePreset(...) is not iterable. Forcing _removalRatio back to 0.3 leaves the whole suite green. contextManager: 'auto' + agent storage does write through (context/<session>/scopes/agent/<id>/…) — only the test got weaker.
  • Passes: triage, context-build, correctness, test-quality, docs-accuracy, API bar-raiser, adversarial. The API and adversarial passes timed out on the deep tier and were re-run on the standard tier, so the API read is somewhat shallower than usual. Raw pass outputs and logs are uploaded as artifacts.

Questions

Blocking

  • Is the _removalRatio 1.0 flip meant for all existing strategies, or was it scoped to the new presets? strands-py/.../offload/base.py:269 keeps 0.3, design 0015:1125 still documents 0.3, and 0011:102 says defaults shouldn't be set on intuition alone. If deliberate, would it be cleaner as its own PR with the benchmark — or as a ratio knob on OffloadConditions so overflowProtection can ask for a full sweep while everything else stays incremental?
  • { contextManager: 'auto', conversationManager: new SlidingWindowConversationManager({ windowSize: 20 }) } now silently discards the window (agent.ts:342; no logger.warn). Pre-PR honoured it and the site docs still promise it. Warn, or throw like the stateful-model guard at agent.ts:540-544 (Python throws at agent.py:660)?
  • src/experimental/index.ts:12-18 already exports ten of these thirteen symbols via @strands-agents/sdk/experimental (#4231); index.ts:279-291 now duplicates them in the root barrel under a code comment TypeDoc can't see. Un-exporting later is itself a break — is root export a deliberate promotion? If not, would moving the block to src/experimental/index.ts be simpler? Either way ContextManagerStrategy, Offload, OffloadStrategyBuilder, StrategyPresetName lack @experimental tags and ContextManagerPreset is referenced by an exported type but not exported.

Non-blocking

  • staleToolCleanup sets neither threshold nor utilization, so it drops older tool results on every model call even at 2% utilization; its preserveRecent: 5 counts tool-result-bearing messages, not "turns" as presets.ts:24 says. Intended?
  • preserveRecent: 0.99 ≈ keep everything, preserveRecent: 1 = keep one message, 1.5 silently floors to 1; Python types it int. Would a separate preserveRecentRatio field avoid the discontinuity?
  • The four STRATEGY_PRESET_NAMES have no Python counterpart and appear in no design doc — is serialized (JSON/YAML) config the reason they're strings rather than exported builders? That'd be worth stating in the PR body; it's the argument for the string layer.

Reading order

  1. strands-ts/src/agent/agent.ts:326-345resolveConversationManager: every non-undefined/non-false value now yields NullConversationManager. The pivot of the PR.
  2. strands-ts/src/context-manager/context-manager.ts:83-115ContextManager.from(), where 'auto'/'agentic' become strategy pipelines; compare with what agent.ts deleted.
  3. strands-ts/src/context-manager/presets.ts — the named presets (the PR's stated purpose); short and self-contained.
  4. strands-ts/src/context-manager/strategies/offload/base.ts:159-168, 295-322 — widest blast radius: preserveRecent as a ratio and the _removalRatio default; these affect every pre-existing strategy.
  5. src/index.ts:279-291, types.ts, types/agent.ts — surface changes. Tests last: agent.context-manager.test.ts shows which behaviours were dropped.
Appendix — non-blocking (9)
  • Stale site docs (not in this diff, but now false for TS): site/.../context-management.mdx:42-47 (auto = SummarizingConversationManager 0.3/0.85 + ContextOffloader; tool named retrieve_offloaded_content, actual stash tool is retrieve_context), :53-54 (co-provided manager "replaces" the auto one; offloader dedupe), :138 (agentic composition), :148 (durable-storage advice → now agent storage or contextManager: { stash: { storage } }); storage.mdx:58-61,247 (offloader/ prefix → context/<session>/scopes/agent/<id>); context-management.ts:21-27 example is now a no-op. Prose is shared py/ts and Python is unchanged, so it needs a <Tabs> split rather than a rewrite.
  • preserveRecent isn't a hard floor when a tool pair straddles the boundary (collectRemovableWithPair pulls the partner out of the preserved window) — pre-existing, but now reachable on every fire because the whole eligible set is selected.
  • Test gaps beyond the inline one: nothing asserts ContextManager.from() expansions (1500/8000, previewTokens 750, preserveRecent: 4); nothing pins message-level removal count (the truncate marker assertion at offload-strategy.test.ts:597-602 was loosened rather than pinned); ratio preserveRecent isn't covered through Offload.*.when(); the deleted param+plugins duplicate-registration test has no replacement now that the instance form is back.
  • Agent.contextManager (agent.ts:432) is public while LocalAgent.contextManager (types/agent.ts:313) is @internal — pick one; with instances back, agent.contextManager!.stash is a plausible user route.
  • ContextManager.from() is public but is Agent-construction plumbing returning ContextManager | undefined; consider @internal.
  • strategies/offload/index.ts:41 @example says "over 2500 tokens" beside .when({ threshold: 1500 }) — pre-existing text, newly published.
  • context-manager.ts:50 "On context overflow, runs the strategy pipeline" omits the BeforeModelCallEvent proactive path, which is the primary one for 'auto'.
  • presets.ts:44 comment restates the module doc; presets.ts:5-6 has a blank line mid-paragraph that breaks TSDoc rendering.
  • Prettier: 4 files, npm run format fixes it (also flagged by the bot).

Comment thread strands-ts/src/context-manager/strategies/offload/base.ts Outdated
Comment thread strands-ts/src/context-manager/presets.ts Outdated
Comment thread strands-ts/src/agent/agent.ts
Comment thread strands-ts/src/context-manager/context-manager.ts
Comment thread strands-ts/src/context-manager/context-manager.ts
Comment thread strands-ts/src/agent/__tests__/agent.storage.test.ts
@lizradway
lizradway force-pushed the cm-presets-and-rewire branch 3 times, most recently from 78d46fb to 553695e Compare September 9, 2026 20:04
…o ContextManager

- Add strategy presets (proactiveSummarization, largeToolOffloading,
  overflowProtection, staleToolCleanup) as named building blocks that
  resolve to concrete Offload strategies. Preset names are the stable
  contract; expansions may change between releases.

- Rewire auto/agentic modes to use ContextManager internally instead of
  SummarizingConversationManager + ContextOffloader.

- ContextManagerStrategy now accepts preset strings, a ContextManagerConfig
  object, or false — users no longer construct ContextManager directly.
  ContextManager.from() resolves all variants into the internal instance.

- Support decimal preserveRecent (0 < n < 1 = ratio, >= 1 = absolute count).

- Default _removalRatio to 1.0 — preserveRecent is the sole brake on what
  gets processed. Emergency truncate keeps its 0.2 override.

- Add isContextManagerPreset type guard for centralized preset checking.
@lizradway
lizradway force-pushed the cm-presets-and-rewire branch from 553695e to 00ce3dc Compare September 9, 2026 20:05
When the provider throws ContextWindowOverflowError, the token estimate
undercounts (excludes system prompt and tool specs), so utilization-gated
strategies skip even though the window is full. Add an overflow flag to
ContextState that bypasses the utilization gate on BaseOffloadStrategy
when the overflow hook fires.
@lizradway

Copy link
Copy Markdown
Member Author

@strandly-the-agent pls review

Comment thread strands-ts/src/context-manager/strategies/offload/base.ts
Comment thread strands-ts/src/context-manager/strategies/offload/base.ts
- Guard eager hook against pinned messages (fix #1)
- Add {@link ContextManagerConfig} to ContextManagerStrategy TSDoc (fix strands-agents#2)
- Remove overflow clear so emergency truncate always fires as safety net (fix strands-agents#3)
- Warn when both contextManager and conversationManager are set (fix strands-agents#4)
- Fix "turns" → "messages" in staleToolCleanup doc (fix strands-agents#5)
- Improve two-pass pinned test to exercise repairAlternation merge (fix strands-agents#8)
@github-actions

Copy link
Copy Markdown
Contributor

Follow-up review — commit d778af406 (round-2 feedback)

Assessment: Request changes (2 blocking items below; the rest of round 2 looks good)

Ran the gates on this head: context suites 135 tests pass, no type errors — but Prettier fails.

🔴 Blocking

  1. Prettier failure — CI will fail. src/context-manager/__tests__/context-manager.test.ts:186 is 123 chars (the new BeforeModelCallEvent({ ... }) one-liner) and exceeds the 120 print width. Prettier wants it wrapped:

    const event = new BeforeModelCallEvent({
      agent,
      model: agent.model,
      invocationState: {},
      projectedInputTokens: 100,
    })

    Please run prettier --write before pushing.

  2. The improved two-pass pinned test (fix models - anthropic #8) still doesn't guard the fix. I verified by reverting the repairAlternation change — the test still passes, because the fixture never actually merges the pinned message. Details + a verified drop-in fixture are in the reply on @strandly-the-agent's thread.

✅ Verified good (round 2)

Still open (design/process)
  • 🔴 _removalRatio 0.3 → 1.0 rationale/scope not captured in the PR description (Python still ships 0.3).
  • 🔴 proactiveSummarization has no preserveRecent.
  • 📋 API bar-raising: api/needs-review label + PR description (use cases / examples / signatures); experimental-vs-root-barrel export decision needs an API reviewer.

@github-actions

Copy link
Copy Markdown
Contributor

Follow-up review — commit b05df8e4d

Assessment: Comment (one blocker cleared; one blocker + design items remain)

Re-ran gates on this head: Prettier clean across the context-manager tree + agent.ts, 135 tests pass, no type errors.

Still open (design/process)
  • 🔴 _removalRatio 0.3 → 1.0 rationale/scope not captured in the PR description (Python still ships 0.3).
  • 🔴 proactiveSummarization has no preserveRecent.
  • 📋 API bar-raising: api/needs-review label + PR description (use cases / examples / signatures); experimental-vs-root-barrel export decision needs an API reviewer.

Thanks for the quick formatting turnaround.

@lizradway

Copy link
Copy Markdown
Member Author

@strandly-the-agent pls review

@strandly-the-agent strandly-the-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow-up on b05df8e — two 🟡s, both fallout from the round-2 changes. Removing the overflow clear (per opieter-aws's thread) fixes the re-gating problem but swings the other way: the emergency truncate now fires on every overflow pass even after summarize has already resolved it, eating two of the four preserved turns (and ignoring pins). And the pinned-merge test still doesn't reach the merge — it passes with the fix reverted. Both have one-line fixes inline. Gates green.

Status:

  • ✅ Eager MessageAddedEvent hook now skips pinned messages; logger.warn on co-provided conversationManager; {@link ContextManagerConfig}; staleToolCleanup doc wording.
  • 🟡 context-manager.ts:208-215 — emergency truncate runs unconditionally under overflow even when earlier strategies acted. Verified with the 'auto' pipeline: [u0+Summarized+u8, a9, u10, a11] after summarize → [u0+Summarized+u8+u10, a11] after emergency.
  • 🟡 offload-strategy.test.ts:678 — with both q10 and a11 appended the fixture is back to even length, so pinned-a3 sits between two user messages and never merges; drop a11 and the test fails without the fix (verified both ways).
  • ⏳ Still open: storage-tests thread (agent.storage.test.ts:15), api/needs-review (bot's index.ts thread).
Details
  • ✅ Reviewed b05df8e4d987bb25745c5421cb4b32b711540f9f (delta from 82402b3: 6 files, +23/−8). Self-run follow-up; each change verified, the overflow change probed with a working summarizer mock.
  • tsc 0 · eslint 0 · prettier 0 (agent.ts + context-manager/) · vitest context-manager + agent cm/storage suites 9 files / 142 passed.
  • ✅ Probe: new ContextManager() (= 'auto'), 12 messages, overflow: true, estimate 0.5 (and 1.2→0.5), summarizer returns SUMMARY. Result [u0+[Summarized: 7]+u8+u10, a11] — versus proactive at 0.9 [u0+[Summarized: 7]+u8, a9, u10, a11]; the difference is the emergency bite (drops a9, merges u10 into the head). With the inline patch: identical to proactive; a noop user strategy still lets emergency fire (a1, u2 dropped); existing context-manager.test.ts 16/16 green.
  • ✅ Pin test: on this head the survives repairAlternation merge test passes with the repairAlternation metadata line removed. With a11 deleted from the fixture it fails without the fix (expected undefined to be true) and passes with it.

Comment thread strands-ts/src/context-manager/context-manager.ts
Comment thread strands-ts/src/context-manager/strategies/__tests__/offload-strategy.test.ts Outdated
… and fix pinned merge test

- Clear strategyContext.overflow before EmergencyTruncateStrategy when
  earlier strategies already acted, preventing double-reduction after
  summarize already fixed the overflow
- Remove a11 from pinned merge test fixture so the odd-length array
  forces repairAlternation to actually merge pinned-a3 with a7
@github-actions

Copy link
Copy Markdown
Contributor

Follow-up — no new commit since b05df8e4d

Reconciling with @strandly-the-agent's follow-up review — we've converged on the same two blockers, so here's the consolidated remaining list. Both have verified one-line fixes on the inline threads.

🔴 Blocking (2)

  1. context-manager.ts:208 — emergency truncate fires on every overflow pass. I originally raised this as an "intended tradeoff, please confirm"; @strandly-the-agent's 'auto' probe shows it's actually a regression — emergency eats 2 of the 4 preserveRecent turns and ignores pins on every overflow, defeating the pinned-message guarantee this PR adds. Re-gate emergency once a prior strategy has acted (fix on the thread).
  2. offload-strategy.test.ts:678 — pinned-merge test is a tautology. Passes with the repairAlternation pin-propagation reverted; the fixture never reaches the merge. Dropping a11 restores odd length so pinned-a3 merges with a7 — then the test fails without the fix (both verified). Comment also needs the a1a7 correction.
Still open (design / process)
  • 🔴 _removalRatio 0.3 → 1.0 rationale/scope not in the PR description (Python still ships 0.3).
  • 🔴 proactiveSummarization has no preserveRecent.
  • 📋 API bar-raising: api/needs-review label + PR description (use cases / examples / signatures); experimental-vs-root-barrel export decision needs an API reviewer.

Gates are green on this head; both blockers are small, well-scoped fixes.

@lizradway

Copy link
Copy Markdown
Member Author

@strandly-the-agent pls review

@strandly-the-agent strandly-the-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Follow-up on ab518bc — both fixes verified; nothing new from me.

  • ✅ Emergency truncate re-gates once a prior strategy acted: 'auto' on overflow now yields exactly the proactive result ([u0+Summarized+u8, a9, u10, a11]); with a no-op user strategy the emergency still fires.
  • ✅ The pinned-merge test now discriminates: with the repairAlternation metadata line reverted it fails (expected undefined to be true).
  • tsc / eslint / prettier clean; context-manager + agent suites 9 files / 142 tests.

Only two things left on the board, neither a code defect: the storage-tests coverage nit (agent.storage.test.ts:15 thread — a two-line storage.list('context/') assertion, non-blocking), and the api/needs-review label for the root-barrel exports, which is the one reason I'm not stamping an approval solo — happy for an API reviewer to take it from here.

Comment thread strands-ts/src/context-manager/presets.ts
Comment thread strands-ts/src/context-manager/types.ts
Comment thread strands-ts/src/context-manager/presets.ts
@mkmeral mkmeral added the api/review-complete An API Bar-raiser reviewed and accepted the APIs label Sep 11, 2026
@lizradway
lizradway enabled auto-merge (squash) September 11, 2026 15:09
@lizradway
lizradway merged commit a8b1b90 into strands-agents:main Sep 11, 2026
30 checks passed
@lizradway
lizradway deleted the cm-presets-and-rewire branch September 11, 2026 16:38
lizradway added a commit to lizradway/harness-sdk that referenced this pull request Sep 11, 2026
…ernalize presets, fix docstring

- Remove _removal_ratio from BaseOffloadStrategy; regular strategies now
  remove all eligible messages (preserve_recent controls what to keep),
  matching TS PR strands-agents#4256
- EmergencyTruncateStrategy gets its own _apply_per_message with a
  module-level _EMERGENCY_REMOVAL_RATIO = 0.2
- Prefix resolve_preset/resolve_strategies with underscore (internal-only)
- Rephrase resolve_conversation_manager docstring to avoid leaking
  NullConversationManager implementation detail
gautamsirdeshmukh pushed a commit to gautamsirdeshmukh/harness-sdk that referenced this pull request Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api/review-complete An API Bar-raiser reviewed and accepted the APIs area-context Session or context related area-language Related to new language development complexity/medium Touched functions have moderate cognitive complexity (11-25) enhancement New feature or request size/m typescript Pull requests that update typescript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants