Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 173 additions & 5 deletions skills/calle/SKILL.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions skills/calle/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "calle"
short_description: "CALL-E phone calls through MCP or API Key"
default_prompt: "Use $calle to prepare a CALL-E phone call through MCP or API Key access."
28 changes: 28 additions & 0 deletions skills/calle/assets/hello-call.request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"phone": "<AUTHORIZED_E164_PHONE>",
"task": "Use English. Identify yourself as an AI assistant making an authorized connection test. Ask whether the recipient can hear you clearly, allow a brief reply, and politely end the call. Do not ask for personal or financial information. Set heard_test to yes only for an explicit confirmation, no only for an explicit negative answer, and unknown when there is no clear answer. Provide a brief factual summary; do not infer an answer from silence.",
"result_schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"heard_test": {
"type": "string",
"enum": [
"yes",
"no",
"unknown"
]
},
"summary": {
"type": "string"
}
},
"required": [
"heard_test",
"summary"
]
},
"metadata": {
"test_case": "skill-api-smoke-v1"
}
}
33 changes: 33 additions & 0 deletions skills/calle/assets/read-only.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# HTTP request templates, not terminal commands or previously executed requests.
# {{...}} marks placeholders; variable substitution syntax depends on the HTTP tool.
# Bind credentials only in the host's secure configuration. Never put a real key here.
# Fixed production API; no base URL variable or environment selection is required.

# Default read-only entry: this file contains only GET requests; offline checks do not execute them.
# Later network access requires separate authorization. Select only the needed request and never guess IDs.

### 1. Read-only authentication check without dialing
GET https://api.heycall-e.com/v1/goals?limit=1
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json

### 2. List visible Goals; use next_cursor as after for pagination
GET https://api.heycall-e.com/v1/goals?limit=20
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json

### 3. Read a known Goal without creating a Run
GET https://api.heycall-e.com/v1/goals/{{GOAL_ID}}
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json

### 5. Read a resource; CALL_RESOURCE_ID is the creation response's id, not the billing call_id
GET https://api.heycall-e.com/v2/calls/{{CALL_RESOURCE_ID}}
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json

### 6. Read events; use the corresponding cursor for the next page
GET https://api.heycall-e.com/v2/calls/{{CALL_RESOURCE_ID}}/events?limit=20
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json

56 changes: 56 additions & 0 deletions skills/calle/assets/tool-map.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"template_notice": "This is a local diagnostic template, not a host configuration or an observed tools/list response.",
"server_url": "https://seleven-mcp-sg.airudder.com/mcp/openagent_oauth",
"authentication_expected": "oauth",
"authentication_source": "user-provided",
"observed_at": null,
"host_name": null,
"connection_verified": false,
"discovery_method": null,
"discovery_completeness": "unknown",
"read_only_check": {
"performed": false,
"actual_tool_name": null,
"outcome": null
},
"tools": [],
"tool_entry_fields": [
"actual_tool_name",
"description",
"input_schema",
"output_schema_if_present",
"annotations_if_present",
"observed_side_effect_semantics"
],
"capability_candidates": {
"read_account_or_tasks": {
"status": "unverified",
"actual_tool_names": []
},
"prepare_call": {
"status": "unverified",
"actual_tool_names": []
},
"create_or_execute_call": {
"status": "unverified",
"actual_tool_names": []
},
"read_call_state_or_result": {
"status": "unverified",
"actual_tool_names": []
},
"read_transcript": {
"status": "unverified",
"actual_tool_names": []
},
"cancel_call": {
"status": "unverified",
"actual_tool_names": []
}
},
"notes": [
"Never store OAuth tokens or API keys here.",
"Do not mark unavailable based only on partial discovery.",
"No tool name in this template is claimed to exist."
]
}
50 changes: 50 additions & 0 deletions skills/calle/assets/write-requests.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Side effects: creation may place a real, billable call; cancellation changes state.
# Each operation needs explicit, specific authorization. Never execute all requests.
# Creation does not authorize cancellation or vice versa. Persist the original body/key before creation; send only the authorized request.
# HTTP request templates, not terminal commands or previously executed requests.
# {{...}} marks placeholders; variable substitution syntax depends on the HTTP tool.
# Bind credentials only in the host's secure configuration. Never put a real key here.
# Fixed production API; no base URL variable or environment selection is required.


### 4. Side effect: send only after this call is authorized and the original body/key are persisted
# Generate and persist {{IDEMPOTENCY_KEY}} once per logical call; keep it unchanged on retries.
POST https://api.heycall-e.com/v2/calls
Authorization: Bearer {{CALLE_API_KEY}}
Content-Type: application/json
Accept: application/json
Idempotency-Key: {{IDEMPOTENCY_KEY}}

{
"phone": "<AUTHORIZED_E164_PHONE>",
"task": "Use English. Identify yourself as an AI assistant making an authorized connection test. Ask whether the recipient can hear you clearly, allow a brief reply, and politely end the call. Do not ask for personal or financial information. Set heard_test to yes only for an explicit confirmation, no only for an explicit negative answer, and unknown when there is no clear answer. Provide a brief factual summary; do not infer an answer from silence.",
"result_schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"heard_test": {
"type": "string",
"enum": [
"yes",
"no",
"unknown"
]
},
"summary": {
"type": "string"
}
},
"required": [
"heard_test",
"summary"
]
},
"metadata": {
"test_case": "skill-api-smoke-v1"
}
}

