Skip to content

feat: support awaited extension continuity across compaction - #683

Closed
phernandez wants to merge 2 commits into
huggingface:mainfrom
phernandez:fix/compaction-lifecycle-memory
Closed

feat: support awaited extension continuity across compaction#683
phernandez wants to merge 2 commits into
huggingface:mainfrom
phernandez:fix/compaction-lifecycle-memory

Conversation

@phernandez

@phernandez phernandez commented Sep 6, 2026

Copy link
Copy Markdown

Why

Refs #506. Memory extensions need to finish a checkpoint before context replacement, recover its receipt on the correct branch, and insert recall before the next prompt without triggering another agent response. Basic Memory is the concrete consumer: basicmachines-co/basic-memory#1489.

What Changed

  • A single CodingSession helper emits awaited extension start/end callbacks for manual, detailed manual, threshold, and overflow compaction. No-op threshold checks emit nothing; failure/cancellation emits an aborted end.
  • context.branch_entries: deep-copied persisted active-path entries, including custom receipts, for reload/resume reconciliation and branch lineage.
  • await context.summarize(messages, instructions=..., timeout=60): bounded tool-free synthesis using the active model/provider, without an agent turn or history mutation. Generation guards reject late results.
  • await tau.append_message(content, custom_type=...): persist reference context while idle before the next prompt. Queued follow-ups—even with trigger_turn=False—can generate another model response; this method does not queue a turn.
  • In-place tree branching emits shutdown/start(reason="branch") on the same runtime. Extensions must support closing and restarting resources.

Design and Boundaries

No persistence destinations, exposed credentials, installed-package patches, or detached summary tasks in core. Extensions select inputs, own cancellation, validate writes and retain receipts. Observation failures preserve the diagnostic-only contract; this is not a compaction veto API.

This addresses extension delivery from #506, not threshold/manual frontend async-iterator or TUI status work, and deliberately does not close that issue. entry_appended delivery is unchanged; persisted active-path inspection supports receipt reconstruction without it.

Verification

  • uv run pytest -q: 1881 passed, 2 Windows-only tests skipped on macOS.
  • uv run mypy: passed for 121 source files.
  • Ruff lint/format: passed.
  • Focused session/continuity tests prove a blocked start handler finishes before replacement, receipts persist through all four paths, no-op/cancellation semantics, summary isolation, zero-turn context insertion, and tree lifecycle notifications.
  • Downstream Basic Memory integration: 51 tests pass, including actual session compaction/reload/branch/resume, headless Textual /reload, and real Basic Memory transcript/checkpoint persistence in temporary projects. Model providers are deterministic fakes; no production user session or paid model was used.

Risks

Summary calls use the active provider's ordinary routing/billing. Extensions must choose bounded inputs and timeouts and must not treat a queued instruction or diagnostic-only callback as acknowledgement of an external write. References inserted with append_message are persisted custom messages and contribute to normal context size until compacted.

Signed-off-by: phernandez <paul@basicmachines.co>
Signed-off-by: phernandez <paul@basicmachines.co>
@phernandez

Copy link
Copy Markdown
Author

Superseded by #687, submitted from the Basic Machines organization fork: https://github.com/basicmachines-co/tau. The replacement contains the identical tested commit; please direct review there. This work supports Basic Memory continuity: basicmachines-co/basic-memory#1489.

@phernandez phernandez closed this Sep 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