Skip to content

Yeaft Engine Configuration ​

To run Yeaft Code Agent you need to tell the native engine which LLM providers to use and which model is primary / fast. That configuration belongs to one Agent instance. The default instance uses ~/.yeaft/config.json; named <name> uses ~/.yeaft/instances/<name>/config.json unless its Yeaft directory is overridden. Anthropic, OpenAI Responses, GitHub Copilot dynamic credentials, Azure/OpenAI-compatible gateways, and local proxies can coexist in one instance config.

For the complete schema, every optional field, and Agent-side .env, see Config Reference.

File location ​

Agent instanceDefault config path
Default service instance~/.yeaft/config.json
Named instance <name>~/.yeaft/instances/<name>/config.json
Explicit Yeaft directory<yeaftDir>/config.json

yeaft-agent local defaults <name> to the sanitized computer hostname; use --name when you want a predictable path. The yeaft-agent llm subcommand does not infer that instance: pass --config <path> for a named/custom instance. If the instance config is missing or has no providers, the engine starts but calls fail with "No LLM adapter configured".

Minimum Working Config ​

json
{
  "providers": [
    {
      "name": "my-proxy",
      "baseUrl": "http://localhost:6628/v1",
      "apiKey": "sk-proxy-xxx",
      "models": ["claude-sonnet-4-20250514"]
    }
  ],
  "primaryModel": "my-proxy/claude-sonnet-4-20250514"
}

That's enough — the engine will run.

json
{
  "providers": [
    {
      "name": "my-proxy",
      "baseUrl": "http://localhost:6628/v1",
      "apiKey": "sk-proxy-xxx",
      "protocol": "openai-responses",
      "models": [
        "claude-sonnet-4-20250514",
        "claude-haiku-3-20250414",
        "gpt-5",
        "deepseek-chat"
      ]
    },
    {
      "name": "github-copilot",
      "baseUrl": "https://api.githubcopilot.com",
      "credentialProvider": "github-copilot",
      "protocol": "openai-responses",
      "models": [
        { "id": "claude-sonnet-4.5", "protocol": "anthropic" },
        "gpt-5"
      ]
    }
  ],
  "primaryModel": "my-proxy/claude-sonnet-4-20250514",
  "fastModel": "my-proxy/claude-haiku-3-20250414",
  "language": "en",
  "debug": false,
  "maxContextTokens": 200000,
  "messageTokenBudget": 32768
}

Top-Level Fields ​

FieldTypeRequiredDefaultDescription
providersProvider[]✓—LLM provider list
primaryModelstring✓—Primary model, format <provider>/<model-id>
fastModelstring—primaryModelLightweight model for active internal tasks such as classification
language'en' | 'zh'—'en'System prompt language
debugboolean—falseLog raw LLM request/response to console
maxContextTokensnumber—200000Provider context-window reference used for request guards
messageTokenBudgetnumber—32768Deterministic provider-request history-window budget; does not modify transcript

Provider Object ​

FieldTypeRequiredDescription
namestring✓unique provider id, used by primaryModel reference
baseUrlstring✓API root URL (no /v1/messages path suffix)
apiKeystring△static API key (or use credentialProvider)
credentialProviderstring△dynamic credential provider name (or use apiKey)
protocol'anthropic' | 'openai-responses'—provider default wire protocol
models(string | ModelEntry)[]✓supported model list

Model Entry ​

Both shapes can be mixed:

json
"models": [
  "gpt-5",                                              // string: use provider default protocol
  { "id": "claude-sonnet-4.5", "protocol": "anthropic" }  // object: per-model protocol override
]
Model entry fieldTypeRequiredDescription
idstring✓model id the vendor recognizes
protocol'anthropic' | 'openai-responses'—overrides provider protocol
contextWindownumber—overrides models.js default
maxOutputnumber—overrides default output cap

Other keys on a model entry are silently dropped. Display names / pricing live in the bundled registry, not in user config.

Protocol Resolution Order ​

(See Yeaft LLM Layer § Protocol Resolution for details.)

  1. per-model protocol
  2. provider-level protocol
  3. heuristic by model id
  4. default openai-responses

