Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ anthropic_bridge:
Known v1 limits:

- non-streaming only
- text content blocks only
- text blocks plus basic `tool_use` / `tool_result`
- `count_tokens` is a local estimate, not provider-exact accounting
- the optional `claude-code-router` hook only adds routing hints; it is not the protocol bridge

Expand All @@ -324,6 +324,12 @@ Local smoke test:
./docs/examples/anthropic-bridge-smoke.sh
```

Client-near validation before release:

```bash
./docs/examples/anthropic-bridge-validation.sh
```

For a fuller operator view, see [docs/anthropic-bridge.md](./docs/anthropic-bridge.md) and [docs/API.md](./docs/API.md).

## API Surface
Expand Down
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This repo does not require a heavy release process. Use lightweight tags plus Gi
10. For hardening-heavy releases, keep the API functional tests green alongside unit and config coverage.
11. Publish the GitHub Release so [`notify-tap`](./.github/workflows/notify-tap.yml) can dispatch the Homebrew tap update automatically.
12. If the tap dispatch fails or the formula needs manual follow-up, bump `Formula/faigate.rb` in the separate [`fusionAIze/homebrew-tap`](https://github.com/fusionAIze/homebrew-tap) repo to the new release tag and update its `sha256`.
13. For Anthropic bridge releases, also run the client-near validation flow in [docs/anthropic-bridge-release-readiness.md](./docs/anthropic-bridge-release-readiness.md) before tagging.

## Example

Expand Down
2 changes: 1 addition & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Response headers make the approximation explicit:
Known v1 bridge limits:

- non-streaming only
- text content blocks only
- text blocks plus basic `tool_use` / `tool_result`
- image or binary content blocks are rejected
- `count_tokens` is an estimate, not provider-exact accounting

Expand Down
3 changes: 3 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ Recommended operational pattern:
- keep direct Anthropic routes, Anthropic-capable aggregators, and local workers all probeable
- be careful with aggregator routes that may still use a BYOK Anthropic key from the same quota domain
- prefer health checks and fallback ordering over assuming every Anthropic-shaped route is independent
- when two routes can burn the same upstream quota, give them the same `transport.quota_group`
- set `transport.billing_mode: byok` on routes where wallet or aggregator billing may still collapse to your own upstream key
- only set `transport.quota_isolated: true` when you are confident that route is operationally independent

For the end-to-end flow and local smoke example, see [Anthropic Bridge](./anthropic-bridge.md).

Expand Down
146 changes: 146 additions & 0 deletions docs/anthropic-bridge-release-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Anthropic Bridge Release Readiness

This checklist is the release gate for shipping the Anthropic bridge as a production-facing feature inside `fusionAIze Gate`.

The intended release position is:

- optional and explicitly enabled
- safe for production early adopters
- not full Anthropic parity yet

The bridge should only ship when the core protocol path, fallback behavior, and operator surfaces all agree.

## Intended Release Scope

Acceptable to release:

- `POST /v1/messages`
- `POST /v1/messages/count_tokens`
- non-streaming text flows
- basic `tool_use` / `tool_result`
- Anthropic header/version tolerance
- shared-quota-aware fallback behavior

Still explicitly out of scope:

- streaming SSE parity
- image or binary content blocks
- provider-exact token counting
- claiming full Claude Desktop or Claude Code parity across all versions

## Preflight Configuration

Before release, verify that the target config has:

- `api_surfaces.anthropic_messages: true`
- `anthropic_bridge.enabled: true`
- at least one stable Claude-facing alias such as `claude-code -> auto`
- at least one non-Anthropic fallback route or local worker for continuity
- shared Anthropic quota domains marked with `transport.quota_group`
- aggregator or wallet-style routes marked with `transport.billing_mode` when BYOK collapse is possible

Recommended example:

```yaml
anthropic_bridge:
enabled: true
model_aliases:
claude-code: auto
claude-code-fast: eco
claude-code-premium: premium

