Install
openclaw skills install alibabacloud-vms-smart-call-by-ttsAlicloud VMS Smart Voice Call Skill. Use for making AI-powered voice calls with natural language intent. The system automatically matches contacts from the address book and generates call content via LLM. Triggers: "智能语音通知", "AI 打电话", "smart voice call", "SubmitIntent", "给某人打电话", "语音通知提醒".
openclaw skills install alibabacloud-vms-smart-call-by-ttsInitiate AI-generated voice calls through Alibaba Cloud Voice Messaging Service (dyvmsapi) by describing the call intent in natural language. The system automatically matches the addressee from the user's address book and generates the spoken content with an LLM.
Architecture: Alibaba Cloud VMS (dyvmsapi) + SubmitIntent API + LLM Content Generation + Contact Book Matching
⚠️ Path-Selection Rules (MUST be followed in this exact order):
- Always try the intranet primary path first: enter §1 and run the full intranet plugin install flow (
cli.aliyun-inc.com). It is not allowed to skip §1 just because "this looks like an external network".- Switch to §1.alt only when §1.3 reports
lookup cli.aliyun-inc.com: no such hostorconnection timeout. Any other error MUST be triaged viareferences/plugin-troubleshooting.mdand MUST NOT be treated as a network failure.- The external fallback only replaces
SubmitIntent: it routes through the scriptscripts/dyvmsapi_rpc.pyto call the public gateway directly (SubmitIntentvisibility is still private, with no SLA).QueryCallDetailByCallIdispublic, and the public-releasedyvmsapiCLI plugin already includes that subcommand (aliyun plugin install --names dyvmsapi, no--source-baseneeded). In external mode, call-detail queries still go through the public CLI plugin; the script only handlesSubmitIntent.- ⚠️ The public-release plugin and the intranet-online plugin share the same name (
aliyun-cli-dyvmsapi) and are mutually exclusive — only one can be installed at a time, and the second install overwrites the first. Priority: install the intranet-online version whenever possible (it ships bothSubmitIntentandQueryCallDetailByCallId); only fall back to the public-release version when the intranet install fails (which losesSubmitIntent, then the script fills the gap). Never install the public-release version while the intranet-online version is available — doing so loses thesubmit-intentsubcommand.- The full external-fallback execution manual lives in
references/external-network-fallback.md.- Switch back to the primary path as soon as intranet connectivity is restored. Do not stay on the fallback long-term. Switch back via:
aliyun plugin uninstall --name dyvmsapi(note the singular--name), then re-runaliyun plugin install ... --source-base ...from §1.3 to reinstall the intranet-online version.
Compared with the legacy SingleCallByTts, this capability:
Capability Boundary: this Skill wraps two capabilities — initiating a smart call (
SubmitIntent) and querying the call detail (QueryCallDetailByCallId). Address-book CRUD operations and phone-number ownership verification are out of scope; the user must perform those in the Alibaba Cloud Voice Service console.
[MUST] Execute steps 1.1 → 1.2 → 1.3 → 1.4 in strict order. Do not skip any step. On any failure, consult
references/plugin-troubleshooting.md.
# Note on --user-agent scope:
# Aliyun CLI system / tooling commands (`version`, `configure`, `plugin`,
# `upgrade`, `oss`, `auto-completion`, `mcp-proxy`, `go-migrate`, `otsutil`,
# and any subcommand invoked with `--help`) DO NOT accept `--user-agent` and
# MUST NOT carry it (passing it raises `unknown flag: --user-agent`).
# The ONLY exception is `aliyun configure ai-mode set-user-agent`, which is
# the dedicated command for declaring the AI-Mode global User-Agent (see §1.1.1).
# Only BUSINESS calls (e.g. `aliyun dyvmsapi submit-intent ...`,
# `aliyun dyvmsapi query-call-detail-by-call-id ...`) accept and MUST carry
# --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"
# so the call can be attributed to this Skill.
aliyun version
✅ Output 3.3.15 or any version ≥ 3.3.8 → continue to 1.1.1
❌ Command not found / version < 3.3.8 → run the environment-aware installer shipped with this Skill. It picks the first strategy that matches the runtime (Homebrew → user-level signed-binary tarball under $HOME/.local/bin), is idempotent, self-verifies, and never executes a remote script via shell pipe:
bash scripts/install_aliyun_cli.sh
Notes:
- Do not run
curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bashto install the CLI: piping a remote script directly to a shell bypasses integrity verification and is treated as a security violation by static scanners; that script also writes to/usr/local/bin/aliyunand silently retries withsudo, which fails in non-interactive shells (agent sandboxes, CI runners) where no tty is available to type the password. The installer above downloads only the signed binary tarball, never executes a remote script, and routes around the sudo issue.- On Apple Silicon Macs the installer pulls
aliyun-cli-macosx-latest-arm64.tgz; never install theamd64build on arm64 hardware — it requires Rosetta 2 and is brittle.- Verify before continuing: the installer exits non-zero if the resulting
aliyun versionis <3.3.8. If it fails, switch to the manual matrix inreferences/cli-installation-guide.md(it covers macOS amd64/arm64, Linux amd64/arm64, and Windows, each with a sudo-less variant).
Why is the floor 3.3.8? §1.3 uses
plugin install --source-base, a flag first introduced in aliyun CLI v3.3.7 (2026-04-16) (PR #1299). The floor is set conservatively to 3.3.8. Versions < 3.3.8 will fail §1.3 withERROR: invalid flag source-base— this is a tooling-version issue, not a network issue; upgrade the CLI.
Enable AI-Mode as soon as §1.1 confirms the CLI is available, and before any other
aliyun ...invocation in this Skill.User-Agent is declared per-command on BUSINESS calls only. Every business
aliyun ...invocation (e.g.aliyun dyvmsapi submit-intent,aliyun dyvmsapi query-call-detail-by-call-id) in SKILL.md andreferences/*.mdMUST explicitly pass the per-Skill UA"AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"so the call can be attributed to this Skill. System / tooling commands (the categories listed in the scope-comment of §1.1) DO NOT accept this UA flag and MUST NOT carry it — passing it raisesunknown flag: --user-agentand aborts the command. The single exception isaliyun configure ai-mode set-user-agent, used below to declare the AI-Mode default UA.
# 1) Enable AI-Mode for this Skill session.
aliyun configure ai-mode enable
# 2) Declare the AI-Mode default UA so the gateway attributes every business
# call below to this Skill. `ai-mode set-user-agent` is the ONLY
# system/tooling command that legitimately accepts the UA flag.
aliyun configure ai-mode set-user-agent \
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts"
[MUST] Disable AI-Mode at EVERY exit point of this Skill (success, failure, or early STOP) by running
aliyun configure ai-mode disable— see §6 step 2 / step 4 and §9 best-practice #5.
submit-intent subcommand already existsaliyun dyvmsapi submit-intent --help 2>&1
Decide based on the output:
| Output Pattern | Verdict | Next Step |
|---|---|---|
Contains API 版本: 2017-05-25 and contains --user-message | Plugin is ready | Skip 1.3, jump to §2 |
unknown command "submit-intent" / command not found | Plugin not installed | Go to 1.3 |
aliyun: command not found | CLI not installed | Back to 1.1 |
| Other | Anomaly | Consult references/plugin-troubleshooting.md |
dyvmsapi plugin
SubmitIntentis distributed only through the Alibaba intranet-online CLI plugin. The public-releasealiyun-cli-dyvmsapidoes not contain this subcommand.
Run the following command verbatim (no parameter may be omitted or modified):
aliyun plugin install --names dyvmsapi \
--version 0.1.0 \
--source-base https://cli.aliyun-inc.com/registry_id/2/env/online/plugins
[MUST] Hard requirements (a single mismatch will fail the install or pull the wrong build):
| Parameter | Correct | Common Mistake |
|---|---|---|
| CLI version | ≥ 3.3.8 | < 3.3.8 → ERROR: invalid flag source-base — go upgrade in §1.1, do NOT switch to the external fallback |
--names | plural s | --name (install fails with invalid flag; the singular form is for uninstall only) |
--version | 0.1.0 (required) | Omitting it fetches the latest public build |
--source-base | the URL above (required) | Omitting it pulls from the public mirror, which lacks submit-intent |
| URL path | env/online/plugins | env/pre/plugins is deprecated |
| URL host | cli.aliyun-inc.com | Resolvable from Alibaba intranet only |
Expected output:
Downloading aliyun-cli-dyvmsapi 0.1.0...
Plugin aliyun-cli-dyvmsapi 0.1.0 installed successfully!
If the output reads
plugin "aliyun-cli-dyvmsapi" is already installed (version X.Y.Z); continuing will replace it with version 0.1.0→ expected behavior (overwrite install). Let it finish.If the output reads
ERROR: invalid flag source-base→ CLI version is < 3.3.8 and does not understand the flag. Re-run the environment-aware fallback chain in §1.1 (it auto-picks brew / system-wide / user-level upgrade) to upgrade, then retry §1.3. [FORBIDDEN] It is strictly forbidden to switch to §1.alt due to this error — this is a tooling-version issue, not a network issue. The external fallback is reserved forno such host/connection timeoutonly.If the output reads
lookup cli.aliyun-inc.com: no such host/connection timeout→ the runtime is not on the Alibaba intranet. Switch to §1.alt and continue (functionally equivalent; no plugin install needed).Other errors → consult
references/plugin-troubleshooting.md.
# `--help` is a help-mode invocation: it MUST NOT carry `--user-agent`
# (passing it raises `unknown flag: --user-agent` and aborts the command).
# See §1.1.1 for the full system-vs-business UA scope rule.
aliyun dyvmsapi submit-intent --help
Validation criteria (ALL must hold before proceeding):
API 版本: 2017-05-25--user-message提交文本意图… or equivalentIf any criterion fails → see references/plugin-troubleshooting.md.
Trigger: §1.3 reports
lookup cli.aliyun-inc.com: no such host, or it has been confirmed that the runtime is on a public network without access to the Alibaba intranet/VPN. Do not enter this path while the primary plugin is functional.
Prerequisites (none may be missing):
python3 --version) — required by step 2 (script-based SubmitIntent)scripts/dyvmsapi_rpc.py (zero third-party dependencies) shipped in this repo — handles SubmitIntent onlydyvmsapi plugin — required by step 4 (CLI-based QueryCallDetailByCallId):
# Refresh the public plugin index so the latest public-release dyvmsapi metadata is used.
aliyun plugin update
# Install the public-release dyvmsapi plugin (default source = public mirror; no --source-base).
aliyun plugin install --names dyvmsapi
⚠️ Mutually exclusive with the intranet-online plugin: if §1.3 successfully installed the intranet-online build (0.1.0), do NOT install the public-release build here — the intranet-online build already includes query-call-detail-by-call-id. Install the public-release build only when §1.3 failed with no such host.dyvmsapi.aliyuncs.comValidate the script is in place:
python3 scripts/dyvmsapi_rpc.py --help
If the output contains dyvmsapi public RPC direct-call script (zero dependencies), proceed to §2 credentials validation. (On the external script path, credentials are auto-injected by the helper scripts/run_with_aliyun_creds.py from the current aliyun configure profile — see §2.)
Important constraints:
aliyun dyvmsapi submit-intent invocation in §6 step 2 MUST be replaced by the script invocation; step 4 (aliyun dyvmsapi query-call-detail-by-call-id) still uses the CLI with the public-release plugin installed above. Details: §6.alt and references/external-network-fallback.md.aliyun ... calls (e.g. aliyun dyvmsapi query-call-detail-by-call-id) MUST carry the per-Skill UA; system / tooling commands MUST NOT — see §1.1.1.Pre-check: Alibaba Cloud Credentials Required
Security Rules:
- NEVER read, echo, or print AK/SK values (e.g.,
echo $ALIBABA_CLOUD_ACCESS_KEY_IDis FORBIDDEN)- NEVER ask the user to input AK/SK directly in the conversation or command line
- NEVER use
aliyun configure setwith literal credential values- ONLY use
aliyun configure listto check credential statusaliyun configure listCheck the output for a valid profile (AK, STS, or OAuth identity).
Note:
Validonly means the local profile fields are well-formed; it does not prove the AK is still active server-side. If a downstream call returnsInvalidAccessKeyId.NotFound/SignatureDoesNotMatch, the credentials are syntactically OK but have been disabled or rotated — cross-check status in the AK Management Console.If no valid profile exists, STOP here.
- Obtain credentials from the Alibaba Cloud Console
- Configure credentials outside of this session by running
aliyun configurein the user's own terminal (or by exporting environment variables in the shell profile). The interactive flow asks for several values including AK ID, AK Secret, and Default Region Id. Only the Region prompt typically blocks users (the CLI does not show candidates), so the agent MUST proactively tell the user: recommendcn-hangzhou—dyvmsapiis a centralized service that is not region-sensitive, so any valid region works; if the user's other Alibaba Cloud resources already live in another region (e.g.cn-shanghai,cn-beijing,cn-shenzhen,cn-hongkong,ap-southeast-1), they may pick that one instead. Full candidate list:references/cli-installation-guide.md.- Return and re-run after
aliyun configure listshows a valid profile
On the primary path, aliyun dyvmsapi submit-intent / query-call-detail-by-call-id automatically read credentials from the current profile. The agent does not need to take any extra action.
Design: The external-fallback script path no longer asks the user to manually
exportAK/SK. Instead, it reuses the user's already-configuredaliyun configurecurrent profile, and the helperscripts/run_with_aliyun_creds.pyauto-injects credentials into the subprocess environment. Three reasons motivate this design: ① a user experience consistent with the primary path; ② cross-process shellexportcannot pass credentials into the agent's subprocess (technically infeasible); ③ since the user has already provided credentials for this profile, asking again would constitute redundant input.[MUST] Standard invocation pattern: agents always go through the helper. Do not extract credentials from
~/.aliyun/config.jsonby hand.# 1) Pre-check: confirm the current profile meets auto-injection requirements python3 scripts/run_with_aliyun_creds.py --check # Expected: `OK profile=default mode=AK ready for auto-injection` → ready # 2) Tell the user which profile will be used (transparency; no credential values) python3 scripts/run_with_aliyun_creds.py --print-profile # Output e.g.: `profile=default mode=AK region=cn-hangzhou` # The agent MUST tell the user explicitly: "I will call SubmitIntent with profile=<name> mode=<mode>" — give the user a chance to refuse. # 3) Make the actual call (helper injects env; the script reads from env; no values are persisted) python3 scripts/run_with_aliyun_creds.py -- \ python3 scripts/dyvmsapi_rpc.py SubmitIntent -P UserMessage="<the user's intent>"Supported modes:
AK/StsToken.StsTokenadditionally injectsALIBABA_CLOUD_SECURITY_TOKEN, which the script then includes as a public parameter in the signature.Unsupported modes (
RamRoleArn/EcsRamRole/OAuth/External/CredentialsURI…): the helper exits 3 and prompts the user to manually obtain temporary AK/SK/STS. In that case, fall back to the primary path (the CLI natively supports all modes) or have the user create a new AK profile.[FORBIDDEN] Prohibited behaviors:
- Bypassing the helper and reading
~/.aliyun/config.json/json.load(...)directly inside agent code is strictly prohibited — three common failure modes follow: hardcodingprofiles[0]instead ofcurrent(wrong profile), missingStsToken'ssts_token, and accidentally leaking credentials through debug output or script logs.- Writing AK/SK/SecurityToken into
ran_scripts/*.sh/outputs/*.md/ any log / any git-visible file is strictly prohibited (placeholder comments such as# AK=<from-config>are also forbidden — they mislead readers).- Passing
SecurityTokenas a business parameter via-P SecurityToken=...is strictly prohibited — it is a public parameter and must participate in the signature; the helper handles this automatically.echo/--debug-printing credential values is strictly prohibited.- Reverting to the legacy
read -s ... && export ...pattern is strictly prohibited — cross-process shell environments cannot propagate to subprocesses; this is technically infeasible.
RAM sub-accounts must be granted dyvms:SubmitIntent and dyvms:QueryCallDetailByCallId. Root accounts need no extra setup. See references/ram-policies.md for the full policy.
[MUST] Permission Failure Handling: When any command or API call fails due to permission errors at any point during execution, follow this process:
- Read
references/ram-policies.mdto get the full list of permissions required by this SKILL- Use the
ram-permission-diagnoseskill to guide the user through requesting the necessary permissions- Pause and wait until the user confirms that the required permissions have been granted
Address-book management is OUT OF SCOPE for this Skill. Before initiating a smart call, the user must complete the following in the Alibaba Cloud Voice Service console:
- Verify phone-number ownership: complete ownership verification for every phone number to be added (verification is valid for ~6 months by default)
- Add contacts: assign each verified number a recognizable Tag, e.g. "Mom", "Manager Zhang", "Lao Wu"
- (Optional) Update or remove existing contacts
Address-book constraints:
TagandPhoneNumberare strictly one-to-one- Tag is the only signal the LLM uses for contact matching — use clear, distinctive names
IMPORTANT: Parameter Confirmation — Before executing the API call, confirm the user's intent (who to call + what to convey). If the user's message already makes both clear, no confirmation is needed — proceed directly. Do NOT iterate on wording or draft the spoken text —
UserMessageis an intent description, not the final playback script; the server-side LLM generates the actual spoken content (Model.CallContent).
| Parameter | Required | Description | Default |
|---|---|---|---|
UserMessage | Yes | Natural-language description of the call intent (NOT the literal spoken text) | None (user must provide) |
UserMessageexamples:
- "Remind Mom I won't be home for dinner tonight"
- "Call Manager Zhang and let him know the meeting is at 10 AM tomorrow"
- "Tell Lao Wu to bring the contract this afternoon"
These are intent descriptions. If who + what are already clear from the user's original message, proceed directly — do not echo back or ask for approval. Do not ask "shall I phrase it as X?" or iterate on wording — the server generates the spoken content.
AI-Mode and User-Agent: AI-Mode was enabled in §1.1.1 (executed immediately after the CLI was verified). Do not re-enable here unless it was previously disabled (see note below Step 3). Every business
aliyun ...invocation below (e.g.aliyun dyvmsapi submit-intent,aliyun dyvmsapi query-call-detail-by-call-id) MUST explicitly pass the per-Skill UA"AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0". System / tooling commands DO NOT accept this flag and MUST NOT carry it — see §1.1.1.[MUST] Disable AI-Mode at EVERY exit point of this Skill — success, failure, early STOP, all exits. The disable command is:
aliyun configure ai-mode disable
Extract who to call and what to convey from the user's message. A natural-language reference is sufficient (e.g. "我爸", "Mom", "张经理") — it does not need to be the exact Tag literal stored in the address book; the server-side LLM performs semantic matching against the user's contact list.
[MUST] Zero or one round, then fire —
UserMessageis NOT the verbatim script that will be spoken; it is an intent description fed to the server-side LLM, which generates the actual spoken content. Once who + what are clear (whether from the original message or a single clarification), proceed to Step 2 immediately. Prohibited behaviors:
- Drafting a "notification script" and asking the user to review wording
- Asking "shall I say it like this?" or offering multiple phrasings
- Asking the user for the exact Tag literal in the address book (e.g. "你爸在通讯录里的 Tag 叫什么?") — the server does semantic matching; a natural-language reference is enough
- Confirming the contact's identity when it is already obvious ("爸"/"老爸"/"爸爸" are all the same role — do not ask "which one?")
- Looping back for a second confirmation unless the user actively says the intent is wrong
[MUST] Never abort on unverifiable Tag — The Agent has no local API to list or verify address-book entries (see §4: CRUD is out of scope). If the Agent cannot confirm whether the user-provided Tag exists, it MUST still proceed to Step 2 and let the server validate. Halting the flow, asking the user to "go check the console first", or refusing to call because the Tag "might not exist" is strictly prohibited — the correct behavior is to fire the API and faithfully relay whatever the server returns (success or error).
aliyun dyvmsapi submit-intent \
--user-message "<user-confirmed natural-language intent>" \
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"
§6.alt External Fallback — If the runtime entered §1.alt (script path), replace this step with the helper-driven invocation (credentials MUST be auto-injected via the helper, see §2.2):
python3 scripts/run_with_aliyun_creds.py -- \ python3 scripts/dyvmsapi_rpc.py SubmitIntent \ -P UserMessage="<user-confirmed natural-language intent>"
- The Key MUST be PascalCase (
UserMessage, notuser-message). Response shape is identical to the CLI; step 3's parsing logic is shared.- Direct invocation of
python3 scripts/dyvmsapi_rpc.py ...without going through the helper is strictly prohibited — the script does not read~/.aliyun/config.jsonitself; missing env will produce[ERROR] AK/SK not provided.- Before the call, run the §2.2 [MUST] 3-step routine (
--check→--print-profileto inform the user → actual call).- Details in
references/external-network-fallback.md.
Code == "OK" and Success == true: the call has been initiated
Model.Tag (matched contact), Model.CallContent (spoken text), Model.CallId to the userreferences/related-commands.mdCode != "OK" is a valid execution result — e.g. contact-not-found, quota exceeded, parameter invalid. Parse the error, report it to the user faithfully, and treat the Skill run as complete (with an error outcome). Do not retry automatically or loop back to Step 1 unless the user explicitly asks.AI-Mode lifecycle after Step 3:
- If
Code != "OK"or the user does not need Step 4 → this is the exit point → disable AI-Mode now.- If
Code == "OK"and Step 4 may follow (user wants to check call result) → do NOT disable yet. Keep AI-Mode enabled until Step 4 completes.- If the Skill session was interrupted (e.g. Agent already disabled AI-Mode after Step 3, then the user later requests Step 4) → re-enable AI-Mode before Step 4, then disable again at the end. This is the only legitimate re-enable scenario.
[FORBIDDEN] Strictly forbidden to fabricate responses or stage Mock deliveries — When step 2 encounters an infrastructure failure (credential missing / expired, network unreachable, non-zero script exit code with no JSON body,
InvalidAccessKeyId,SignatureDoesNotMatch):
- Before STOP, ALWAYS run
aliyun configure ai-mode disablefirst (AI-Mode was enabled in §1.1.1; disable is mandatory at every exit point including failure paths).- STOP IMMEDIATELY, report the error to the user faithfully and verbatim, and ask them to fix the issue and retry.
- Fabricating a
Code: OK/ fakeCallId/ fakeModel.Tag/ fakeModel.CallContentis strictly prohibited.- Writing falsified
call_result.json/task_summary.md/executed_actions.shto mimic a successful delivery is strictly prohibited.- Wording such as "simulated" / "mock" / "assume the user has" / "since this is a simulated environment" used to bypass real invocation is strictly prohibited.
- Any of the above is treated as a fraudulent delivery.
The
Model.CallIdreturned bySubmitIntentonly signifies that the call has been accepted, not that the callee has answered. If the user wants to confirm whether the call connected, invokequery-call-detail-by-call-id.
# Take the CallId returned by SubmitIntent (format: <ms-timestamp>^<call-sequence>, e.g. "1779785134472^9876543210").
CALL_ID="<Model.CallId from step 2 response>"
# The first segment of CallId is already a Unix-millisecond timestamp; reuse it as query-date.
# `--query-date` is an int (Unix-millisecond timestamp), NOT a yyyyMMdd string — do NOT call any datetime conversion.
QUERY_DATE="${CALL_ID%%^*}"
aliyun dyvmsapi query-call-detail-by-call-id \
--call-id "$CALL_ID" \
--prod-id 11000000300006 \
--query-date "$QUERY_DATE" \
--user-agent "AlibabaCloud-Agent-Skills/alibabacloud-vms-smart-call-by-tts/1.0.0"
Hard requirements:
--prod-id MUST be 11000000300006 (the Voice Notification product ID). SubmitIntent is dispatched under this product; any other prod-id will return Code: OK with no Data.--query-date MUST be on the same day as the CallId (millisecond timestamp).Code: OK returns with no Data, retry once after another 30–60 seconds. Do not hard-wait 1–2 minutes blindly.§6.alt External — step 4 still uses the CLI.
QueryCallDetailByCallIdvisibility ispublic; the public-releasealiyun-cli-dyvmsapiplugin already includes it:aliyun plugin update aliyun plugin install --names dyvmsapi # public-release; no --source-baseThe public-release plugin should already be installed from §1.alt. If for any reason it is not yet present, run the two commands above first. After install, the
aliyun dyvmsapi query-call-detail-by-call-id ...command above works as-is. On the external path, the script only replacesSubmitIntent; CDR queries still go through the CLI. Details inreferences/external-network-fallback.md.
Response parsing:
Data is a JSON string (requires a second parse) and contains:
| Field | Meaning |
|---|---|
stateDesc | Localized state description, e.g. 用户接听 (user answered) / 未接听 (no answer) / 呼叫中 (in progress) |
state | State code (200000 = answered) |
duration | Call duration in seconds |
bRingTime / bStartTime / bEndTime | Ring / answer / hangup timestamps |
callee | Dialed number (this CDR API returns the full number — only the account owner can view their own CDR; this does not contradict the SubmitIntent rule that phone numbers are not passed to the LLM) |
gmtCreate | Time the call request was accepted by the platform |
calleeShowNumber | Caller-display number |
[MUST] Readable Presentation — Strictly forbidden to dump the raw
DataJSON string to the user. After parsing, render the result as three real Markdown tables (NOT a fenced code block, NOT ASCII separator lines like─────— those get absorbed as<hr>by Markdown renderers and reflow the rest into a single line):Call Result
✅ Status <stateDesc>(state=<state>)👤 Callee <callee_masked>📲 Display No. <calleeShowNumber>⏰ Duration <duration>secondsTimeline
🕐 Accepted <gmtCreate>🔔 Ringing <bRingTime>(+<offset_after_accepted>s)📞 Answered <bStartTime>(+<offset_after_ringing>s after ring)🔚 Hung up <bEndTime>(talk<duration>s)👋 Hangup by <callee-initiated|caller-initiated>(hangupDirection=<0|1>)Reference
🆔 CallId <callId>Rules:
- Render real Markdown tables. Do NOT wrap the layout in a fenced code block, and do NOT use ASCII separators (
─────,===,---inside cells, etc.) — they get absorbed as<hr>by Markdown renderers and reflow the rest of the text into a single line.- Show the localized
stateDescnext to the numericstate. Don't show the raw number alone.- The callee number MUST be masked: first 3, then
****, then last 4 — this is what<callee_masked>represents in the table. Never output the full number.- Time fields must include relative offsets (accepted → ringing, ringing → answered) so the user can perceive the timeline.
hangupDirection:0= callee hung up,1= caller hung up.- For unanswered cases (
state ≠ 200000), omit the Timeline answered/hung-up rows and use a one-line summary, e.g. "✗ Callee did not answer (rang for X seconds, then hung up)".
For the full parameter reference and response examples, see references/related-commands.md.
[MUST] Disable AI-Mode at EVERY exit point — before delivering the final response for ANY reason, run
aliyun configure ai-mode disablefirst.
See references/verification-method.md.
Quick check: Code == "OK" and a non-empty Model.CallId in the response = the call has been initiated successfully.
See references/related-commands.md.
UserMessage must reference a contact explicitly: use a recognizable tag the user believes is in their address book (e.g. "Mom", "Manager Zhang"); avoid pronouns ("him", "that person").aliyun configure ai-mode disable.| File | Content |
|---|---|
references/cli-installation-guide.md | Aliyun CLI installation guide |
references/plugin-troubleshooting.md | dyvmsapi plugin install troubleshooting (MUST consult on any §1 failure) |
references/ram-policies.md | RAM policy (minimum-Action) |
references/related-commands.md | CLI command reference, parameters, error codes |
references/verification-method.md | Verification methods |
references/acceptance-criteria.md | Acceptance criteria |
references/external-network-fallback.md | External fallback execution manual (enter only when the primary path is unavailable) |
scripts/dyvmsapi_rpc.py | Zero-dependency Python script that calls the public dyvmsapi gateway directly |
scripts/run_with_aliyun_creds.py | Credential-injection helper: auto-injects env from the aliyun configure current profile, then exec's the subcommand (mandatory entrypoint for the external fallback path) |
scripts/install_aliyun_cli.sh | Environment-aware installer / upgrader for the Aliyun CLI (Homebrew → user-level signed-binary tarball; idempotent and self-verifying). Invoked from §1.1 when the CLI is missing or below 3.3.8. |
related_apis.yaml | Dependent API inventory |