Files
nanobot/nanobot/session/summary.py
T
chengyongruandGitHub d81aa5a4ab refactor(agent): let runner own context compaction (#5568)
* refactor(agent): consolidate accepted history under pressure

* fix(agent): align provider and session compaction

* refactor(agent): simplify runner context compaction

* refactor(agent): remove background token consolidation

* fix(agent): keep injected transcript messages distinct

* refactor(agent): unify native compaction summaries

* fix(agent): preserve native compaction boundary

* fix(agent): unify context compaction paths

* fix(agent): preserve exact compaction request boundaries
2026-09-02 18:05:54 +08:00

49 lines
1.4 KiB
Python

"""Helpers for validated session-summary metadata."""
from __future__ import annotations
from collections.abc import Mapping
from dataclasses import dataclass
from datetime import datetime
from typing import TypedDict, cast
SUMMARY_CONTINUATION_TEXT = (
"Continue the active task from the working-memory checkpoint above."
)
class SessionSummary(TypedDict):
text: str
last_active: str
@dataclass(frozen=True, slots=True)
class SessionSummaryCheckpoint:
"""A replacement summary and the raw transcript boundary it covers."""
summary: str
transcript_boundary: int
def session_summary_from_metadata(
metadata: Mapping[str, object] | None,
*,
fallback_last_active: datetime,
) -> SessionSummary | None:
raw: object = metadata.get("_last_summary") if metadata is not None else None
if not isinstance(raw, Mapping):
return None
summary_data = cast(Mapping[str, object], raw)
text = summary_data.get("text")
if not isinstance(text, str) or not text:
return None
raw_last_active = summary_data.get("last_active")
if isinstance(raw_last_active, str):
try:
datetime.fromisoformat(raw_last_active)
last_active = raw_last_active
except ValueError:
last_active = fallback_last_active.isoformat()
else:
last_active = fallback_last_active.isoformat()
return {"text": text, "last_active": last_active}