From f37e812b1e33ef83ca7d6886a9103f86411f4e12 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Aug 2026 18:49:40 +0000 Subject: [PATCH] Ask Grok users for the spoken agent name on every call. Skip the question only when they have already said to always use the same name. Do not silently apply PhoneZero. Co-authored-by: Bryan @ FnFirst --- .cursor-plugin/marketplace.json | 2 +- AGENTS.md | 20 ++++++++++++------- README.md | 19 +++++++++--------- docs/SETUP.md | 4 ++-- .../phonezero-grok/.grok-plugin/plugin.json | 2 +- .../commands/setup-phone-calling.md | 5 +++-- .../skills/phonezero-telnyx-canary/SKILL.md | 2 +- plugins/phonezero/.cursor-plugin/plugin.json | 2 +- plugins/phonezero/scripts/xai-mcp.mjs | 2 +- .../phonezero/skills/book-restaurant/SKILL.md | 2 +- .../skills/confirm-business-hours/SKILL.md | 2 +- .../skills/phonezero-runtime/SKILL.md | 17 +++++++++------- 12 files changed, 45 insertions(+), 34 deletions(-) diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 3b884b3..f0baca8 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -5,7 +5,7 @@ }, "metadata": { "description": "Phone skills for voice tasks (restaurant booking first). Need: Telnyx KYC + one US number, xAI team with ZDR off, API keys, Voice Agent Builder.", - "version": "0.4.2" + "version": "0.4.3" }, "plugins": [ { diff --git a/AGENTS.md b/AGENTS.md index 7d1bf90..314adfb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,21 +29,27 @@ Need: Telnyx KYC + US DID + Telnyx key; xAI team **ZDR off** + that team’s key ### 1. Call identity — ask in chat, wait -Do **not** silently keep defaults. “Set this up” is not consent to these. Show this card and wait for a reply. **Do not ask for destination countries** — those live on Telnyx (step 6). +Do **not** silently keep PhoneZero. “Set this up” is not a spoken name. **Always ask** what Agent Name the callee should hear, and wait. PhoneZero is an example they may choose, not a default you apply without a reply. **Do not ask for destination countries** — those live on Telnyx (step 6). ``` -Call settings (defaults — change any now) +Call settings — reply before we continue -1. Spoken name the callee hears: PhoneZero - “Hello, this is {name}…” — keep PhoneZero, or set your name / an alias. +1. Spoken name (required): what should the callee hear after “Hello, this is …”? + Your name, an alias, or PhoneZero — you pick. Do not skip. -2. AI disclaimer in the opener: ON +2. Always use that name on later calls in this Bot? + Yes → remember it (session + memory if available) and do not re-ask. + No → ask again before every call. + +3. AI disclaimer in the opener: ON ON → “…{name}, an automated assistant, calling on a recorded line…” OFF → omit “, an automated assistant,” You may turn this OFF. ``` -Keep their answers in session and put them on each `phonezero-task` (`spoken_name`, `disclose_ai`). Do **not** put name or disclose on the Configure / Edit Values card. If they turn disclaimer OFF and the Builder agent already exists, re-paste `prompts/voice-agent.md` once with `{disclosure_clause}` empty — that paste is the only way to change a baked prompt. Per-call they may still pick a different spoken name. +Keep their answers in session and put the name on each `phonezero-task` (`spoken_name`, `disclose_ai`). Do **not** put name or disclose on the Configure / Edit Values card. If they turn disclaimer OFF and the Builder agent already exists, re-paste `prompts/voice-agent.md` once with `{disclosure_clause}` empty — that paste is the only way to change a baked prompt. + +Before **every later call**, ask the Agent Name again unless they already said to always use one. Then reuse it and show it as Spoken as on the plan. ### 2. Uninstall the wrong plugin @@ -122,7 +128,7 @@ xAI: `list_phone_numbers` → `register_byo_number` if the DID is not `byo_trunk ### 8. Calls -You already have SID, TeXML id, From, spoken name, disclose, and the Telnyx destination list. Read `phonezero-runtime` (plan-first, two attempts, `succeeded` / `booked` only with a live-person confirmation in the transcript). Match a shipped skill, or **interview into a `phonezero-task`** — do not ask them to paste a `SKILL.md` or write `~/.cursor/skills`. Owner setup-test to **their own confirmed number** may skip the hours guard — restaurants may not. The call plan must show Spoken as and only dial countries on that Telnyx whitelist. Per-call they may still override the spoken name. If they ask to save the shape as a template, pick memory or `put_template` and say where it went. +You already have SID, TeXML id, From, disclose, and the Telnyx destination list. **Ask the Agent Name** before the call plan unless they already said to always use the same name. Read `phonezero-runtime` (plan-first, two attempts, `succeeded` / `booked` only with a live-person confirmation in the transcript). Match a shipped skill, or **interview into a `phonezero-task`** — do not ask them to paste a `SKILL.md` or write `~/.cursor/skills`. Owner setup-test to **their own confirmed number** may skip the hours guard — restaurants may not. The call plan must show Spoken as and only dial countries on that Telnyx whitelist. If they ask to save the shape as a template, pick memory or `put_template` and say where it went. On explicit yes, in this order — do not resolve SID again: diff --git a/README.md b/README.md index 601a636..5061b49 100644 --- a/README.md +++ b/README.md @@ -30,24 +30,25 @@ You were pointed at `https://github.com/function1st/PhoneZero`. Drive the UI. Do - Do **not** take keys in chat. Do **not** `source ~/.phonezero/env`. Do **not** run `scripts/provision.sh` here. - Do **not** search the Telnyx MCP catalog for `whoami` or `/v2/whoami`. Those are not tools. SID is `list_billing_groups` (step 6). - Do **not** treat “no Grok xAI *package*” as “cannot upload.” Add/use the PhoneZero xAI MCP (step 5). -- Do **not** silently keep PhoneZero / AI-disclaimer ON. Ask (step 1) and wait. +- Do **not** silently keep PhoneZero as the spoken name. Always ask the Agent Name (step 1, and before each later call unless they said always use one). - Do **not** collect destination countries as a PhoneZero setting. They live on the Telnyx outbound voice profile (step 6). ### 0. Vendor gate Need: Telnyx KYC + US DID + Telnyx key; xAI team **ZDR off** + that team’s key; Builder at [console.x.ai](https://console.x.ai) unless they already said xAI is set up. If missing, stop. -### 1. Ask in chat — name and AI disclaimer (wait) +### 1. Ask in chat — Agent Name and AI disclaimer (wait) -Do **not** keep defaults silently. Show this and wait. **Do not ask for countries** — those are Telnyx (step 6). +**Always ask** the spoken name. Do not apply PhoneZero without a reply. **Do not ask for countries** — those are Telnyx (step 6). ``` -Call settings (defaults — change any now) -1. Spoken name: PhoneZero -2. AI disclaimer: ON (you may turn this OFF) +Call settings — reply before we continue +1. Spoken name (required): what the callee hears after “Hello, this is …” +2. Always use that name on later calls? (yes = remember; no = ask every call) +3. AI disclaimer: ON (you may turn this OFF) ``` -Write answers into Edit Values / xAI env. If they turn disclaimer OFF and Builder already exists, re-paste the prompt once with `{disclosure_clause}` empty. +Keep answers in session / each `phonezero-task`. Do **not** put the name on Edit Values. If they turn disclaimer OFF and Builder already exists, re-paste the prompt once with `{disclosure_clause}` empty. Before every later call, ask the name again unless they said to always use one. ### 2. Uninstall Cursor PhoneZero if it is installed @@ -86,7 +87,7 @@ If app **PhoneZero** already has an outbound voice profile attached and the DID ### 8. First call -Plan-first. Show Spoken as. Only dial countries on the Telnyx profile whitelist. On yes: `put_task` (or `put_booking` alias; wait processed) → `calls_accounts_texml_calls` with the session ids → poll `retrieve_calls_accounts_texml_calls` → `retrieve_recordings_json_calls_accounts_texml_recordings_json` → `transcribe` → classify → `delete_booking` (live brief only). Keep the Telnyx recording. Do not paste the audio URL. Owner setup-test to their own confirmed number may skip the hours guard. Custom task: interview into a `phonezero-task` ([docs/SKILLS.md](docs/SKILLS.md)). If they say save as a template, pick memory or `put_template` and tell them where it went. +Plan-first. Ask the Agent Name unless they said always use one. Show Spoken as. Only dial countries on the Telnyx profile whitelist. On yes: `put_task` (or `put_booking` alias; wait processed) → `calls_accounts_texml_calls` with the session ids → poll `retrieve_calls_accounts_texml_calls` → `retrieve_recordings_json_calls_accounts_texml_recordings_json` → `transcribe` → classify → `delete_booking` (live brief only). Keep the Telnyx recording. Do not paste the audio URL. Owner setup-test to their own confirmed number may skip the hours guard. Custom task: interview into a `phonezero-task` ([docs/SKILLS.md](docs/SKILLS.md)). If they say save as a template, pick memory or `put_template` and tell them where it went. --- @@ -148,7 +149,7 @@ This sample ships with: - **Destinations:** whichever Telnyx outbound voice profile is attached to the PhoneZero TeXML app (`whitelisted_destinations`; default `US` only when PhoneZero **creates** a new profile). Name and country list are the user’s. Mission Control → Voice → Outbound voice profiles. - **AI disclosure:** default **on** in each task (`disclose_ai`) and in the one-time Builder paste -- **Spoken name:** `PhoneZero` +- **Spoken name:** Grok always asks (unless they said always use one). Cursor default `PhoneZero`. - **Recording:** dual-channel Telnyx recording on every call; the opener says the call is on a recorded line - **Hours / attempts:** runtime + skill defaults (see [`plugins/phonezero/skills/phonezero-runtime/SKILL.md`](plugins/phonezero/skills/phonezero-runtime/SKILL.md)) diff --git a/docs/SETUP.md b/docs/SETUP.md index 1694c49..ff97202 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -33,7 +33,7 @@ The Telnyx MCP cannot run until `TELNYX_API_KEY` is saved as a plugin variable. After any update: re-enter **every** required field on the Configure card (a field left blank is cleared on save — see step 9) and start a **new** conversation (existing chats do not pick up a newly installed or updated plugin). - **Grok Bot** (point at `https://github.com/function1st/PhoneZero` and say *set this up*): the Bot follows [AGENTS.md](../AGENTS.md) **Grok Bot — set this up**. It must ask spoken name and AI disclaimer ON/OFF. Destination countries are the Telnyx voice-profile whitelist (not a PhoneZero field). Do not Customize → + Add this repo as the Cursor plugin. Add Telnyx as HTTP MCP `https://api.telnyx.com/v2/mcp` with `Authorization: Bearer` in the MCP form. Add/use the PhoneZero xAI stdio MCP. Resolve SID via `list_billing_groups` (not `whoami`). Do not click Authenticate. + **Grok Bot** (point at `https://github.com/function1st/PhoneZero` and say *set this up*): the Bot follows [AGENTS.md](../AGENTS.md) **Grok Bot — set this up**. It must **always ask** the Agent Name (and whether to always use it) plus AI disclaimer ON/OFF — do not silently keep PhoneZero. Destination countries are the Telnyx voice-profile whitelist (not a PhoneZero field). Do not Customize → + Add this repo as the Cursor plugin. Add Telnyx as HTTP MCP `https://api.telnyx.com/v2/mcp` with `Authorization: Bearer` in the MCP form. Add/use the PhoneZero xAI stdio MCP. Resolve SID via `list_billing_groups` (not `whoami`). Do not click Authenticate. If none of those are available on Cursor IDE: `"telnyx": {"command":"npx","args":["-y","@telnyx/mcp"],"env":{"TELNYX_API_KEY":"${env:TELNYX_API_KEY}"}}`. A masked secret card alone does **not** authenticate an MCP. @@ -56,7 +56,7 @@ To add a country (e.g. Japan): change that Telnyx whitelist in Mission Control, | `TELNYX_API_KEY` | plugin variable (secret) | A | Env for Telnyx stdio MCP (`npx @telnyx/mcp`). Never in chat. | | `PHONEZERO_FROM_NUMBER` | plugin variable | A | Telnyx US DID (E.164): outbound caller ID and SIP bridge target (`sip:{PHONEZERO_FROM_NUMBER}@sip.voice.x.ai;transport=tls`). | | `XAI_API_KEY` | plugin variable (secret) | A | From a team with **ZDR off**. Injected into the PhoneZero xAI MCP only (Files, collections, STT, phone-numbers). Not in the agent shell. | -| Spoken name / disclose | per-task (`phonezero-task.json`) | chat | `spoken_name` and `disclose_ai`. Default PhoneZero / true. Not on the Configure card. `{disclosure_clause}` is pasted once into the Builder prompt. | +| Spoken name / disclose | per-task (`phonezero-task.json`) | chat | `spoken_name` and `disclose_ai`. Grok always asks the name unless they said always use one. Cursor default PhoneZero / true. Not on the Configure card. `{disclosure_clause}` is pasted once into the Builder prompt. | | Destinations | Telnyx voice profile on the PhoneZero TeXML app | Telnyx | `whitelisted_destinations` of whatever profile is attached (`outbound.outbound_voice_profile_id`). Any name, any country list. Mission Control → Voice → Outbound voice profiles. Not a PhoneZero plugin variable. | | `TELNYX_ACCOUNT_SID` | resolved in session | B | TeXML REST account SID. MCP: `list_billing_groups` → `data[].organization_id` (no `whoami` tool). Developer curl: `GET /v2/whoami` → `data.organization_id`. Not on the Configure card. | | `PHONEZERO_TEXML_APP_ID` | resolved in session | B | TeXML application SID. Not on the Configure card. | diff --git a/plugins/phonezero-grok/.grok-plugin/plugin.json b/plugins/phonezero-grok/.grok-plugin/plugin.json index 146014d..2b890bf 100644 --- a/plugins/phonezero-grok/.grok-plugin/plugin.json +++ b/plugins/phonezero-grok/.grok-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "phonezero-grok", "displayName": "PhoneZero (Grok)", - "version": "0.4.2", + "version": "0.4.3", "description": "Grok Bot: phone skills (restaurant first). Telnyx hosted HTTP + PhoneZero xAI stdio. Edit Values for keys. Do not click Authenticate on Telnyx.", "author": { "name": "Function1st" diff --git a/plugins/phonezero-grok/commands/setup-phone-calling.md b/plugins/phonezero-grok/commands/setup-phone-calling.md index a1a21ea..3a83fd6 100644 --- a/plugins/phonezero-grok/commands/setup-phone-calling.md +++ b/plugins/phonezero-grok/commands/setup-phone-calling.md @@ -7,9 +7,10 @@ description: Grok Bot — ask name / AI disclaimer, then wire Telnyx HTTP + xAI You are a computer-use agent. Run **Grok Bot — set this up** in repo-root `AGENTS.md` (same steps in `README.md`) **in order**. Do not install Cursor PhoneZero. Do not click Authenticate. Do not take keys in chat. -After the vendor gate, **ask in chat and wait** before wiring. Do not silently keep defaults: +After the vendor gate, **ask in chat and wait** before wiring. **Always ask** the Agent Name (spoken name). Do not silently use PhoneZero. -- Spoken name (default PhoneZero) — what the callee hears +- Spoken name (required) — what the callee hears. PhoneZero is an example they may pick, not a default you apply without a reply. +- Always use that name on later calls? If yes, remember it and do not re-ask. If no, ask again before every call. - AI disclaimer ON or OFF — they may turn it OFF **Do not ask for destination countries.** Read them from Telnyx after the HTTP MCP is proven: the outbound voice profile **attached to the PhoneZero TeXML app** (any name) → `whitelisted_destinations`. `list_outbound_voice_profiles` with **no name filter**; pick the id on that TeXML app. Show the actual name + codes. That setting is Telnyx Mission Control → Voice → Outbound voice profiles. PATCH only if they ask to add or remove countries. Do not give legal advice. diff --git a/plugins/phonezero-grok/skills/phonezero-telnyx-canary/SKILL.md b/plugins/phonezero-grok/skills/phonezero-telnyx-canary/SKILL.md index 4823802..bf8b3e3 100644 --- a/plugins/phonezero-grok/skills/phonezero-telnyx-canary/SKILL.md +++ b/plugins/phonezero-grok/skills/phonezero-telnyx-canary/SKILL.md @@ -8,7 +8,7 @@ description: Grok Bot PhoneZero setup when pointed at https://github.com/functio Computer-use. Drive the UI. Do these steps **in order**. Same playbook: repo-root [README.md](../../../../README.md) and [AGENTS.md](../../../../AGENTS.md). After ids are in session: [plugins/phonezero/skills/phonezero-runtime/SKILL.md](../../../phonezero/skills/phonezero-runtime/SKILL.md) and the matching phone skill (or interview a custom `phonezero-task` — do not ask for a `SKILL.md` paste). 1. **Not** Cursor + Add. **Not** Authenticate. **Not** keys in chat. **Not** `source ~/.phonezero/env`. **Not** `scripts/provision.sh`. -2. Vendor gate, then **ask in chat and wait** — spoken name and AI disclaimer ON/OFF only. Do **not** ask for destination countries. +2. Vendor gate, then **ask in chat and wait** — Agent Name (required; do not silently use PhoneZero) and whether to always use that name, plus AI disclaimer ON/OFF. Do **not** ask for destination countries. Before every later call, ask the name again unless they said to always use one. 3. HTTP MCP: `https://api.telnyx.com/v2/mcp` + `Authorization: Bearer` in the form. Edit Values: keys + From only. Name / disclose stay in chat. 4. `list_api_endpoints` — real list or stop. “6 tools” proves nothing. There is **no** MCP tool named `whoami`. 5. If `put_task` / `put_booking` is missing: add stdio `xai` from [`plugins/phonezero/mcp.json`](../../../phonezero/mcp.json) with **real** env (not `${…}`). Then `get_call_config` + `ensure_collection`. If they said xAI is already set up, do not open the Builder. Ignore the wizard number. If they turned disclaimer OFF and Builder already exists, or the agent still searches `phonezero-booking.json`, re-paste `prompts/voice-agent.md` and `prompts/end_call.md` once. diff --git a/plugins/phonezero/.cursor-plugin/plugin.json b/plugins/phonezero/.cursor-plugin/plugin.json index 218e326..369501b 100644 --- a/plugins/phonezero/.cursor-plugin/plugin.json +++ b/plugins/phonezero/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "phonezero", "displayName": "PhoneZero", - "version": "0.4.2", + "version": "0.4.3", "description": "Phone skills for voice tasks (restaurant booking first). Need: Telnyx KYC + one US number, xAI team with ZDR off, API keys, Voice Agent Builder. Then /setup-phone-calling.", "author": { "name": "Function1st" diff --git a/plugins/phonezero/scripts/xai-mcp.mjs b/plugins/phonezero/scripts/xai-mcp.mjs index 05a0cfb..90c5161 100755 --- a/plugins/phonezero/scripts/xai-mcp.mjs +++ b/plugins/phonezero/scripts/xai-mcp.mjs @@ -808,7 +808,7 @@ async function handle(msg) { ok(id, { protocolVersion: params?.protocolVersion || "2024-11-05", capabilities: { tools: {} }, - serverInfo: { name: "phonezero-xai", version: "0.4.2" }, + serverInfo: { name: "phonezero-xai", version: "0.4.3" }, }); return; } diff --git a/plugins/phonezero/skills/book-restaurant/SKILL.md b/plugins/phonezero/skills/book-restaurant/SKILL.md index e571299..4a4b0aa 100644 --- a/plugins/phonezero/skills/book-restaurant/SKILL.md +++ b/plugins/phonezero/skills/book-restaurant/SKILL.md @@ -17,7 +17,7 @@ Read `phonezero-runtime` for Setup, preconditions, plan-first, hours hard cap, d | Restaurant-local hours when hours unknown | 10:30–20:30 restaurant-local (user TZ if unknown) | user-stated hours | | Window if they said “around 7” | propose preferred ± 30–60 min + ranked in-window slots | user-supplied window | | Calendar offer after `succeeded` | offer ~90 minutes | skip | -| Spoken name | PhoneZero | per-call (`spoken_name` in the brief) | +| Spoken name | Cursor: PhoneZero. **Grok: ask every call** unless they said always use one. | per-call (`spoken_name` in the brief) | ## Collect diff --git a/plugins/phonezero/skills/confirm-business-hours/SKILL.md b/plugins/phonezero/skills/confirm-business-hours/SKILL.md index 60d546e..674dd9f 100644 --- a/plugins/phonezero/skills/confirm-business-hours/SKILL.md +++ b/plugins/phonezero/skills/confirm-business-hours/SKILL.md @@ -16,7 +16,7 @@ Collect who to call and what we need confirmed. No OpenTable step. Hand off to [ | Callback | E.164. Default to the user's phone; confirm it. | | Expected hours (optional) | What we think the hours are, or a specific question (“open Saturday?”, “today’s holiday hours?”). | -Spoken name defaults to PhoneZero; override per call. Fail closed if there is no business or no number after one clarifying turn. +Spoken name: Cursor defaults PhoneZero; **Grok always asks** unless they said to always use one. Fail closed if there is no business or no number after one clarifying turn. ## Call plan diff --git a/plugins/phonezero/skills/phonezero-runtime/SKILL.md b/plugins/phonezero/skills/phonezero-runtime/SKILL.md index 28c46e3..5df0618 100644 --- a/plugins/phonezero/skills/phonezero-runtime/SKILL.md +++ b/plugins/phonezero/skills/phonezero-runtime/SKILL.md @@ -9,7 +9,7 @@ Shared outbound loop for every phone skill. First-party skills (`book-restaurant Destinations must be in the Telnyx outbound voice profile **attached to the PhoneZero TeXML app** (`whitelisted_destinations`, ISO 3166-1 alpha-2). Read that list via Telnyx MCP — it is **not** a PhoneZero plugin variable. The profile may have **any name** and any country list the user set. Never filter by a hardcoded name such as `PhoneZero US-only`. Never place a call to a country not on that list. Never place bulk or multi-destination calls. Never auto-dial. -**Defaults (not compliance advice).** Destinations default `US` on a new Telnyx profile. Disclose defaults on (per-task `disclose_ai`, and the one-time Builder `{disclosure_clause}`). Every call is recorded (dual-channel); the opener says so. Spoken name defaults to PhoneZero per task. Task JSON is English; after pickup the voice agent speaks the answerer’s language. The person using this sample is solely responsible for complying with all applicable laws and vendor terms — see repo [DISCLAIMER.md](../../../../DISCLAIMER.md). Do not give legal guidance in chat. +**Defaults (not compliance advice).** Destinations default `US` on a new Telnyx profile. Disclose defaults on (per-task `disclose_ai`, and the one-time Builder `{disclosure_clause}`). Every call is recorded (dual-channel); the opener says so. Spoken name: **Grok always asks** unless they said to always use one; Cursor defaults PhoneZero. Task JSON is English; after pickup the voice agent speaks the answerer’s language. The person using this sample is solely responsible for complying with all applicable laws and vendor terms — see repo [DISCLAIMER.md](../../../../DISCLAIMER.md). Do not give legal guidance in chat. **Bootstrap from repo.** `AGENTS.md` at the repo root is the hook. **Grok Bot** (pointed at `https://github.com/function1st/PhoneZero` or “set this up”): execute **Grok Bot — set this up** in `AGENTS.md` first — do not + Add the Cursor plugin. **Cursor IDE:** this file’s Setup, after the Cursor package is installed. After install or update, start a **new** conversation. @@ -27,9 +27,9 @@ Before collecting a task or touching Telnyx, verify these variables are present. | `TELNYX_ACCOUNT_SID` | **Not on the Configure card.** Telnyx MCP has **no** `whoami` tool. `invoke_api_endpoint` `list_billing_groups` → first `data[].organization_id`. Developer curl `GET /v2/whoami` is the same value. TeXML paths: `/v2/texml/Accounts/{TELNYX_ACCOUNT_SID}/…`. | | `PHONEZERO_TEXML_APP_ID` | **Not on the Configure card.** Resolve with Telnyx MCP: list TeXML apps, use the one named `PhoneZero`. | | `PHONEZERO_XAI_COLLECTION_ID` | **Not on the Configure card.** Find-or-create collection name `PhoneZero bookings`. Attach it to the Builder agent (knowledge / file search). | -| Spoken name / disclose | **Not on the Configure card.** Per-task: `spoken_name` and `disclose_ai` in `phonezero-task.json`. Default PhoneZero / true if they do not say otherwise. `{disclosure_clause}` is substituted once when pasting the Builder prompt. | +| Spoken name / disclose | **Not on the Configure card.** Per-task: `spoken_name` and `disclose_ai` in `phonezero-task.json`. **Grok:** always ask the spoken name unless they said to always use one (see §2). Cursor: default PhoneZero / true if they do not say otherwise. `{disclosure_clause}` is substituted once when pasting the Builder prompt. | -Call-time required: working Telnyx MCP, working PhoneZero xAI MCP, a From number from `get_call_config` or Telnyx list. Resolve `TELNYX_ACCOUNT_SID` and `PHONEZERO_TEXML_APP_ID` **before** the call plan — not after `put_task`. SID: `invoke_api_endpoint` `list_billing_groups` `{ "jq_filter": "[.data[].organization_id] | unique" }`. TeXML id: `invoke_api_endpoint` `list_texml_applications` `{ "filter": { "friendly_name": "PhoneZero" }, "jq_filter": ".data[] | {id, friendly_name, outbound}" }`. Destinations: that app’s `outbound.outbound_voice_profile_id`, then `invoke_api_endpoint` `list_outbound_voice_profiles` `{ "jq_filter": ".data[] | {id, name, whitelisted_destinations}" }` and pick the matching `id`. **No name filter.** Spoken name / disclose come from this call’s collect (defaults PhoneZero / true). Collection via xAI MCP `ensure_collection`. +Call-time required: working Telnyx MCP, working PhoneZero xAI MCP, a From number from `get_call_config` or Telnyx list. Resolve `TELNYX_ACCOUNT_SID` and `PHONEZERO_TEXML_APP_ID` **before** the call plan — not after `put_task`. SID: `invoke_api_endpoint` `list_billing_groups` `{ "jq_filter": "[.data[].organization_id] | unique" }`. TeXML id: `invoke_api_endpoint` `list_texml_applications` `{ "filter": { "friendly_name": "PhoneZero" }, "jq_filter": ".data[] | {id, friendly_name, outbound}" }`. Destinations: that app’s `outbound.outbound_voice_profile_id`, then `invoke_api_endpoint` `list_outbound_voice_profiles` `{ "jq_filter": ".data[] | {id, name, whitelisted_destinations}" }` and pick the matching `id`. **No name filter.** Spoken name / disclose: Grok asks the name unless they said always use one; Cursor defaults PhoneZero / true. Collection via xAI MCP `ensure_collection`. If Telnyx MCP or xAI MCP is missing / 401s, or From cannot be resolved: **stop. Do not dial.** Tell the user to re-save Plugins → Configure and start a **new** conversation, then `/setup-phone-calling`. Never paste keys in chat. Never `source ~/.phonezero/env`. An old chat not seeing new MCP tools is not a failure. @@ -37,7 +37,7 @@ Do not invent `{TELNYX_ACCOUNT_SID}`. ## Setup (when the user says *Set up phone calling* or runs `/setup-phone-calling`) -Human/developer mirrors: `docs/SETUP.md`, and `scripts/provision.sh` — developer-only, run on a personal machine that may hold keys, never on this computer. Never `source ~/.phonezero/env`. Telnyx account + KYC + buying the DID stay manual. Telnyx API steps go through the Telnyx MCP. xAI Files / collections / STT / phone-numbers go through the PhoneZero xAI MCP on **both** hosts. **Grok Bot:** add that stdio `xai` server if `put_task` / `put_booking` is missing (`AGENTS.md` / README). REST on `api.x.ai` is fallback only. Do not take the key from chat. **Grok must ask** spoken name and AI disclaimer ON/OFF — do not silently keep PhoneZero / true. Destination countries are the Telnyx profile whitelist; read and show them, do not ask as a PhoneZero field. +Human/developer mirrors: `docs/SETUP.md`, and `scripts/provision.sh` — developer-only, run on a personal machine that may hold keys, never on this computer. Never `source ~/.phonezero/env`. Telnyx account + KYC + buying the DID stay manual. Telnyx API steps go through the Telnyx MCP. xAI Files / collections / STT / phone-numbers go through the PhoneZero xAI MCP on **both** hosts. **Grok Bot:** add that stdio `xai` server if `put_task` / `put_booking` is missing (`AGENTS.md` / README). REST on `api.x.ai` is fallback only. Do not take the key from chat. **Grok must ask** the Agent Name (spoken name) and wait — do not silently keep PhoneZero. Skip that question only if they already said to always use a specific name. Also ask AI disclaimer ON/OFF. Destination countries are the Telnyx profile whitelist; read and show them, do not ask as a PhoneZero field. **First message, before any API call:** @@ -63,7 +63,7 @@ If any of those are missing, **stop**. - Fallback (no plugin, Cursor IDE): `"telnyx": {"command":"npx","args":["-y","@telnyx/mcp"],"env":{"TELNYX_API_KEY":"${env:TELNYX_API_KEY}"}}`. Never the literal key in the file or chat. - **Verify with a `tools/call`, never the tool count.** Call `list_api_endpoints`. If `get_call_config.from_wired` is false, take From from Telnyx `list_phone_numbers` (PhoneZero TeXML DID). -**Keys first.** Required on the Configure card: `TELNYX_API_KEY`, `PHONEZERO_FROM_NUMBER`, `XAI_API_KEY`. Spoken name and disclose are **not** on the card — ask in chat (Grok: the `AGENTS.md` call-settings card; Cursor: per task, default PhoneZero / true) and write them into `phonezero-task.json`. Destinations are **not** on the card. Read destinations from Telnyx (the profile attached to the PhoneZero TeXML app → `whitelisted_destinations`) and show the **actual profile name** plus the codes. PATCH that profile only if they ask to add/remove countries (Mission Control → Voice → Outbound voice profiles is the same setting). Account SID, TeXML app id, and collection id are **not** on the card. If Telnyx MCP or the PhoneZero xAI MCP is unwired, send the user to Plugins → Configure and a **new** conversation. Then, field-for-field: +**Keys first.** Required on the Configure card: `TELNYX_API_KEY`, `PHONEZERO_FROM_NUMBER`, `XAI_API_KEY`. Spoken name and disclose are **not** on the card — ask in chat (Grok: always ask the Agent Name unless they said to always use one; Cursor: per task, default PhoneZero / true) and write them into `phonezero-task.json`. Destinations are **not** on the card. Read destinations from Telnyx (the profile attached to the PhoneZero TeXML app → `whitelisted_destinations`) and show the **actual profile name** plus the codes. PATCH that profile only if they ask to add/remove countries (Mission Control → Voice → Outbound voice profiles is the same setting). Account SID, TeXML app id, and collection id are **not** on the card. If Telnyx MCP or the PhoneZero xAI MCP is unwired, send the user to Plugins → Configure and a **new** conversation. Then, field-for-field: 1. `TELNYX_ACCOUNT_SID` via Telnyx MCP `invoke_api_endpoint` `list_billing_groups` (`data[].organization_id`). Do not search the catalog for `whoami`. 2. Outbound voice profile — **do not require a specific name.** Resolve in this order: (a) the profile already attached to the PhoneZero TeXML app (`outbound.outbound_voice_profile_id`); (b) if they have exactly one outbound voice profile, use it; (c) if they have several, list `{id, name, whitelisted_destinations}` and ask which to attach; (d) if they have none, create one. Create defaults: name `PhoneZero` unless they pick another, `traffic_type=conversational`, `service_plan=global`, `usage_payment_method=rate-deck`, `whitelisted_destinations` default `["US"]` **on create only**, `daily_spend_limit="5.00"`, `daily_spend_limit_enabled=true` (`POST /v2/outbound_voice_profiles`; any other combo → Telnyx error 10015). **This Telnyx profile is the destination enforcement** — Telnyx rejects calls outside `whitelisted_destinations`. Keep an existing whitelist and name. `PATCH` only when the user asks to add or remove countries. They may name the profile anything and set any region list in Telnyx Mission Control → Voice → Outbound voice profiles. @@ -96,6 +96,8 @@ Match the user ask: Do not dial until the bound skill (or ad-hoc interview) has every required field. Fail closed after one clarifying turn if the task stays vague. +**Grok Bot — spoken name.** Always ask what Agent Name the callee should hear (`spoken_name`). Wait for a reply. Do **not** silently use PhoneZero or any leftover default. PhoneZero is an example they may choose, not a name you apply without asking. **Exception:** if they have already instructed you to **always use the same name** (this chat, or Grok memory), reuse it, show it as Spoken as on the plan, and do not re-ask unless they change it. A one-call name does not stick — ask again next call. If they say “always use {name},” keep it in session and write it to Grok memory when the host has it. Not a Configure / Edit Values field. Cursor IDE may still default to PhoneZero. + ## 3. Plan-first confirmation Present the plan in chat. Do not dial in the same turn as the plan. Use the skill’s plan template if it has one; otherwise: @@ -165,7 +167,7 @@ Envelope (no extra top-level keys except `kind`): } ``` -`disclose_ai` defaults true unless they turned it off for this call (or at setup, for the Builder paste). `{agent_name}` is this call's spoken name (default PhoneZero). Keep `playbook` short — collection search truncates. +`disclose_ai` defaults true unless they turned it off for this call (or at setup, for the Builder paste). `{agent_name}` is this call's spoken name (Grok: they answered, or the always-use name; Cursor: default PhoneZero). Keep `playbook` short — collection search truncates. **Both hosts:** PhoneZero xAI MCP `put_task` (or `put_booking` alias). **Grok Bot:** if those tools are missing, add stdio `xai` from `plugins/phonezero/mcp.json` (secure-field env, not `${…}`) — do not say upload is impossible. Fallback: `https://api.x.ai/v1` Bearer; sequence is `putTask` / `putBooking` in `scripts/xai-mcp.mjs`. Never echo the key. If the user said xAI is already set up, do not open the Builder. @@ -316,7 +318,7 @@ Do **not** ask them to paste a `SKILL.md`, clone a gist, or write a skill folder | What must a **live person** say before we call this a win? | `success` | | What to leave on voicemail | `voicemail` | | Any extra facts | `facts` | -| Spoken name override | `spoken_name` | +| Spoken name (Grok: always ask unless they said always use one) | `spoken_name` | 4. Same safety as shipped skills. Show the JSON in the call plan. Dial only on yes. Classify with §8 + this brief’s `success` / `constraints`. 5. Do not open the Builder. The JSON is the shape of the call. @@ -337,6 +339,7 @@ Cursor may save a template as a local skill folder when they ask. That is not th ## Hard rules - No call without §1 call-time variables, a complete collect (skill or ad-hoc), an hours check, and an explicit yes to the current plan. +- Grok Bot: no call plan until they have answered the Agent Name, unless they already said to always use a specific name. - No `succeeded` / `booked` unless all five gates in §8 hold. - No secrets, no keys in chat, no non-fixture numbers written into skills or examples. - One callee, one task, max two attempts, 20 minutes apart.