Skip to content

Compaction

CompactionDetails

class CompactionDetails(read_files: list[str] = list(), modified_files: list[str] = list())

tau_agent_core.compaction.CompactionDetails

File-operation details stored alongside a compaction (pi: CompactionDetails).

Constructor parameters

  • read_files: list[str] = list() — (no description)
  • modified_files: list[str] = list() — (no description)

CompactionError

class CompactionError(code: str, message: str)

tau_agent_core.compaction.CompactionError

Raised when a compaction cannot complete.

Pythonic translation of pi's Result<T, CompactionError> error arm (types.ts:161). code is one of "aborted", "summarization_failed", or "invalid_session". Fail-Early: callers handle the failure rather than receive a fabricated summary.

Constructor parameters

  • code: str — (no description)
  • message: str — (no description)

CompactionPolicy

class CompactionPolicy(mode: PolicyMode, max_turns: int | None = None, max_tokens_per_turn: int | None = None, summarizer_model: Model | None = None, summarizer_api_key: str | None = None, reserve_tokens: int = DEFAULT_COMPACTION_SETTINGS.reserve_tokens, keep_recent_tokens: int = DEFAULT_COMPACTION_SETTINGS.keep_recent_tokens)

tau_agent_core.compaction_policy.CompactionPolicy

One run's declared answer to "what happens when the context fills up?".

Construct through :meth:disabled, :meth:local_summarizer or :meth:turn_cap — the constructors are what make the mode/field pairing checkable. There is no default instance and no default mode.

Constructor parameters

  • mode: PolicyMode — (no description)
  • max_turns: int | None = None — (no description)
  • max_tokens_per_turn: int | None = None — (no description)
  • summarizer_model: Model | None = None — (no description)
  • summarizer_api_key: str | None = None — (no description)
  • reserve_tokens: int = DEFAULT_COMPACTION_SETTINGS.reserve_tokens — (no description)
  • keep_recent_tokens: int = DEFAULT_COMPACTION_SETTINGS.keep_recent_tokens — (no description)

admit_turn

admit_turn(turns_used: int) -> None

tau_agent_core.compaction_policy.CompactionPolicy.admit_turn

Admit the turns_used-th user turn, or raise (premise P2).

turns_used is 1-based and counts prompt() calls, which is the unit a scripted scenario is written in.

Parameters

  • turns_used: int — (no description)

bind_to

bind_to(model: Model) -> None

tau_agent_core.compaction_policy.CompactionPolicy.bind_to

Check this declaration against the model it will run under; raise if not.

Called once, at session construction. Everything checkable before a token is spent is checked here rather than discovered at turn 40 of a scenario run.

Parameters

  • model: Model — (no description)

compaction_settings

tau_agent_core.compaction_policy.CompactionPolicy.compaction_settings: CompactionSettings

The :class:CompactionSettings this policy puts in force.

turn_cap leaves compaction enabled: the point of that policy is that the measured system stays the shipped system, and the threshold is kept out of reach by the budget rather than by switching the mechanism off.

disabled

disabled(*, max_turns: int) -> CompactionPolicy

tau_agent_core.compaction_policy.CompactionPolicy.disabled

Compaction off, bounded by user-turn count (§16.8 option 1).

max_turns is not decoration: with compaction off, nothing else stops the conversation growing past the model window, and the bound is the whole of what makes this policy safe. Exceeding it raises rather than letting the run continue into a provider-side overflow whose cause is not recoverable from the artifact.

Parameters

  • max_turns: int — (no description)

local_summarizer

local_summarizer(*, model: Model, api_key: str) -> CompactionPolicy

tau_agent_core.compaction_policy.CompactionPolicy.local_summarizer

Compaction on, through a separately declared model (§16.8 option 2).

api_key is required rather than inherited from the session: a summariser on the near side of a partition is a different endpoint with different credentials, and silently reusing the session's key is the kind of guess that works in the lab and fails on the board. Pass the literal the local server expects (many ignore it) — but pass it.

The key is never written to a manifest; see :meth:to_manifest.

Parameters

  • model: Model — (no description)
  • api_key: str — (no description)

observe_context

observe_context(*, turns_used: int, context_tokens: int, context_window: int) -> None

tau_agent_core.compaction_policy.CompactionPolicy.observe_context

Check the run against its declared budget at the auto-compaction site.

Called at the one place should_compact is evaluated, before the enabled/threshold gates, so a turn_cap run that has broken its premise dies here rather than making the full-window model call the policy exists to keep out of the measurement.

Modes other than turn_cap declare no per-turn token bound, so there is nothing here for them to violate. That asymmetry is not an oversight: it is the reason turn_cap is the stronger declaration.

Parameters

  • turns_used: int — (no description)
  • context_tokens: int — (no description)
  • context_window: int — (no description)

summarizer_for

