From 3156627e1f6bcbaa41dc4b070773ef6c053d9321 Mon Sep 17 00:00:00 2001 From: pufit Date: Mon, 9 Nov 2026 17:30:36 -0500 Subject: [PATCH 1/2] =?UTF-8?q?Models:=20Claude=20Fable=205.2=20=E2=80=94?= =?UTF-8?q?=20pricing=20row,=20picker=20fallback,=20fable=20alias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit claude-fable-5-2 ($8/$40 per MTok, cache write $10/$16, cache read $0.20) was priced by the bare "fable-5" row, i.e. Fable 5.1's $10/$50 — a row whose $1.00 cache read is Fable 5's rate, not 5.1's $0.25. Give 5.2 and 5.1 their own rows ahead of it, make 5.2 the built-in picker's second entry, and default the CLI's "fable" alias to that constant the way "opus" and "haiku" already track theirs. Examples and docs follow. --- config.example.yaml | 13 +++++++------ docs/api.md | 4 ++-- docs/config.md | 2 +- nerve/agent/backends/claude.py | 10 ++++++---- nerve/config.py | 11 ++++++----- nerve/db/usage.py | 6 ++++++ tests/test_cache_policy.py | 15 +++++++++++++++ tests/test_default_models.py | 4 +++- tests/test_engine.py | 3 +++ tests/test_setup_api.py | 2 +- tests/test_usage_cache_ttl.py | 21 +++++++++++++++++++++ 11 files changed, 71 insertions(+), 20 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index 84fac8f3f..916f9d607 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -57,20 +57,21 @@ timezone: America/New_York # Agent agent: model: claude-opus-5-5 # Primary model for conversations (Nerve's default) - # Use claude-fable-5-1 for Anthropic's newest generation (Mythos-class). - # Note: ~2x the cost of Opus ($10/$50 per MTok in/out). + # Use claude-fable-5-2 for Anthropic's newest generation (Mythos-class). + # Note: 2x the cost of Opus 5.5 ($8/$40 per MTok in/out). cron_model: claude-sonnet-5-5 # Cheaper model for cron jobs title_model: claude-haiku-5-5 # Session title generation # outcome_titles: false # Keep the first-message title instead of renaming once the first answer ends # Model-alias remapping for the CLI: short aliases ("opus") used in # Agent/Workflow tool model options and skill frontmatter resolve to the - # mapped ID. Supported: opus, sonnet, haiku, fable. opus → claude-opus-5-5 - # and haiku → claude-haiku-5-5 are the built-in defaults (not applied on - # Bedrock); "" unsets an alias. The CLI also uses the haiku model for its - # background calls. + # mapped ID. Supported: opus, sonnet, haiku, fable. opus → claude-opus-5-5, + # haiku → claude-haiku-5-5 and fable → claude-fable-5-2 are the built-in + # defaults (not applied on Bedrock); "" unsets an alias. The CLI also uses + # the haiku model for its background calls. # model_aliases: # opus: claude-opus-5-5 # haiku: claude-haiku-5-5 + # fable: claude-fable-5-2 # Claude models selectable in the web composer's model picker. The # configured `model` above is always offered first; entries here extend # the list. Unset → the models the Anthropic Models API reports for your diff --git a/docs/api.md b/docs/api.md index a7815884f..8ee171255 100644 --- a/docs/api.md +++ b/docs/api.md @@ -539,10 +539,10 @@ the `reason` names the variable. ```json Response: { "models": [{ "id": "claude-opus-5-5", "label": "Claude Opus 5.5", "family": "opus", "recommended": true }, + { "id": "claude-fable-5-2", "label": "Claude Fable 5.2", "family": "fable", "recommended": false }, { "id": "claude-haiku-5-5", "label": "Claude Haiku 5.5", "family": "haiku", "recommended": false }, { "id": "claude-sonnet-5-5", "label": "Claude Sonnet 5.5", "family": "sonnet", "recommended": false }, - { "id": "claude-fable-5-1", "label": "Claude Fable 5.1", "family": "fable", "recommended": false }, - { "id": "claude-opus-5", "label": "Claude Opus 5", "family": "opus", "recommended": false }], + { "id": "claude-fable-5-1", "label": "Claude Fable 5.1", "family": "fable", "recommended": false }], "current": { "model": "claude-opus-5-5", "effort": "xhigh" }, "efforts": ["max", "xhigh", "high", "medium", "low"], "discovered": true, diff --git a/docs/config.md b/docs/config.md index 4b94b41d8..a933ee25b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -986,7 +986,7 @@ Backups follow the same rule: | `agent.models` | list | `[]` | Claude models offered in the composer's model picker. `agent.model` always leads; entries extend the list. Empty → the discovered catalog (see `agent.model_discovery`), else a built-in current-generation list (opus / fable / sonnet / haiku); on Bedrock only configured models are offered | | `agent.model_discovery` | bool | `true` | Ask the Anthropic Models API (`GET /v1/models`) which models the configured credentials' catalog endpoint advertises, and offer those in the picker — so a newly released model needs no config edit. Catalog membership is not a serving guarantee (an advertised ID can still 404 on send; discovery runs no serving probe — see `agent.model_discovery_excluded_models`). Primed at gateway startup, cached in-process (6h) and refreshed in the background. Best-effort: ignored when `agent.models` is set, on Bedrock (the Bedrock client has no Models API), without an API key, or when the API is unreachable — the built-in list applies | | `agent.model_discovery_excluded_models` | list | `[]` | Model-ID substrings pruned from **discovery** results before the picker sees them (case-insensitive; empty/whitespace patterns ignored). A proxy/provider catalog is not a serving guarantee — e.g. a retired ID that `GET /v1/models` still advertises but that 404s on send — so this drops such entries without a code change, and hot-reloads (read at pick time, not baked into the 6h discovery cache). Applied only to discovered entries: `agent.model` and an explicit `agent.models` list are never filtered, so naming a model in config overrides an exclusion. Excluding everything discovery returns just leaves the configured default (not a fallback to the built-in list) | -| `agent.model_aliases` | map | `{opus: claude-opus-5-5, haiku: claude-haiku-5-5}` | Alias → model ID remapping for the CLI (emitted as `ANTHROPIC_DEFAULT__MODEL` env vars). Aliases (`opus`, `sonnet`, `haiku`, `fable`) used in Agent/Workflow tool model options, skill frontmatter, and cron overrides resolve to the mapped ID. Entries merge over the built-in `opus → claude-opus-5-5` and `haiku → claude-haiku-5-5` defaults (the `agent.model` and `memory.fast_model` defaults; not applied on Bedrock — set geo-prefixed IDs explicitly there); `""` unsets an alias. The CLI also uses the `haiku` model for its background calls unless `ANTHROPIC_SMALL_FAST_MODEL` is set | +| `agent.model_aliases` | map | `{opus: claude-opus-5-5, haiku: claude-haiku-5-5, fable: claude-fable-5-2}` | Alias → model ID remapping for the CLI (emitted as `ANTHROPIC_DEFAULT__MODEL` env vars). Aliases (`opus`, `sonnet`, `haiku`, `fable`) used in Agent/Workflow tool model options, skill frontmatter, and cron overrides resolve to the mapped ID. Entries merge over the built-in `opus → claude-opus-5-5`, `haiku → claude-haiku-5-5` and `fable → claude-fable-5-2` defaults (the `agent.model` and `memory.fast_model` defaults and the picker's second built-in entry; not applied on Bedrock — set geo-prefixed IDs explicitly there); `""` unsets an alias. The CLI also uses the `haiku` model for its background calls unless `ANTHROPIC_SMALL_FAST_MODEL` is set | | `agent.max_turns` | int | `1000` | Max agentic turns (model ↔ tool round-trips) per request on the Claude backend; a request that reaches it fails with "Reached maximum number of turns (N)". A last-resort stop for a looping agent, not a budget — real work routinely passes 50 and 100. `0` = no cap (the CLI gets no `--max-turns` flag). Read when a session's CLI client is built, so a changed value applies to new sessions, and to existing ones once their client is rebuilt | | `agent.max_concurrent` | int | `32` | Max concurrent agent sessions | | `agent.cache_ttl` | string | `"5m"` | Prompt-cache write TTL policy: `5m` (status quo), `1h` (always request the 1-hour TTL), or `auto` (per session at client-build time: sparse-cadence sessions — persistent crons, wakeup loops, spaced chats — get `1h`; dense sessions stay on `5m`). Per-cron-job override via `cache_ttl` in jobs.yaml. See `nerve/agent/cache_policy.py` | diff --git a/nerve/agent/backends/claude.py b/nerve/agent/backends/claude.py index d981fa37c..417ace0a6 100644 --- a/nerve/agent/backends/claude.py +++ b/nerve/agent/backends/claude.py @@ -895,20 +895,22 @@ def _build_env( # Model-alias remapping: short aliases ("opus", "sonnet", ...) used # in Agent/Workflow tool model options, skill frontmatter, and cron # overrides resolve INSIDE the CLI via ANTHROPIC_DEFAULT__MODEL - # env vars. Nerve defaults "opus" → nerve.config.DEFAULT_MODEL and - # "haiku" → nerve.config.DEFAULT_FAST_MODEL (skipped on Bedrock, where + # env vars. Nerve defaults "opus" → nerve.config.DEFAULT_MODEL, + # "haiku" → nerve.config.DEFAULT_FAST_MODEL and "fable" → + # nerve.config.DEFAULT_FALLBACK_MODEL (skipped on Bedrock, where # model IDs need a geo prefix — set agent.model_aliases with explicit # prefixed IDs there). The haiku value is also the CLI's small fast # model for background calls: the CLI reads ANTHROPIC_SMALL_FAST_MODEL # first and falls back to ANTHROPIC_DEFAULT_HAIKU_MODEL. # User-configured aliases merge over the defaults; an empty value # unsets one (CLI built-in mapping wins). - from nerve.config import DEFAULT_FAST_MODEL, DEFAULT_MODEL + from nerve.config import DEFAULT_FALLBACK_MODEL, DEFAULT_FAST_MODEL, DEFAULT_MODEL aliases: dict[str, str] = {} if not config.provider.is_bedrock: aliases["opus"] = DEFAULT_MODEL aliases["haiku"] = DEFAULT_FAST_MODEL + aliases["fable"] = DEFAULT_FALLBACK_MODEL aliases.update(config.agent.model_aliases) for alias, target in aliases.items(): env_name = _MODEL_ALIAS_ENV_VARS.get(alias.strip().lower()) @@ -1164,7 +1166,7 @@ def _parse_thinking_config( # Ordered most-specific to least-specific; first match wins. Mirrors the # pattern used by MODEL_PRICING in nerve/db/usage.py. _MODEL_EFFORT_LEVELS: dict[str, tuple[str, ...]] = { - "fable-5": ("low", "medium", "high", "xhigh", "max"), + "fable-5": ("low", "medium", "high", "xhigh", "max"), # Fable 5 / 5.1 / 5.2 "opus-5-5": ("low", "medium", "high", "xhigh", "max"), "opus-5": ("low", "medium", "high", "xhigh", "max"), "sonnet-5-5": ("low", "medium", "high", "xhigh", "max"), diff --git a/nerve/config.py b/nerve/config.py index 4aab519a1..f97531e3f 100644 --- a/nerve/config.py +++ b/nerve/config.py @@ -32,7 +32,7 @@ # # This block is the only place a default model id is spelled. Every other # site (the setup writer, the Bedrock geo-prefixed ids, the Claude CLI's -# ``opus`` and ``haiku`` aliases, the terminal wizard's example line) +# ``opus``, ``haiku`` and ``fable`` aliases, the terminal wizard's example line) # references these names, and ``tests/test_default_models.py`` fails on a # model-id literal anywhere else under ``nerve/`` — so the next update is one # edit here plus the regenerated goldens, examples and docs. @@ -42,7 +42,7 @@ DEFAULT_RECALL_MODEL = "claude-sonnet-5-5" # memory.recall_model DEFAULT_MEMORIZE_MODEL = "claude-sonnet-5-5" # memory.memorize_model DEFAULT_FAST_MODEL = "claude-haiku-5-5" # memory.fast_model; also the CLI's ``haiku`` alias -DEFAULT_FALLBACK_MODEL = "claude-fable-5-1" # second entry of the built-in picker list +DEFAULT_FALLBACK_MODEL = "claude-fable-5-2" # second entry of the built-in picker list; also the CLI's ``fable`` alias DEFAULT_EFFORT = "xhigh" # agent.effort (conversations); max is slower for no real gain on the 5.5 models # Fallback for the composer's Claude model picker when ``agent.models`` is @@ -1096,9 +1096,10 @@ class AgentConfig: # emitted as ANTHROPIC_DEFAULT__MODEL env vars so short aliases # ("opus" in Agent/Workflow tool calls, skill frontmatter, cron model # overrides) resolve to the mapped model. Supported aliases: opus, - # sonnet, haiku, fable. Nerve defaults opus → DEFAULT_MODEL and - # haiku → DEFAULT_FAST_MODEL on non-Bedrock providers; the CLI also uses - # the haiku model for its background calls. Entries here merge over those + # sonnet, haiku, fable. Nerve defaults opus → DEFAULT_MODEL, + # haiku → DEFAULT_FAST_MODEL and fable → DEFAULT_FALLBACK_MODEL on + # non-Bedrock providers; the CLI also uses the haiku model for its + # background calls. Entries here merge over those # defaults, and an empty value ("") unsets one (falls back to the CLI's # built-in mapping). model_aliases: dict[str, str] = field(default_factory=dict) diff --git a/nerve/db/usage.py b/nerve/db/usage.py index 12a8cf09b..77d5dd931 100644 --- a/nerve/db/usage.py +++ b/nerve/db/usage.py @@ -14,6 +14,12 @@ # Key: canonical model short-name substring → (input, output, cache_read, # cache_write_5m, cache_write_1h, web_search_per_req) MODEL_PRICING: dict[str, tuple[float, float, float, float, float, float]] = { + # Fable: 5.2 is the current one ($8/$40, cache reads at 0.025x = $0.20); + # 5.1 kept the $10/$50 tier but already read the cache at 0.025x ($0.25); + # Fable 5 reads at the usual 0.1x ($1). Most-specific key first — the bare + # "fable-5" row must not catch 5.1 or 5.2. Verified 2026-11-09. + "fable-5-2": (8, 40, 0.20, 10.00, 16.00, 0.01), # Fable 5.2 (2x Opus 5.5) + "fable-5-1": (10, 50, 0.25, 12.50, 20.00, 0.01), # Fable 5.1 "fable-5": (10, 50, 1.00, 12.50, 20.00, 0.01), # Fable 5 (Mythos-class, ~2x Opus) "opus-5-5": (4, 20, 0.20, 5.00, 8.00, 0.01), # Opus 5.5 standard (verified 2026-09-22) "opus-5": (5, 25, 0.50, 6.25, 10.00, 0.01), # Opus 5 standard (verified 2026-07-28) diff --git a/tests/test_cache_policy.py b/tests/test_cache_policy.py index fd1beb84c..329983312 100644 --- a/tests/test_cache_policy.py +++ b/tests/test_cache_policy.py @@ -251,6 +251,21 @@ def test_build_env_default_haiku_alias_maps_to_the_fast_model(): assert "ANTHROPIC_SMALL_FAST_MODEL" not in env +def test_build_env_default_fable_alias_maps_to_the_fallback_model(): + # The "fable" alias resolves to nerve.config.DEFAULT_FALLBACK_MODEL (the + # picker's second built-in entry), so an Agent/Workflow call asking for + # "fable" gets Nerve's current Fable whatever the CLI's own default is. + from nerve.config import DEFAULT_FALLBACK_MODEL + + env = _make_env_backend()._build_env() + assert env["ANTHROPIC_DEFAULT_FABLE_MODEL"] == DEFAULT_FALLBACK_MODEL == "claude-fable-5-2" + # Config overrides it and "" unsets it like the other defaults; Bedrock gets none. + env = _make_env_backend(aliases={"fable": "claude-fable-5-1"})._build_env() + assert env["ANTHROPIC_DEFAULT_FABLE_MODEL"] == "claude-fable-5-1" + assert "ANTHROPIC_DEFAULT_FABLE_MODEL" not in _make_env_backend(aliases={"fable": ""})._build_env() + assert "ANTHROPIC_DEFAULT_FABLE_MODEL" not in _make_env_backend(is_bedrock=True)._build_env() + + def test_build_env_haiku_alias_config_overrides_and_unsets_default(): env = _make_env_backend(aliases={"haiku": "claude-haiku-4-5"})._build_env() assert env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] == "claude-haiku-4-5" diff --git a/tests/test_default_models.py b/tests/test_default_models.py index e5966b7d5..5bb08dd7c 100644 --- a/tests/test_default_models.py +++ b/tests/test_default_models.py @@ -60,6 +60,7 @@ def test_no_default_model_literal_outside_the_constants_block(): def test_the_constants_agree_with_each_other(): assert DEFAULT_MODEL == "claude-opus-5-5" assert DEFAULT_TITLE_MODEL == DEFAULT_FAST_MODEL == "claude-haiku-5-5" + assert DEFAULT_FALLBACK_MODEL == "claude-fable-5-2" assert DEFAULT_CLAUDE_MODELS[0] == DEFAULT_MODEL assert DEFAULT_CLAUDE_MODELS[1] == DEFAULT_FALLBACK_MODEL assert len(set(DEFAULT_CLAUDE_MODELS)) == len(DEFAULT_CLAUDE_MODELS) @@ -119,7 +120,7 @@ def test_the_writer_and_the_cli_alias_use_the_constants(): assert bedrock["memory"]["fast_model"] == f"{geo}.anthropic.{DEFAULT_FAST_MODEL}" assert bedrock["memory"]["fast_model"] == "eu.anthropic.claude-haiku-5-5" - # The Claude CLI's built-in `opus` and `haiku` aliases are the defaults. + # The Claude CLI's built-in `opus`, `haiku` and `fable` aliases are the defaults. from types import SimpleNamespace from nerve.agent.backends.claude import ClaudeBackend @@ -137,6 +138,7 @@ def test_the_writer_and_the_cli_alias_use_the_constants(): env = ClaudeBackend(SimpleNamespace(config=lambda: config))._build_env() assert env["ANTHROPIC_DEFAULT_OPUS_MODEL"] == DEFAULT_MODEL assert env["ANTHROPIC_DEFAULT_HAIKU_MODEL"] == DEFAULT_FAST_MODEL + assert env["ANTHROPIC_DEFAULT_FABLE_MODEL"] == DEFAULT_FALLBACK_MODEL def test_the_examples_and_templates_carry_the_default(): diff --git a/tests/test_engine.py b/tests/test_engine.py index d1c7fd116..681c41040 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -31,6 +31,9 @@ ("max", "claude-fable-5", "max"), ("xhigh", "claude-fable-5", "xhigh"), ("low", "claude-fable-5", "low"), + # Fable 5.2 keeps the full ladder (default effort high; verified 2026-11-09) + ("max", "claude-fable-5-2", "max"), + ("xhigh", "claude-fable-5-2", "xhigh"), # Opus 5 supports the full ladder (verified via Models API 2026-07-28) ("max", "claude-opus-5", "max"), ("xhigh", "claude-opus-5", "xhigh"), diff --git a/tests/test_setup_api.py b/tests/test_setup_api.py index a66ec106b..b04024eea 100644 --- a/tests/test_setup_api.py +++ b/tests/test_setup_api.py @@ -2662,7 +2662,7 @@ def test_model_labels_are_formatted_consistently(): from nerve.config import DEFAULT_CLAUDE_MODELS assert [setup_routes._label(m) for m in DEFAULT_CLAUDE_MODELS] == [ - "Claude Opus 5.5", "Claude Fable 5.1", "Claude Sonnet 5.5", "Claude Haiku 5.5", + "Claude Opus 5.5", "Claude Fable 5.2", "Claude Sonnet 5.5", "Claude Haiku 5.5", ] diff --git a/tests/test_usage_cache_ttl.py b/tests/test_usage_cache_ttl.py index 33655bf2a..162a6326a 100644 --- a/tests/test_usage_cache_ttl.py +++ b/tests/test_usage_cache_ttl.py @@ -191,6 +191,27 @@ def test_fable_5_rates(self): assert c5m == 12.50 assert c1h == 20.00 + def test_fable_5_2_rates(self): + # Fable 5.2 (verified 2026-11-09): base $8/MTok in, $40/MTok out, + # 5m write = 1.25x = $10/MTok, 1h write = 2x = $16/MTok, cache reads + # at 0.025x = $0.20/MTok. The Fable 5.x generations differ in more + # than the base rate, so each carries its own row. + from nerve.db.usage import MODEL_PRICING, _get_pricing + p_in, p_out, p_read, c5m, c1h, _ = _get_pricing("claude-fable-5-2") + assert (p_in, p_out, p_read, c5m, c1h) == (8, 40, 0.20, 10.00, 16.00) + assert _get_pricing("us.anthropic.claude-fable-5-2") == MODEL_PRICING["fable-5-2"] + + def test_fable_5_x_rows_do_not_bleed_into_each_other(self): + # "fable-5" is a substring of "fable-5-1" and "fable-5-2", so the + # specific rows must be checked first. Fable 5.1 kept Fable 5's + # $10/$50 tier but reads the cache at 0.025x ($0.25, not $1). + from nerve.db.usage import MODEL_PRICING, _get_pricing + assert _get_pricing("claude-fable-5-2") == MODEL_PRICING["fable-5-2"] + assert _get_pricing("claude-fable-5-1") == MODEL_PRICING["fable-5-1"] + assert _get_pricing("claude-fable-5-1")[2] == 0.25 + assert _get_pricing("claude-fable-5") == MODEL_PRICING["fable-5"] + assert _get_pricing("claude-fable-5")[2] == 1.00 + def test_opus_5_rates(self): # Anchor: Opus 5 — same tier as 4.8 (verified against published # pricing 2026-07-28). Base $5/MTok in, $25/MTok out, 5m write = From f8afbca5683d41562c4b74dd8f4cd9389495c73e Mon Sep 17 00:00:00 2001 From: pufit Date: Mon, 9 Nov 2026 17:31:13 -0500 Subject: [PATCH 2/2] Deps: claude-agent-sdk 0.2.180 (Claude Code 2.1.321) for Fable 5.2 The 2.1.316 bundle in 0.2.176 takes claude-fable-5-2 as an unrecognized model: a 200K context window and Opus 5.5 prices, which is what Nerve books as the turn's cost. 2.1.321 knows the model. Floor raised to match. --- pyproject.toml | 8 +++++++- uv.lock | 18 +++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dd5f177d0..312e34256 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,13 @@ dependencies = [ # rejects models released after it with "does not support this model; # version 2.1.251 or newer is required". 0.2.150 bundles 2.1.257. Every # release in 0.2.141..0.2.150 is a CLI-bundle bump only — no API change. - "claude-agent-sdk>=0.2.161", + # Floor raised to 0.2.180 (bundles 2.1.321) for Claude Fable 5.2: 0.2.176's + # 2.1.316 accepts the id but as an "unrecognized_model" — it reports a + # 200K context window (auto-compaction at a fifth of the real 1M) and + # prices the turn at Opus 5.5 rates, which is what Nerve records as the + # turn's cost. 0.2.177..0.2.180 change no Python API (one optional hook + # option added). + "claude-agent-sdk>=0.2.180", # Declared explicitly because nerve/mcp_server/ imports `mcp` directly # rather than only through claude-agent-sdk. Both bounds are load-bearing: # nerve/mcp_server/ is written against the 2.x lowlevel API (constructor diff --git a/uv.lock b/uv.lock index 4cc307d48..02c6f9c02 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 5 +revision = 3 requires-python = ">=3.13" resolution-markers = [ "python_full_version >= '3.14'", @@ -616,7 +616,7 @@ wheels = [ [[package]] name = "claude-agent-sdk" -version = "0.2.176" +version = "0.2.180" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -624,13 +624,13 @@ dependencies = [ { name = "mcp" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/94/382ca423a52365adb435fcdd129c0e58933177b26142a07ac11743518433/claude_agent_sdk-0.2.176.tar.gz", hash = "sha256:4793044584fc741bd1ab3a7d8751398f58edab8c89df5db1fc9ab58e66fd9068", size = 398753, upload-time = "2026-10-31T01:45:30.882Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/23/1483388a34190c4cb41790aa5201126e40d8ad90b363bf090abb273f4dc5/claude_agent_sdk-0.2.180.tar.gz", hash = "sha256:1c0935c881a1b5232e6b6b894078ee79b315d75d449408af2202bddfa990a16c", size = 400210, upload-time = "2026-11-09T20:07:56.832Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/67/310c9bc16a904abdea0d17a93e991a706cae82f53bb9a54c6aaca1f4f791/claude_agent_sdk-0.2.176-py3-none-macosx_11_0_arm64.whl", hash = "sha256:171777b8748694db5a1cd86d6b1fd02687794e74e0a3e89439aa6e44c94876f3", size = 134026265, upload-time = "2026-10-31T01:45:36.159Z" }, - { url = "https://files.pythonhosted.org/packages/f0/a0/bb69c5d9682b8a941f8c89148426e11e2dcebfe92feda21afa1615fd71b1/claude_agent_sdk-0.2.176-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:481f8972a57b75517f6bbcaf18325ec950f31cf145befec5859da6a39598dbef", size = 141087278, upload-time = "2026-10-31T01:45:40.467Z" }, - { url = "https://files.pythonhosted.org/packages/67/51/279f34e17cccb5cd3c162a75eb6d73af8f1d5c94eb13994f17d542c14b07/claude_agent_sdk-0.2.176-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:96cf916ace964deef719926f396292bd6b058aa9ab8f0c0fa24bcf96f2622185", size = 144514054, upload-time = "2026-10-31T01:45:45.023Z" }, - { url = "https://files.pythonhosted.org/packages/28/cd/8ca722a99d92f154820785a38113976c7b9c0e0620a3ddcb194dffd303ba/claude_agent_sdk-0.2.176-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:ab2cdaa8d5b38844e1f61344004c47d9eb465b3ca3169054e9bcaeaec371719a", size = 145380725, upload-time = "2026-10-31T01:45:49.806Z" }, - { url = "https://files.pythonhosted.org/packages/32/c4/431b98c5f68e6bebcff7f4b2531692971ef28b1a11227417df1ec347156d/claude_agent_sdk-0.2.176-py3-none-win_amd64.whl", hash = "sha256:d62e5de30e31d24ff0d4f1298038e1e837e951ef76f03f48e3f1685e343067a8", size = 148766209, upload-time = "2026-10-31T01:45:54.784Z" }, + { url = "https://files.pythonhosted.org/packages/28/02/55d54b457dddf96e39de01a0ebb84853e57c115c027c87bc7d7e9c229932/claude_agent_sdk-0.2.180-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a4177b29a877f820abfd1b7862e61bcea14e1cd7f16c75fcee364b4d95f4c7c4", size = 140102932, upload-time = "2026-11-09T20:08:02.69Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e1/8df5fe6648de3f4404f159ae5054d8f73deec2c6e11aac17d2fb6264180b/claude_agent_sdk-0.2.180-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:4025c4f1e91ff7e7d16279bf112c6b2487678cc500a4173a5509c88821809cc6", size = 147396833, upload-time = "2026-11-09T20:08:07.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/ce/b4a05bb0a53ae21537f6c4ecc84d6e9411327a08399b521dadbcfea3bb7d/claude_agent_sdk-0.2.180-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:c1cef7b79747f9d3663555bb37c72d996efc99a727dd68b1cbac62e4d2479f99", size = 151758489, upload-time = "2026-11-09T20:08:12.905Z" }, + { url = "https://files.pythonhosted.org/packages/b9/28/740605fe81c0afc5216074adc1486d43e8985abfa9e318e761eb78f6298c/claude_agent_sdk-0.2.180-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:0e5237ce189ae316ffbdfbb205277ea9387222b9c3cb6668ce533335ce7c759d", size = 152129633, upload-time = "2026-11-09T20:08:18.949Z" }, + { url = "https://files.pythonhosted.org/packages/2b/8e/95525f07beb63966ef09129da3f4823fdc805d0781288f1c463340ec7a5d/claude_agent_sdk-0.2.180-py3-none-win_amd64.whl", hash = "sha256:77c8186cf29c928bd424b5803caf4c69ac91ad00c058bddc86b7bb4e7893c551", size = 153848873, upload-time = "2026-11-09T20:08:25.188Z" }, ] [[package]] @@ -1661,7 +1661,7 @@ requires-dist = [ { name = "anthropic", extras = ["bedrock"], specifier = ">=0.45.0" }, { name = "apscheduler", specifier = ">=3.11.0" }, { name = "bcrypt", specifier = ">=4.2.0" }, - { name = "claude-agent-sdk", specifier = ">=0.2.161" }, + { name = "claude-agent-sdk", specifier = ">=0.2.180" }, { name = "click", specifier = ">=8.1.0" }, { name = "fastapi", specifier = ">=0.142.0" }, { name = "html2text", specifier = ">=2024.2.26" },