### 7. Side effect: send only when the user explicitly requests cancellation of the specified call
POST https://api.heycall-e.com/v2/calls/{{CALL_RESOURCE_ID}}/cancel
Authorization: Bearer {{CALLE_API_KEY}}
Accept: application/json
71 changes: 71 additions & 0 deletions skills/calle/references/api-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# CALL-E core HTTP contract

Reviewed on 2026-10-13. Scope: Calls v2 and read-only Goals v1, not the complete Developer API. See the official [Calls API Reference](https://docs.heycall-e.com/api-reference/calls) for more detailed fields.

## Endpoints

| Method | Path | Purpose | Side effects |
| --- | --- | --- | --- |
| GET | /v1/goals?limit=1 | Minimal access check | Read |
| GET | /v1/goals | List published Goals visible to the current owner | Read |
| GET | /v1/goals/{goal_id} | Read the specified published interface | Read |
| POST | /v2/calls | Immediately create one call | May place a real call and incur charges |
| GET | /v2/calls/{call_id} | Query Call status, results, and transcript | Read |
| GET | /v2/calls/{call_id}/events | Query a JSON page of persisted events | Read |
| POST | /v2/calls/{call_id}/cancel | Attempt cancellation before provider submission | State change |

Every path requires an API Key. The Goals list accepts `limit` from 1 to 100; read pagination values from `next_cursor` and pass the next page's query parameter as `after`. Do not derive a cursor from a Goal ID. An empty list does not mean authentication failed; never blindly select and execute the first Goal.

## Example create request

This example is for preparation only. It contains an explicit, non-dialable placeholder and must not be sent unchanged.

```json
{
"phone": "<AUTHORIZED_E164_PHONE>",
"task": "Use English. Identify yourself as an AI assistant making an authorized connection test. Ask whether the recipient can hear you clearly, allow a brief reply, and politely end the call. Do not ask for personal or financial information. Set heard_test to yes only for an explicit confirmation, no only for an explicit negative answer, and unknown when there is no clear answer. Provide a brief factual summary; do not infer an answer from silence.",
"result_schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"heard_test": {"type": "string", "enum": ["yes", "no", "unknown"]},
"summary": {"type": "string"}
},
"required": ["heard_test", "summary"]
},
"metadata": {"test_case": "skill-api-smoke-v1"}
}
```

This package defines the test script; it is not a verbatim official example. The user may change the language. Check regional coverage, lines, and supported languages against the actual account and official Regions documentation. Do not silently change the requested call language because the conversation uses Chinese.

Every intentional new call needs a new logical operation record and idempotency key; `metadata.test_case` is not an idempotency mechanism. Fields such as region and locale omitted from the original body must remain omitted in recovery requests.

## Responses and identifiers

A successful create is supported by HTTP 202 and the actual response. Save `id`, the API resource identifier. The separate top-level `call_id` is a Billing correlation identifier and may be null; it must not replace the resource ID.

The bundled OpenAPI uses permissive response objects describing only reviewed core fields. It does not incorrectly require every illustrative field or invent real account responses.

`result_status` determines whether to keep waiting. `pending` can coexist with completed execution; an `available` result may be `{}`; `unavailable` may have both result=null and error=null; `not_applicable` covers situations with no applicable business result. Do not replace explicit status checks with truthiness checks such as `if result`.

## Events

GET events supports `limit` (1-100, server default 50) and `cursor`. Use the returned `next_cursor` to read existing pages. After the final page, retain the last returned event's `id` as the cursor for later polling. An empty page must not clear a saved cursor. Event IDs belong to an individual Call; deduplicate by ID.

Events are JSON pages, not SSE. `call.asr` may contain partial or revised recognition fragments. Prefer the Call's top-level transcript for the final conversation; do not simply concatenate all recognition events.

## Error decisions

| Situation | Skill action |
| --- | --- |
| 401 / 403 | Check credentials/permissions and stop blind retries. |
| 400 result_schema_invalid | This is an explicit input rejection; correct the schema before resubmitting. |
| 422 input_incomplete | Show missing_inputs and obtain the missing facts; this request did not create a Call. |
| 422 unsupported_region / unsupported_language | Check and correct the user's intended settings against the supported range; do not silently change region/language. |
| 409 + creation_in_progress | Preserve the body/key and retry a bounded number of times after backoff. |
| Other idempotency_conflict | Recover the original body/identity first; do not automatically change the key. |
| 429 / 503 / network timeout / unexpected response | Follow the actual error and retry guidance; preserve the original body/key for uncertain creation and do not infer that no call was placed. |
| cancel returns call_cannot_cancel | Do not claim cancellation succeeded or the call hung up. |

Calls v2 recovery rules do not apply to legacy `/v1/calls` or MCP tools.
Loading
Loading