217 lines
5.4 KiB
Markdown
217 lines
5.4 KiB
Markdown
# Subscription Bridges
|
|
|
|
Subscription bridges let the gateway route requests to user-owned AI subscription tools through
|
|
a local HTTP interface.
|
|
|
|
The bridge pattern is:
|
|
|
|
```text
|
|
gateway
|
|
-> local bridge
|
|
-> installed CLI or local adapter
|
|
-> subscription-backed response
|
|
```
|
|
|
|
The gateway does not need direct access to the subscription account material. The CLI or adapter
|
|
keeps its own authentication state.
|
|
|
|
## Why Bridges Exist
|
|
|
|
Many subscription tools are designed for interactive use, not direct API access. A bridge gives
|
|
the gateway a small, testable HTTP surface around those tools:
|
|
|
|
- `GET /health`
|
|
- `POST /api/generate`
|
|
- `POST /v1/chat/completions`
|
|
|
|
This makes subscription tools easier to test, monitor, and route alongside other providers.
|
|
|
|
## Discovery
|
|
|
|
Discovery checks:
|
|
|
|
- CLI binary availability
|
|
- version probe result
|
|
- authentication status when a safe probe exists
|
|
- default bridge health
|
|
- configured bridge URL
|
|
|
|
Run discovery:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/scan \
|
|
-H "Authorization: Bearer <key>"
|
|
```
|
|
|
|
List subscriptions:
|
|
|
|
```bash
|
|
curl http://localhost:3100/api/subscriptions \
|
|
-H "Authorization: Bearer <key>"
|
|
```
|
|
|
|
Search:
|
|
|
|
```bash
|
|
curl "http://localhost:3100/api/subscriptions?search=claude" \
|
|
-H "Authorization: Bearer <key>"
|
|
```
|
|
|
|
## Join
|
|
|
|
Join records that the operator wants to use a subscription.
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/join \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <key>" \
|
|
-d '{ "subscription_id": "chatgpt", "auto_spawn": true }'
|
|
```
|
|
|
|
Joining does not expose OAuth state or account credentials.
|
|
The subscription summary returned by the list endpoint contains the generated access card,
|
|
including the direct gateway API URL for that subscription.
|
|
|
|
## Spawn
|
|
|
|
Spawn one bridge:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/bridges \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <key>" \
|
|
-d '{ "subscription_id": "chatgpt" }'
|
|
```
|
|
|
|
Spawn all eligible bridges:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/bridges \
|
|
-H "Authorization: Bearer <key>"
|
|
```
|
|
|
|
## Test
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/test \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <key>" \
|
|
-d '{
|
|
"subscription_id": "chatgpt",
|
|
"message": "Reply with a bridge smoke test."
|
|
}'
|
|
```
|
|
|
|
The test response should include:
|
|
|
|
- subscription ID
|
|
- model
|
|
- bridge URL
|
|
- HTTP status
|
|
- latency
|
|
- response snippet
|
|
|
|
## Call A Joined Subscription
|
|
|
|
Every joined subscription can be called through its own OpenAI-compatible gateway URL:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/api/subscriptions/chatgpt/v1/chat/completions \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <key>" \
|
|
-d '{
|
|
"model": "gpt-4-turbo",
|
|
"messages": [
|
|
{ "role": "user", "content": "Reply through the ChatGPT subscription bridge." }
|
|
]
|
|
}'
|
|
```
|
|
|
|
The unified endpoint can also target a specific subscription:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:3100/v1/chat/completions \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <key>" \
|
|
-H "X-LLM-Gateway-Subscription: chatgpt" \
|
|
-d '{
|
|
"model": "gpt-4-turbo",
|
|
"messages": [
|
|
{ "role": "user", "content": "Reply through the ChatGPT subscription bridge." }
|
|
]
|
|
}'
|
|
```
|
|
|
|
For ambiguous model IDs, prefer the direct subscription URL or the
|
|
`X-LLM-Gateway-Subscription` header. This keeps routing explicit when several subscription
|
|
tools expose similar model names.
|
|
|
|
Chat messages are compressed before bridge dispatch when compression can reduce the request.
|
|
Responses include gateway compression metadata where available.
|
|
|
|
## Access Card
|
|
|
|
Each subscription summary includes an access card with:
|
|
|
|
- gateway base URL
|
|
- chat completions URL
|
|
- per-subscription chat completions URL
|
|
- model list
|
|
- default model
|
|
- required headers
|
|
- `X-LLM-Gateway-Subscription` header value
|
|
- bridge URL
|
|
- bridge env var
|
|
- curl example
|
|
|
|
Use the gateway endpoint from the access card in client applications, not the subscription
|
|
credentials.
|
|
|
|
## Adding A Bridge Implementation
|
|
|
|
Add or update:
|
|
|
|
- `packages/gateway/src/modules/subscription-discovery.ts`
|
|
- `packages/gateway/src/modules/bridge-spawner.ts`
|
|
- `packages/gateway/src/routes/subscriptions.ts`
|
|
- `packages/gateway/src/pipeline/external-providers.ts`
|
|
|
|
Minimum checklist:
|
|
|
|
1. Add a catalog entry.
|
|
2. Add a version probe.
|
|
3. Add an auth probe if the CLI supports one safely.
|
|
4. Pick a localhost bridge port.
|
|
5. Add one or more model IDs.
|
|
6. Implement the CLI invocation.
|
|
7. Return OpenAI-compatible chat output where possible.
|
|
8. Add health behavior.
|
|
9. Add tests or a documented smoke test.
|
|
|
|
## Security Rules
|
|
|
|
- Bind local bridges to localhost.
|
|
- Do not print OAuth artifacts.
|
|
- Do not return subscription account data in API responses.
|
|
- Avoid logging full prompts by default.
|
|
- Treat bridge errors as operational state, not as successful routing.
|
|
- Prefer explicit join before auto-spawn in shared environments.
|
|
|
|
## Troubleshooting
|
|
|
|
### Installed But Not Authenticated
|
|
|
|
Log in through the CLI directly, then run scan again.
|
|
|
|
### Bridge Port Already In Use
|
|
|
|
Check whether a previous bridge process is still running or configure a different bridge URL.
|
|
|
|
### Unified Chat Returns Provider Missing
|
|
|
|
Check whether the selected model ID belongs to a discovered, joined, and running subscription.
|
|
|
|
### CLI Works But Bridge Fails
|
|
|
|
Run the gateway with a verbose log level and test the bridge endpoint directly.
|