Skip to content

Recipes

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.

  1. 1

    Edit local config

    Goal: Use config.toml as the runtime source of truth.

    Do
    • Set protocol-keyed defaults under [routing.default_provider_names].
    • Define one provider with protocol, base_url, and api_key.

    Verify: Requests using the configured inbound protocol select the default provider.

  2. 2

    Connect the client

    Goal: Send client traffic to ProxAI, not directly to the provider.

    Do
    • Use the local /v1 base URL.
    • Keep real provider credentials in ProxAI config.

    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 = "..."

Route OpenAI Responses to an Anthropic provider

Section titled “Route OpenAI Responses to an Anthropic provider”
  1. 1

    Select the provider by inbound protocol

    Goal: Keep the client on /v1/responses while sending Anthropic Messages upstream.

    Do
    • Set openai_responses default provider to the Anthropic-compatible provider name.
    • Set that provider 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"
  1. 1

    Add an explicit route

    Goal: Override defaults only for the selected model pattern.

    Do
    • Choose match_kind and model_pattern.
    • Set provider to the target provider name.
    • Add upstream_model only when the upstream model name differs.

    Verify: A matching explicit route wins over protocol defaults.

  2. 2

    Use a request protocol guard only when needed

    Goal: Avoid endpoint ambiguity for the same model pattern.

    Do
    • Add request_protocol when the same model pattern must route differently by endpoint.
    • Do not add it when all inbound endpoints should share the same route.

    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 protocolAuth header sent upstreamSource of truth
openai_responses / openai_chat_completionsAuthorization: Bearer <provider api_key>providers.<name>.api_key
anthropic_messagesx-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.

  1. 1

    Switch the local error format

    Goal: Make SDK clients receive structured errors during debugging.

    Do
    • Set [error_responses].format = "json".
    • Reproduce the failing request.
    • Switch back to text if human-readable local debugging is preferred.

    Verify: The error payload matches the stable error response reference.

[error_responses]
format = "json"
  1. 1

    Pick one phase

    Goal: Minimize private data exposure.

    Do
    • Choose the narrowest phase that answers the question.
    • Prefer provider_request for outbound payload issues and upstream_response for provider return issues.

    Verify: You can explain why this phase is enough.

  2. 2

    Reproduce once and disable capture

    Goal: Avoid accumulating private artifacts.

    Do
    • Enable capture for the chosen phase.
    • Send one minimal request.
    • Disable capture immediately after reproduction.

    Verify: The capture artifact exists locally and is not committed.

Terminal window
proxai capture enable provider-request
# reproduce once
proxai capture disable provider-request
QuestionPhase
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:

Terminal window
proxai --route-override m3_chat_to_anthropic.model_pattern=MiniMax-M3-preview \
--route-override m3_chat_to_anthropic.upstream_model=MiniMax-M3

Supported override fields are request_protocol, match_kind, model_pattern, provider, and upstream_model. See CLI.

No bytes arrive

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.

Tool arguments start but never finish

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.

Malformed client event

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.