Skip to content

OpenAI-compatible Providers

Use the same Chat API with OpenRouter, Azure v1, or another OpenAI-compatible provider. Set the provider's endpoint and tell the Chat which environment variable holds its API key. You can save those settings with the prompt; the key itself stays out of the YAML.

Use OpenRouter with a saved Chat

Save this as datafiles/chatsnack/OpenRouterSnack.yml. If you've set CHATSNACK_BASE_DIR, save it in that directory instead:

params:
  model: z-ai/glm-5.3-flash
  base_url: https://openrouter.ai/api/v1
  api_key_env: OPENROUTER_API_KEY
messages:
  - system: Answer tersely and recommend excellent snacks.

Then load the Chat by name:

from chatsnack import Chat

openrouter = Chat(name="OpenRouterSnack")
print(openrouter.ask("Name one movie-night snack."))

thread = openrouter.chat("Name one salty snack.")
thread = thread.chat("What drink pairs with it?")
print(thread.last)

Supply base_url and api_key_env together. Before loading this example, set OPENROUTER_API_KEY to your key. The variable must have a nonblank value; chatsnack reads it when the Chat loads.

Create the Chat in Python

You can pass the same settings to Chat():

from chatsnack import Chat

openrouter = Chat(
    "Answer tersely and recommend excellent snacks.",
    model="z-ai/glm-5.3-flash",
    base_url="https://openrouter.ai/api/v1",
    api_key_env="OPENROUTER_API_KEY",
)

Use Azure v1

For Azure v1, use the full URL ending in /openai/v1/ and put your deployment name in model:

params:
  model: my-deployment
  base_url: https://my-resource.openai.azure.com/openai/v1/
  api_key_env: AZURE_OPENAI_API_KEY
messages:
  - system: Answer tersely.

This setup uses a static API key. The built-in provider settings don't support Microsoft Entra authentication yet.

Choosing a connection

Custom endpoints use Responses HTTP, with SSE for streaming. Set runtime explicitly if you need a different transport. If you leave out base_url and api_key_env, the OpenAI SDK uses OPENAI_API_KEY and OPENAI_BASE_URL as usual, and chatsnack defaults to Responses WebSocket. The verified Muse Wonder model has its own defaults, described below.

A Chat reads its connection settings when it's created or first loaded. Continuing or copying the Chat keeps those settings, and reset() doesn't read a fresh key from the environment. To change the endpoint, key, or transport, create a new Chat.

Muse Wonder

With MODEL_API_KEY available in your environment, the model name is enough:

from chatsnack import Chat

wonder = Chat("Invent cheerful, crunchy snacks.", model="muse-wonder-1.0")
print(wonder.ask("Name one snack for a moon picnic."))

thread = wonder.chat("Name one snack for a moon picnic.")
thread = thread.chat("Give it a two-word name.")
print(thread.last)

Keep a useful prompt for another occasion:

menu = (
    Chat(name="WonderMenu", model="muse-wonder-1.0")
    .system("Invent cheerful, crunchy snacks.")
    .user("Recommend one snack for {occasion}.")
)
print(menu.yaml)
menu.save()

reused = Chat(name="WonderMenu")
print(reused.ask(occasion="a moon picnic"))

The equivalent authored YAML is small:

params:
  model: muse-wonder-1.0
messages:
  - system: Invent cheerful, crunchy snacks.
  - user: Recommend one snack for {occasion}.

Use ordinary Python utensils with utensils=[...] and .chat(). See MuseWonder.ipynb for a pantry check, saved prompts, fillings, continued chats, and streaming.

Connection and compatibility notes

AUTO recognizes muse-wonder-1.0 and supplies https://api.meta.ai/v1 with MODEL_API_KEY. Explicit connection pairs and OPENAI_BASE_URL take precedence; runtime and session choices keep their existing precedence. Copies, continuations, and reset() keep the original binding. Changing .model later keeps that connection too; create a new Chat to move providers. Saving records the resolved endpoint and credential variable name; a fresh load reads the current named key. An injected custom runtime owns submission, so AUTO does not infer SDK connection or encrypted-replay defaults for it. Injected built-in adapters still use the Chat's connection. A custom runtime can also load a saved connection without its credential; that named key is required only if the Chat's SDK client is actually used. Built-in adapters still capture the credential on construction or fresh load.

