Download mindxtrain/operator/context.py from PYTHAI/mindXtrain: direct link, hf CLI and curl.
- Browser
- Download file 3.99 kB
-
https://huggingface.co/PYTHAI/mindXtrain/resolve/refs%2Fpr%2F1/mindxtrain/operator/context.py
- Command line
-
hf download hf://PYTHAI/mindXtrain@refs/pr/1/mindxtrain/operator/context.py
-
curl -L -o context.py https://huggingface.co/PYTHAI/mindXtrain/resolve/refs%2Fpr%2F1/mindxtrain/operator/context.py
3.99 kB
| """ContextManager — token-budgeted compaction window (ml-intern pattern). | |
| Tracks per-message token estimates, summarizes oldest turns when the window | |
| exceeds `target_tokens`, preserves the system prompt and the most recent | |
| user/tool turns verbatim. Pure stdlib; optional summarizer callback. | |
| """ | |
| from __future__ import annotations | |
| from collections.abc import Callable | |
| from typing import Any | |
| from pydantic import BaseModel, ConfigDict, Field | |
| class ContextManagerConfig(BaseModel): | |
| model_config = ConfigDict(extra="forbid") | |
| target_tokens: int = Field(default=170_000, ge=1024) | |
| keep_recent: int = Field( | |
| default=8, | |
| ge=1, | |
| description="messages from the end to keep verbatim", | |
| ) | |
| chars_per_token: float = Field(default=4.0, gt=0.0) | |
| def estimate_tokens(text: str, chars_per_token: float = 4.0) -> int: | |
| """Cheap whitespace/char-rate token estimate (no tokenizer dep).""" | |
| if not text: | |
| return 0 | |
| # 4 chars/token is the OpenAI / Anthropic rule of thumb for English text. | |
| return max(1, int(len(text) / chars_per_token)) | |
| def message_tokens(message: dict[str, Any], chars_per_token: float = 4.0) -> int: | |
| """Estimate tokens for one chat message.""" | |
| text_parts: list[str] = [str(message.get("role", "")), str(message.get("content", "") or "")] | |
| for c in message.get("tool_calls") or []: | |
| fn = c.get("function", {}) | |
| text_parts.append(str(fn.get("name", ""))) | |
| text_parts.append(str(fn.get("arguments", ""))) | |
| return estimate_tokens(" ".join(text_parts), chars_per_token) | |
| SummarizeFn = Callable[[list[dict[str, Any]]], str] | |
| class ContextManager: | |
| """Trim message lists to fit `target_tokens`.""" | |
| def __init__( | |
| self, | |
| cfg: ContextManagerConfig | None = None, | |
| summarize: SummarizeFn | None = None, | |
| ) -> None: | |
| self.cfg = cfg or ContextManagerConfig() | |
| self.summarize = summarize | |
| def estimate(self, messages: list[dict[str, Any]]) -> int: | |
| return sum(message_tokens(m, self.cfg.chars_per_token) for m in messages) | |
| def compact(self, messages: list[dict[str, Any]]) -> list[dict[str, Any]]: | |
| """Return a trimmed message list whose token estimate is <= target_tokens. | |
| Strategy: | |
| 1. Always keep the leading system message (if present) verbatim. | |
| 2. Always keep the trailing `keep_recent` messages verbatim. | |
| 3. The middle band is replaced with a single summary turn (via | |
| `summarize` callback) or simply elided with a meta note. | |
| """ | |
| if not messages: | |
| return [] | |
| if self.estimate(messages) <= self.cfg.target_tokens: | |
| return list(messages) | |
| head: list[dict[str, Any]] = [] | |
| if messages and messages[0].get("role") == "system": | |
| head = [messages[0]] | |
| body = messages[1:] | |
| else: | |
| body = list(messages) | |
| if len(body) <= self.cfg.keep_recent: | |
| return head + body | |
| recent = body[-self.cfg.keep_recent :] | |
| elided = body[: -self.cfg.keep_recent] | |
| if self.summarize is not None: | |
| summary_text = self.summarize(elided) | |
| else: | |
| summary_text = ( | |
| f"[context compacted: {len(elided)} earlier messages elided" | |
| f" to fit {self.cfg.target_tokens}-token window]" | |
| ) | |
| summary_msg = {"role": "system", "content": summary_text} | |
| compacted = [*head, summary_msg, *recent] | |
| # If still over, recurse with a tighter `keep_recent` until it fits or is minimal. | |
| if self.estimate(compacted) > self.cfg.target_tokens and self.cfg.keep_recent > 1: | |
| tighter_cfg = self.cfg.model_copy(update={"keep_recent": max(1, self.cfg.keep_recent // 2)}) | |
| return ContextManager(tighter_cfg, self.summarize).compact(messages) | |
| return compacted | |
| __all__ = ["ContextManager", "ContextManagerConfig", "estimate_tokens", "message_tokens"] | |