← ElevenLabsCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to ElevenLabs
Snapshot Sep 30, 2026 · 22:53 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "code-tools",
"description": "Generate JavaScript/TypeScript modules for ElevenLabs code tools — sandbox tools that export a default async (ctx) => function, call APIs via fetch with ctx.secrets / ctx.config / ctx.auth_connections, and return a minimized result to the agent. Use when the user says 'write a code tool', 'code tools', 'ElevenLabs code tool', 'create a code tool', 'egress with auth connection', 'code tool allowed domains', 'X-With-Auth-Connection', or pastes a brief for custom JS/TS tool logic that should run on ElevenLabs infrastructure.",
"included_files": [
{
"relative_path": "README.md",
"size_in_bytes": 5083
},
{
"relative_path": "ctx.example.json",
"size_in_bytes": 76
},
{
"relative_path": "examples.md",
"size_in_bytes": 6291
},
{
"relative_path": "local-executor.mjs",
"size_in_bytes": 4231
}
],
"skill_md_contents": "---\nname: code-tools\ndescription: \"Generate JavaScript/TypeScript modules for ElevenLabs code tools — sandbox tools that export a default async (ctx) => function, call APIs via fetch with ctx.secrets / ctx.config / ctx.auth_connections, and return a minimized result to the agent. Use when the user says 'write a code tool', 'code tools', 'ElevenLabs code tool', 'create a code tool', 'egress with auth connection', 'code tool allowed domains', 'X-With-Auth-Connection', or pastes a brief for custom JS/TS tool logic that should run on ElevenLabs infrastructure.\"\n---\n\n# ElevenLabs Code Tools\n\nGenerate paste-ready JS/TS for ElevenLabs **code tools**: custom logic that runs on ElevenLabs infrastructure, not a customer webhook.\n\n## Canonical runtime model\n\nYour code is a single JavaScript/TypeScript module that exports one default async function. It receives a `ctx` object and returns the tool result (same downstream uses as a server tool response: agent, transcript, dynamic variables).\n\n```ts\nexport default async (ctx) => {\n const { city } = ctx.args;\n return { message: `Hello from ${city}!` };\n};\n```\n\nHelpers and top-level variables outside the default export are fine.\n\n### `ctx` API (use these names only)\n\n| Property | Description |\n|---|---|\n| `ctx.args.<paramName>` | Tool-call parameters from the LLM, already typed (string, number, boolean, object). |\n| `ctx.secrets.<NAME>` | Workspace secret mapped into this tool's Context object. |\n| `ctx.config.<NAME>` | Plain string env/config value mapped into Context. |\n| `ctx.auth_connections.<NAME>` | Auth-connection reference. Pass as the `X-With-Auth-Connection` header on outbound `fetch`; ElevenLabs attaches the credential — the raw secret never enters your code. |\n\nWhich secrets, auth connections, and config values appear under `ctx` (and under what name) is configured in the tool's **Context object** section in the studio — same idea as headers/params on a webhook tool.\n\n### Naming gotchas (do not emit)\n\n| Wrong | Right |\n|---|---|\n| `ctx.pargs` | `ctx.args` |\n| `ctx.authConnections` | `ctx.auth_connections` |\n\n### Hard constraints\n\n- **No npm packages.** Built-in JavaScript + Web APIs only (`fetch`, `Promise`, `setTimeout`, `JSON`, `URL`, `encodeURIComponent`, etc.). No `import` from external packages.\n- **Network allowlist.** Outbound requests only succeed for domains listed under the agent's **General Settings → Code tool allowed domains** (wildcards like `*.example.com` OK). Only workspace **admins** can add domains — flag that if the user is not an admin.\n- **Timeout.** Each run must finish within the tool's response timeout (**1–30 seconds**). Cap any poll loops so total wait fits under that budget.\n- **Return value = LLM context.** Everything you return is read by the model. Project to the few fields the agent needs — never dump full DB rows, internal notes, risk scores, audit logs, or other PII/internal fields.\n- **Auth.** API keys → `ctx.secrets`. Plain URLs/base strings → `ctx.config`. OAuth / managed credentials → `ctx.auth_connections` + `\"X-With-Auth-Connection\"` header. Never hardcode secrets or put raw OAuth tokens in code.\n- **Errors.** Both a structured return and a throw \"work\" — the difference is control. A structured `{ error: \"...\" }` return is always visible to the agent; `throw new Error(...)` lets you decide whether the failure reason surfaces to the LLM at all. Prefer structured returns for expected failures (not found, bad input); throw for unexpected upstream failures where a loud transcript failure helps debugging. Either way, try/catch and return or throw something meaningful. Best-effort side effects (logging) should swallow errors so they never break the tool.\n\n## Intake\n\nAsk only for what's missing:\n\n1. **Tool name** + one-line purpose\n2. **Parameters** (name, type, description) the LLM will fill → become `ctx.args`\n3. **Upstream APIs / domains** to call\n4. **Auth style** — secret vs auth connection vs plain config — and suggested Context object names\n5. **Return shape** — fields the agent should see\n\nIf the brief is already complete, skip questions and generate.\n\n## Output template (always)\n\nProduce all six sections every time:\n\n### 1. Code\n\nComplete default-export module ready to paste into the studio code editor.\n\n### 2. Parameters\n\nTable for Setup params UI:\n\n| Name | Type | Description |\n|---|---|---|\n| … | string / number / boolean / … | … |\n\n### 3. Context object mapping\n\n| `ctx` path | Kind | Maps to |\n|---|---|---|\n| `ctx.secrets.EXAMPLE_API_KEY` | secret | workspace secret … |\n| `ctx.config.SUPABASE_URL` | value | literal / config string … |\n| `ctx.auth_connections.EXAMPLE_CRM` | auth connection | configured connection … |\n\n### 4. Allowed domains checklist\n\nExact hostnames or wildcards an admin must add under **General Settings → Code tool allowed domains**. Call out that only admins can edit this list.\n\n### 5. Run-in-editor test plan\n\n- Sample **Params** values\n- Expected **Output**\n- Optional: `console.log(ctx)` / specific fields if debugging\n\n### 6. Agent-facing notes\n\nOne short tool description / trigger guidance for when the LLM should call this tool.\n\n## Generation patterns\n\nKeep recipes short here; full sources live in [examples.md](examples.md). Read that file when implementing a matching pattern.\n\n1. **Field-minimizing REST lookup** — fetch a rich row; return only agent-safe fields.\n2. **Parallel fan-out** — independent calls via `Promise.all`.\n3. **Bounded poll / long-running job** — start work, poll with capped attempts + delay; return `still_*` + id if not done.\n4. **Best-effort side-effect via auth connection** — `X-With-Auth-Connection`; try/catch so logging never fails the tool.\n5. **Secret-based API key call** — `Authorization` / `apikey` from `ctx.secrets`.\n\n## Anti-patterns (reject or fix)\n\n- Returning entire upstream JSON blobs — return only the fields strictly necessary for the agent; if it's genuinely unclear which fields matter, returning the rest of the object is fine (sometimes that's the intended behavior), but PII/internal fields (notes, risk scores, audit logs) still must never be returned, per the hard constraint above\n- Hardcoding secrets or base URLs that belong in Context\n- Calling domains without listing them in the Allowed domains checklist\n- Polling without attempt/time caps relative to the 30s ceiling\n- Putting real OAuth tokens in code instead of `X-With-Auth-Connection`\n- Adding npm `import`s\n- Using `ctx.pargs` or `ctx.authConnections`\n\n## Minimal egress example (secret)\n\n```ts\nexport default async (ctx) => {\n const orderId = String(ctx.args?.order_id ?? \"\").trim();\n if (!orderId) return { error: \"order_id is required\" };\n\n const response = await fetch(\n `https://api.example.com/orders/${encodeURIComponent(orderId)}`,\n {\n headers: {\n Authorization: `Bearer ${ctx.secrets.EXAMPLE_API_KEY}`,\n },\n },\n );\n\n if (!response.ok) {\n throw new Error(`Upstream error: ${response.status}`);\n }\n\n const order = await response.json();\n return { orderId: order.id, status: order.status };\n};\n```\n\nMap `EXAMPLE_API_KEY` in Context; allowlist `api.example.com`. Return only the fields the agent needs.\n\n## Minimal OAuth / auth-connection example\n\n```ts\nexport default async (ctx) => {\n const customerId = String(ctx.args?.customer_id ?? \"\").trim();\n if (!customerId) return { error: \"customer_id is required\" };\n\n const response = await fetch(\n `https://api.example.com/customers/${encodeURIComponent(customerId)}`,\n {\n headers: {\n \"X-With-Auth-Connection\": ctx.auth_connections.EXAMPLE_CRM,\n },\n },\n );\n\n if (!response.ok) {\n throw new Error(`Upstream error: ${response.status}`);\n }\n\n const customer = await response.json();\n return { customerId: customer.id, name: customer.name };\n};\n```\n\nMap `EXAMPLE_CRM` to a configured auth connection in Context. Return only the fields the agent needs.\n\n## Testing reminder\n\nBefore saving in the studio, use **Run** in the code editor:\n\n- **Params** — test values for each defined parameter\n- **Output** — returned result or error\n- **Logs** — `console.log` / `warn` / `error`, plus build and execution timing\n\nOptional pre-studio check: `node local-executor.mjs <tool-file> <ctx.json>` (see [README.md](README.md#run-locally-before-pasting-into-the-studio)) runs the module locally against a mocked `ctx`, enforcing the same 1–30s timeout.\n"
}SHA-256: a72b5344f1628b3b7c02cf6f039ac35cfca663ea1d1582672e540aa11cd89f22