feat: add custom base URL support for Anthropic-compatible endpoints (#246)
Support ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN in .env to route SDK requests through proxies or gateways. Preflight now validates the custom endpoint is reachable instead of skipping credential checks.
This commit is contained in:
+12
-4
@@ -13,7 +13,14 @@ ANTHROPIC_API_KEY=your-api-key-here
|
|||||||
# CLAUDE_CODE_OAUTH_TOKEN=your-oauth-token-here
|
# CLAUDE_CODE_OAUTH_TOKEN=your-oauth-token-here
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# OPTION 2: Router Mode (use alternative providers)
|
# OPTION 2: Custom Base URL (compatible proxies, gateways, etc.)
|
||||||
|
# =============================================================================
|
||||||
|
# Point the SDK at an alternative Anthropic-compatible endpoint.
|
||||||
|
# ANTHROPIC_BASE_URL=https://your-proxy.example.com
|
||||||
|
# ANTHROPIC_AUTH_TOKEN=your-auth-token # Auth token for the custom endpoint
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# OPTION 3: Router Mode (use alternative providers)
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Enable router mode by running: ./shannon start ... ROUTER=true
|
# Enable router mode by running: ./shannon start ... ROUTER=true
|
||||||
# Then configure ONE of the providers below:
|
# Then configure ONE of the providers below:
|
||||||
@@ -27,15 +34,16 @@ ANTHROPIC_API_KEY=your-api-key-here
|
|||||||
# ROUTER_DEFAULT=openrouter,google/gemini-3-flash-preview
|
# ROUTER_DEFAULT=openrouter,google/gemini-3-flash-preview
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Model Tier Overrides (Anthropic API / OAuth / Bedrock)
|
# Model Tier Overrides (Anthropic API / OAuth / Custom Base URL / Bedrock)
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Override which model is used for each tier. Defaults are used if not set.
|
# Override which model is used for each tier. Defaults are used if not set.
|
||||||
|
# Optional for direct Anthropic and custom base URL modes. Required for Bedrock/Vertex.
|
||||||
# ANTHROPIC_SMALL_MODEL=... # Small tier (default: claude-haiku-4-5-20251001)
|
# ANTHROPIC_SMALL_MODEL=... # Small tier (default: claude-haiku-4-5-20251001)
|
||||||
# ANTHROPIC_MEDIUM_MODEL=... # Medium tier (default: claude-sonnet-4-6)
|
# ANTHROPIC_MEDIUM_MODEL=... # Medium tier (default: claude-sonnet-4-6)
|
||||||
# ANTHROPIC_LARGE_MODEL=... # Large tier (default: claude-opus-4-6)
|
# ANTHROPIC_LARGE_MODEL=... # Large tier (default: claude-opus-4-6)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# OPTION 3: AWS Bedrock
|
# OPTION 4: AWS Bedrock
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/
|
# https://aws.amazon.com/blogs/machine-learning/accelerate-ai-development-with-amazon-bedrock-api-keys/
|
||||||
# Requires the model tier overrides above to be set with Bedrock-specific model IDs.
|
# Requires the model tier overrides above to be set with Bedrock-specific model IDs.
|
||||||
@@ -49,7 +57,7 @@ ANTHROPIC_API_KEY=your-api-key-here
|
|||||||
# AWS_BEARER_TOKEN_BEDROCK=your-bearer-token
|
# AWS_BEARER_TOKEN_BEDROCK=your-bearer-token
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# OPTION 4: Google Vertex AI
|
# OPTION 5: Google Vertex AI
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models
|
# https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-partner-models
|
||||||
# Requires a GCP service account with roles/aiplatform.user.
|
# Requires a GCP service account with roles/aiplatform.user.
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ Shannon Pro supports a self-hosted runner model (similar to GitHub Actions self-
|
|||||||
- [Configuration (Optional)](#configuration-optional)
|
- [Configuration (Optional)](#configuration-optional)
|
||||||
- [AWS Bedrock](#aws-bedrock)
|
- [AWS Bedrock](#aws-bedrock)
|
||||||
- [Google Vertex AI](#google-vertex-ai)
|
- [Google Vertex AI](#google-vertex-ai)
|
||||||
|
- [Custom Base URL](#custom-base-url)
|
||||||
- [[EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)](#experimental---unsupported-router-mode-alternative-providers)
|
- [[EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)](#experimental---unsupported-router-mode-alternative-providers)
|
||||||
- [Output and Results](#output-and-results)
|
- [Output and Results](#output-and-results)
|
||||||
- [Sample Reports](#-sample-reports)
|
- [Sample Reports](#-sample-reports)
|
||||||
@@ -454,6 +455,33 @@ ANTHROPIC_LARGE_MODEL=claude-opus-4-6
|
|||||||
|
|
||||||
Set `CLOUD_ML_REGION=global` for global endpoints, or a specific region like `us-east5`. Some models may not be available on global endpoints — see the [Vertex AI Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) for region availability.
|
Set `CLOUD_ML_REGION=global` for global endpoints, or a specific region like `us-east5`. Some models may not be available on global endpoints — see the [Vertex AI Model Garden](https://console.cloud.google.com/vertex-ai/model-garden) for region availability.
|
||||||
|
|
||||||
|
### Custom Base URL
|
||||||
|
|
||||||
|
Shannon supports pointing the SDK at any Anthropic-compatible endpoint (proxies, gateways, etc.) via `ANTHROPIC_BASE_URL`.
|
||||||
|
|
||||||
|
#### Quick Setup
|
||||||
|
|
||||||
|
1. Add your endpoint and auth token to `.env`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ANTHROPIC_BASE_URL=https://your-proxy.example.com
|
||||||
|
ANTHROPIC_AUTH_TOKEN=your-auth-token
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Optionally override model tiers (defaults are used if not set):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ANTHROPIC_SMALL_MODEL=claude-haiku-4-5-20251001
|
||||||
|
ANTHROPIC_MEDIUM_MODEL=claude-sonnet-4-6
|
||||||
|
ANTHROPIC_LARGE_MODEL=claude-opus-4-6
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run Shannon as usual:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./shannon start URL=https://example.com REPO=repo-name
|
||||||
|
```
|
||||||
|
|
||||||
### [EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)
|
### [EXPERIMENTAL - UNSUPPORTED] Router Mode (Alternative Providers)
|
||||||
|
|
||||||
Shannon can experimentally route requests through alternative AI providers using claude-code-router. This mode is not officially supported and is intended primarily for:
|
Shannon can experimentally route requests through alternative AI providers using claude-code-router. This mode is not officially supported and is intended primarily for:
|
||||||
|
|||||||
@@ -142,9 +142,12 @@ cmd_start() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for API key (Bedrock and router modes can bypass this)
|
# Check for API key (Bedrock, Vertex, router, and custom base URL modes can bypass this)
|
||||||
if [ -z "$ANTHROPIC_API_KEY" ] && [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
|
if [ -z "$ANTHROPIC_API_KEY" ] && [ -z "$CLAUDE_CODE_OAUTH_TOKEN" ]; then
|
||||||
if [ "$CLAUDE_CODE_USE_BEDROCK" = "1" ]; then
|
if [ -n "$ANTHROPIC_BASE_URL" ] && [ -n "$ANTHROPIC_AUTH_TOKEN" ]; then
|
||||||
|
# Custom base URL mode — use auth token as API key for SDK initialization
|
||||||
|
echo "Using custom base URL: $ANTHROPIC_BASE_URL"
|
||||||
|
elif [ "$CLAUDE_CODE_USE_BEDROCK" = "1" ]; then
|
||||||
# Bedrock mode — validate required AWS credentials
|
# Bedrock mode — validate required AWS credentials
|
||||||
MISSING=""
|
MISSING=""
|
||||||
[ -z "$AWS_REGION" ] && MISSING="$MISSING AWS_REGION"
|
[ -z "$AWS_REGION" ] && MISSING="$MISSING AWS_REGION"
|
||||||
|
|||||||
@@ -160,10 +160,35 @@ function classifySdkError(
|
|||||||
async function validateCredentials(
|
async function validateCredentials(
|
||||||
logger: ActivityLogger
|
logger: ActivityLogger
|
||||||
): Promise<Result<void, PentestError>> {
|
): Promise<Result<void, PentestError>> {
|
||||||
// 1. Router mode — can't validate provider keys, just warn
|
// 1. Custom base URL — validate endpoint is reachable via SDK query
|
||||||
if (process.env.ANTHROPIC_BASE_URL) {
|
if (process.env.ANTHROPIC_BASE_URL) {
|
||||||
logger.warn('Router mode detected — skipping API credential validation');
|
const baseUrl = process.env.ANTHROPIC_BASE_URL;
|
||||||
return ok(undefined);
|
logger.info(`Validating custom base URL: ${baseUrl}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
for await (const message of query({ prompt: 'hi', options: { model: resolveModel('small'), maxTurns: 1 } })) {
|
||||||
|
if (message.type === 'assistant' && message.error) {
|
||||||
|
return classifySdkError(message.error, `custom endpoint (${baseUrl})`);
|
||||||
|
}
|
||||||
|
if (message.type === 'result') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Custom base URL OK');
|
||||||
|
return ok(undefined);
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
|
return err(
|
||||||
|
new PentestError(
|
||||||
|
`Custom base URL unreachable: ${baseUrl} — ${message}`,
|
||||||
|
'network',
|
||||||
|
false,
|
||||||
|
{ baseUrl },
|
||||||
|
ErrorCode.AUTH_FAILED
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Bedrock mode — validate required AWS credentials are present
|
// 2. Bedrock mode — validate required AWS credentials are present
|
||||||
|
|||||||
Reference in New Issue
Block a user