Credential Provider ​

When credentialProvider is set, each request gets a token dynamically. Mutually exclusive with apiKey.

Built-in today:

  • github-copilot — reads ~/.config/github-copilot/hosts.json OAuth token → exchanges for Copilot API token
json
{
  "name": "github-copilot",
  "baseUrl": "https://api.githubcopilot.com",
  "credentialProvider": "github-copilot",
  "models": ["claude-sonnet-4.5", "gpt-5"]
}

The github-copilot credential provider here is a completely different path from Copilot Mode (which spawns copilot --acp subprocess). The former lets the Yeaft engine directly call the Copilot API; the latter uses the Copilot CLI as a 1:1 chat backend in Yeaft Web Code Agent. Both reuse the same GitHub OAuth credential.

Model Reference Format ​

<provider-name>/<model-id>

Examples:

  • my-proxy/claude-sonnet-4-20250514
  • github-copilot/gpt-5
  • github-copilot/claude-sonnet-4.5

Common Provider Snippets ​

Anthropic Official ​

json
{
  "name": "anthropic",
  "baseUrl": "https://api.anthropic.com",
  "apiKey": "sk-ant-xxx",
  "protocol": "anthropic",
  "models": ["claude-sonnet-4-20250514", "claude-haiku-3-20250414"]
}

OpenAI Official ​

json
{
  "name": "openai",
  "baseUrl": "https://api.openai.com",
  "apiKey": "sk-xxx",
  "protocol": "openai-responses",
  "models": ["gpt-5", "gpt-5-mini", "o3"]
}

Azure OpenAI (baseUrl includes deployment path + api-version) ​

json
{
  "name": "azure-openai",
  "baseUrl": "https://<resource>.openai.azure.com/openai/deployments/<deployment>?api-version=2024-12-01-preview",
  "apiKey": "<azure-key>",
  "protocol": "openai-responses",
  "models": ["gpt-5"]
}

The engine has no per-provider header-injection knob — pass Azure's api-version as a query string on baseUrl instead.

Self-Hosted OpenAI-Compatible Proxy ​

json
{
  "name": "my-proxy",
  "baseUrl": "http://localhost:6628/v1",
  "apiKey": "any-string-the-proxy-accepts",
  "protocol": "openai-responses",
  "models": [
    "claude-sonnet-4-20250514",
    "gpt-5",
    "deepseek-chat",
    "qwen-max"
  ]
}

GitHub Copilot (dynamic creds + dual protocol) ​

json
{
  "name": "github-copilot",
  "baseUrl": "https://api.githubcopilot.com",
  "credentialProvider": "github-copilot",
  "protocol": "openai-responses",
  "models": [
    { "id": "claude-sonnet-4.5", "protocol": "anthropic" },
    "gpt-5",
    "gpt-5-mini",
    "o3-mini"
  ]
}

Hot Reload ​

The Agent re-reads its resolved instance config.json at the start of every turn, so model and provider changes typically take effect without a restart — edit the correct instance file and start a new turn.

Changes that do require restarting the Agent:

  • language / debug
  • Global maxContextTokens / messageTokenBudget
  • Anything else read at startup rather than per-turn

Verify Configuration ​

Yeaft Web UI: Settings → Yeaft / LLM → pick model → Test connection — sends a ping request to confirm endpoint + auth.

CLI:

bash
node -e "
import('./agent/yeaft/config.js').then(async ({ loadConfig }) => {
  const cfg = await loadConfig();
  console.log(JSON.stringify(cfg, null, 2));
});
"

Common Errors ​

ErrorCauseFix
No LLM adapter configuredproviders: [] or file missingAdd a provider
Cannot find model 'xxx/yyy'primaryModel reference <provider>/<model-id> not in providersAdd the model to the matching provider's models array
The chat-completions adapter was removed in Phase 7Old config used "protocol": "openai" or "chat-completions"Change to "openai-responses" or "anthropic"
Cannot find credential provider github-copilotGitHub Copilot OAuth not installedRun gh auth login + copilot setup first
LLMAuthError 401apiKey wrong or expiredUpdate apiKey; for dynamic providers, re-login

Released under the MIT License.