218 lines
5.4 KiB
Markdown
218 lines
5.4 KiB
Markdown
# 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
|
|
```
|
|
|
|
Options:
|
|
|
|
- `--host`: default `127.0.0.1`
|
|
- `--port`, `-p`: default `4141`
|
|
- `--endpoint-url`: default `https://genai-nexus.api.corpinter.net`
|
|
- `--api-key`: optional; fallback to ignored local config, `NEXUS_API_KEY`, then `AWS_BEARER_TOKEN_BEDROCK`
|
|
- `--model`: default `claude-sonnet-4.6`
|
|
- `--small-model`: default `claude-haiku-4.5`
|
|
- `--claude-code`: print Claude Code launch command
|
|
- `--verbose`, `-v`: debug logging without secrets
|
|
|
|
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`, ignored local `nexus-claude-api.local.json`, `NEXUS_API_KEY`, or `AWS_BEARER_TOKEN_BEDROCK`.
|
|
|
|
## Model Mapping
|
|
|
|
Public local model IDs:
|
|
|
|
- `claude-sonnet-4.6`
|
|
- `claude-opus-4.6`
|
|
- `claude-haiku-4.5`
|
|
|
|
Backend IDs are resolved through a mapping table. The initial default mapping keeps the same IDs, except common short aliases are supported:
|
|
|
|
- `claude-sonnet-4` -> `claude-sonnet-4.6`
|
|
- `claude-opus-4` -> `claude-opus-4.6`
|
|
- `claude-haiku-4` -> `claude-haiku-4.5`
|
|
|
|
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 local Nexus credential: startup failure
|
|
- 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.
|