When: The client waits and no new upstream bytes are observed.
Choose: Inspect transport connectivity and read_idle_timeout_secs.
Why: This is an idle-read problem, not necessarily a protocol semantic problem.
Recipes are short task paths. They intentionally point back to reference pages for exact fields, defaults, and behavior contracts instead of duplicating every rule inline.
Goal: Use config.toml as the runtime source of truth.
[routing.default_provider_names].protocol, base_url, and api_key.Verify: Requests using the configured inbound protocol select the default provider.
Goal: Send client traffic to ProxAI, not directly to the provider.
/v1 base URL.Verify: ProxAI logs show local inbound traffic and upstream provider selection.
[routing.default_provider_names]openai_responses = "openai"openai_chat_completions = "openai"
[providers.openai]protocol = "openai_responses"base_url = "https://api.openai.com"api_key = "..."Goal: Keep the client on /v1/responses while sending Anthropic Messages upstream.
openai_responses default provider to the Anthropic-compatible provider name.protocol = "anthropic_messages".Verify: The conversion pair is listed as supported before relying on it.
[routing.default_provider_names]openai_responses = "anthropic_upstream"
[providers.anthropic_upstream]protocol = "anthropic_messages"base_url = "https://example.invalid"api_key = "..."compatibility = "anthropic_compatible"Goal: Override defaults only for the selected model pattern.
match_kind and model_pattern.provider to the target provider name.upstream_model only when the upstream model name differs.Verify: A matching explicit route wins over protocol defaults.
Goal: Avoid endpoint ambiguity for the same model pattern.
request_protocol when the same model pattern must route differently by endpoint.Verify: A model match with the wrong explicit request_protocol fails instead of silently falling through.
[[routing.routes]]name = "m3_chat_to_anthropic"request_protocol = "openai_chat_completions"match_kind = "exact"model_pattern = "MiniMax-M3-preview"provider = "minimax"upstream_model = "MiniMax-M3"
[providers.minimax]protocol = "anthropic_messages"base_url = "https://example.invalid"api_key = "..."compatibility = "anthropic_compatible"| Provider protocol | Auth header sent upstream | Source of truth |
|---|---|---|
openai_responses / openai_chat_completions | Authorization: Bearer <provider api_key> | providers.<name>.api_key |
anthropic_messages | x-api-key: <provider api_key> | providers.<name>.api_key |
If the client requires an API key field, use a dummy local value and keep the real key in config.toml. See Behavior Contracts.
Goal: Make SDK clients receive structured errors during debugging.
[error_responses].format = "json".text if human-readable local debugging is preferred.Verify: The error payload matches the stable error response reference.
[error_responses]format = "json"Goal: Minimize private data exposure.
provider_request for outbound payload issues and upstream_response for provider return issues.Verify: You can explain why this phase is enough.
Goal: Avoid accumulating private artifacts.
Verify: The capture artifact exists locally and is not committed.
proxai capture enable provider-request# reproduce onceproxai capture disable provider-request| Question | Phase |
|---|---|
| What did the client send? | inbound_request |
| What did ProxAI send upstream? | provider_request |
| What did the provider return? | upstream_response |
| What did the client receive? | outbound_response |
Use CLI route overrides for one run when you do not want to edit long-lived config:
proxai --route-override m3_chat_to_anthropic.model_pattern=MiniMax-M3-preview \ --route-override m3_chat_to_anthropic.upstream_model=MiniMax-M3Supported override fields are request_protocol, match_kind, model_pattern, provider, and upstream_model. See CLI.
When: The client waits and no new upstream bytes are observed.
Choose: Inspect transport connectivity and read_idle_timeout_secs.
Why: This is an idle-read problem, not necessarily a protocol semantic problem.
When: Tool-call deltas begin but the semantic completion event never arrives.
Choose: Inspect [tool_calls].timeout_secs and provider stream events.
Why: ProxAI closes stalled tool-call argument streams predictably.
When: The client receives bytes but cannot parse the event sequence.
Choose: Inspect protocol conversion and SSE reconstruction.
Why: The carrier may be healthy while the translated event stream is invalid.
Start with Streaming behavior, then use Streaming Internals if you are debugging implementation behavior.