providers:
anthropic-sonnet:
transport:
quota_group: anthropic-main
kilo-sonnet:
transport:
billing_mode: byok
quota_group: anthropic-main
local-worker:
transport:
quota_isolated: true
```

## Validation Sequence

Run these in order on a product-like config:

1. `./docs/examples/anthropic-bridge-smoke.sh`
2. `./docs/examples/anthropic-bridge-validation.sh`
3. `./scripts/faigate-doctor`
4. `./scripts/faigate-provider-probe --json`

If you validate against a non-default config or env file, export those first so the script, doctor, and probe all inspect the same runtime:

```bash
export FAIGATE_BASE_URL=http://127.0.0.1:18090
export FAIGATE_CONFIG_FILE=/tmp/faigate-bridge-live.yaml
export FAIGATE_ENV_FILE=/opt/homebrew/etc/faigate/faigate.env
./docs/examples/anthropic-bridge-validation.sh
```

The second script is the more complete client-near validation path. It checks:

- Anthropic messages with version/beta headers
- basic tool-use / tool-result bridge handling
- `count_tokens`
- doctor and provider-probe output after the same config is live

## Required Test Baseline

Before release, keep these green:

```bash
env PYTHONPATH=. ./.venv-check-313/bin/pytest -q \
tests/test_config.py \
tests/test_providers.py \
tests/test_anthropic_api.py \
tests/test_anthropic_bridge.py \
tests/test_request_hooks.py
```

and:

```bash
rtk ruff check faigate/config.py faigate/providers.py faigate/main.py \
faigate/canonical.py faigate/bridges/anthropic/adapter.py \
tests/test_config.py tests/test_providers.py tests/test_anthropic_api.py \
tests/test_anthropic_bridge.py tests/test_request_hooks.py
```

## Release Criteria

Ship only if all of these are true:

- Anthropic bridge requests succeed through the normal routing core
- tool-use / tool-result flows stay on the same execution path
- Anthropic error mapping stays coherent under direct provider failures
- version/beta headers survive roundtrip handling
- shared-quota routes are skipped when one route in the same quota group fails with quota, rate-limit, or auth pressure
- doctor and provider-probe still explain route readiness clearly
- docs match the real v1 limits

## No-Go Signals

Do not release if any of these are still observed:

- a quota-exhausted Anthropic route still retries an aggregator route that shares the same upstream quota domain
- the bridge silently drops tool-use or tool-result semantics
- the bridge claims streaming support without a tested SSE implementation
- `count_tokens` is described as exact anywhere in the docs
- doctor or provider-probe make Anthropic-shaped routes look independent when they are actually BYOK-coupled

## Release Call

If the checks above pass, the bridge is reasonable to release as:

- production-usable
- opt-in
- early-adopter safe

It should not yet be marketed as:

- full Anthropic API parity
- full Claude Code parity
- full Claude Desktop parity
18 changes: 17 additions & 1 deletion docs/anthropic-bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Recommended pattern:
- keep direct Anthropic routes probeable and clearly named
- keep Anthropic-capable aggregators as explicit mirrors or secondary routes
- do not assume a premium Anthropic mirror is independent if it uses the same exhausted account
- mark routes that can burn the same upstream quota with a shared `transport.quota_group`
- use `transport.billing_mode: byok` on aggregator routes when the wallet path may still collapse to your own upstream account
- use `faigate-doctor`, `faigate-provider-probe`, `/health`, and `/api/providers` to validate which routes are actually request-ready

## Claude Code / Claude Desktop
Expand Down Expand Up @@ -131,10 +133,24 @@ This covers:
- `POST /v1/messages`
- `POST /v1/messages/count_tokens`

For a client-near validation pass before release, run:

```bash
./docs/examples/anthropic-bridge-validation.sh
```

That broader check adds:

- bridge headers and Anthropic version/beta tolerance
- basic `tool_use` / `tool_result` flow shape
- doctor and provider-probe output after the same config is live

For the explicit release gate, see [Anthropic Bridge Release Readiness](./anthropic-bridge-release-readiness.md).

## Known v1 Limits

- non-streaming only
- text content blocks only
- text blocks plus basic `tool_use` / `tool_result`
- `count_tokens` returns a deterministic local estimate
- image or binary content blocks are not bridged yet
- the optional `claude-code-router` hook only adds routing hints
93 changes: 93 additions & 0 deletions docs/examples/anthropic-bridge-validation.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
set -euo pipefail

BASE_URL="${FAIGATE_BASE_URL:-http://127.0.0.1:8090}"
MODEL_ALIAS="${FAIGATE_ANTHROPIC_MODEL_ALIAS:-claude-code}"
CONFIG_FILE="${FAIGATE_CONFIG_FILE:-}"
ENV_FILE="${FAIGATE_ENV_FILE:-}"

echo "==> Validation context"
echo "BASE_URL=${BASE_URL}"
echo "MODEL_ALIAS=${MODEL_ALIAS}"
if [ -n "${CONFIG_FILE}" ]; then
echo "FAIGATE_CONFIG_FILE=${CONFIG_FILE}"
fi
if [ -n "${ENV_FILE}" ]; then
echo "FAIGATE_ENV_FILE=${ENV_FILE}"
fi
printf '\n'

echo "==> Health"
rtk curl -fsS "${BASE_URL}/health"
printf '\n\n'

echo "==> Provider inventory"
rtk curl -fsS "${BASE_URL}/api/providers"
printf '\n\n'

echo "==> Anthropic messages with bridge headers"
rtk curl -i -fsS "${BASE_URL}/v1/messages" \
-H 'Content-Type: application/json' \
-H 'anthropic-client: claude-code' \
-H 'anthropic-version: 2023-06-01' \
-H 'anthropic-beta: tools-2024-04-04' \
-d "{
\"model\": \"${MODEL_ALIAS}\",
\"system\": \"Respond as a concise operator helper.\",
\"messages\": [
{\"role\": \"user\", \"content\": \"Summarize why one local gateway endpoint helps with Anthropic quota limits.\"}
]
}"
printf '\n\n'

echo "==> Anthropic tool roundtrip shape"
rtk curl -i -fsS "${BASE_URL}/v1/messages" \
-H 'Content-Type: application/json' \
-H 'anthropic-client: claude-code' \
-d "{
\"model\": \"${MODEL_ALIAS}\",
\"messages\": [
{\"role\": \"user\", \"content\": \"Load the deployment guide.\"},
{
\"role\": \"assistant\",
\"content\": [
{
\"type\": \"tool_use\",
\"id\": \"toolu_demo\",
\"name\": \"lookup_doc\",
\"input\": {\"id\": \"deploy-guide\"}
}
]
},
{
\"role\": \"user\",
\"content\": [
{
\"type\": \"tool_result\",
\"tool_use_id\": \"toolu_demo\",
\"content\": \"Deployment guide loaded successfully.\"
}
]
}
]
}"
printf '\n\n'

echo "==> Anthropic count_tokens"
rtk curl -i -fsS "${BASE_URL}/v1/messages/count_tokens" \
-H 'Content-Type: application/json' \
-H 'anthropic-version: 2023-06-01' \
-d "{
\"model\": \"${MODEL_ALIAS}\",
\"messages\": [
{\"role\": \"user\", \"content\": \"Count the bridge tokens for this request.\"}
]
}"
printf '\n\n'

echo "==> Doctor"
./scripts/faigate-doctor
printf '\n\n'

echo "==> Provider probe"
./scripts/faigate-provider-probe --json
printf '\n'
6 changes: 6 additions & 0 deletions docs/examples/provider-kilocode.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@ providers:
model: "anthropic/claude-sonnet-4.6"
max_tokens: 16000
tier: mid
transport:
billing_mode: byok
quota_group: anthropic-main
kilo-opus:
backend: openai-compat
base_url: "${KILOCODE_BASE_URL:-https://api.kilo.ai/api/gateway}"
api_key: "${KILOCODE_API_KEY}"
model: "anthropic/claude-opus-4.6"
max_tokens: 32000
tier: mid
transport:
billing_mode: byok
quota_group: anthropic-main

fallback_chain:
- kilo-sonnet
Expand Down
Loading
Loading