- harness/es.py: append-only event store + проекции (образец — кооп-портал) - harness/levels.py: уровни 1с/1м/1ч/1д, контекст ∝ масштабу - harness/scheduler.py: уровневые потоки, идемпотентные тики, absorbed-стабы - harness/isolated_runner.py + _llm_worker.py: LLM-тик в сабпроцессе (глобальный asyncio-рантайм Strands не переживает 2+ create_harness) - cli.py: init/task/tasks/status/events + requeue (написан самим минутным агентом) - 9router: отдельный ключ sk-simbiot, модель auto (glm-5.3 первым)
199 lines
7.3 KiB
Python
199 lines
7.3 KiB
Python
"""Default model metadata lookup tables.
|
|
|
|
Provides context window limits for known model IDs across all providers.
|
|
Values sourced from provider documentation and
|
|
https://github.com/BerriAI/litellm/blob/litellm_internal_staging/model_prices_and_context_window.json
|
|
|
|
Applied to providers with well-known, fixed model IDs: Bedrock, Anthropic, OpenAI,
|
|
OpenAI Responses, Gemini, and Mistral. Providers that use local/custom model IDs
|
|
(Ollama, LlamaCpp, SageMaker) or proxy to other providers with their own prefixed
|
|
ID format (LiteLLM) are excluded — their context windows depend on deployment config,
|
|
not a static table.
|
|
"""
|
|
|
|
import logging
|
|
from collections.abc import Mapping
|
|
from typing import TypeVar
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_C = TypeVar("_C", bound=Mapping[str, object])
|
|
|
|
# Default context window limit (in tokens) when the model does not report one.
|
|
DEFAULT_CONTEXT_WINDOW_LIMIT = 200_000
|
|
|
|
# Context window limits (in tokens) for known model IDs.
|
|
#
|
|
# Best-effort lookup table — unknown models return None and callers
|
|
# fall back gracefully (e.g. proactive compression is disabled).
|
|
# Users can always override with an explicit context_window_limit in their model config.
|
|
#
|
|
# For Bedrock models with cross-region prefixes (e.g. us., eu., global.),
|
|
# get_context_window_limit strips prefixes before lookup so only the base model ID is needed here.
|
|
_CONTEXT_WINDOW_LIMITS: dict[str, int] = {
|
|
# Anthropic (direct API)
|
|
"claude-sonnet-4-6": 1_000_000,
|
|
"claude-sonnet-4-20250514": 1_000_000,
|
|
"claude-sonnet-4-5": 200_000,
|
|
"claude-sonnet-4-5-20250929": 200_000,
|
|
"claude-opus-4-6": 1_000_000,
|
|
"claude-opus-4-6-20260205": 1_000_000,
|
|
"claude-opus-4-7": 1_000_000,
|
|
"claude-opus-4-7-20260416": 1_000_000,
|
|
"claude-opus-4-8": 1_000_000,
|
|
"claude-opus-5": 1_000_000,
|
|
"claude-fable-5": 1_000_000,
|
|
"claude-sonnet-5": 1_000_000,
|
|
"claude-opus-4-5": 200_000,
|
|
"claude-opus-4-5-20251101": 200_000,
|
|
"claude-opus-4-20250514": 200_000,
|
|
"claude-opus-4-1": 200_000,
|
|
"claude-opus-4-1-20250805": 200_000,
|
|
"claude-haiku-4-5": 200_000,
|
|
"claude-haiku-4-5-20251001": 200_000,
|
|
"claude-3-7-sonnet-20250219": 200_000,
|
|
"claude-3-5-sonnet-20241022": 200_000,
|
|
"claude-3-5-sonnet-20240620": 200_000,
|
|
"claude-3-5-haiku-20241022": 200_000,
|
|
"claude-3-opus-20240229": 200_000,
|
|
"claude-3-haiku-20240307": 200_000,
|
|
# Bedrock Anthropic (base model IDs — cross-region prefixes stripped by get_context_window_limit)
|
|
"anthropic.claude-sonnet-4-6": 1_000_000,
|
|
"anthropic.claude-sonnet-4-20250514-v1:0": 1_000_000,
|
|
"anthropic.claude-sonnet-4-5-20250929-v1:0": 200_000,
|
|
"anthropic.claude-opus-4-6-v1": 1_000_000,
|
|
"anthropic.claude-opus-4-7": 1_000_000,
|
|
"anthropic.claude-opus-4-8": 1_000_000,
|
|
"anthropic.claude-opus-5": 1_000_000,
|
|
"anthropic.claude-fable-5": 1_000_000,
|
|
"anthropic.claude-sonnet-5": 1_000_000,
|
|
"anthropic.claude-opus-4-5-20251101-v1:0": 200_000,
|
|
"anthropic.claude-opus-4-20250514-v1:0": 200_000,
|
|
"anthropic.claude-opus-4-1-20250805-v1:0": 200_000,
|
|
"anthropic.claude-haiku-4-5-20251001-v1:0": 200_000,
|
|
"anthropic.claude-haiku-4-5@20251001": 200_000,
|
|
"anthropic.claude-3-7-sonnet-20250219-v1:0": 200_000,
|
|
"anthropic.claude-3-7-sonnet-20240620-v1:0": 200_000,
|
|
"anthropic.claude-3-5-sonnet-20241022-v2:0": 200_000,
|
|
"anthropic.claude-3-5-sonnet-20240620-v1:0": 200_000,
|
|
"anthropic.claude-3-5-haiku-20241022-v1:0": 200_000,
|
|
"anthropic.claude-3-opus-20240229-v1:0": 200_000,
|
|
"anthropic.claude-3-haiku-20240307-v1:0": 200_000,
|
|
"anthropic.claude-3-sonnet-20240229-v1:0": 200_000,
|
|
"anthropic.claude-mythos-preview": 1_000_000,
|
|
# Bedrock Amazon Nova
|
|
"amazon.nova-pro-v1:0": 300_000,
|
|
"amazon.nova-lite-v1:0": 300_000,
|
|
"amazon.nova-micro-v1:0": 128_000,
|
|
"amazon.nova-premier-v1:0": 1_000_000,
|
|
"amazon.nova-2-lite-v1:0": 1_000_000,
|
|
"amazon.nova-2-pro-preview-20251202-v1:0": 1_000_000,
|
|
# Bedrock Z.AI
|
|
"zai.glm-4.7": 203_000,
|
|
# OpenAI
|
|
"gpt-6-astra": 1_050_000,
|
|
"gpt-5.6": 1_050_000,
|
|
"gpt-5.6-sol": 1_050_000,
|
|
"gpt-5.6-terra": 1_050_000,
|
|
"gpt-5.6-luna": 1_050_000,
|
|
"gpt-5.5": 1_050_000,
|
|
"gpt-5.5-pro": 1_050_000,
|
|
"gpt-5.4": 1_050_000,
|
|
"gpt-5.4-pro": 1_050_000,
|
|
"gpt-5.4-mini": 272_000,
|
|
"gpt-5.4-nano": 272_000,
|
|
"gpt-5.2": 272_000,
|
|
"gpt-5.2-pro": 272_000,
|
|
"gpt-5.1": 272_000,
|
|
"gpt-5": 272_000,
|
|
"gpt-5-mini": 272_000,
|
|
"gpt-5-nano": 272_000,
|
|
"gpt-5-pro": 128_000,
|
|
"gpt-4.1": 1_047_576,
|
|
"gpt-4.1-mini": 1_047_576,
|
|
"gpt-4.1-nano": 1_047_576,
|
|
"gpt-4o": 128_000,
|
|
"gpt-4o-mini": 128_000,
|
|
"gpt-4-turbo": 128_000,
|
|
"o3": 200_000,
|
|
"o3-mini": 200_000,
|
|
"o3-pro": 200_000,
|
|
"o4-mini": 200_000,
|
|
"o1": 200_000,
|
|
# Google Gemini
|
|
"gemini-2.5-flash": 1_048_576,
|
|
"gemini-2.5-flash-lite": 1_048_576,
|
|
"gemini-2.5-pro": 1_048_576,
|
|
"gemini-2.0-flash": 1_048_576,
|
|
"gemini-2.0-flash-lite": 1_048_576,
|
|
"gemini-3-pro-preview": 1_048_576,
|
|
"gemini-3-flash-preview": 1_048_576,
|
|
"gemini-3.6-flash": 1_048_576,
|
|
"gemini-3.5-flash": 1_048_576,
|
|
"gemini-3.5-flash-lite": 1_048_576,
|
|
"gemini-3.1-flash-lite": 1_048_576,
|
|
"gemini-3.1-pro-preview": 1_048_576,
|
|
"gemini-3.1-flash-lite-preview": 1_048_576,
|
|
# Mistral
|
|
"mistral-large-latest": 262_144,
|
|
"mistral-large-2512": 262_144,
|
|
"mistral-large-3": 262_144,
|
|
"mistral-medium-latest": 131_072,
|
|
"mistral-medium-2505": 131_072,
|
|
"mistral-small-latest": 131_072,
|
|
"mistral-small-3-2-2506": 131_072,
|
|
}
|
|
|
|
|
|
def get_context_window_limit(model_id: str) -> int | None:
|
|
"""Look up the context window limit for a model ID.
|
|
|
|
For Bedrock model IDs with prefixes (e.g. ``us.anthropic.claude-sonnet-4-6``),
|
|
prefixes are stripped as a fallback if the direct lookup fails.
|
|
|
|
Args:
|
|
model_id: The model ID to look up.
|
|
|
|
Returns:
|
|
The context window limit in tokens, or None if not found.
|
|
"""
|
|
direct = _CONTEXT_WINDOW_LIMITS.get(model_id)
|
|
if direct is not None:
|
|
return direct
|
|
|
|
# Fallback: strip prefixes before each dot and retry (handles nested cross-region prefixes and ARNs)
|
|
stripped = model_id
|
|
while (dot_index := stripped.find(".")) != -1:
|
|
stripped = stripped[dot_index + 1 :]
|
|
result = _CONTEXT_WINDOW_LIMITS.get(stripped)
|
|
if result is not None:
|
|
logger.debug(
|
|
"model_id=<%s>, stripped_id=<%s> | resolved context window limit via prefix strip", model_id, stripped
|
|
)
|
|
return result
|
|
|
|
return None
|
|
|
|
|
|
def resolve_config_metadata(config: _C, model_id: str) -> _C:
|
|
"""Resolve model metadata fields on a config dict from built-in lookup tables.
|
|
|
|
When ``context_window_limit`` is not explicitly set, looks it up from the built-in table.
|
|
Explicit values pass through unchanged. Returns a new dict only when resolution adds a field;
|
|
otherwise returns the original config to avoid unnecessary allocation.
|
|
|
|
Args:
|
|
config: The stored model config dict.
|
|
model_id: The model ID to look up.
|
|
|
|
Returns:
|
|
The config with resolved metadata, or the original config if nothing to resolve.
|
|
"""
|
|
if "context_window_limit" in config:
|
|
return config
|
|
|
|
limit = get_context_window_limit(model_id)
|
|
if limit is None:
|
|
return config
|
|
|
|
return {**config, "context_window_limit": limit} # type: ignore[return-value]
|