# Z Code

Z Code is the desktop coding agent from Z.ai. It keeps its model providers in
`~/.zcode/v2/provider_config.json`. Add the exchange to that file as a custom
provider with an OpenAI-compatible endpoint.

Step 1 writes the provider with a script. To make the same settings in the
app, see [Set up in the app](#set-up-in-the-app).

## Print the setup with the Liquid CLI

Z Code has its own settings screen, so the [Liquid CLI](https://inference.ai.exchange/docs/cli.md) cannot start it. `liquid connect zcode` prints the values to paste, with your model filled in.

```bash
curl -fsSL https://inference.ai.exchange/cli/install.sh | bash
liquid login
liquid connect zcode
```

To enter the values yourself, follow the steps below.

## Before you start

- A workspace with a balance and a `spend` key. See [API keys](https://inference.ai.exchange/docs/keys.md).
- Z Code installed from [zcode.z.ai](https://zcode.z.ai). This setup is tested with Z Code 3.15.1.
- `jq`, for the script in step 1.

## 1. Write the provider

Quit Z Code. Then replace the placeholder with your buyer key and run this
script:

```bash
export LIQUID_API_KEY=sk-liquid-...
set -e
umask 077
zcode_config="$HOME/.zcode/v2/provider_config.json"
mkdir -p "$HOME/.zcode/v2"
[ -s "$zcode_config" ] || printf '{"schemaVersion":1,"config":{}}' > "$zcode_config"
jq --arg key "$LIQUID_API_KEY" --argjson names '["liquid.auto"]' '
  .config.providerConfigRules.providerRules = [(.config.providerConfigRules.providerRules // [])[] | select(.providerId != "liquid")] + [{
    providerId: "liquid",
    providerName: "Liquid Inference",
    enabled: true,
    config: {
      group: "standard-personal",
      access: { type: "api-key", apiKey: $key },
      api: {
        type: "openai-chat-completions",
        baseUrl: "https://router.inference.ai.exchange/v1",
        headers: { "x-liquid-cap-usd": "1.00" }
      },
      personalModelIds: $names,
      modelOrder: $names
    }
  }]
  | .config.modelConfigRules.providerModelRules = [(.config.modelConfigRules.providerModelRules // [])[] | select(.providerId != "liquid")] + [$names[] | {
    providerId: "liquid",
    modelId: .,
    config: ({ optionSpecs: { maxOutputTokens: { max: 8192 }, reasoningLevel: { map: "{}" } } })
  }]
  | .config.modelConfigRules.manualProviderModelRules = [(.config.modelConfigRules.manualProviderModelRules // [])[] | select(.providerId != "liquid")]
  | if .config.providerOrder then .config.providerOrder = [.config.providerOrder[] | select(. != "liquid")] + ["liquid"] else . end
  | .config.defaultModelSelection = { providerId: "liquid", modelId: "liquid.auto" }
' "$zcode_config" > "$zcode_config.new" && mv "$zcode_config.new" "$zcode_config"
```

The script adds a provider with the ID `liquid` and keeps your other
providers. It replaces a provider with the same ID. It does these things:

- It adds each model name in the list as a model of the provider.
- It sets the output limit of each model to 8,192 tokens, and it sets the
  reasoning mapping to `{}`. See [Notes](#notes).
- It sets the context window of the model that you picked, when the book
  states it.
- It adds a header that caps each request.
- It makes the model that you picked the default model of Z Code.

Z Code keeps the key in the file. The script sets `umask 077`, so a new file
is readable only by you.

## 2. Start Z Code

Start Z Code. The model selector shows the models under **Liquid Inference**.
To use other models, run the script again with a different list of names.

## Set up in the app

The app has no field for headers. The cap needs one edit of the file.

### Add the provider

Open the model settings from the model selector. Click **Create custom
provider**, and enter a name:

```
Liquid Inference
```

Do not select a vendor. Set **API format** to **Chat completions**:

```
Chat completions
```

Enter the base URL. It ends in `/v1`, because Z Code adds `/chat/completions`
to it:

```
https://router.inference.ai.exchange/v1
```

Paste your key into **API key**:

```
sk-liquid-...
```

### Add the models

Click **Add model** and type a model ID. Add each ID separately. For example:

```
liquid.auto
```

Z Code does not read the model list of the exchange. Use an exact model, a
router model or a preset. To get the current names, see the **Market** page.
See [Market data](https://inference.ai.exchange/docs/market.md).

Open the **Advanced settings** of each model. Set **Max output tokens** and
**Reasoning parameter mapping**:

```
8192
```

```
{}
```

Set **Context window** to the real window of the model. Z Code uses it to
decide when to compact a session. Turn on image input only for a model that
reads images. Then enable the provider.

### Set a cap on each request

Quit Z Code. Open `~/.zcode/v2/provider_config.json` and find the provider in
`config.providerConfigRules.providerRules`. Add this to the `api` object of the
provider:

```
{"headers":{"x-liquid-cap-usd":"1.00"}}
```

The app keeps these headers when you change the provider in the app later.

## Notes

- **Output limit.** For a model that it does not know, Z Code asks for 32,000
  output tokens. The exchange sends a request only to an offer that accepts its
  output limit. Thus the setup sets a smaller limit.
- **Reasoning effort.** For a model that it does not know, Z Code also sends a
  high reasoning effort. The exchange sends such a request only to an offer
  that accepts one. When no offer accepts one, the exchange refuses the
  request. The mapping `{}` stops Z Code from sending reasoning parameters. The
  model then uses its default reasoning.
- The cap limits each request. It does not limit the total charge of a task.
  To limit total spend, set a spending limit on the key. See
  [API keys](https://inference.ai.exchange/docs/keys.md).
- The receipt names Z Code as the client. You do not need to set a header for
  this.
- Use a preset for other purchasing rules. See [Purchasing rules](https://inference.ai.exchange/docs/rules.md).

## Troubleshooting

| Symptom                                          | Cause and fix                                                                                                                                      |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`                                            | The key is empty, wrong or expired. Paste it again into **API key**, or run the script again.                                                      |
| `403`                                            | Check the key's `spend` scope, address restriction and preset rules.                                                                               |
| `402`                                            | Add credit to the workspace or check the key's spend limit.                                                                                        |
| `404`                                            | Keep `/v1` at the end of the base URL.                                                                                                             |
| `model_not_found`                                | The model ID is not on the book. Use an exact name from the **Market** page.                                                                       |
| `reasoning.effort` is not supported by any offer | Set the reasoning parameter mapping of the model to `{}`.                                                                                          |
| A refusal that names the output limit            | Set **Max output tokens** of the model to 8192 or less.                                                                                            |
| The provider sends no cap.                       | Add the headers to the `api` of the provider in `~/.zcode/v2/provider_config.json`. Z Code does not read providers from `~/.zcode/v2/config.json`. |
| A request is refused for lack of funds.          | The workspace balance cannot cover the cap. Add funds on the **Credits** page.                                                                     |

See [Errors](https://inference.ai.exchange/docs/errors.md) for the exchange's error codes and causes.

## Next steps

- [Cline](https://inference.ai.exchange/docs/connect-cline.md): the VS Code agent, with the same kind of provider.
- [Market data](https://inference.ai.exchange/docs/market.md): models and live offers.
- [API keys](https://inference.ai.exchange/docs/keys.md): scopes and spending limits.
