Add Anthropic as a first-class inference provider, bypassing OpenRouter for direct API access. Uses the native Anthropic SDK with a full format adapter (same pattern as the codex_responses api_mode). ## Auth (three methods, priority order) 1. ANTHROPIC_API_KEY env var (regular API key, sk-ant-api-*) 2. ANTHROPIC_TOKEN / CLAUDE_CODE_OAUTH_TOKEN env var (setup-token, sk-ant-oat-*) 3. Auto-discovery from ~/.claude/.credentials.json (Claude Code subscription) - Reads Claude Code's OAuth credentials - Checks token expiry with 60s buffer - Setup tokens use Bearer auth + anthropic-beta: oauth-2025-04-20 header - Regular API keys use standard x-api-key header ## Changes by file ### New files - agent/anthropic_adapter.py — Client builder, message/tool/response format conversion, Claude Code credential reader, token resolver. Handles system prompt extraction, tool_use/tool_result blocks, thinking/reasoning, orphaned tool_use cleanup, cache_control. - tests/test_anthropic_adapter.py — 36 tests covering all adapter logic ### Modified files - pyproject.toml — Add anthropic>=0.39.0 dependency - hermes_cli/auth.py — Add 'anthropic' to PROVIDER_REGISTRY with three env vars, plus 'claude'/'claude-code' aliases - hermes_cli/models.py — Add model catalog, labels, aliases, provider order - hermes_cli/main.py — Add 'anthropic' to --provider CLI choices - hermes_cli/runtime_provider.py — Add Anthropic branch returning api_mode='anthropic_messages' (before generic api_key fallthrough) - hermes_cli/setup.py — Add Anthropic setup wizard with Claude Code credential auto-discovery, model selection, OpenRouter tools prompt - agent/auxiliary_client.py — Add claude-haiku-4-5 as aux model - agent/model_metadata.py — Add bare Claude model context lengths - run_agent.py — Add anthropic_messages api_mode: * Client init (Anthropic SDK instead of OpenAI) * API call dispatch (_anthropic_client.messages.create) * Response validation (content blocks) * finish_reason mapping (stop_reason -> finish_reason) * Token usage (input_tokens/output_tokens) * Response normalization (normalize_anthropic_response) * Client interrupt/rebuild * Prompt caching auto-enabled for native Anthropic - tests/test_run_agent.py — Update test_anthropic_base_url_accepted to expect native routing, add test_prompt_caching_native_anthropic
89 lines
2.4 KiB
TOML
89 lines
2.4 KiB
TOML
[build-system]
|
|
requires = ["setuptools>=61.0"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "hermes-agent"
|
|
version = "0.2.0"
|
|
description = "The self-improving AI agent — creates skills from experience, improves them during use, and runs anywhere"
|
|
readme = "README.md"
|
|
requires-python = ">=3.11"
|
|
authors = [{ name = "Nous Research" }]
|
|
license = { text = "MIT" }
|
|
dependencies = [
|
|
# Core
|
|
"openai",
|
|
"anthropic>=0.39.0",
|
|
"python-dotenv",
|
|
"fire",
|
|
"httpx",
|
|
"rich",
|
|
"tenacity",
|
|
"pyyaml",
|
|
"requests",
|
|
"jinja2",
|
|
"pydantic>=2.0",
|
|
# Interactive CLI (prompt_toolkit is used directly by cli.py)
|
|
"prompt_toolkit",
|
|
# Tools
|
|
"firecrawl-py",
|
|
"fal-client",
|
|
# Text-to-speech (Edge TTS is free, no API key needed)
|
|
"edge-tts",
|
|
# mini-swe-agent deps (terminal tool)
|
|
"litellm>=1.75.5",
|
|
"typer",
|
|
"platformdirs",
|
|
# Skills Hub (GitHub App JWT auth — optional, only needed for bot identity)
|
|
"PyJWT[crypto]",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
modal = ["swe-rex[modal]>=1.4.0"]
|
|
daytona = ["daytona>=0.148.0"]
|
|
dev = ["pytest", "pytest-asyncio", "pytest-xdist", "mcp>=1.2.0"]
|
|
messaging = ["python-telegram-bot>=20.0", "discord.py>=2.0", "aiohttp>=3.9.0", "slack-bolt>=1.18.0", "slack-sdk>=3.27.0"]
|
|
cron = ["croniter"]
|
|
slack = ["slack-bolt>=1.18.0", "slack-sdk>=3.27.0"]
|
|
cli = ["simple-term-menu"]
|
|
tts-premium = ["elevenlabs"]
|
|
pty = [
|
|
"ptyprocess>=0.7.0; sys_platform != 'win32'",
|
|
"pywinpty>=2.0.0; sys_platform == 'win32'",
|
|
]
|
|
honcho = ["honcho-ai>=2.0.1"]
|
|
mcp = ["mcp>=1.2.0"]
|
|
homeassistant = ["aiohttp>=3.9.0"]
|
|
yc-bench = ["yc-bench @ git+https://github.com/collinear-ai/yc-bench.git"]
|
|
all = [
|
|
"hermes-agent[modal]",
|
|
"hermes-agent[daytona]",
|
|
"hermes-agent[messaging]",
|
|
"hermes-agent[cron]",
|
|
"hermes-agent[cli]",
|
|
"hermes-agent[dev]",
|
|
"hermes-agent[tts-premium]",
|
|
"hermes-agent[slack]",
|
|
"hermes-agent[pty]",
|
|
"hermes-agent[honcho]",
|
|
"hermes-agent[mcp]",
|
|
"hermes-agent[homeassistant]",
|
|
]
|
|
|
|
[project.scripts]
|
|
hermes = "hermes_cli.main:main"
|
|
hermes-agent = "run_agent:main"
|
|
|
|
[tool.setuptools]
|
|
py-modules = ["run_agent", "model_tools", "toolsets", "batch_runner", "trajectory_compressor", "toolset_distributions", "cli", "hermes_constants"]
|
|
|
|
[tool.setuptools.packages.find]
|
|
include = ["tools", "hermes_cli", "gateway", "cron", "honcho_integration"]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
markers = [
|
|
"integration: marks tests requiring external services (API keys, Modal, etc.)",
|
|
]
|
|
addopts = "-m 'not integration' -n auto"
|