summarizer_for(session_model: Model) -> tuple[Model, str | None]

tau_agent_core.compaction_policy.CompactionPolicy.summarizer_for

The (model, api_key) a compaction under this policy summarises through.

For every mode but local_summarizer that is the session's own model and the session's own key — which is exactly the shipped behaviour, restated rather than changed. Returning None for the key means "whatever the session was constructed with"; the session substitutes its own.

Parameters

  • session_model: Model — (no description)

to_manifest

to_manifest() -> dict[str, Any]

tau_agent_core.compaction_policy.CompactionPolicy.to_manifest

The manifest fragment. JSON-serialisable, and it never carries a secret.

Everything a later reader needs to know what population a number came from, and nothing that would make the artifact unsafe to keep.

turn_cap

turn_cap(*, max_turns: int, max_tokens_per_turn: int) -> CompactionPolicy

tau_agent_core.compaction_policy.CompactionPolicy.turn_cap

Compaction as shipped, under a budget proven to keep it out of reach.

See the module docstring for the proof and for which half of it is checked where. Both numbers are the caller's to supply: this module will not invent a per-turn token bound, because an invented bound turns the proof back into the estimate §16.8 refuses.

Parameters

  • max_turns: int — (no description)
  • max_tokens_per_turn: int — (no description)

CompactionPolicyError

tau_agent_core.compaction_policy.CompactionPolicyError

A compaction policy declaration is inadmissible.

Raised at declaration time or at bind time — never mid-run. Either the fields do not match the declared mode, or the budget does not close against the model the policy was bound to.

CompactionPolicyViolation

tau_agent_core.compaction_policy.CompactionPolicyViolation

A bound run exceeded the budget its policy declared.

The run is void: a measurement taken past its own declared bound describes a configuration nobody wrote down. Raised at the site the bound was crossed, with the numbers, so the failure is legible rather than a plausible value.

This is not a compaction failure and is deliberately not a :class:~tau_agent_core.compaction.CompactionError — compaction did not fail, the run's premise did.

CompactionPreparation

class CompactionPreparation(first_kept_entry_id: str, messages_to_summarize: list[dict[str, Any]], turn_prefix_messages: list[dict[str, Any]], is_split_turn: bool, tokens_before: int, file_ops: FileOperations, settings: CompactionSettings, previous_summary: str | None = None, compacted_entry_ids: list[str] = list())

tau_agent_core.compaction.CompactionPreparation

Prepared inputs for a compaction run (pi: CompactionPreparation).

Constructor parameters

  • first_kept_entry_id: str — (no description)
  • messages_to_summarize: list[dict[str, Any]] — (no description)
  • turn_prefix_messages: list[dict[str, Any]] — (no description)
  • is_split_turn: bool — (no description)
  • tokens_before: int — (no description)
  • file_ops: FileOperations — (no description)
  • settings: CompactionSettings — (no description)
  • previous_summary: str | None = None — (no description)
  • compacted_entry_ids: list[str] = list() — (no description)

CompactionResult

class CompactionResult(summary: str, first_kept_entry_id: str, tokens_before: int, details: CompactionDetails | None = None, compacted_entry_ids: list[str] = list(), tokens_saved: int = 0, usage: dict[str, int] = zero_usage())

tau_agent_core.compaction.CompactionResult

Generated compaction data ready to persist (pi: CompactionResult).

compacted_entry_ids and tokens_saved are τ additions — pi computes these in its persistence layer; τ threads them through so SessionManager.apply_compaction can record them on the compaction entry.

Constructor parameters

  • summary: str — (no description)
  • first_kept_entry_id: str — (no description)
  • tokens_before: int — (no description)
  • details: CompactionDetails | None = None — (no description)
  • compacted_entry_ids: list[str] = list() — (no description)
  • tokens_saved: int = 0 — (no description)
  • usage: dict[str, int] = zero_usage() — (no description)

CompactionSettings

class CompactionSettings(enabled: bool = True, reserve_tokens: int = 16384, keep_recent_tokens: int = 20000)

tau_agent_core.compaction.CompactionSettings

Compaction thresholds and retention settings (pi: CompactionSettings).

Constructor parameters

  • enabled: bool = True — (no description)
  • reserve_tokens: int = 16384 — (no description)
  • keep_recent_tokens: int = 20000 — (no description)

ContextUsageEstimate

class ContextUsageEstimate(tokens: int, usage_tokens: int, trailing_tokens: int, last_usage_index: int | None)

tau_agent_core.compaction.ContextUsageEstimate

Estimated context-token usage for a message list (pi: ContextUsageEstimate).

Constructor parameters

  • tokens: int — (no description)
  • usage_tokens: int — (no description)
  • trailing_tokens: int — (no description)
  • last_usage_index: int | None — (no description)

calculate_context_tokens

calculate_context_tokens(usage: dict[str, Any]) -> int