Use chat.reasoning.effort for minimal, low, medium, high, xhigh, or max, and chat.reasoning.summary for auto, concise, or detailed. none gets an advisory warning and still passes through. Meta accepts only tool_choice="auto"; other choices also warn and pass through.

HTTP/SSE and encrypted reasoning replay are automatic on the model-only path. Utensil-generated include entries merge with the encrypted-replay default. Authored Responses options remain escape hatches: an explicit include overrides the replay default. Missing encrypted reasoning gets a warning and is omitted from generated stateless input while the saved transcript stays intact. Stored continuations and raw extra_body.input pass through unchanged.

This baseline covers text, reasoning replay, local Python utensils, saved conversations, and SSE. Hosted tools and file workflows still need provider integration work. Muse Wonder Full is available through Muse Code subscriptions, rather than Model API; aliases and undocumented snapshots do not infer defaults.

Provider requirements verified October 13, 2026 against Meta's models, reasoning, Responses, and tool calling documentation.

GPT-6

Set model to gpt-6-astra, gpt-6.1-sol, gpt-6-sol, or gpt-6-luna. Here's a small request using Responses:

chat = Chat("Respond tersely.", model="gpt-6-astra", runtime="responses")
chat.reasoning.effort = "low"
print(chat.ask("Name one movie snack."))

The same Chat in YAML:

params:
  model: gpt-6-astra
  runtime: responses
  responses:
    reasoning:
      effort: low
messages:
  - system: Respond tersely.

For Astra and GPT-6.1 Sol, choose low, medium, high, xhigh, or max. GPT-6 Sol and Luna also support none; their default is medium. For a reasoning summary, use chat.reasoning.summary = "auto". GPT-6 Sol, Luna, and GPT-6.1 Sol also accept concise and detailed; chatsnack has verified only auto for Astra. A completed GPT-6.1 Sol response may omit summary text even when the summary setting is accepted. Chatsnack's GPT-6 checks recognize these four exact model IDs. Other variants and dated snapshots still need verification.

Use Responses for tool calls with reasoning. Pass your Python functions in utensils=[...]. If you're moving an existing Chat from Chat Completions, create a new one with runtime="responses". There's a complete example that saves a stock helper and continues the conversation in ReasoningModelValidation.ipynb. To run its live calls, set CHATSNACK_RUN_LIVE_TESTS=1 and provide an API key.

When sending gpt-6-astra directly to OpenAI, remove these unsupported options:

  • temperature, top_p, and top_logprobs on either API.
  • logprobs on Chat Completions.
  • message.output_text.logprobs from include on Responses.

For gpt-6-astra, chatsnack warns about these options and sends the request as you wrote it. The checks use the sending SDK client's URL and apply only to https://api.openai.com/v1. Custom or unidentified endpoints and other model names won't receive these request warnings. You'll also get a warning for reasoning values outside the verified table, and those values still pass through. See OpenAI's migration guidance for the provider's requirements.

You can use Responses text calls and synchronous Python utensils today. Support for OpenAI's async tool-calling protocol, mid-turn steering, and ordered reasoning updates is planned. The SDK requirement remains openai>=3.5.0,<4.0.0; offline serialization and adapter checks passed on 3.5.0 and 3.8.0.

Migrate legacy Azure configuration

If your Chat still uses api_base, api_type, api_version, or deployment, replace those fields. Chatsnack no longer accepts them. Use:

  • base_url for the complete Azure v1 endpoint
  • api_key_env for the name of the credential environment variable
  • model for the Azure deployment name

The old OPENAI_AZURE_ENDPOINT and OPENAI_API_BASE environment variables also raise a migration error unless you've supplied a new endpoint. Set base_url and api_key_env on each Chat, or use OPENAI_BASE_URL to set the endpoint through the environment.