Set up calling
Configure calling under channels.agent-wechat.calls. Voice and video each default
to disabled. The current daemon and plugin handle direct voice calls.
Connect the daemon
-
Finish Quick setup and check
wx calls status. The daemon must advertisedirectAudio: true; see Calling for build options. -
Give the channel token the
callsscope alongside its existing messaging scopes:Terminal window wx tokens create openclaw-calling --accounts ACCOUNT_ID \--scopes read --scopes media --scopes send --scopes login \--scopes read-state --scopes callsUse the returned token in the channel’s existing
native.tokenSecretRef. A token withoutcallscannot use the call endpoints.
Configure speech and access
Merge this example into your existing channel and agent configuration. Replace
the example contact and owner IDs.
Set OPENAI_API_KEY in the Gateway process’s environment.
{ "secrets": { "providers": { "voiceenv": { "source": "env", "allowlist": ["OPENAI_API_KEY"] } } }, "agents": { "entries": { "main": { "tools": { "alsoAllow": ["wechat_call"] } } } }, "channels": { "agent-wechat": { "calls": { "voice": { "enabled": true, "agentId": "main", "inboundPolicy": "allowlist", "inboundAllowFrom": ["allowed-contact-id"], "outboundPolicy": "allowlist", "outboundAllowTo": ["allowed-contact-id"], "outboundToolAllowFrom": ["owner-id"], "maxDurationSeconds": 3600, "realtime": { "provider": "openai", "voice": "marin", "instructions": "Keep spoken replies concise.", "agentContext": { "enabled": true }, "providers": { "openai": { "apiKey": { "source": "env", "provider": "voiceenv", "id": "OPENAI_API_KEY" } } } }, "toolPolicy": "none" }, "video": { "enabled": false } } } }}apiKey also accepts an OpenClaw file/exec/store SecretRef or a key string.
When omitted, OpenClaw uses the selected agent’s OpenAI authentication or Gateway
environment. A text-agent subscription alone does not necessarily grant realtime
API access. The daemon token and OpenAI key are separate credentials.
wechat_call is optional: the example grants it to main for status, outbound
calls and hangup. Grant it to any other agent that should place calls for you,
such as the agent that answers a group; the call itself always runs as
calls.voice.agentId. Automatic inbound answering does not require this tool.
Restart the Gateway after saving the configuration. An enabled, prepared voice
service reports available when the daemon is free; provider or capability
failure reports unavailable and leaves calls unanswered.
Models and behavior
All paths below are relative to calls.voice.
| Setting | Behavior / default |
|---|---|
realtime.provider | Required; openai is the supported adapter. |
realtime.model, realtime.voice | Optional speech model/voice overrides; otherwise provider defaults. |
realtime.instructions | Optional conversation guidance, up to 4,000 characters. |
realtime.agentContext.enabled | Defaults to false. Set to true to include excerpts from the selected agent’s IDENTITY.md and SOUL.md. |
agentId | Required. Selects the voice persona, provider authentication and agent for permitted consultations. |
toolPolicy | none, safe-read-only, or owner. Opting in to session persistence defaults to safe-read-only. |
allowConsultSessionPersistence | Set to true to allow consultation in OpenClaw sessions for calls. |
sessionScope | per-contact (one session per contact, so the agent remembers earlier calls) or per-call. See Remember earlier calls. |
consultation.summary, consultation.recentMessages, realtime.recentContext | Summarize each answered call and share recent chat with the agent (on by default), and give the next call a recap (off by default). See Remember earlier calls. |
realtime.consultPolicy | auto lets the provider choose when to consult. substantive directs it to consult for facts and context. always also starts a consult from the caller’s current turn if the provider skips it. |
realtime.consultThinkingLevel, realtime.consultFastMode | Optional OpenClaw reasoning level and fast-mode override for consultations. |
consultation.inboundSessionKey | Optional existing session of the selected agent that seeds a new call session for inbound calls. |
consultation.timeoutMs | 30,000 by default; 1,000–120,000 ms. |
maxDurationSeconds | 3,600 (one hour) by default; 30–3,600 seconds. The plugin hangs up when it is reached. The native daemon currently ends calls after 20 minutes. |
The speech model handles conversation; the selected OpenClaw agent handles
delegated questions and permitted tools. Incoming/outgoing policies default to disabled;
allowlists accept exact IDs, without *. Tool callers must also be authorized
owners in outboundToolAllowFrom. Messaging permissions do not authorize calls.
Set realtime.model to one of these OpenAI models. Omit it to use the
provider’s default, gpt-realtime-2.1.
| Model | Conversation | Agent consultation | Sign-in |
|---|---|---|---|
gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2 | Takes turns; stops when the caller interrupts. | Through a tool. | OpenAI API key. |
gpt-live-1-codex (voice cove) | Listens while it talks and handles interruptions itself. Introduces itself as ChatGPT: this route does not use the agent’s name or persona. | Delegates to the agent. consultPolicy: "always" is not supported. | The agent’s ChatGPT sign-in in OpenClaw (2026.10.10 or later), then the API key. |
gpt-live-1 (voice marin) | Listens while it talks and handles interruptions itself. Uses the agent’s name and persona. | Same as gpt-live-1-codex. | OpenAI API key. |
The speech model receives the selected agent’s configured identity. When workspace context is enabled, the realtime provider also receives bounded excerpts of the two persona files. Keep those files suitable for this use.
Calls placed with wechat_call use the requesting session as context when
consultation is enabled and that session belongs to calls.voice.agentId. Set consultation.inboundSessionKey to do the same for
inbound calls. OpenClaw copies that session’s context into the call’s session
when the call session is first created. Choose a session whose history is
suitable for the callers.
With toolPolicy: "owner", a call participant whose WeChat ID exactly matches
an agent-wechat:<WeChat ID> entry in commands.ownerAllowFrom can consult
with the agent’s normal tool policy. An owner can use a bound session with the
same WeChat peer and channel account. Other allowed participants get read-only
consultation in a separate session. Add inbound callers to inboundAllowFrom
separately.
Consultations run like the agent’s normal chat turns. They use its configured
model, including CLI runtimes such as claude-cli, and its fallback models.