tau_agent_core.compaction.calculate_context_tokens

Total context tokens from a Usage dict (pi: calculateContextTokens).

Prefers the provider-reported total_tokens; falls back to the sum of the component counts when total is absent/zero.

Parameters

  • usage: dict[str, Any] — (no description)

compact

compact(preparation: CompactionPreparation, model: Model, api_key: str | None, *, custom_instructions: str | None = None, thinking_level: str | None = None) -> CompactionResult

tau_agent_core.compaction.compact

Generate the compaction summary from prepared history (pi: compact).

On a split turn, the history and the turn prefix are summarized concurrently and stitched together (pi uses Promise.all).

Parameters

  • preparation: CompactionPreparation — (no description)
  • model: Model — (no description)
  • api_key: str | None — (no description)
  • custom_instructions: str | None = None — (no description)
  • thinking_level: str | None = None — (no description)

estimate_context_tokens

estimate_context_tokens(messages: list[dict[str, Any]]) -> ContextUsageEstimate

tau_agent_core.compaction.estimate_context_tokens

Estimate context tokens, anchoring on the last assistant Usage when present.

Faithful port of pi's estimateContextTokens (compaction.ts:165): the provider is the source of truth for everything up to the last assistant turn; only the trailing messages after it are heuristically estimated.

Parameters

  • messages: list[dict[str, Any]] — (no description)

estimate_span_tokens

estimate_span_tokens(entries: list[dict[str, Any]]) -> int

tau_agent_core.compaction.estimate_span_tokens

Estimated context tokens a SPAN of active-path entries contributes.

The one spelling of "what did this span cost the context", so the number a splice anchor RECORDS (coveredTokens on a compaction/elide entry — TREE-BROWSER-AS-EDITOR.md §8.1, §8.2) is produced by the same arithmetic as the tokensBefore it sits beside (prepare_compaction, :func:estimate_tokens via :func:estimate_context_tokens). Two spellings would let a browser row show "folds 12 entries, 8k tokens" against a tokensBefore computed on a different basis, and nothing would report the mismatch.

Public because the value must be named at the CALL SITE: §11.3 makes the provenance a required keyword argument on the appenders precisely so a caller that cannot compute it fails there (AgentSession._perform_compaction and tree_ops.elide_span / commit_branch). Computing it inside the five SessionLog implementations instead would put this arithmetic — and the entry→message flattening under it — in five places.

Non-message entries contribute nothing, exactly as they contribute nothing to model input: an agent_spec/customEntry/navigate node in the span is counted by coveredEntries and priced at zero here, which is the truth.

Parameters

  • entries: list[dict[str, Any]] — (no description)

estimate_tokens

estimate_tokens(message: dict[str, Any]) -> int

tau_agent_core.compaction.estimate_tokens

Estimate token count for one message dict (pi: estimateTokens).

Conservative ~4-chars-per-token heuristic over the textual payload, by role.

Parameters

  • message: dict[str, Any] — (no description)

policy_for_scenario

policy_for_scenario(scenario: str, *, max_turns: int, max_tokens_per_turn: int) -> CompactionPolicy

tau_agent_core.compaction_policy.policy_for_scenario

Build the declared policy for a lettered scenario (§7.3-§7.7).

Raises on an unknown scenario rather than falling back to anything: an unrecognised scenario letter is a harness bug, and the failure mode a default would produce is a run measured under a policy nobody chose.

Parameters

  • scenario: str — the scenario letter, "A"-"E".
  • max_turns: int — the run's declared bound on user turns.
  • max_tokens_per_turn: int — the run's declared bound on per-turn context growth.

Raises

  • CompactionPolicyError — unknown scenario, or the scenario's declared mode is not one this builder can construct from these arguments.

prepare_compaction

prepare_compaction(path_entries: list[dict[str, Any]], settings: CompactionSettings) -> CompactionPreparation | None

tau_agent_core.compaction.prepare_compaction

Prepare active-path entries for compaction, or None when inapplicable.

Faithful port of pi's prepareCompaction (compaction.ts:542), reading τ entry dicts. Returns None when there is nothing to compact: an empty path, a path that already ends in a compaction entry, or — τ's one divergence from pi here, see the comment at the guard — a cut that would remove no message from the context at all, which is what the shipped keep_recent_tokens produces for every conversation smaller than it.

Parameters

  • path_entries: list[dict[str, Any]] — (no description)
  • settings: CompactionSettings — (no description)

Raises

  • CompactionError('invalid_session') — when the chosen first-kept entry has no id.

should_compact

should_compact(context_tokens: int, context_window: int, settings: CompactionSettings) -> bool

tau_agent_core.compaction.should_compact

Whether context usage exceeds the compaction threshold (pi: shouldCompact).

Parameters

  • context_tokens: int — (no description)
  • context_window: int — (no description)
  • settings: CompactionSettings — (no description)