mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-23 10:55:31 -06:00
75fcaba919
* fix(voice-call): survive gateway in-process restart and stop CLI dead-ends The gateway's in-process restart (SIGUSR1 config reload) reuses the cached plugin registry, so service stop/start run on the same retained voice-call registration. Generation fencing from #120289 treated that restart as a stale actor: stop retired the generation forever, the next start silently bailed, and every voicecall.* RPC answered UNAVAILABLE "runtime generation is retired" while the webhook never rebound. - Registrations now hold a replaceable generation: service start after stop mints a fresh generation, takes over a running slot owned by a retired predecessor, and reports start failures to service health instead of silently returning. - The voicecall CLI classifies gateway failures with typed guards instead of message substrings: standalone/store fallback only when the gateway is genuinely absent; reachable-but-failed (request errors, auth, timeout) exits with actionable text; a standalone webhook port collision explains that a running Gateway probably owns the port instead of raw EADDRINUSE. - Plugin SDK gateway-runtime exports structural isGatewayTransportError / isGatewayClientRequestError guards (+2 documented surface budget). - Regression coverage: same-registration stop/start restart, retired-owner takeover, typed CLI fallback classification, and a real token-auth gateway server routing voicecall.status through callGatewayFromCli. * refactor(voice-call): split CLI modules and dedupe gateway fallbacks Collapse the four duplicated gateway-or-runtime command blocks (speak, dtmf, end, continue fallback) into one generic runGatewayManagerCommand helper — the continue command owns its legacy-method fallback and operation polling via a gatewayCall closure, so the helper carries no per-command policy. Smoke reuses the shared initiateVoiceCall path instead of a bespoke fallback. Split the 988-line cli.ts into concept modules (cli-gateway-call, cli-call-log, cli-command-io) and drop its grandfathered max-lines suppression plus the now-stale max-lines and assertion-safety baseline entries (shrink-only ratchet maintenance). Behavior-frozen: stdout/exit semantics unchanged; net -2 production LOC. * fix(voice-call): redact gateway URLs in CLI operational errors ClawSweeper P1: the operational-error formatter interpolated the raw connectionDetails.url, so a configured gateway URL with userinfo or query tokens would print credentials into terminal output. Redact the composed message once with the canonical net-policy redactor (also covers remote-controlled close-reason text), exported through the plugin SDK gateway-runtime subpath (+1 documented surface budget). Regression test covers a credential-bearing URL in both the URL and message fields.
222 lines
9.6 KiB
Markdown
222 lines
9.6 KiB
Markdown
---
|
|
summary: "CLI reference for `openclaw voicecall` (voice-call plugin command surface)"
|
|
read_when:
|
|
- You use the voice-call plugin and want every CLI entry point
|
|
- You need flag tables and defaults for setup, smoke, call, continue, speak, dtmf, end, status, tail, latency, expose, and start
|
|
title: "Voicecall"
|
|
---
|
|
|
|
# `openclaw voicecall`
|
|
|
|
`voicecall` is a plugin-provided command. It only appears when the voice-call
|
|
plugin is installed and enabled.
|
|
|
|
When the Gateway is running, operational commands (`call`, `start`,
|
|
`continue`, `speak`, `dtmf`, `end`, `status`) route to that Gateway's
|
|
voice-call runtime. If no Gateway is reachable, they fall back to a standalone
|
|
CLI runtime. `status` uses the persisted call store instead of starting that
|
|
runtime.
|
|
|
|
Fallback is limited to transport-level absence. If the Gateway responds with a
|
|
request or authentication error, or does not answer before the timeout, the
|
|
command exits nonzero and points to `openclaw gateway status`; it does not start
|
|
a second webhook server. If standalone fallback cannot bind the configured
|
|
`serve.port`, the error identifies the likely running Gateway instead of
|
|
printing a raw `EADDRINUSE` failure.
|
|
|
|
## Subcommands
|
|
|
|
```bash
|
|
openclaw voicecall setup [--json]
|
|
openclaw voicecall smoke [-t <phone>] [--message <text>] [--mode <m>] [--yes] [--json]
|
|
openclaw voicecall call -m <text> [-t <phone>] [--mode <m>]
|
|
openclaw voicecall start --to <phone> [--message <text>] [--mode <m>]
|
|
openclaw voicecall continue --call-id <id> --message <text>
|
|
openclaw voicecall speak --call-id <id> --message <text>
|
|
openclaw voicecall dtmf --call-id <id> --digits <digits>
|
|
openclaw voicecall end --call-id <id>
|
|
openclaw voicecall status [--call-id <id>] [--json]
|
|
openclaw voicecall tail [--file <path>] [--since <n>] [--poll <ms>]
|
|
openclaw voicecall latency [--file <path>] [--last <n>]
|
|
openclaw voicecall expose [--mode <m>] [--path <p>] [--port <port>] [--serve-path <p>]
|
|
```
|
|
|
|
| Subcommand | Description |
|
|
| ---------- | --------------------------------------------------------------- |
|
|
| `setup` | Show provider and webhook readiness checks. |
|
|
| `smoke` | Run readiness checks; place a live test call only with `--yes`. |
|
|
| `call` | Initiate an outbound voice call. |
|
|
| `start` | Alias for `call` with `--to` required and `--message` optional. |
|
|
| `continue` | Speak a message and wait for the next response. |
|
|
| `speak` | Speak a message without waiting for a response. |
|
|
| `dtmf` | Send DTMF digits to an active call. |
|
|
| `end` | Hang up an active call. |
|
|
| `status` | Inspect active calls (or one by `--call-id`). |
|
|
| `tail` | Tail `calls.jsonl` (useful during provider tests). |
|
|
| `latency` | Summarize turn-latency metrics from `calls.jsonl`. |
|
|
| `expose` | Toggle Tailscale serve/funnel for the webhook endpoint. |
|
|
|
|
## Setup and smoke
|
|
|
|
### `setup`
|
|
|
|
Prints human-readable readiness checks by default. Pass `--json` for scripts.
|
|
|
|
```bash
|
|
openclaw voicecall setup
|
|
openclaw voicecall setup --json
|
|
```
|
|
|
|
### `smoke`
|
|
|
|
Runs the same readiness checks. Places a real phone call only when both
|
|
`--to` and `--yes` are present.
|
|
|
|
| Flag | Default | Description |
|
|
| ------------------ | --------------------------------- | --------------------------------------- |
|
|
| `-t, --to <phone>` | (none) | Phone number to call for a live smoke. |
|
|
| `--message <text>` | `OpenClaw voice call smoke test.` | Message to speak during the smoke call. |
|
|
| `--mode <mode>` | `notify` | Call mode: `notify` or `conversation`. |
|
|
| `--yes` | `false` | Actually place the live outbound call. |
|
|
| `--json` | `false` | Print machine-readable JSON. |
|
|
|
|
```bash
|
|
openclaw voicecall smoke
|
|
openclaw voicecall smoke --to "+15555550123" # dry run
|
|
openclaw voicecall smoke --to "+15555550123" --yes # live notify call
|
|
```
|
|
|
|
<Note>
|
|
For external providers (`plivo`, `telnyx`, `twilio`), `setup` and `smoke` require a public webhook URL from `publicUrl`, a tunnel, or Tailscale exposure. A loopback or private serve fallback is rejected because carriers cannot reach it.
|
|
</Note>
|
|
|
|
## Call lifecycle
|
|
|
|
### `call`
|
|
|
|
Initiate an outbound voice call.
|
|
|
|
| Flag | Required | Default | Description |
|
|
| ---------------------- | -------- | ----------------- | -------------------------------------------------------------------------- |
|
|
| `-m, --message <text>` | yes | (none) | Message to speak when the call connects. |
|
|
| `-t, --to <phone>` | no | config `toNumber` | E.164 phone number to call. |
|
|
| `--mode <mode>` | no | `conversation` | Call mode: `notify` (hang up after message) or `conversation` (stay open). |
|
|
|
|
```bash
|
|
openclaw voicecall call --to "+15555550123" --message "Hello"
|
|
openclaw voicecall call -m "Heads up" --mode notify
|
|
```
|
|
|
|
### `start`
|
|
|
|
Alias for `call` with a different default flag shape.
|
|
|
|
| Flag | Required | Default | Description |
|
|
| ------------------ | -------- | -------------- | ---------------------------------------- |
|
|
| `--to <phone>` | yes | (none) | Phone number to call. |
|
|
| `--message <text>` | no | (none) | Message to speak when the call connects. |
|
|
| `--mode <mode>` | no | `conversation` | Call mode: `notify` or `conversation`. |
|
|
|
|
### `continue`
|
|
|
|
Speak a message and wait for a response.
|
|
|
|
| Flag | Required | Description |
|
|
| ------------------ | -------- | ----------------- |
|
|
| `--call-id <id>` | yes | Call ID. |
|
|
| `--message <text>` | yes | Message to speak. |
|
|
|
|
### `speak`
|
|
|
|
Speak a message without waiting for a response.
|
|
|
|
| Flag | Required | Description |
|
|
| ------------------ | -------- | ----------------- |
|
|
| `--call-id <id>` | yes | Call ID. |
|
|
| `--message <text>` | yes | Message to speak. |
|
|
|
|
### `dtmf`
|
|
|
|
Send DTMF digits to an active call.
|
|
|
|
| Flag | Required | Description |
|
|
| ------------------- | -------- | ------------------------------------------------ |
|
|
| `--call-id <id>` | yes | Call ID. |
|
|
| `--digits <digits>` | yes | DTMF digits (for example `ww123456#` for waits). |
|
|
|
|
### `end`
|
|
|
|
Hang up an active call.
|
|
|
|
| Flag | Required | Description |
|
|
| ---------------- | -------- | ----------- |
|
|
| `--call-id <id>` | yes | Call ID. |
|
|
|
|
### `status`
|
|
|
|
Inspect active calls.
|
|
|
|
| Flag | Default | Description |
|
|
| ---------------- | ------- | ---------------------------- |
|
|
| `--call-id <id>` | (none) | Restrict output to one call. |
|
|
| `--json` | `false` | Print machine-readable JSON. |
|
|
|
|
```bash
|
|
openclaw voicecall status
|
|
openclaw voicecall status --json
|
|
openclaw voicecall status --call-id <id>
|
|
```
|
|
|
|
## Logs and metrics
|
|
|
|
### `tail`
|
|
|
|
Tail the voice-call JSONL log. Prints the last `--since` lines on start, then
|
|
streams new lines as they are written.
|
|
|
|
| Flag | Default | Description |
|
|
| --------------- | -------------------------- | ------------------------------ |
|
|
| `--file <path>` | resolved from plugin store | Path to `calls.jsonl`. |
|
|
| `--since <n>` | `25` | Lines to print before tailing. |
|
|
| `--poll <ms>` | `250` (minimum 50) | Poll interval in milliseconds. |
|
|
|
|
### `latency`
|
|
|
|
Summarize turn-latency and listen-wait metrics from `calls.jsonl`. Output is
|
|
JSON with `recordsScanned`, `turnLatency`, and `listenWait` summaries.
|
|
|
|
| Flag | Default | Description |
|
|
| --------------- | -------------------------- | ------------------------------------ |
|
|
| `--file <path>` | resolved from plugin store | Path to `calls.jsonl`. |
|
|
| `--last <n>` | `200` (minimum 1) | Number of recent records to analyze. |
|
|
|
|
## Exposing webhooks
|
|
|
|
### `expose`
|
|
|
|
Enable, disable, or change the Tailscale serve/funnel configuration for the
|
|
voice webhook. When realtime or streaming audio is enabled, the command also
|
|
exposes or clears that mode's WebSocket stream path.
|
|
|
|
| Flag | Default | Description |
|
|
| --------------------- | ----------------------------------------- | ----------------------------------------------- |
|
|
| `--mode <mode>` | `funnel` | `off`, `serve` (tailnet), or `funnel` (public). |
|
|
| `--path <path>` | config `tailscale.path` or `--serve-path` | Tailscale path to expose. |
|
|
| `--port <port>` | config `serve.port` or `3334` | Local webhook port. |
|
|
| `--serve-path <path>` | config `serve.path` or `/voice/webhook` | Local webhook path. |
|
|
|
|
```bash
|
|
openclaw voicecall expose --mode serve
|
|
openclaw voicecall expose --mode funnel
|
|
openclaw voicecall expose --mode off
|
|
```
|
|
|
|
<Warning>
|
|
Only expose the webhook endpoint to networks you trust. Prefer Tailscale Serve over Funnel when possible.
|
|
</Warning>
|
|
|
|
## Related
|
|
|
|
- [CLI reference](/cli)
|
|
- [Voice call plugin](/plugins/voice-call)
|