Files
nexus-claude-api/docs/REQUIREMENTS_DESIGN.md

254 lines
6.8 KiB
Markdown
Raw Permalink Normal View History

2026-06-26 17:02:21 +08:00
# 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
```text
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:
```powershell
uv run nexus-claude-api start --port 4141 --claude-code
```
User configuration command:
```powershell
nexus-claude-api config set --api-key <key>
```
2026-06-26 17:02:21 +08:00
Options:
- `--host`: default `127.0.0.1`
- `--port`, `-p`: default `4141`
- `--endpoint-url`: default `https://genai-nexus.api.corpinter.net`
- `--api-key`: optional; overrides config files and environment variables
- `--model`: default `claude-opus-4.6`
- `--small-model`: default `claude-opus-4.6`
2026-06-26 17:02:21 +08:00
- `--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:
1. `--api-key`
2. Current-mode config file
3. `NEXUS_API_KEY`
4. `AWS_BEARER_TOKEN_BEDROCK`
Config file paths:
- Default mode: `~/.config/nexus-claude-api/config.json`
- Development mode with `--dev`: current-directory `nexus-claude-api.local.json`
Log file paths:
- Default mode: `~/.config/nexus-claude-api/logs/nexus-claude-api-YYYY-MM-DD.log`
- Development mode with `--dev`: current-directory `logs/nexus-claude-api-YYYY-MM-DD.log`
2026-06-26 17:02:21 +08:00
When `--claude-code` is used, print a PowerShell command that sets:
- `ANTHROPIC_BASE_URL`
- `ANTHROPIC_AUTH_TOKEN`
- `ANTHROPIC_MODEL`
- `ANTHROPIC_DEFAULT_SONNET_MODEL`
- `ANTHROPIC_DEFAULT_OPUS_MODEL`
- `ANTHROPIC_SMALL_FAST_MODEL`
- `ANTHROPIC_DEFAULT_HAIKU_MODEL`
- `DISABLE_NON_ESSENTIAL_MODEL_CALLS`
- `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`
## HTTP API Contract
Expose:
- `GET /`
- `GET /health`
- `GET /v1/models`
- `POST /v1/messages`
- `POST /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`.
2026-06-26 17:02:21 +08:00
## 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`:
2026-06-26 17:02:21 +08:00
- `claude-sonnet-4.6` -> `claude-opus-4.6`
- `claude-haiku-4.5` -> `claude-opus-4.6`
- `claude-sonnet-4` -> `claude-opus-4.6`
2026-06-26 17:02:21 +08:00
- `claude-opus-4` -> `claude-opus-4.6`
- `claude-haiku-4` -> `claude-opus-4.6`
2026-06-26 17:02:21 +08:00
If Nexus requires different backend IDs, update the mapping without changing Claude Code-facing model IDs.
## Request Translation
Anthropic to Bedrock:
- `model` -> `modelId`
- `messages[].role` -> `role`
- string content -> `{ "text": "..." }`
- `{ "type": "text", "text": "..." }` -> `{ "text": "..." }`
- Anthropic image block -> Bedrock image block
- assistant `tool_use` -> Bedrock `toolUse`
- user `tool_result` -> Bedrock `toolResult`
- `system` -> Bedrock `system`
- `max_tokens`, `temperature`, `top_p` -> `inferenceConfig`
- `stop_sequences` -> `stopSequences`
- `tools` and `tool_choice` -> `toolConfig`
Unsupported content blocks should return `400 invalid_request_error`.
## Response Translation
Bedrock to Anthropic:
- Bedrock text content -> Anthropic text block.
- Bedrock `toolUse` -> Anthropic `tool_use`.
- Bedrock usage -> Anthropic `usage`.
- Bedrock stop reason maps to Anthropic stop reason.
Stop reason mapping:
- `end_turn` -> `end_turn`
- `max_tokens` -> `max_tokens`
- `stop_sequence` -> `stop_sequence`
- `tool_use` -> `tool_use`
- unknown -> `end_turn`
## Streaming Translation
Use `converse_stream`.
Translate Bedrock stream events to Anthropic SSE events:
- `messageStart` -> `message_start`
- `contentBlockStart` -> `content_block_start`
- `contentBlockDelta.delta.text` -> `content_block_delta` with `text_delta`
- tool input deltas -> `content_block_delta` with `input_json_delta`
- `contentBlockStop` -> `content_block_stop`
- `messageStop` -> `message_delta`, then `message_stop`
- `metadata.usage` -> usage update on final `message_delta`
- backend error -> `error`
SSE frame format:
```text
event: <event_type>
data: <json>
```
## Error Handling
Return Anthropic-compatible errors:
```json
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "..."
}
}
```
Status mapping:
- invalid request: `400`
- missing Nexus credential: startup failure
2026-06-26 17:02:21 +08:00
- Nexus auth failure: `401` or `403`
- Nexus throttling: `429`
- Nexus network/timeout: `502` or `504`
- 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 /health`
- `GET /v1/models`
- `POST /v1/messages` non-stream
- `POST /v1/messages` stream
- `POST /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-key` overrides config files and config files override environment variables.
Logging tests:
- Default-mode log path resolves to `~/.config/nexus-claude-api/logs/nexus-claude-api-YYYY-MM-DD.log`.
- Development-mode log path resolves to current-directory `logs/nexus-claude-api-YYYY-MM-DD.log`.
- Verbose logging enables debug details without logging secrets.