- Introduced user configuration command to set API key. - Updated README and documentation for user config and logging paths. - Refactored logging to support user-specific log files. - Added tests for user configuration and logging behavior.
6.7 KiB
nexus-claude-api Requirements Design
Technical Stack
- Python
>=3.11 - Package manager:
uv - Web framework: FastAPI
- ASGI server: Uvicorn
- Nexus client: boto3 Bedrock Runtime client
- Validation: Pydantic
- CLI: standard library
argparse - Tests: pytest
All project dependencies must be managed by uv and the project virtual environment. Do not install global Python dependencies.
Project Structure
nexus-claude-api/
pyproject.toml
README.md
docs/
AI_NEXUS_CLAUDE.md
PRD.md
REQUIREMENTS_DESIGN.md
src/
nexus_claude_api/
__init__.py
__main__.py
cli.py
config.py
errors.py
models.py
nexus_client.py
server.py
shell.py
tokens.py
routes/
health.py
messages.py
models.py
translators/
anthropic_to_bedrock.py
bedrock_to_anthropic.py
stream.py
tests/
CLI Contract
Primary command:
uv run nexus-claude-api start --port 4141 --claude-code
User configuration command:
nexus-claude-api config set --api-key <key>
Options:
--host: default127.0.0.1--port,-p: default4141--endpoint-url: defaulthttps://genai-nexus.api.corpinter.net--api-key: optional; overrides config files and environment variables--model: defaultclaude-opus-4.6--small-model: defaultclaude-opus-4.6--claude-code: print Claude Code launch command--verbose,-v: debug logging without secrets--dev: use current-directory development config and logs--dry-run: validate config and print helper output without starting the server
Credential lookup order:
--api-key- Current-mode config file
NEXUS_API_KEYAWS_BEARER_TOKEN_BEDROCK
Config file paths:
- Default mode:
~/.config/nexus-claude-api/config.json - Development mode with
--dev: current-directorynexus-claude-api.local.json
Log file paths:
- Default mode:
~/.config/nexus-claude-api/logs/nexus-claude-api.log - Development mode with
--dev: current-directorylogs/nexus-claude-api.log
When --claude-code is used, print a PowerShell command that sets:
ANTHROPIC_BASE_URLANTHROPIC_AUTH_TOKENANTHROPIC_MODELANTHROPIC_DEFAULT_SONNET_MODELANTHROPIC_DEFAULT_OPUS_MODELANTHROPIC_SMALL_FAST_MODELANTHROPIC_DEFAULT_HAIKU_MODELDISABLE_NON_ESSENTIAL_MODEL_CALLSCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
HTTP API Contract
Expose:
GET /GET /healthGET /v1/modelsPOST /v1/messagesPOST /v1/messages/count_tokens
ANTHROPIC_AUTH_TOKEN is printed as dummy because Claude Code expects an Anthropic auth token variable to exist. This local proxy does not validate that inbound token by default. It is not the Nexus key.
Inbound authentication headers are accepted for compatibility but not validated by default because the service is local. Outbound Nexus authentication uses --api-key, the current-mode config file, NEXUS_API_KEY, or AWS_BEARER_TOKEN_BEDROCK.
Model Mapping
Public local model IDs:
claude-opus-4.6
Backend IDs are resolved through a mapping table. This deployment exposes Opus and maps common Sonnet/Haiku aliases to Opus for users whose Nexus access is limited to claude-opus-4.6:
claude-sonnet-4.6->claude-opus-4.6claude-haiku-4.5->claude-opus-4.6claude-sonnet-4->claude-opus-4.6claude-opus-4->claude-opus-4.6claude-haiku-4->claude-opus-4.6
If Nexus requires different backend IDs, update the mapping without changing Claude Code-facing model IDs.
Request Translation
Anthropic to Bedrock:
model->modelIdmessages[].role->role- string content ->
{ "text": "..." } { "type": "text", "text": "..." }->{ "text": "..." }- Anthropic image block -> Bedrock image block
- assistant
tool_use-> BedrocktoolUse - user
tool_result-> BedrocktoolResult system-> Bedrocksystemmax_tokens,temperature,top_p->inferenceConfigstop_sequences->stopSequencestoolsandtool_choice->toolConfig
Unsupported content blocks should return 400 invalid_request_error.
Response Translation
Bedrock to Anthropic:
- Bedrock text content -> Anthropic text block.
- Bedrock
toolUse-> Anthropictool_use. - Bedrock usage -> Anthropic
usage. - Bedrock stop reason maps to Anthropic stop reason.
Stop reason mapping:
end_turn->end_turnmax_tokens->max_tokensstop_sequence->stop_sequencetool_use->tool_use- unknown ->
end_turn
Streaming Translation
Use converse_stream.
Translate Bedrock stream events to Anthropic SSE events:
messageStart->message_startcontentBlockStart->content_block_startcontentBlockDelta.delta.text->content_block_deltawithtext_delta- tool input deltas ->
content_block_deltawithinput_json_delta contentBlockStop->content_block_stopmessageStop->message_delta, thenmessage_stopmetadata.usage-> usage update on finalmessage_delta- backend error ->
error
SSE frame format:
event: <event_type>
data: <json>
Error Handling
Return Anthropic-compatible errors:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "..."
}
}
Status mapping:
- invalid request:
400 - missing Nexus credential: startup failure
- Nexus auth failure:
401or403 - Nexus throttling:
429 - Nexus network/timeout:
502or504 - unexpected server error:
500
Testing
Unit tests:
- Minimal Anthropic text request -> Bedrock payload.
- System prompt conversion.
- Image block conversion.
- Tool config conversion.
- Tool use and tool result conversion.
- Bedrock text response -> Anthropic response.
- Bedrock tool response -> Anthropic tool response.
- Bedrock streaming events -> Anthropic SSE sequence.
- Token counting approximation.
Route tests:
GET /healthGET /v1/modelsPOST /v1/messagesnon-streamPOST /v1/messagesstreamPOST /v1/messages/count_tokens
CLI tests:
nexus-claude-api --help- Claude Code command generation.
- Missing API key validation.
- User config writing with
nexus-claude-api config set --api-key <key>. - Default-mode user config lookup from
~/.config/nexus-claude-api/config.json. - Default mode ignores current-directory
nexus-claude-api.local.json. - Development mode uses current-directory
nexus-claude-api.local.json. --api-keyoverrides config files and config files override environment variables.
Logging tests:
- Default-mode log path resolves to
~/.config/nexus-claude-api/logs/nexus-claude-api.log. - Development-mode log path resolves to current-directory
logs/nexus-claude-api.log. - Verbose logging enables debug details without logging secrets.