Part of the v0.58.7 → HEAD TinyAgents-migration audit (see parent issue).
Problem
assemble_turn_harness installs the crate ContextCompressionMiddleware (src/openhuman/tinyagents/mod.rs:1317-1329). Two regressions vs the legacy engine:
- Summarizer failure now aborts the turn. The crate's
before_model does self.summarizer.summarize(...).await?; any provider hiccup maps to TinyAgentsError::Model (summarize.rs:123-131) and fails the run. Legacy (v0.58.7 engine/core.rs ~300): compaction failure was warn! + circuit breaker + fall back to deterministic trim; the turn continued. New hard failure mode on exactly the longest, most valuable threads.
- Compaction re-runs on every model call once over threshold. The crate middleware rewrites only the per-call
request.messages clone; the loop's working transcript never shrinks (crate agent_loop/mod.rs:354 rebuilds the request from messages.clone() each iteration). Once a thread crosses the 90% threshold, every subsequent model call in the turn triggers a fresh full-transcript summarizer LLM call — cost and latency multiply with tool-loop length.
Fix plan
- Wrap the summarizer we hand the crate in a fault-tolerant adapter: on
Err, log a warn with the cause, trip a per-turn circuit breaker, and return a deterministic trim of the input (reusing MessageTrimMiddleware logic) instead of propagating. Turn must never fail because compaction failed.
- Avoid re-summarizing per call. Options:
a. Cache the summarization result keyed by (message-count, hash of compacted prefix) inside our adapter, so repeat calls within a turn are free until the transcript grows past the threshold again;
b. or upstream a crate change to apply compression to the loop's working transcript (with provenance events), then adopt it.
- Emit a compaction event (what was summarized, token before/after) — the spec's "move context compaction provenance into TinyAgents events" checkbox — so silent compaction is observable.
Acceptance criteria
- Scripted summarizer failure mid-turn: turn completes via deterministic trim; warn logged; no
chat_error.
- A long turn over the threshold performs at most one summarizer call per transcript growth step, not one per model call (assert call count via mock provider).
Part of the v0.58.7 → HEAD TinyAgents-migration audit (see parent issue).
Problem
assemble_turn_harnessinstalls the crateContextCompressionMiddleware(src/openhuman/tinyagents/mod.rs:1317-1329). Two regressions vs the legacy engine:before_modeldoesself.summarizer.summarize(...).await?; any provider hiccup maps toTinyAgentsError::Model(summarize.rs:123-131) and fails the run. Legacy (v0.58.7engine/core.rs~300): compaction failure waswarn!+ circuit breaker + fall back to deterministic trim; the turn continued. New hard failure mode on exactly the longest, most valuable threads.request.messagesclone; the loop's working transcript never shrinks (crateagent_loop/mod.rs:354rebuilds the request frommessages.clone()each iteration). Once a thread crosses the 90% threshold, every subsequent model call in the turn triggers a fresh full-transcript summarizer LLM call — cost and latency multiply with tool-loop length.Fix plan
Err, log a warn with the cause, trip a per-turn circuit breaker, and return a deterministic trim of the input (reusingMessageTrimMiddlewarelogic) instead of propagating. Turn must never fail because compaction failed.a. Cache the summarization result keyed by (message-count, hash of compacted prefix) inside our adapter, so repeat calls within a turn are free until the transcript grows past the threshold again;
b. or upstream a crate change to apply compression to the loop's working transcript (with provenance events), then adopt it.
Acceptance criteria
chat_error.