Coverage for little_loops / context_window.py: 25%
24 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-06-26 17:38 -0500
« prev ^ index » next coverage.py v7.12.0, created at 2026-06-26 17:38 -0500
1"""Single source of truth for model → context-window size mapping.
3Precedence (highest to lowest):
41. Explicit ``override`` argument (non-zero)
52. ``LL_CONTEXT_LIMIT`` environment variable (non-zero integer)
63. ``[1m]`` suffix on model id → 1_000_000
74. Exact model-id lookup in MODEL_CONTEXT_WINDOW
85. 200_000 conservative floor
10# keep in sync with hooks/scripts/context-monitor.sh:get_context_limit()
11"""
13from __future__ import annotations
15import os
17# Known model context windows in tokens.
18# Models not listed here fall back to the 200_000 floor.
19MODEL_CONTEXT_WINDOW: dict[str, int] = {
20 # Claude 4.x — 200k base context
21 "claude-opus-4-8": 200_000,
22 "claude-opus-4-7": 200_000,
23 "claude-opus-4-6": 200_000,
24 "claude-opus-4-5": 200_000,
25 "claude-sonnet-4-6": 200_000,
26 "claude-sonnet-4-5": 200_000,
27 "claude-haiku-4-5": 200_000,
28 "claude-haiku-4-5-20251001": 200_000,
29 # Claude 3.x (legacy)
30 "claude-opus-3-7": 200_000,
31 "claude-sonnet-3-7": 200_000,
32 "claude-haiku-3-5": 200_000,
33}
35_DEFAULT_CONTEXT_WINDOW = 200_000
36_1M_CONTEXT_WINDOW = 1_000_000
39def context_window_for(model: str | None, override: int | None = None) -> int:
40 """Resolve context-window size for a model id.
42 Args:
43 model: Model identifier string (e.g. ``"claude-opus-4-8[1m]"``),
44 or ``None`` to use env-var / floor.
45 override: Explicit token count; takes top precedence when non-zero.
47 Returns:
48 Context window size in tokens (always a positive int).
49 """
50 # 1. Explicit override argument
51 if override:
52 return int(override)
54 # 2. LL_CONTEXT_LIMIT environment variable
55 env_val = os.environ.get("LL_CONTEXT_LIMIT", "")
56 if env_val:
57 try:
58 parsed = int(env_val)
59 if parsed > 0:
60 return parsed
61 except ValueError:
62 pass
64 if model is None:
65 return _DEFAULT_CONTEXT_WINDOW
67 # 3. [1m] suffix → 1M context
68 if model.endswith("[1m]"):
69 return _1M_CONTEXT_WINDOW
71 # 4. Exact model-id lookup
72 window = MODEL_CONTEXT_WINDOW.get(model)
73 if window is not None:
74 return window
76 # 5. Conservative floor
77 return _DEFAULT_CONTEXT_WINDOW