Providers

A3S Code reads runtime configuration from ACL. A config source can be an .acl file path or an inline ACL string. JSON and legacy HCL configs are not part of the current config surface.

Basic Shape

ACL
default_model = "provider/model-id"
max_parallel_tasks = 4
auto_parallel = false
providers "provider" {
apiKey = env("PROVIDER_API_KEY")
baseUrl = env("PROVIDER_BASE_URL")
models "model-id" {
name = "Human readable model name"
tool_call = true
limit = {
context = 128000
output = 4096
}
}
}
storage_backend = "file"
sessions_dir = ".a3s/sessions"

apiKey and api_key are accepted aliases. baseUrl and base_url are accepted aliases. Commit templates and non-secret defaults only; keep real API keys, private endpoints, and account-specific model names in the environment or in a secret manager.

Provider Families

The built-in factory covers three paths:

Provider nameClient pathNotes
anthropic / claudeAnthropic clientUses the configured model id and optional provider base URL.
openai / gptOpenAI-compatible clientUse this for OpenAI-compatible Chat Completions endpoints.
glm / zhipu / bigmodelZhipu-compatible clientUse environment variables for the key and base URL.
Any other provider nameOpenAI-compatible fallbackUseful for private or self-hosted OpenAI-compatible services.

Coding Plan bases such as https://open.bigmodel.cn/api/coding/paas/v4 join correctly to /chat/completions (no /v1 suffix and no duplicated /paas/v4).

The runtime does not hard-code model names. default_model and per-session model values are identifiers in the provider/model-id form that must match the provider blocks you define.

Delegation Controls

ACL
agent_dirs = ["./.a3s/agents"]
auto_delegation {
enabled = true
auto_parallel = false
allow_manual_delegation = true
min_confidence = 0.72
max_tasks = 4
}

max_parallel_tasks limits bounded sibling fan-out. auto_delegation.enabled turns on automatic subagent delegation. The top-level auto_parallel = false overrides auto_delegation.auto_parallel and disables only automatic parallel child-agent fan-out; manual task fan-out remains available. When allow_manual_delegation = false, the model-visible task tool is not registered.

Storage

ACL
sessions_dir = ".a3s/sessions"

sessions_dir is what makes ACL-loaded sessions resumable: when it is set, each session gets a file session store in that directory, and the sync Rust Agent::session path returns AsyncSessionBuildRequired. Without sessions_dir or an explicit store, sessions are not persisted. storage_backend (memory, file, or custom; any other value reads as file) and storage_url are parsed and kept in the config, but no runtime path reads them, so they neither create nor disable a store. SDK hosts can always pass sessionStore: new FileSessionStore(...) / opts.session_store = FileSessionStore(...) directly.

Proxies

Model HTTP clients, MCP HTTP transports (SSE and streamable HTTP), and MCP OAuth read the proxy only from explicit environment variables:

VariableEffect
http_proxy / HTTP_PROXYProxy for http:// requests
https_proxy / HTTPS_PROXYProxy for https:// requests; falls back to the HTTP proxy
NO_PROXY / no_proxyHosts that bypass either proxy, such as localhost or an internal MCP host

System proxy discovery is disabled on these clients, so an unset variable means a direct connection. An invalid proxy URL fails client construction with Invalid HTTP proxy URL or Invalid HTTPS proxy URL.

Private Provider Checks

Real-provider smoke tests should point at a local, git-ignored ACL file through A3S_CONFIG_FILE. Do not copy provider values into commands, logs, docs, pull requests, or committed fixtures.

SHELLSCRIPT
A3S_CONFIG_FILE=/path/to/local/config.acl \
scripts/real_config_env_integration.sh

SDK parity is covered by a separate real-provider check:

SHELLSCRIPT
A3S_CONFIG_FILE=/path/to/local/config.acl \
scripts/sdk_real_config_env_integration.sh

Both wrappers find the provider named in default_model, then write a temporary owner-only copy of the ACL whose apiKey and baseUrl for that provider read from A3S_OPENAI_API_KEY and A3S_OPENAI_BASE_URL. They take the values from A3S_<PROVIDER>_API_KEY / A3S_<PROVIDER>_BASE_URL, then from the provider block, then from the existing A3S_OPENAI_* variables. Provider-specific suites, such as the DeepSeek adversarial test, load the ACL directly:

SHELLSCRIPT
A3S_CONFIG_FILE=/absolute/path/to/.a3s/config.acl \
cargo test -p a3s-code-core --test test_deepseek_adversarial_e2e -- \
--ignored --test-threads=1 --nocapture

The complete Node.js, Python, and Go DeepSeek retrieval matrix uses A3S_REAL_EVAL_ROOT=/absolute/path/to/a3s; see the cross-SDK evaluation contract for platform-specific commands and gates.

Keep secret-bearing raw provider evidence with the release or CI artifact, not in public documentation. Aggregate redacted metrics may be published when they contain no endpoint, header, environment-variable name, credential, prompt, or source text. For the complete local API surface, see API Contract.