From b5bddae16274a727fae2610b416ac4d8ea1c1f55 Mon Sep 17 00:00:00 2001 From: august l-r Date: Wed, 22 Apr 2026 14:07:50 +0000 Subject: [PATCH 01/21] initial update --- .../agents/agent-base/add-skill-by-name.mdx | 36 +++++ .../agents/agent-base/add-skill.mdx | 11 +- .../agent-base/auto-map-sip-usernames.mdx | 13 ++ .../agent-base/clear-swaig-query-params.mdx | 12 ++ .../agents/agent-base/enable-debug-routes.mdx | 13 ++ .../agents/agent-base/get-prompt-pom.mdx | 14 ++ .../typescript/agents/agent-base/index.mdx | 36 +++++ .../agent-base/remove-skill-by-name.mdx | 19 +++ .../agents/agent-base/reset-contexts.mdx | 17 +++ .../agent-base/set-function-includes.mdx | 21 +++ .../agent-base/set-internal-fillers.mdx | 33 +++++ .../agents/agent-base/set-prompt-pom.mdx | 19 +++ .../agents/agent-base/set-pronunciations.mdx | 23 ++++ .../agents/agent-base/validate-tool-token.mdx | 28 ++++ .../agents/context-builder/context/index.mdx | 3 + .../context/set-initial-step.mdx | 38 ++++++ .../agents/context-builder/index.mdx | 3 + .../agents/context-builder/reset.mdx | 29 ++++ .../agents/livewire/agent-session/say.mdx | 7 + .../agents/livewire/agent/index.mdx | 79 ++++++++--- .../agents/prefabs/concierge-agent.mdx | 100 ++++++-------- .../agents/prefabs/faq-bot-agent.mdx | 22 ++- .../agents/prefabs/info-gatherer-agent.mdx | 127 ++++++++++-------- .../agents/prefabs/receptionist-agent.mdx | 79 +++++------ .../agents/prefabs/survey-agent.mdx | 35 ++++- .../agents/skill-base/get-data-map-tools.mdx | 43 ++++++ .../agents/skill-base/get-hints.mdx | 19 +-- .../skill-base/get-parameter-schema.mdx | 17 +-- .../agents/skill-base/get-prompt-sections.mdx | 17 +-- .../agents/skill-base/get-tools.mdx | 68 ++++++++++ .../typescript/agents/skill-base/index.mdx | 120 +++++++++++------ .../typescript/agents/skill-base/setup.mdx | 32 +++-- .../agents/skill-manager/add-skill.mdx | 30 ++++- .../agents/skill-manager/has-skill-by-key.mdx | 19 +++ .../typescript/agents/skill-manager/index.mdx | 16 ++- .../agents/skill-manager/list-skill-keys.mdx | 12 ++ .../skill-manager/load-skill-by-name.mdx | 35 +++++ .../agents/skill-manager/load-skill.mdx | 37 +++++ .../agents/skill-registry/get-manifest.mdx | 17 --- .../agents/skill-registry/index.mdx | 17 +-- .../list-registered-with-manifests.mdx | 15 --- .../agents/skill-registry/register.mdx | 40 ++++-- .../agents/skills/datasphere-serverless.mdx | 79 +++++++---- .../typescript/agents/skills/datasphere.mdx | 73 +++++++--- .../typescript/agents/skills/index.mdx | 25 ++-- .../agents/skills/info-gatherer.mdx | 69 +++++----- .../typescript/agents/skills/mcp-gateway.mdx | 80 ++++++++--- .../agents/skills/native-vector-search.mdx | 113 ++++++++++++---- .../typescript/agents/skills/spider.mdx | 81 +++++++++-- .../agents/skills/swml-transfer.mdx | 96 ++++++++++--- .../typescript/agents/skills/web-search.mdx | 59 ++++++-- .../agents/skills/wikipedia-search.mdx | 24 ++-- .../typescript/rest/phone-numbers/index.mdx | 7 + .../reference/typescript/rest/rest-error.mdx | 8 +- .../products/server-sdks/sdk-source-sync.json | 4 +- fern/products/server-sdks/server-sdks.yml | 73 +++++----- 56 files changed, 1597 insertions(+), 565 deletions(-) create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill-by-name.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-data-map-tools.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-tools.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/has-skill-by-key.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/list-skill-keys.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill-by-name.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill.mdx delete mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-manifest.mdx delete mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-registered-with-manifests.mdx diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill-by-name.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill-by-name.mdx new file mode 100644 index 000000000..bb5174e74 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill-by-name.mdx @@ -0,0 +1,36 @@ +--- +title: "addSkillByName" +slug: /reference/typescript/agents/agent-base/add-skill-by-name +description: Look up a skill class in the global registry and add it by name. +max-toc-depth: 3 +--- + +[ref-registry]: /docs/server-sdks/reference/typescript/agents/skill-registry +[ref-addskill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill + +Look up a skill class by name in the global +[`SkillRegistry`][ref-registry], instantiate it, and add it to the agent via +[`addSkill`][ref-addskill]. Fails closed like `addSkill`. + +## **Parameters** + + + Registered skill name (read from the target class's `SKILL_NAME`). + + + + Optional configuration forwarded to the skill constructor. + + +## **Returns** + +`Promise` — the agent for method chaining. + +## **Example** + +```typescript {3} +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +agent.setPromptText('You are a helpful assistant.'); +await agent.addSkillByName('datetime'); +await agent.addSkillByName('web_search', { num_results: 3 }); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill.mdx index 658f6b3e3..a8cfa5911 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-skill.mdx @@ -15,8 +15,15 @@ takes a `SkillBase` instance (not a string name). This is an `async` method that returns `Promise`. Use `await` when calling. -Throws `Error` if a duplicate non-multi-instance skill is added. Check available -skills with [`listSkills()`][list-skills] or consult the [skills catalog][skills-catalog]. + +`addSkill()` **fails closed**: it throws if a duplicate non-multi-instance +skill is added, if required environment variables or packages are missing, +if the skill's parameter schema is empty, or if the skill's `setup()` +returns `false`. The method also registers any DataMap-style tools the +skill exposes via `getDataMapTools()`. + +Check available skills with [`listSkills()`][list-skills] or consult the +[skills catalog][skills-catalog]. ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx new file mode 100644 index 000000000..4b45ca454 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx @@ -0,0 +1,13 @@ +--- +title: "autoMapSipUsernames" +slug: /reference/typescript/agents/agent-base/auto-map-sip-usernames +description: Auto-register the agent's route as the default SIP username target. +max-toc-depth: 3 +--- + +Auto-register the agent's route as the default SIP username routing target. +Port of Python's `auto_map_sip_usernames()`. + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx new file mode 100644 index 000000000..f07743a17 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx @@ -0,0 +1,12 @@ +--- +title: "clearSwaigQueryParams" +slug: /reference/typescript/agents/agent-base/clear-swaig-query-params +description: Remove every SWAIG query-param override set on the agent. +max-toc-depth: 3 +--- + +Remove every SWAIG query-param override set via `addSwaigQueryParams`. + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx new file mode 100644 index 000000000..42c80ffe5 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx @@ -0,0 +1,13 @@ +--- +title: "enableDebugRoutes" +slug: /reference/typescript/agents/agent-base/enable-debug-routes +description: Expose the agent's debug HTTP endpoints. +max-toc-depth: 3 +--- + +Expose the agent's debug HTTP endpoints on the Hono server. Use in +development to inspect live state; avoid in production. + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx new file mode 100644 index 000000000..d33f791c1 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx @@ -0,0 +1,14 @@ +--- +title: "getPromptPom" +slug: /reference/typescript/agents/agent-base/get-prompt-pom +description: Return the current prompt as a POM (Prompt Object Model) array. +max-toc-depth: 3 +--- + +Return the current prompt as a POM (Prompt Object Model) array — the +structured, section-based representation. Returns `null` when the agent is +configured with a raw text prompt (`usePom: false`). + +## **Returns** + +`Record[] | null` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx index 8a69a8cc5..36a689ba3 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx @@ -245,6 +245,42 @@ await agent.run(); Load and activate a skill on the agent. + + Look up a skill class in the global registry and add it by name. + + + Remove every skill instance matching a given name. + + + Clear every context from the agent's ContextBuilder. + + + Return the current POM-structured prompt. + + + Replace the prompt with the supplied POM array. + + + Replace every pronunciation rule in a single call. + + + Set every internal-filler entry in one call. + + + Replace the SWAIG function-includes list. + + + Auto-register the agent's route as the SIP username target. + + + Validate a per-tool HMAC token. + + + Remove every SWAIG query-param override. + + + Expose the agent's debug HTTP endpoints. + Append query parameters to all SWAIG webhook URLs. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx new file mode 100644 index 000000000..9df8bc28b --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx @@ -0,0 +1,19 @@ +--- +title: "removeSkillByName" +slug: /reference/typescript/agents/agent-base/remove-skill-by-name +description: Remove every skill instance matching a given skill name. +max-toc-depth: 3 +--- + +Remove every skill instance whose `skillName` matches the given name. +`cleanup()` is invoked on each instance before removal. + +## **Parameters** + + + Skill name to match. + + +## **Returns** + +`Promise` — `true` if at least one instance was removed. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx new file mode 100644 index 000000000..6dd42bb9d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx @@ -0,0 +1,17 @@ +--- +title: "resetContexts" +slug: /reference/typescript/agents/agent-base/reset-contexts +description: Clear every context defined on this agent's ContextBuilder. +max-toc-depth: 3 +--- + +[ref-ctxbuilder]: /docs/server-sdks/reference/typescript/agents/context-builder + +Remove every context defined on this agent's internal +[`ContextBuilder`][ref-ctxbuilder], returning the builder to its initial +state. Use this inside a dynamic-config callback to rebuild contexts per +request. + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx new file mode 100644 index 000000000..7413dcca9 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx @@ -0,0 +1,21 @@ +--- +title: "setFunctionIncludes" +slug: /reference/typescript/agents/agent-base/set-function-includes +description: Replace the agent's SWAIG function-includes list. +max-toc-depth: 3 +--- + +[ref-add-include]: /docs/server-sdks/reference/typescript/agents/agent-base/add-function-include + +Replace the agent's SWAIG function-includes list in one call. Use +[`addFunctionInclude`][ref-add-include] to append a single include instead. + +## **Parameters** + + + Ordered list of function-include entries. + + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx new file mode 100644 index 000000000..5b9330e24 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx @@ -0,0 +1,33 @@ +--- +title: "setInternalFillers" +slug: /reference/typescript/agents/agent-base/set-internal-fillers +description: Set every internal-filler entry in one call. +max-toc-depth: 3 +--- + +Set every internal-filler entry on the agent in one call. Unknown filler +names (not in the SWML schema's supported set) are rejected with a warning. + +## **Parameters** + +>"} required={true} toc={true}> + Outer key: filler name (e.g. `"pre_speech"`). Inner key: language code + (e.g. `"en-US"`). Value: array of filler phrases. + + +## **Returns** + +`this` — the agent for method chaining. + +## **Example** + +```typescript {1-9} +agent.setInternalFillers({ + pre_speech: { + 'en-US': ['one moment', 'let me check'], + }, + summary: { + 'en-US': ['so to summarize', 'in short'], + }, +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx new file mode 100644 index 000000000..9e1b44223 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx @@ -0,0 +1,19 @@ +--- +title: "setPromptPom" +slug: /reference/typescript/agents/agent-base/set-prompt-pom +description: Replace the agent's prompt with the supplied POM sections. +max-toc-depth: 3 +--- + +Replace the agent's prompt with the supplied POM (Prompt Object Model) array. +Requires the agent to be constructed with `usePom: true` — throws otherwise. + +## **Parameters** + +[]"} required={true} toc={true}> + Ordered array of POM section objects. + + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx new file mode 100644 index 000000000..d656adf81 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx @@ -0,0 +1,23 @@ +--- +title: "setPronunciations" +slug: /reference/typescript/agents/agent-base/set-pronunciations +description: Replace the agent's pronunciation rules in a single call. +max-toc-depth: 3 +--- + +[ref-add-pronunciation]: /docs/server-sdks/reference/typescript/agents/agent-base/add-pronunciation + +Replace every pronunciation rule on the agent with the provided array. Use +[`addPronunciation`][ref-add-pronunciation] to add a single rule without +replacing the list. + +## **Parameters** + + + Ordered list of pronunciation rules. Each rule maps a spelled-out token to + its phonetic replacement. + + +## **Returns** + +`this` — the agent for method chaining. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx new file mode 100644 index 000000000..e3a7472e1 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx @@ -0,0 +1,28 @@ +--- +title: "validateToolToken" +slug: /reference/typescript/agents/agent-base/validate-tool-token +description: Validate a per-tool HMAC token attached to a SWAIG function call. +max-toc-depth: 3 +--- + +Validate a per-tool HMAC token attached to a SWAIG function call. Delegates +to `SessionManager.validateToolToken` after short-circuiting for tools +registered without `secure: true`. + +## **Parameters** + + + Name of the SWAIG function the token was issued for. + + + + HMAC token to validate. + + + + Call ID the token is bound to. + + +## **Returns** + +`boolean` — `true` when the token is valid for the given function and call. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/index.mdx index a88ed2549..dc523e6a7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/index.mdx @@ -90,6 +90,9 @@ You obtain a Context by calling `addContext()` on a ContextBuilder or by calling Set whether to fully reset conversation history when entering this context. + + Set which step the context starts on when entered. + Set whether to truncate conversation history when entering this context. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx new file mode 100644 index 000000000..dd66e2075 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx @@ -0,0 +1,38 @@ +--- +title: "setInitialStep" +slug: /reference/typescript/agents/context-builder/context/set-initial-step +description: Set which step the context starts on when entered. +max-toc-depth: 3 +--- + +[ref-context]: /docs/server-sdks/reference/typescript/agents/context-builder/context + +Set which step the context starts on when entered. By default, a context +starts on its first step (index 0). Use this to skip a preamble step on +re-entry via `change_context`. + +The step name is validated by `ContextBuilder.validate()` — the target step +must exist in this context or validation throws. + +## **Parameters** + + + The step to start on when the context is entered. Must be an existing step + in this context. + + +## **Returns** + +[`Context`][ref-context] — self for method chaining. + +## **Example** + +```typescript {6} +import { ContextBuilder } from '@signalwire/sdk'; + +const builder = new ContextBuilder(); +const billing = builder.addContext('billing'); +billing.addStep('greeting').setText('Welcome to billing.'); +billing.addStep('verify').setText('Please verify your account.'); +billing.setInitialStep('verify'); // skip the greeting on re-entry +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx index 5760cb7a3..28030739e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx @@ -38,6 +38,9 @@ automatically. Retrieve an existing context by name. + + Remove all contexts, returning the builder to its initial state. + Convert all contexts to a dictionary for SWML generation. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx new file mode 100644 index 000000000..96c905f16 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx @@ -0,0 +1,29 @@ +--- +title: "reset" +slug: /reference/typescript/agents/context-builder/reset +description: Remove all contexts, returning the builder to its initial state. +max-toc-depth: 3 +--- + +[ref-context-builder]: /docs/server-sdks/reference/typescript/agents/context-builder + +Remove all contexts, returning the builder to its initial state. Use this +inside a dynamic-config callback when you need to rebuild contexts from +scratch for a specific request, rather than mutating the shared builder. + +## **Returns** + +[`ContextBuilder`][ref-context-builder] — self for method chaining. + +## **Example** + +```typescript {3} +agent.onRequest((req, builder) => { + if (req.query.tenant === 'billing') { + builder.reset(); + builder.addContext('default') + .addStep('greeting') + .setText('Welcome to billing.'); + } +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/say.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/say.mdx index 5266d1053..1e51fb940 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/say.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/say.mdx @@ -8,6 +8,13 @@ max-toc-depth: 3 Queue text to be spoken by the agent. Internally, this appends a prompt section to the underlying SignalWire `AgentBase` so the AI speaks the provided text. + +Calls to `say()` made **before** `start({ agent })` are buffered on an internal +queue and replayed in order when the session starts (matches the Python SDK's +always-queue semantics). You do not need to await start before queuing +greetings. + + ## **Signature** ```typescript {1} diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent/index.mdx index b79aaec87..20acb749e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent/index.mdx @@ -9,8 +9,8 @@ max-toc-depth: 3 [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [functiontool]: /docs/server-sdks/reference/typescript/agents/livewire/function-tool -The `Agent` class mirrors a LiveKit voice agent. It holds the system prompt -(instructions), a map of tools, and optional user data. When bound to an +The `Agent` class mirrors a LiveKit voice agent. It holds the system +prompt (instructions), a set of tools, and optional user data. When bound to an [`AgentSession`][agentsession], the session translates this into a SignalWire [`AgentBase`][agentbase] under the hood. @@ -27,28 +27,46 @@ const getWeather = tool({ const agent = new Agent({ instructions: 'You are a helpful weather assistant.', - tools: { getWeather }, + tools: [getWeather], }); ``` ## **Constructor** -```typescript {1} -new Agent(options: { - instructions: string; - tools?: Record; +```typescript {1-13} +new Agent(options?: { + instructions?: string; + tools?: FunctionTool[]; userData?: UserData; + chatCtx?: unknown; + stt?: unknown; + tts?: unknown; + llm?: unknown; + vad?: unknown; + turnDetection?: unknown; + mcpServers?: unknown; + allowInterruptions?: boolean; + minEndpointingDelay?: number; + maxEndpointingDelay?: number; }) ``` - - The system prompt text for the agent. Mapped to the SignalWire prompt when the - session starts. + +The constructor options are source-compatible with LiveKit's `Agent` +constructor, including pipeline fields like `stt`, `tts`, `vad`, +`turnDetection`, and `mcpServers`. SignalWire handles speech, TTS, and VAD on +the control plane, so those fields are accepted but logged as a no-op the +first time they are supplied. + + + + System prompt text. Mapped to the SignalWire prompt when the session starts. - - A map of tool names to [`FunctionTool`][functiontool] definitions. Each tool is - registered as a SWAIG function on the underlying SignalWire agent. + + Array of [`FunctionTool`][functiontool] objects. Stored internally as a + name-keyed record; each tool is registered as a SWAIG function on the + underlying agent. @@ -56,6 +74,32 @@ new Agent(options: { `RunContext.userData`. + + Accepted for LiveKit parity. Pipeline mapping hint — SignalWire selects the + model from the SWML `ai.params`. + + + + Accepted for LiveKit parity. Forwarded to the SignalWire AI params when the + session starts. + + + + Accepted for LiveKit parity. Forwarded to the SignalWire AI params when the + session starts. + + + + Accepted for LiveKit parity. Forwarded to the SignalWire AI params when the + session starts. + + + + Accepted for LiveKit source compatibility. SignalWire handles these + capabilities on the control plane; passing a value logs a one-time + "no-op" advisory and does not affect behavior. + + ## **Properties** @@ -63,13 +107,18 @@ new Agent(options: { - The map of registered tools. + Internal name-keyed map of registered tools. The user data attached to this agent. + + The [`AgentSession`][agentsession] bound to this agent, if any. Set when + `session.start({ agent })` is called. + + ## **Example** ```typescript {13-17} @@ -87,7 +136,7 @@ const agentDef = defineAgent({ entry: async (ctx: JobContext) => { const agent = new Agent({ instructions: 'You are a customer support agent. Help users with their accounts.', - tools: { lookupAccount }, + tools: [lookupAccount], userData: { department: 'support' }, }); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/concierge-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/concierge-agent.mdx index b48358472..0b90a05ae 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/concierge-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/concierge-agent.mdx @@ -1,14 +1,15 @@ --- title: "ConciergeAgent" slug: /reference/typescript/agents/prefabs/concierge-agent -description: A concierge agent that provides multi-department routing with a knowledge base of department info, hours of operation, and call transfer capabilities. +description: A virtual concierge for a venue — provides information about services, amenities, hours of operation, and directions. --- [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [functionresult]: /docs/server-sdks/reference/typescript/agents/function-result -A concierge that provides multi-department routing with a knowledge base of department -info, hours of operation, and call transfer capabilities. +A virtual concierge for a venue or business. Answers questions about +services, amenities, and hours of operation, and offers directions and +recommendations. ```typescript {3} import { ConciergeAgent } from '@signalwire/sdk'; @@ -18,80 +19,64 @@ const agent = new ConciergeAgent({ /* ConciergeConfig */ }); ## ConciergeConfig - - List of departments available for routing. Each `Department` object has: + + Name of the venue or business (used in greetings and prompts). + + + + List of services offered by the venue. + - - `name` (string, required) -- Department name (e.g., `"Sales"`). - - `description` (string, required) -- What this department handles. - - `transferNumber` (string) -- Phone number or SIP address for transfers. - - `keywords` (string[]) -- Keywords that help route callers to this department. - - `hoursOfOperation` (string) -- Human-readable hours (e.g., `"Mon-Fri 9am-5pm EST"`). +>"} required={true} toc={true}> + Map of amenity names to detail key/value pairs. For example, + `{ "Pool": { "hours": "9am-9pm", "location": "3rd floor" } }`. - - Company name used in greetings and prompts. +"} default={'{ default: "9 AM - 5 PM" }'} toc={true}> + Hours of operation by category. Use `"default"` for a single block, or + keyed entries like `{ weekdays: "9-5", weekends: "10-4" }`. - - General company information the agent can share with callers. + + Extra instruction bullets appended to the agent's prompt. - - Message spoken when a department is closed or has no transfer number. + + Optional custom welcome message played as a non-bargeable static greeting. - + Agent display name. + + HTTP route for the agent. + + Additional [`AgentBase`][agentbase] options forwarded to the constructor. -## Built-in Tools - -| Tool | Description | Parameters | -|------|-------------|------------| -| `list_departments` | List all departments with descriptions and hours | (none) | -| `get_department_info` | Get detailed info about a specific department | `department_name` (string) | -| `transfer_to_department` | Transfer the caller to a department via its transfer number | `department_name` (string) | - - -The `transfer_to_department` tool uses `FunctionResult.connect()` to transfer the call. -If the department has no `transferNumber`, the agent returns the `afterHoursMessage` instead. - - ## Example ```typescript {3} import { ConciergeAgent } from '@signalwire/sdk'; const agent = new ConciergeAgent({ - companyName: 'Riverside Resort', - generalInfo: 'A luxury resort on the riverfront with 200 rooms.', - departments: [ - { - name: 'Front Desk', - description: 'Check-in, check-out, and room inquiries', - transferNumber: '+15551001001', - hoursOfOperation: '24 hours', - keywords: ['room', 'reservation', 'check-in'], - }, - { - name: 'Spa', - description: 'Spa treatments and wellness appointments', - transferNumber: '+15551001002', - hoursOfOperation: '9 AM - 9 PM', - keywords: ['massage', 'facial', 'wellness'], - }, - { - name: 'Restaurant', - description: 'Dining reservations and room service', - transferNumber: '+15551001003', - hoursOfOperation: '7 AM - 10 PM', - }, + venueName: 'Riverside Resort', + services: ['Dining', 'Spa', 'Concierge'], + amenities: { + Pool: { hours: '9 AM - 9 PM', location: 'Level 3' }, + Gym: { hours: '24 hours', access: 'Room key' }, + }, + hoursOfOperation: { + default: '9 AM - 5 PM', + weekends: '10 AM - 4 PM', + }, + specialInstructions: [ + 'Always mention our weekend jazz brunch when discussing dining.', ], - afterHoursMessage: 'This department is currently closed. Please call back during business hours.', + welcomeMessage: 'Welcome to Riverside Resort. How can I help you?', }); agent.serve(); @@ -103,9 +88,8 @@ agent.serve(); import { createConciergeAgent } from '@signalwire/sdk'; const agent = createConciergeAgent({ - companyName: 'Riverside Resort', - departments: [ - { name: 'Front Desk', description: 'Room inquiries', transferNumber: '+15551001001' }, - ], + venueName: 'Riverside Resort', + services: ['Dining'], + amenities: { Pool: { hours: '9-9' } }, }); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/faq-bot-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/faq-bot-agent.mdx index c52524d08..145243481 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/faq-bot-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/faq-bot-agent.mdx @@ -25,6 +25,24 @@ const agent = new FAQBotAgent({ /* FAQBotConfig */ }); - `question` (string, required) -- The representative question text. - `answer` (string, required) -- The answer to provide when matched. - `keywords` (string[]) -- Additional keywords to boost matching accuracy. + - `categories` (string[]) -- Taxonomy categories used for filtering and hints. + + + + Agent display name. + + + + HTTP route for the agent. + + + + Whether to suggest related questions alongside a match. + + + + Custom personality description injected into the agent's "Personality" + prompt section. Defaults to a helpful-FAQ-bot persona. @@ -39,10 +57,6 @@ const agent = new FAQBotAgent({ /* FAQBotConfig */ }); Phone number to transfer to on escalation. If not set, the `escalate` tool is not registered. - - Agent display name. - - Additional [`AgentBase`][agentbase] options forwarded to the constructor. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/info-gatherer-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/info-gatherer-agent.mdx index 54866d866..d5e3c2e5b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/info-gatherer-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/info-gatherer-agent.mdx @@ -1,15 +1,15 @@ --- title: "InfoGathererAgent" slug: /reference/typescript/agents/prefabs/info-gatherer-agent -description: An info gatherer agent that sequentially collects named fields from a caller through conversational interaction with validation and completion callbacks. +description: A prefab agent that collects answers to a series of questions — supporting both static and dynamic (per-request callback) modes. --- [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [functionresult]: /docs/server-sdks/reference/typescript/agents/function-result -Sequentially collects named fields from a caller through conversational interaction. -Tracks fields per call, validates values with optional regex patterns, and fires an -`onComplete` callback once all required fields are gathered. +Sequentially asks a caller a list of questions and stores each answer in +`global_data`. Supports **static mode** (questions provided at construction) +and **dynamic mode** (questions resolved per request via a callback). ```typescript {3} import { InfoGathererAgent } from '@signalwire/sdk'; @@ -19,83 +19,92 @@ const agent = new InfoGathererAgent({ /* InfoGathererConfig */ }); ## InfoGathererConfig - - Fields to collect from the caller. Each `InfoGathererField` object has: + + Questions to ask (static mode). Each `InfoGathererQuestion` has: - - `name` (string, required) -- Unique field name used as the key in collected data. - - `description` (string, required) -- Human-readable description shown to the AI agent. - - `required` (boolean, default `true`) -- Whether this field must be collected before completion. - - `validation` (RegExp | string) -- Optional validation pattern. Strings are compiled to `RegExp`. - + - `key_name` (string, required) — key used to store the caller's answer. + - `question_text` (string, required) — the question to ask. + - `confirm` (boolean) — when `true`, the agent insists the caller confirms + the answer before moving on. - - Opening message the agent speaks when the call starts. + Omit this field to run the agent in dynamic mode (see `questionCallback` / + `setQuestionCallback()`). - - Message spoken after all required fields are gathered. - + + Convenience alternative to calling `setQuestionCallback()` after + construction. Consulted only when `questions` is not provided. Signature: + + ```typescript + (queryParams, bodyParams, headers) => InfoGathererQuestion[] | Promise + ``` - - Callback fired when all required fields have been collected. Receives a record of - field names to their collected values. + If the callback throws or is not registered in dynamic mode, the agent + falls back to a built-in two-question list (name + "how can I help"). - + Agent display name. + + HTTP route for the agent. + + Additional [`AgentBase`][agentbase] options forwarded to the constructor. +## **Methods** + +### setQuestionCallback + +```typescript +setQuestionCallback(callback: InfoGathererQuestionCallback): this +``` + +Register (or replace) the callback that resolves questions per request. Only +used in dynamic mode (when `questions` was not supplied at construction). + ## Built-in Tools -| Tool | Description | Parameters | -|------|-------------|------------| -| `save_field` | Save a collected field value, validating against the field's pattern if configured | `field_name` (string), `value` (string) | -| `get_status` | Get the current collection status showing collected and remaining fields | (none) | +| Tool | Description | +|------|-------------| +| `start_questions` | Begin the question sequence with the first question. | +| `submit_answer` | Submit the caller's answer to the current question and advance. | -## Example +## Example — static mode ```typescript {3} import { InfoGathererAgent } from '@signalwire/sdk'; const agent = new InfoGathererAgent({ - fields: [ - { name: 'full_name', description: 'Full legal name' }, - { - name: 'email', - description: 'Email address', - validation: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, - }, - { - name: 'phone', - description: 'Phone number', - validation: '^\\+?\\d{10,15}$', - }, - { - name: 'preferred_date', - description: 'Preferred appointment date', - }, - { - name: 'notes', - description: 'Any additional notes', - required: false, - }, + questions: [ + { key_name: 'full_name', question_text: 'What is your full name?' }, + { key_name: 'email', question_text: 'What is your email address?', confirm: true }, + { key_name: 'issue', question_text: 'How can we help you today?' }, ], - introMessage: 'Hi! I need a few details to schedule your appointment.', - confirmationMessage: 'All set! Your appointment details have been recorded.', - onComplete: (data) => { - console.log('Collected data:', data); - // { full_name: "Jane Doe", email: "jane@example.com", ... } - }, - name: 'appointment-scheduler', + name: 'intake-agent', }); -agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); -agent.promptAddSection('Brand', { - body: 'You are scheduling appointments for Dr. Smith\'s office.', +agent.serve(); +``` + +## Example — dynamic mode + +```typescript {3-14} +import { InfoGathererAgent, type InfoGathererQuestion } from '@signalwire/sdk'; + +const agent = new InfoGathererAgent({ + questionCallback: async (queryParams) => { + const tenant = queryParams['tenant'] ?? 'default'; + const rows = await db.loadQuestions(tenant); + return rows.map((r) => ({ + key_name: r.key, + question_text: r.prompt, + confirm: r.requiresConfirmation, + })); + }, }); agent.serve(); @@ -107,9 +116,9 @@ agent.serve(); import { createInfoGathererAgent } from '@signalwire/sdk'; const agent = createInfoGathererAgent({ - fields: [ - { name: 'name', description: 'Full name' }, - { name: 'issue', description: 'Describe your issue' }, + questions: [ + { key_name: 'name', question_text: 'What is your name?' }, + { key_name: 'issue', question_text: 'Describe your issue' }, ], }); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx index 908a59f85..d95decbc7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx @@ -1,15 +1,14 @@ --- title: "ReceptionistAgent" slug: /reference/typescript/agents/prefabs/receptionist-agent -description: A front-desk agent that handles visitor check-in, department directory lookup, and call transfers by extension. +description: A front-desk agent that greets callers, looks up departments, and transfers calls. Optional visitor check-in. --- [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [functionresult]: /docs/server-sdks/reference/typescript/agents/function-result -A front-desk agent that handles visitor check-in, department directory lookup, and -call transfers by extension. The `check_in_visitor` tool is enabled by default and -fires an optional callback when a visitor checks in. +A front-desk agent that greets callers and transfers them to the correct +department by phone number or SIP address. Visitor check-in is opt-in. ```typescript {3} import { ReceptionistAgent } from '@signalwire/sdk'; @@ -19,50 +18,60 @@ const agent = new ReceptionistAgent({ /* ReceptionistConfig */ }); ## ReceptionistConfig - - Company name displayed in greetings and prompts. + + Departments the agent can transfer callers to. Each `ReceptionistDepartment` + has: + + - `name` (string, required) — department identifier (e.g. `"sales"`). + - `description` (string, required) — description shown to the AI. + - `number` (string, required) — phone number or SIP address dialed by + `transfer_call`. - - Departments with extensions for the directory. Each `ReceptionistDepartment` object has: + + Initial greeting spoken when the call starts. + - - `name` (string, required) -- Department name (e.g., `"Engineering"`). - - `extension` (string, required) -- Internal extension number or SIP address. - - `description` (string) -- Optional description of the department. + + Voice identifier passed to `addLanguage`. - - Custom welcome message. Defaults to `"Welcome to {companyName}! How may I help you today?"`. + + Optional company name appended to the greeting. - - Whether visitor check-in functionality is enabled. When `true`, the `check_in_visitor` tool is registered. + + When `true`, registers the `check_in_visitor` tool. - Callback fired when a visitor checks in. Receives a record with `visitor_name`, `purpose`, - `visiting`, and `checked_in_at` fields. + Callback fired when a visitor checks in. Receives a record with the fields + collected during check-in. - + Agent display name. + + HTTP route for the agent. + + Additional [`AgentBase`][agentbase] options forwarded to the constructor. ## Built-in Tools -| Tool | Description | Parameters | -|------|-------------|------------| -| `get_department_list` | List all departments with extensions and descriptions | (none) | -| `transfer_to_department` | Transfer the caller to a department by dialing its extension | `department_name` (string) | -| `check_in_visitor` | Check in a visitor (only when `checkInEnabled` is `true`) | `visitor_name` (string), `purpose` (string), `visiting` (string) | +| Tool | Description | +|------|-------------| +| `get_department_list` | List all departments with descriptions and numbers. | +| `transfer_call` | Dial a department's number and transfer the caller. | +| `check_in_visitor` | Record a visitor check-in (only when `checkInEnabled` is `true`). | -The `transfer_to_department` tool uses [`FunctionResult.connect()`][functionresult] to -dial the department's extension and transfer the call. +`transfer_call` uses [`FunctionResult.connect()`][functionresult] to dial the +department's configured `number`. ## Example @@ -72,22 +81,18 @@ import { ReceptionistAgent } from '@signalwire/sdk'; const agent = new ReceptionistAgent({ companyName: 'Acme Corporation', + greeting: 'Thank you for calling Acme Corporation. How may I direct your call?', departments: [ - { name: 'Sales', extension: '1001', description: 'New orders and pricing' }, - { name: 'Support', extension: '1002', description: 'Technical issues' }, - { name: 'Billing', extension: '1003', description: 'Invoices and payments' }, - { name: 'HR', extension: '1004', description: 'Employment and benefits' }, + { name: 'sales', description: 'New orders and pricing', number: '+15551001001' }, + { name: 'support', description: 'Technical issues', number: '+15551001002' }, + { name: 'billing', description: 'Invoices and payments', number: '+15551001003' }, ], - welcomeMessage: 'Thank you for calling Acme Corporation. How may I direct your call?', + checkInEnabled: true, onVisitorCheckIn: (visitor) => { - console.log(`Visitor checked in: ${visitor.visitor_name} visiting ${visitor.visiting}`); + console.log(`Visitor checked in: ${JSON.stringify(visitor)}`); }, }); -agent.promptAddSection('Company', { - body: 'You are the receptionist for Acme Corporation.', -}); - agent.serve(); ``` @@ -97,10 +102,8 @@ agent.serve(); import { createReceptionistAgent } from '@signalwire/sdk'; const agent = createReceptionistAgent({ - companyName: 'Acme Corporation', departments: [ - { name: 'Sales', extension: '1001', description: 'New orders' }, - { name: 'Support', extension: '1002' }, + { name: 'sales', description: 'Orders', number: '+15551001001' }, ], }); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx index 9a9bbfcae..a9f29de6a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx @@ -19,6 +19,10 @@ const agent = new SurveyAgent({ /* SurveyConfig */ }); ## SurveyConfig + + Human-readable survey name used in prompts and global data. + + Ordered list of survey questions. Each `SurveyQuestion` object has: @@ -26,26 +30,40 @@ const agent = new SurveyAgent({ /* SurveyConfig */ }); - `text` (string, required) -- The question text to ask the caller. - `type` (string, required) -- One of `"multiple_choice"`, `"open_ended"`, `"rating"`, or `"yes_no"`. - `options` (string[]) -- Required for `multiple_choice` questions. + - `scale` (number, default `5`) -- For `rating` questions, the upper bound of the scale (1..scale). + - `required` (boolean, default `true`) -- Whether the question must be answered. - `nextQuestion` (string | Record<string, string>) -- Next question ID, or a map from answer value to next question ID for branching. If omitted, proceeds in array order. - `points` (number | Record<string, number>) -- Fixed points for any answer, or per-answer scoring map. - - Opening message before the first question. + + Opening message before the first question. Defaults to a generic intro. + + + + Closing message spoken after the survey completes. - - Message after the survey is complete. + + Brand or company name the agent represents. Used in prompt sections. + + + + Maximum number of times to retry invalid answers before moving on. Callback fired when the survey is finished. Receives all responses and the total score. - + Agent display name. + + HTTP route for the agent. + + Additional [`AgentBase`][agentbase] options forwarded to the constructor. @@ -73,8 +91,10 @@ for any answer. A `Record` awards different points per answer va import { SurveyAgent } from '@signalwire/sdk'; const agent = new SurveyAgent({ - introMessage: 'Thank you for purchasing our product. We\'d love your feedback!', - completionMessage: 'Thanks for your time. Your feedback helps us improve!', + surveyName: 'Product Feedback', + brandName: 'Acme Corporation', + introduction: 'Thank you for purchasing our product. We\'d love your feedback!', + conclusion: 'Thanks for your time. Your feedback helps us improve!', questions: [ { id: 'overall_rating', @@ -125,6 +145,7 @@ agent.serve(); import { createSurveyAgent } from '@signalwire/sdk'; const agent = createSurveyAgent({ + surveyName: 'Quick Feedback', questions: [ { id: 'q1', text: 'How was your experience?', type: 'rating' }, { id: 'q2', text: 'Any comments?', type: 'open_ended' }, diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-data-map-tools.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-data-map-tools.mdx new file mode 100644 index 000000000..0dffa9743 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-data-map-tools.mdx @@ -0,0 +1,43 @@ +--- +title: "getDataMapTools" +slug: /reference/typescript/agents/skill-base/get-data-map-tools +description: Return fully-built SWAIG function dicts (DataMap-style tools). +max-toc-depth: 3 +--- + +[ref-skillbase]: /docs/server-sdks/reference/typescript/agents/skill-base +[ref-datamap]: /docs/server-sdks/reference/typescript/agents/data-map + +Return fully-built SWAIG function dicts for tools that this skill builds via +[`DataMap`][ref-datamap] or any other path that produces a complete SWAIG +function object (rather than a `SkillToolDefinition` handled by the default +tool pipeline). + +When a skill is added to an agent, `AgentBase.addSkill()` iterates the result +and registers each entry via `registerSwaigFunction`. + +Default returns `[]`. Skills that only use the declarative `getTools()` path +do not need to override this method. + +## **Returns** + +`Record[]` — array of pre-built SWAIG function dicts. + +## **Example** + +```typescript {6-10} +import { SkillBase, DataMap } from '@signalwire/sdk'; + +class LookupSkill extends SkillBase { + static override SKILL_NAME = 'lookup'; + static override SKILL_DESCRIPTION = 'Server-side lookup via DataMap'; + + override getDataMapTools(): Record[] { + const dm = new DataMap('do_lookup') + .description('Look up a value by id') + .parameter('id', 'string', 'Record id', { required: true }) + .webhook('GET', 'https://api.example.com/lookup/${args.id}'); + return [dm.toSwaigFunction()]; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-hints.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-hints.mdx index 140a36d89..46bf44901 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-hints.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-hints.mdx @@ -18,23 +18,16 @@ Takes no parameters. ## **Example** -```typescript {17} -import { SkillBase, SkillManifest, SkillToolDefinition } from '@signalwire/sdk'; +```typescript {9} +import { SkillBase, type SkillToolDefinition } from '@signalwire/sdk'; class WeatherSkill extends SkillBase { - constructor(config?: Record) { - super('weather', config); - } - - getManifest(): SkillManifest { - return { name: 'weather', description: 'Provides weather information', version: '1.0.0' }; - } + static override SKILL_NAME = 'weather'; + static override SKILL_DESCRIPTION = 'Provides weather information'; - getTools(): SkillToolDefinition[] { - return []; - } + override getTools(): SkillToolDefinition[] { return []; } - getHints(): string[] { + override getHints(): string[] { return ['weather', 'temperature', 'forecast', 'humidity', 'wind speed']; } } diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-parameter-schema.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-parameter-schema.mdx index 8ee4cd8f2..ba8a1fb58 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-parameter-schema.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-parameter-schema.mdx @@ -32,15 +32,14 @@ and values describe the parameter. ## **Example** -```typescript {8} -import { SkillBase, SkillManifest, SkillToolDefinition, ParameterSchemaEntry } from '@signalwire/sdk'; +```typescript {7} +import { SkillBase, type SkillToolDefinition, type ParameterSchemaEntry } from '@signalwire/sdk'; class WeatherSkill extends SkillBase { - constructor(config?: Record) { - super('weather', config); - } + static override SKILL_NAME = 'weather'; + static override SKILL_DESCRIPTION = 'Provides weather information'; - static getParameterSchema(): Record { + static override getParameterSchema(): Record { return { ...super.getParameterSchema(), units: { @@ -59,11 +58,7 @@ class WeatherSkill extends SkillBase { }; } - getManifest(): SkillManifest { - return { name: 'weather', description: 'Provides weather information', version: '1.0.0' }; - } - - getTools(): SkillToolDefinition[] { + override getTools(): SkillToolDefinition[] { return []; } } diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-prompt-sections.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-prompt-sections.mdx index 82f0cde40..5a83b9feb 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-prompt-sections.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-prompt-sections.mdx @@ -22,23 +22,18 @@ and either a `body` string or a `bullets` array. An optional `numbered` boolean ## **Example** -```typescript {17} -import { SkillBase, SkillManifest, SkillToolDefinition, SkillPromptSection } from '@signalwire/sdk'; +```typescript {11} +import { SkillBase, type SkillToolDefinition, type SkillPromptSection } from '@signalwire/sdk'; class WeatherSkill extends SkillBase { - constructor(config?: Record) { - super('weather', config); - } - - getManifest(): SkillManifest { - return { name: 'weather', description: 'Provides weather information', version: '1.0.0' }; - } + static override SKILL_NAME = 'weather'; + static override SKILL_DESCRIPTION = 'Provides weather information'; - getTools(): SkillToolDefinition[] { + override getTools(): SkillToolDefinition[] { return []; } - protected _getPromptSections(): SkillPromptSection[] { + protected override _getPromptSections(): SkillPromptSection[] { return [ { title: 'Weather Information', diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-tools.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-tools.mdx new file mode 100644 index 000000000..d5bada4af --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-tools.mdx @@ -0,0 +1,68 @@ +--- +title: "getTools" +slug: /reference/typescript/agents/skill-base/get-tools +description: Return the SWAIG tool definitions this skill exposes. +max-toc-depth: 3 +--- + +[ref-skillbase]: /docs/server-sdks/reference/typescript/agents/skill-base + +Return the SWAIG tool definitions this skill exposes. Called by the +`SkillManager` at SWML render time to collect every tool that should appear in +the agent's SWAIG block. + +The default implementation returns tools registered imperatively via +`defineTool()`. Skills that build their tool list declaratively should +override this method to return a static array. + + +This replaces the Python `register_tools()` abstract method. TS uses a pull +model: you return the list, rather than calling back into the agent once per +tool. + + +## **Returns** + +`SkillToolDefinition[]` — array of tool definitions. + +## **Example — declarative override** + +```typescript {8-17} +import { SkillBase, type SkillToolDefinition } from '@signalwire/sdk'; + +class WeatherSkill extends SkillBase { + static override SKILL_NAME = 'weather'; + static override SKILL_DESCRIPTION = 'Provides weather information'; + + override getTools(): SkillToolDefinition[] { + return [{ + name: 'get_weather', + description: 'Get current weather for a location', + parameters: { + location: { type: 'string', description: 'City name' }, + }, + required: ['location'], + handler: async (args) => ({ response: `Weather in ${args.location}: sunny, 72F` }), + }]; + } +} +``` + +## **Example — imperative via defineTool()** + +```typescript {5-13} +class ConfigurableSkill extends SkillBase { + static override SKILL_NAME = 'configurable'; + static override SKILL_DESCRIPTION = 'Tools depend on config'; + + override async setup(): Promise { + this.defineTool({ + name: this.getConfig('tool_name', 'run'), + description: this.getConfig('description', 'Run the action'), + parameters: {}, + handler: async () => ({ response: 'done' }), + }); + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx index d467a6288..5b2a67da1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx @@ -7,6 +7,7 @@ max-toc-depth: 3 [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [skills]: /docs/server-sdks/reference/typescript/agents/skills +[skillregistry]: /docs/server-sdks/reference/typescript/agents/skill-registry [cleanup]: /docs/server-sdks/reference/typescript/agents/skill-base/cleanup [getglobaldata]: /docs/server-sdks/reference/typescript/agents/skill-base/get-global-data [gethints]: /docs/server-sdks/reference/typescript/agents/skill-base/get-hints @@ -23,22 +24,51 @@ max-toc-depth: 3 SkillBase is the abstract base class for all agent skills. Skills are modular, reusable capabilities -- such as weather lookup, web search, or calendar access -- -that can be added to any [`AgentBase`][agentbase] -agent with a single call to `agent.addSkill()`. +that can be added to any [`AgentBase`][agentbase] agent with a single call to +`agent.addSkill()`. -Extend SkillBase to create custom skills. You must implement the abstract methods -`getManifest()` and `getTools()`, and optionally override lifecycle and prompt methods. +Extend SkillBase to create custom skills. Metadata (name, description, version, +required packages, required environment variables, multi-instance support) is +declared as **static class constants** on the subclass — the [`SkillRegistry`][skillregistry] +and `SkillManager` read these constants directly. You override `getTools()` to +expose SWAIG tools and optionally override lifecycle and prompt methods. For the catalog of built-in skills and their configuration parameters, see the [Skills][skills] page. -## **Static Members** +## **Static Class Constants** + +Subclasses declare their identity and requirements by overriding these static +members. The [`SkillRegistry`][skillregistry] reads them directly — no manifest +object is exchanged. + + + Unique skill name used for registration. Subclasses **must** override with a + non-empty string; the constructor throws otherwise. + + + + Human-readable description. Subclasses **must** override with a non-empty + string; the constructor throws otherwise. + + + + Semantic version string. + + + + NPM packages the skill depends on. Checked at load time by `validatePackages()`. + + + + Environment variables the skill requires. Checked at load time by `validateEnvVars()`. + When `true`, the same skill can be added to an agent multiple times with - different configurations. + different configurations (distinguished by `tool_name`). @@ -49,21 +79,22 @@ the [Skills][skills] page. ## **Constructor** ```typescript {1} -constructor(skillName: string, config?: SkillConfig) +constructor(config?: SkillConfig) ``` - - Unique identifier for the skill (e.g., `"weather"`, `"web_search"`). - +The skill name, description, and version come from the subclass's static +constants — not from constructor arguments. - Optional configuration key-value pairs for the skill instance. + Optional configuration key-value pairs for the skill instance. Any + `swaig_fields` entry is extracted and automatically merged into tool + definitions. ## **Instance Properties** - The registered name for this skill instance (readonly). + The registered name for this skill instance, copied from `SKILL_NAME` (readonly). @@ -83,11 +114,17 @@ constructor(skillName: string, config?: SkillConfig) - Initialize the skill and prepare resources. + Initialize the skill. Return `false` to fail-closed on missing config. Release resources when the skill is removed or the agent shuts down. + + Return SWAIG tool definitions this skill exposes. + + + Return fully-built SWAIG function dicts (DataMap style). + Return metadata about all parameters the skill accepts. @@ -123,23 +160,17 @@ constructor(skillName: string, config?: SkillConfig) -### getManifest (abstract) +### defineTool (protected) ```typescript {1} -abstract getManifest(): SkillManifest +protected defineTool(toolDef: SkillToolDefinition): void ``` -Returns the skill's metadata including name, description, version, required environment -variables, and required packages. You **must** implement this in every subclass. - -### getTools (abstract) - -```typescript {1} -abstract getTools(): SkillToolDefinition[] -``` - -Returns the SWAIG tool definitions this skill provides. You **must** implement this -in every subclass. Each tool is registered with the agent when the skill is loaded. +Imperatively register a tool. Use from `setup()` when the tool shape depends on +config evaluated at runtime. The method merges `this.swaigFields` into the +definition and pushes it onto the internal dynamic-tools list; the default +`getTools()` returns that list. Skills with a static tool list should override +`getTools()` directly instead. ### getConfig @@ -147,8 +178,7 @@ in every subclass. Each tool is registered with the agent when the skill is load getConfig(key: string, defaultValue?: T): T ``` -Read a configuration value by key, with an optional fallback default. Returns the -value cast to type `T`, or `defaultValue` if the key is not present. +Read a configuration value by key, with an optional fallback default. The configuration key to look up. @@ -158,23 +188,28 @@ value cast to type `T`, or `defaultValue` if the key is not present. Value to return if the key is not present in the config. +### hasAllEnvVars / hasAllPackages + +```typescript {1-2} +hasAllEnvVars(): boolean +async hasAllPackages(): Promise +``` + +Boolean wrappers around `validateEnvVars()` and `validatePackages()`. + ## **Examples** ### Custom skill -```typescript {3} -import { SkillBase, SkillManifest, SkillToolDefinition } from '@signalwire/sdk'; +```typescript {4-6} +import { SkillBase, type SkillToolDefinition } from '@signalwire/sdk'; class MyWeatherSkill extends SkillBase { - constructor(config?: Record) { - super('my_weather', config); - } - - getManifest(): SkillManifest { - return { name: 'my_weather', description: 'Look up weather', version: '1.0.0' }; - } + static override SKILL_NAME = 'my_weather'; + static override SKILL_DESCRIPTION = 'Look up weather'; + static override SKILL_VERSION = '1.0.0'; - getTools(): SkillToolDefinition[] { + override getTools(): SkillToolDefinition[] { return [{ name: 'get_weather', description: 'Get current weather for a city', @@ -191,12 +226,11 @@ class MyWeatherSkill extends SkillBase { import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'weather-agent' }); -agent.setPromptText("You are a helpful assistant.") -agent.addSkill("weather") +agent.setPromptText("You are a helpful assistant."); +agent.addSkill("weather"); // Or with custom configuration -agent.addSkill("weather", { units: "celsius" }) +agent.addSkill("weather", { units: "celsius" }); -// Entry point -agent.run() +agent.run(); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/setup.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/setup.mdx index 31c920ae3..7f55c066e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/setup.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/setup.mdx @@ -1,31 +1,45 @@ --- title: "setup" slug: /reference/typescript/agents/skill-base/setup -description: Initialize the skill and prepare resources. +description: Initialize the skill and prepare resources. Return false to fail closed. max-toc-depth: 3 --- [ref-skillbase]: /docs/server-sdks/reference/typescript/agents/skill-base +[ref-addskill]: /docs/server-sdks/reference/typescript/agents/skill-manager/add-skill Initialize the skill: validate environment variables, initialize API clients, and -prepare resources. Called once when the skill is loaded. +prepare resources. Called once when the skill is loaded, before any tool +registration. -This is a concrete method with a default no-op implementation. Override it in your -[SkillBase][ref-skillbase] subclass if you need initialization logic. +This is a concrete method with a default that returns `true`. Override it in +your [SkillBase][ref-skillbase] subclass when you need initialization logic or +need to short-circuit loading on invalid config. + + +Returning `false` from `setup()` causes [`SkillManager.addSkill()`][ref-addskill] +(and `AgentBase.addSkill()`) to **fail closed**: the skill is not registered +and the call throws. This matches the Python SDK's behavior — never silently +continue with a half-initialized skill. + Takes no parameters. ## **Returns** -`Promise` +`Promise` — `true` on success, `false` to signal that the skill +cannot be loaded (invalid config, missing credentials, failed handshake, etc.). ## **Example** -```typescript {2} +```typescript {2-9} class MySkill extends SkillBase { - async setup(): Promise { - // Initialize API connections, validate config - console.log('Skill setup complete'); + override async setup(): Promise { + if (!this.hasAllEnvVars()) return false; + const missing = await this.validatePackages(); + if (missing.length) return false; + // Initialize API connections here + return true; } } ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/add-skill.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/add-skill.mdx index b047144c4..0bd8332df 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/add-skill.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/add-skill.mdx @@ -1,14 +1,28 @@ --- title: "addSkill" slug: /reference/typescript/agents/skill-manager/add-skill -description: "Add and initialize a skill instance." +description: "Add and initialize a skill instance. Fails closed on invalid config." --- [ref-skillbase]: /docs/server-sdks/reference/typescript/agents/skill-base +[ref-setup]: /docs/server-sdks/reference/typescript/agents/skill-base/setup -Add a skill to the manager. Validates env vars, calls `setup()`, and marks -the skill as initialized. Throws `Error` if a duplicate non-multi-instance -skill is added. +Add a skill to the manager. The call sequence is: + +1. Deduplicate by instance key (multi-instance skills with the same key are + skipped with a warning; single-instance duplicates throw). +2. Validate required environment variables — throws if any are missing. +3. Validate that the skill's `getParameterSchema()` returns a non-empty object. +4. Validate required NPM packages — throws if any cannot be imported. +5. Call [`setup()`][ref-setup] — **throws if it returns `false`**. +6. Mark the skill initialized and register it. + + +`addSkill` **fails closed**: any validation miss or a `setup()` returning +`false` throws and the skill is not registered. The wrapper methods +`loadSkill` / `loadSkillByName` catch and convert the throw into a +`[false, message]` tuple that matches the Python SDK's `load_skill` contract. + ## **Parameters** @@ -19,3 +33,11 @@ skill is added. ## **Returns** `Promise` + +## **Throws** + +- `Error` — duplicate single-instance skill already loaded. +- `Error` — missing required environment variables. +- `Error` — `getParameterSchema()` returns an empty object. +- `Error` — missing required NPM packages. +- `Error` — `setup()` returned `false`. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/has-skill-by-key.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/has-skill-by-key.mdx new file mode 100644 index 000000000..524b8a9df --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/has-skill-by-key.mdx @@ -0,0 +1,19 @@ +--- +title: "hasSkillByKey" +slug: /reference/typescript/agents/skill-manager/has-skill-by-key +description: "Check if a skill with the given instance key is loaded." +--- + +Direct map lookup by instance key (matches Python's `has_skill(skill_identifier)` +semantics). Use `hasSkill(name)` to search by skill name instead. + +## **Parameters** + + + The instance key to look up (e.g., `"weather"` for single-instance skills, or + `"weather_forecast"` for a multi-instance skill keyed by `tool_name`). + + +## **Returns** + +`boolean` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx index 7e9b1f79f..da2c94506 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx @@ -32,7 +32,13 @@ Most users should use `AgentBase.addSkill()`, `AgentBase.removeSkill()`, and - Add and initialize a skill instance. + Add and initialize a skill instance (fails closed). + + + Instantiate a skill class and add it; returns [ok, error]. + + + Look up a skill by name in the global registry and add it. Remove a skill by key or ID. @@ -41,7 +47,13 @@ Most users should use `AgentBase.addSkill()`, `AgentBase.removeSkill()`, and Remove all instances of a named skill. - Check if a skill is loaded. + Check if any skill with the given name is loaded. + + + Check if a skill with the given instance key is loaded. + + + List instance keys of all loaded skills. Get a skill instance by key or ID. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/list-skill-keys.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/list-skill-keys.mdx new file mode 100644 index 000000000..d84e2fe2c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/list-skill-keys.mdx @@ -0,0 +1,12 @@ +--- +title: "listSkillKeys" +slug: /reference/typescript/agents/skill-manager/list-skill-keys +description: "List instance keys of all currently loaded skills." +--- + +Matches Python's `list_loaded_skills() -> List[str]`. Use `listSkills()` for +richer objects (name, instanceId, initialized flag). + +## **Returns** + +`string[]` — array of instance key strings. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill-by-name.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill-by-name.mdx new file mode 100644 index 000000000..9cbfb95de --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill-by-name.mdx @@ -0,0 +1,35 @@ +--- +title: "loadSkillByName" +slug: /reference/typescript/agents/skill-manager/load-skill-by-name +description: "Look up a skill class in the global registry by name and load it." +--- + +[ref-addskill]: /docs/server-sdks/reference/typescript/agents/skill-manager/add-skill +[ref-registry]: /docs/server-sdks/reference/typescript/agents/skill-registry + +Look up a registered skill class by name in the global +[`SkillRegistry`][ref-registry], construct an instance, and add it via +[`addSkill`][ref-addskill]. Returns `[false, message]` if the name is not +registered, the instantiation fails, or `addSkill` throws. + +## **Parameters** + + + Registered skill name (read from the target class's `SKILL_NAME`). + + + + Optional configuration forwarded to the skill constructor. + + +## **Returns** + +`Promise<[boolean, string]>` — `[true, '']` on success, `[false, errorMessage]` +otherwise. + +## **Example** + +```typescript {1} +const [ok, err] = await agent.skillManager.loadSkillByName('datetime'); +if (!ok) throw new Error(err); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill.mdx new file mode 100644 index 000000000..afec519da --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/load-skill.mdx @@ -0,0 +1,37 @@ +--- +title: "loadSkill" +slug: /reference/typescript/agents/skill-manager/load-skill +description: "Instantiate a skill class and add it; returns a [success, error] tuple." +--- + +[ref-addskill]: /docs/server-sdks/reference/typescript/agents/skill-manager/add-skill +[ref-skillbase]: /docs/server-sdks/reference/typescript/agents/skill-base + +Construct a skill instance from the provided class and add it via +[`addSkill`][ref-addskill]. Catches any throw from `addSkill` and returns a +`[success, errorMessage]` tuple — matching the Python SDK's `load_skill` +return contract. + +## **Parameters** + + + A concrete subclass of [`SkillBase`][ref-skillbase]. + + + + Optional configuration forwarded to the skill constructor. + + +## **Returns** + +`Promise<[boolean, string]>` — `[true, '']` on success, `[false, errorMessage]` +on any validation or setup failure. + +## **Example** + +```typescript {3} +import { MyCustomSkill } from './my-skill.js'; + +const [ok, err] = await agent.skillManager.loadSkill(MyCustomSkill, { api_key: 'secret' }); +if (!ok) console.error(err); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-manifest.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-manifest.mdx deleted file mode 100644 index a2f52b74c..000000000 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-manifest.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "getManifest" -slug: /reference/typescript/agents/skill-registry/get-manifest -description: "Get the manifest for a registered skill." ---- - -Get the manifest for a registered skill, if available. - -## **Parameters** - - - The skill name to look up. - - -## **Returns** - -`SkillManifest | undefined` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx index a53073915..8e4aef2bf 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx @@ -9,9 +9,10 @@ max-toc-depth: 3 [ref-skills]: /docs/server-sdks/reference/typescript/agents/skills `SkillRegistry` is a global singleton for registering, discovering, and -instantiating skills by name. Skills can be registered programmatically or -auto-discovered from directories via the `SIGNALWIRE_SKILL_PATHS` environment -variable. +instantiating skills by class reference. Skills can be registered +programmatically by passing the class itself (the registry reads metadata from +static class properties like `SKILL_NAME`), or auto-discovered from +directories via the `SIGNALWIRE_SKILL_PATHS` environment variable. ```typescript {1} import { SkillRegistry } from '@signalwire/sdk'; @@ -24,7 +25,7 @@ import { SkillRegistry } from '@signalwire/sdk'; Get the global singleton instance. - Register a skill factory by name. + Register a skill class. Create a skill instance from the registry. @@ -41,12 +42,6 @@ import { SkillRegistry } from '@signalwire/sdk'; List all registered skill names. - - List skills with manifests. - - - Get a skill's manifest. - Add a directory for skill discovery. @@ -85,7 +80,7 @@ import { SkillRegistry } from '@signalwire/sdk'; import { SkillRegistry, SkillBase } from '@signalwire/sdk'; const registry = SkillRegistry.getInstance(); -registry.register('my-skill', (config) => new MySkill(config)); +registry.register(MySkill); // class reference — name read from MySkill.SKILL_NAME console.log(registry.listRegistered()); // ['my-skill', ...] // Create an instance from the registry diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-registered-with-manifests.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-registered-with-manifests.mdx deleted file mode 100644 index 1053f4bab..000000000 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-registered-with-manifests.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: "listRegisteredWithManifests" -slug: /reference/typescript/agents/skill-registry/list-registered-with-manifests -description: "List all registered skills with their manifests." ---- - -List all registered skills with their optional manifests. - -## **Parameters** - -None. - -## **Returns** - -`{ name: string; manifest?: SkillManifest }[]` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/register.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/register.mdx index 84bc967f3..1053914fc 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/register.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/register.mdx @@ -1,25 +1,41 @@ --- title: "register" slug: /reference/typescript/agents/skill-registry/register -description: "Register a skill factory by name." +description: "Register a skill class by its static SKILL_NAME." --- -Register a skill factory by name. Optionally provide a manifest for metadata. +Register a skill class. The skill name is read from the class's static +`SKILL_NAME`. The registry validates that `SKILL_NAME` is non-empty and that +`getParameterSchema()` returns a non-empty object before registering. ## **Parameters** - - Unique skill name. - - - - Factory function `(config?: SkillConfig) => SkillBase` that creates skill instances. - - - - Optional manifest metadata for the skill. + + A concrete subclass of `SkillBase` with a non-empty static `SKILL_NAME` and + a non-empty `getParameterSchema()` return value. ## **Returns** `void` + +## **Throws** + +- `Error` if the class has no `SKILL_NAME`. +- `Error` if `getParameterSchema()` throws or returns an empty object. + +Locked skill names (see [`lock`](/docs/server-sdks/reference/typescript/agents/skill-registry/lock)) +are skipped with a warning rather than throwing. + +## **Example** + +```typescript {5} +import { SkillRegistry, SkillBase } from '@signalwire/sdk'; + +class MySkill extends SkillBase { + static override SKILL_NAME = 'my-skill'; + // ... +} + +SkillRegistry.getInstance().register(MySkill); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx index 5a1f667a8..1943abce2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx @@ -1,61 +1,92 @@ --- title: "DataSphereServerlessSkill" slug: /reference/typescript/agents/skills/datasphere-serverless -description: Search SignalWire DataSphere documents using a DataMap for serverless execution. +description: Search a SignalWire DataSphere document via a serverless DataMap tool — no agent webhook round-trip. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill [ref-datamap]: /docs/server-sdks/reference/typescript/agents/data-map -Search SignalWire DataSphere documents using a [DataMap][ref-datamap] for -serverless execution. Unlike the standard `datasphere` skill, this version -executes entirely server-side without a webhook round-trip. +Same DataSphere search as +[`DataSphereSkill`](/docs/server-sdks/reference/typescript/agents/skills/datasphere), +but the tool is registered as a [DataMap][ref-datamap] — the SignalWire +platform executes the search directly, without calling back to your agent +process. + +Credentials and URL are **baked into the DataMap** from config at registration +time, so the same parameters are required here as on DataSphereSkill. **Class:** `DataSphereServerlessSkill` -**Tools:** `search_datasphere` +**Tools:** Custom per instance via `tool_name` (default `search_knowledge`), +registered as a DataMap-style SWAIG function. + +**Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_TOKEN` + +**Multi-instance:** yes + + + Custom tool name for this instance. + + + + SignalWire space name. + + + + SignalWire project ID. Falls back to `SIGNALWIRE_PROJECT_ID`. + -**Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_TOKEN`, `SIGNALWIRE_SPACE` + + SignalWire API token. Falls back to `SIGNALWIRE_TOKEN`. + -**Multi-instance:** Yes + + DataSphere document ID to search within. + - - Custom tool name for this instance. Required when using multiple instances. + + Number of results to return (range `1-10`). - - SignalWire space name. Falls back to the `SIGNALWIRE_SPACE` environment variable. + + Maximum distance threshold (range `0-10`; lower is more relevant). - - SignalWire project ID. Falls back to the `SIGNALWIRE_PROJECT_ID` environment variable. + + Tags to filter results. - - SignalWire auth token. Falls back to the `SIGNALWIRE_TOKEN` environment variable. + + Language code for query expansion (e.g., `"en"`, `"es"`). - - Restrict search to a specific document ID. + + Parts of speech to expand with synonyms. Entries must be one of `"NOUN"`, + `"VERB"`, `"ADJ"`, `"ADV"`. - - Maximum number of results to return. + + Maximum number of synonyms used for query expansion (range `1-10`). - - Maximum distance threshold for results (0-1, lower is more similar). + + Message returned when no results match the query. -```typescript {6-9} +## Example + +```typescript {6-11} import { AgentBase, DataSphereServerlessSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new DataSphereServerlessSkill({ - document_id: 'YOUR_DOCUMENT_ID', - max_results: 3, + space_name: 'mycompany', + document_id: 'doc_1234', + count: 3, + tool_name: 'search_product_docs', })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx index 2ec04aea7..0e0e43be9 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx @@ -1,59 +1,88 @@ --- title: "DataSphereSkill" slug: /reference/typescript/agents/skills/datasphere -description: Search documents uploaded to SignalWire DataSphere using semantic search. +description: Search a SignalWire DataSphere knowledge document via the RAG stack. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Search documents uploaded to SignalWire DataSphere using semantic search. -Executes the search via a webhook call from the agent process. +Search a document uploaded to SignalWire DataSphere using the RAG stack. +The skill issues the search via a webhook call from the agent process. + +Credentials (`space_name`, `project_id`, `token`, `document_id`) are all +required — `setup()` fails closed if any are missing. **Class:** `DataSphereSkill` -**Tools:** `search_datasphere` +**Tools:** Custom per instance via `tool_name` (default `search_knowledge`) **Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_TOKEN`, `SIGNALWIRE_SPACE` -**Multi-instance:** Yes +**Multi-instance:** yes + + + Custom tool name for this DataSphere instance. + + + + SignalWire space name (e.g., `"mycompany"` from + `mycompany.signalwire.com`). Falls back to `SIGNALWIRE_SPACE`. + + + + SignalWire project ID. Falls back to `SIGNALWIRE_PROJECT_ID`. + + + + SignalWire API token. Falls back to `SIGNALWIRE_TOKEN`. + - - Custom tool name for this instance. Required when using multiple instances. + + DataSphere document ID to search within. - - SignalWire space name. Falls back to the `SIGNALWIRE_SPACE` environment variable. + + Number of results to return (range `1-10`). - - SignalWire project ID. Falls back to the `SIGNALWIRE_PROJECT_ID` environment variable. + + Maximum distance threshold (range `0-10`; lower is more relevant). - - SignalWire auth token. Falls back to the `SIGNALWIRE_TOKEN` environment variable. + + Tags to filter search results. - - Restrict search to a specific document ID. + + Language code for query expansion (e.g., `"en"`, `"es"`). - - Maximum number of results to return. + + Parts of speech to expand with synonyms. Each entry must be one of + `"NOUN"`, `"VERB"`, `"ADJ"`, `"ADV"`. - - Maximum distance threshold for results (0-1, lower is more similar). + + Maximum number of synonyms used for query expansion (range `1-10`). -```typescript {6-9} + + Message returned when no results match the query. + + +## Example + +```typescript {6-11} import { AgentBase, DataSphereSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new DataSphereSkill({ - max_results: 3, - distance_threshold: 0.5, + document_id: 'doc_1234', + count: 3, + distance: 2.5, + tool_name: 'search_product_docs', })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx index a0d9396bf..72cfd6578 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx @@ -144,20 +144,20 @@ them with the `SkillRegistry`. ### Defining a Custom Skill -```typescript {10} +```typescript {10-14} import { SkillBase, FunctionResult } from '@signalwire/sdk'; import type { - SkillManifest, SkillToolDefinition, SkillPromptSection, - SkillConfig, ParameterSchemaEntry, } from '@signalwire/sdk'; export class StockPriceSkill extends SkillBase { - constructor(config?: SkillConfig) { - super('stock_price', config); - } + // Identity is declared with static class constants. + static override SKILL_NAME = 'stock_price'; + static override SKILL_DESCRIPTION = 'Look up current stock prices.'; + static override SKILL_VERSION = '1.0.0'; + static override REQUIRED_ENV_VARS = ['STOCK_API_KEY'] as const; static override getParameterSchema(): Record { return { @@ -172,16 +172,7 @@ export class StockPriceSkill extends SkillBase { }; } - getManifest(): SkillManifest { - return { - name: 'stock_price', - description: 'Look up current stock prices.', - version: '1.0.0', - requiredEnvVars: ['STOCK_API_KEY'], - }; - } - - getTools(): SkillToolDefinition[] { + override getTools(): SkillToolDefinition[] { return [ { name: 'get_stock_price', @@ -226,7 +217,7 @@ import { SkillRegistry } from '@signalwire/sdk'; import { StockPriceSkill } from './stock-price-skill.js'; const registry = SkillRegistry.getInstance(); -registry.register('stock_price', (config) => new StockPriceSkill(config)); +registry.register(StockPriceSkill); // pass the class; name comes from SKILL_NAME ``` ### Using a Custom Skill diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/info-gatherer.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/info-gatherer.mdx index e59bd42b9..7175a1244 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/info-gatherer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/info-gatherer.mdx @@ -1,61 +1,64 @@ --- title: "InfoGathererSkill" slug: /reference/typescript/agents/skills/info-gatherer -description: Collect structured information from the user based on configurable fields. +description: Gather answers to a configurable list of questions, one at a time. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Collect structured information from the user based on configurable fields. Fields -support optional validation patterns and required/optional flags. Collected data -can be stored in global data. +Collect answers to a configured list of questions. The skill registers a +`start_questions` tool and a `submit_answer` tool; the agent advances through +the question list and reports completion when every question is answered. + +Fails closed during `setup()` when `questions` is missing or invalid. **Class:** `InfoGathererSkill` -**Tools:** `save_info`, `get_gathered_info` +**Tools:** `start_questions`, `submit_answer` (names are prefixed when +`prefix` is set) **Env vars:** None -[]"} toc={true}> - Array of field definitions to collect. Each object has: - - `name` (string, required) -- Field name used as the parameter key. - - `description` (string, required) -- Description of what this field collects. - - `required` (boolean, optional) -- Whether this field must be provided. - - `validation` (string, optional) -- Regex pattern for validating the field value. - - `type` (string, optional) -- Parameter type for the tool schema (defaults to `"string"`). - +**Multi-instance:** yes - - A description of why this information is being collected (shown in prompt). + + Ordered list of questions to ask. Each question has: + + - `key_name` (string, required) — key used to store the caller's answer. + - `question_text` (string, required) — the question to ask. + - `confirm` (boolean) — when `true`, the agent asks the caller to confirm + the answer before moving on. + - `prompt_add` (string) — optional extra prompt text appended while this + question is active. - - Custom message returned after successful info collection. + + Optional prefix for tool names and the global-data namespace. When set, + tools are named `_start_questions` / `_submit_answer` and + state is stored under `skill:`. Required when loading multiple + `InfoGathererSkill` instances on the same agent. - - Whether to store gathered info in global data. + + Message returned after every question has been answered. Defaults to a + generic completion message. -```typescript {6-15} +## Example + +```typescript {6-14} import { AgentBase, InfoGathererSkill } from '@signalwire/sdk'; -const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); -agent.setPromptText('You are a helpful assistant.'); +const agent = new AgentBase({ name: 'intake', route: '/intake' }); +agent.setPromptText('Collect contact information for follow-up.'); await agent.addSkill(new InfoGathererSkill({ - purpose: 'Collect contact information for follow-up.', - fields: [ - { name: 'name', description: 'Full name', required: true }, - { - name: 'email', - description: 'Email address', - required: true, - validation: '^[\\w.+-]+@[\\w-]+\\.[\\w.]+$', - }, - { name: 'phone', description: 'Phone number', required: false }, + questions: [ + { key_name: 'full_name', question_text: 'What is your full name?' }, + { key_name: 'email', question_text: 'What is your email address?', confirm: true }, + { key_name: 'phone', question_text: 'What is your phone number?' }, ], - store_globally: true, + completion_message: 'Thanks — we will be in touch shortly.', })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx index 8d44b367f..153087531 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx @@ -1,45 +1,91 @@ --- title: "McpGatewaySkill" slug: /reference/typescript/agents/skills/mcp-gateway -description: Placeholder skill for future Model Context Protocol (MCP) server integration. +description: Bridge an MCP Gateway server into SWAIG functions for the agent. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Placeholder skill for future Model Context Protocol (MCP) server integration. -Currently provides a stub `mcp_invoke` tool. +Bridge a Model Context Protocol (MCP) Gateway service with SWAIG functions. +The skill connects to the gateway at load time, enumerates the configured +services and tools, and registers each as a SWAIG function on the agent. + +The gateway URL is validated by an SSRF guard — private, loopback, and +cloud-metadata endpoints are rejected. Requests use retry semantics with +`retry_attempts` and a per-request timeout of `request_timeout` seconds. **Class:** `McpGatewaySkill` -**Tools:** `mcp_invoke` (placeholder, not yet functional) +**Tools:** Dynamically registered from the gateway (prefixed by `tool_prefix`) -**Env vars:** None +**Required packages:** `undici` - - URL of the MCP gateway server. - +**Env vars:** `MCP_GATEWAY_AUTH_TOKEN`, `MCP_GATEWAY_AUTH_USER`, +`MCP_GATEWAY_AUTH_PASSWORD` - - Prefix for tool names from this gateway. + + URL of the MCP Gateway service. Must pass the SSRF guard. - Authentication token for the MCP gateway. + Bearer token for authentication. Falls back to the + `MCP_GATEWAY_AUTH_TOKEN` environment variable. Takes precedence over + basic auth when provided. + + + + Basic-auth username (used when `auth_token` is not supplied). Falls back + to `MCP_GATEWAY_AUTH_USER`. + + + + Basic-auth password. Falls back to `MCP_GATEWAY_AUTH_PASSWORD`. + + + + Services to expose. Each entry has: + + - `name` (string) — service name registered on the gateway. + - `tools` (`"*"` or `string[]`) — which tools to expose from that service. + + Empty array exposes every available service/tool. + + + + Gateway session timeout in seconds. + + + + Prefix prepended to each SWAIG function name registered from the gateway. + + + + Number of retry attempts for failed requests. + + + + Per-request timeout in seconds. + + + + Whether to verify SSL certificates on outbound requests. - -This skill is a placeholder. The `mcp_invoke` tool returns a "not yet implemented" -message. Full MCP integration is planned for a future release. - +## Example -```typescript {6-8} +```typescript {6-13} import { AgentBase, McpGatewaySkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new McpGatewaySkill({ - gateway_url: 'http://localhost:8080', + gateway_url: 'https://mcp.internal.example.com', + services: [ + { name: 'search', tools: '*' }, + { name: 'calendar', tools: ['list_events', 'create_event'] }, + ], + tool_prefix: 'mcp_', })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx index 92bd9defe..32d9e776b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx @@ -1,56 +1,119 @@ --- title: "NativeVectorSearchSkill" slug: /reference/typescript/agents/skills/native-vector-search -description: In-memory document search using TF-IDF-like word overlap scoring. +description: Vector + keyword document search against a local .swsearch index or remote search server. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -In-memory document search using TF-IDF-like word overlap scoring. No external -dependencies or API keys required. Documents are provided via config and indexed -at construction time. +Search documents using vector similarity and keyword matching. Supports two +backends: + +- **Local (SQLite)** — point `index_file` at a `.swsearch` index, or set + `build_index: true` and `source_dir` to index at startup. +- **Remote (network)** — point `remote_url` at a search server and optionally + name the index via `index_name`. + +The remote mode enforces an SSRF guard before each request and uses a 5-second +health-check timeout. **Class:** `NativeVectorSearchSkill` -**Tools:** `search_documents` +**Tools:** `search_documents` (default — `tool_name` override supported) **Env vars:** None -**Multi-instance:** Yes +**Multi-instance:** yes - Custom tool name for this instance. Required when using multiple instances. + Custom tool name for this instance. Set when registering multiple + NativeVectorSearch instances on the same agent. + + + + Path to a local `.swsearch` SQLite index file. + + + + When `true`, the skill builds an in-process index at startup from + `source_dir`. + + + + Directory containing documents to index. Required when `build_index` is + `true`. + + + + URL of the remote search server (network mode). Validated by the SSRF guard. + + + + Name of the index on the remote server (network mode only). + + + + Number of results to return (range `1-20`). + + + + Minimum similarity score (0.0 — no limit, 1.0 — exact match). + + + + Tag filter applied to search queries. + + + + Tags applied to every indexed document at build time. + + + + File extensions to include when building an index. -[]"} toc={true}> - Array of documents to index. Each object has: - - `id` (string, required) -- Unique document identifier. - - `text` (string, required) -- Full text content of the document. - - `metadata` (object, optional) -- Metadata associated with the document. + + Glob patterns excluded from index builds. Defaults include `**/node_modules/**`, + `**/.git/**`, `**/dist/**`, `**/build/**`. - - Default number of top results to return. + + Message returned when no results match. Supports `{query}` placeholder. + Defaults to `"No information found for '{query}'"`. - - Minimum relevance score threshold. + + Prefix prepended to the search response. -```typescript {6-13} + + Suffix appended to the search response. + + +## Example — local index + +```typescript {6-10} import { AgentBase, NativeVectorSearchSkill } from '@signalwire/sdk'; -const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); -agent.setPromptText('You are a helpful assistant.'); +const agent = new AgentBase({ name: 'kb-bot', route: '/kb' }); +agent.setPromptText('Answer questions from the knowledge base.'); await agent.addSkill(new NativeVectorSearchSkill({ - tool_name: 'search_faqs', - documents: [ - { id: 'faq-1', text: 'To reset your password, visit the settings page...' }, - { id: 'faq-2', text: 'Refund requests must be submitted within 30 days...' }, - ], - num_results: 3, + tool_name: 'search_kb', + index_file: './kb.swsearch', + count: 5, })); agent.run(); ``` + +## Example — remote server + +```typescript {6-9} +await agent.addSkill(new NativeVectorSearchSkill({ + remote_url: 'https://search.internal.example.com', + index_name: 'support-kb', + count: 3, + similarity_threshold: 0.4, +})); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx index ec85f4d45..f563167d1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx @@ -1,36 +1,95 @@ --- title: "SpiderSkill" slug: /reference/typescript/agents/skills/spider -description: Scrape webpage content using the Spider API. +description: Fast web scraping and crawling using cheerio-based extraction with SSRF protection. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Scrape webpage content using the Spider API. Extracts text or markdown from any -public URL, with optional CSS selector filtering. +Fast web scraping and crawling. Extracts text, markdown, or structured data +from any public URL, optionally following links up to a bounded depth. Uses +`cheerio` for parsing and enforces an SSRF guard on crawl hops. **Class:** `SpiderSkill` **Tools:** `scrape_url` -**Env vars:** `SPIDER_API_KEY` +**Required packages:** `cheerio` - - Spider API key. Falls back to the `SPIDER_API_KEY` environment variable. +**Env vars:** None + + + Delay between requests in seconds (minimum `0`). + + + + Number of concurrent requests allowed (range `1-20`). + + + + Per-request timeout in seconds (range `1-60`). + + + + Maximum number of pages to scrape (range `1-100`). + + + + Maximum crawl depth. `0` restricts to a single page; range `0-5`. + + + + Content extraction method. One of `"fast_text"`, `"clean_text"`, + `"full_text"`, `"html"`, `"markdown"`, `"structured"`, `"custom"`. + + + + Maximum extracted text length in characters (range `100-100000`). - - Maximum length of returned content in characters. + + Whether to clean extracted text (trim whitespace, collapse runs, etc.). -```typescript {6-8} +"} default="{}" toc={true}> + Map of name → CSS selector used for structured extraction. + + + + URL patterns to follow when crawling. + + + + User-Agent header for outbound requests. Defaults to a Chrome-compatible + UA string. + + +"} default="{}" toc={true}> + Additional HTTP headers sent with each request. + + + + Whether to respect `robots.txt`. Defaults to `false` to match Python's + runtime behavior. + + + + Whether to cache scraped pages in memory. + + +## Example + +```typescript {6-11} import { AgentBase, SpiderSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); -agent.setPromptText('You are a helpful assistant.'); +agent.setPromptText('You are a research assistant.'); await agent.addSkill(new SpiderSkill({ - max_content_length: 10000, + extract_type: 'markdown', + max_pages: 5, + max_depth: 1, + follow_patterns: ['/docs/'], })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx index e8b573bd7..f38b77879 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx @@ -1,37 +1,85 @@ --- title: "SwmlTransferSkill" slug: /reference/typescript/agents/skills/swml-transfer -description: Transfer calls using SWML transfer actions. +description: Transfer calls between agents/endpoints based on pattern matching. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Transfer calls using SWML transfer actions. Supports named pattern-based transfers -with friendly destination names, or arbitrary direct-destination transfers. +Transfer calls between agents or endpoints using SWML transfer actions. The +skill accepts either a **Python-style `transfers`** config (regex pattern → +per-entry config) or a **TypeScript-style `patterns`** array of named +destinations. At least one of the two shapes is required — `setup()` fails +closed otherwise. **Class:** `SwmlTransferSkill` -**Tools:** `transfer_call` (always), `list_transfer_destinations` (when `patterns` are configured) +**Tools:** `transfer_call` (always registered) **Env vars:** None -[]"} toc={true}> - Array of named transfer patterns. Each object has: - - `name` (string, required) -- Friendly name for the destination. - - `destination` (string, required) -- SIP URI, phone number, or agent URL. - - `description` (string, optional) -- Human-readable description. +"} required={true} toc={true}> + Python-style map of transfer configs keyed by regex pattern (or name). Each + entry includes either `url` or `address` (not both), plus optional + `message`, `return_message`, `post_process`, `final`, and `from_addr`. + + Either `transfers` or `patterns` must be provided; both may be combined. + + + + TypeScript-style array of named transfer patterns. Each object has: + + - `name` (string, required) — friendly name for the destination. + - `destination` (string, required) — SIP URI, phone number, or agent URL. + - `description` (string) — optional human-readable description. + - `message` / `returnMessage` / `postProcess` / `final` / `fromAddr` — + optional per-pattern overrides. - Whether to allow transfers to arbitrary destinations not in the patterns list. - Defaults to `true` when no patterns are configured, `false` when patterns exist. + Whether to allow transfers to arbitrary destinations not listed in + `patterns` / `transfers`. When unset, defaults depend on whether any + patterns are configured. + + + + Name of the transfer tool exposed to the AI. + + + + Description for the transfer tool shown to the AI. + + + + Name of the parameter that accepts the transfer type. + + + + Description for the transfer-type parameter. + + + + Message spoken when no pattern matches. + + + + Whether to post-process the default message with the AI. - - Default message to say before transferring. +"} default="{}" toc={true}> + Map of additional fields (name → description) the agent must collect before + a transfer. -```typescript {6-16} + +Regex patterns in `transfers` are matched **case-sensitively**. Use character +classes or flags in the source pattern when case-insensitive matching is +needed. + + +## Example — TypeScript patterns + +```typescript {6-20} import { AgentBase, SwmlTransferSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); @@ -50,7 +98,25 @@ await agent.addSkill(new SwmlTransferSkill({ description: 'Technical support line', }, ], - default_message: 'Let me connect you now.', + default_message: 'Please specify sales or support.', +})); + +agent.run(); +``` + +## Example — Python-style transfers + +```typescript {6-14} +import { AgentBase, SwmlTransferSkill } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +agent.setPromptText('You are a helpful assistant.'); + +await agent.addSkill(new SwmlTransferSkill({ + transfers: { + '^sales$': { address: 'sip:sales@signalwire.com' }, + '^support$': { url: 'https://your-server.com/support-agent' }, + }, })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx index 51187f78c..dcedc2ee4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx @@ -1,45 +1,80 @@ --- title: "WebSearchSkill" slug: /reference/typescript/agents/skills/web-search -description: Search the web using the Google Custom Search JSON API. +description: Search the web via Google Custom Search, scrape results, and quality-filter the output. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Search the web using the Google Custom Search JSON API. Returns titles, links, -and snippets. +Search the web using the Google Custom Search JSON API. The skill fetches +more results than requested, scrapes each page, scores the extracted +content, and returns only the highest-quality matches to the AI. **Class:** `WebSearchSkill` **Tools:** `web_search` -**Env vars:** `GOOGLE_SEARCH_API_KEY`, `GOOGLE_SEARCH_CX` +**Env vars:** `GOOGLE_SEARCH_API_KEY`, `GOOGLE_SEARCH_ENGINE_ID` (legacy +`GOOGLE_SEARCH_CX` is still accepted) - Google Custom Search API key. Falls back to the `GOOGLE_SEARCH_API_KEY` environment variable. + Google Custom Search API key. Falls back to the `GOOGLE_SEARCH_API_KEY` + environment variable. - Google Custom Search Engine ID (CX). Falls back to the `GOOGLE_SEARCH_CX` environment variable. + Google Custom Search Engine ID. Falls back to the + `GOOGLE_SEARCH_ENGINE_ID` environment variable (or the legacy + `GOOGLE_SEARCH_CX`). - - Maximum number of results to return (1-10). + + Custom tool name for this Web Search instance (useful when registering + multiple instances at once). - - Safe search level: `"off"`, `"medium"`, or `"high"`. + + Number of high-quality results to return (range `1-10`). -```typescript {6-9} + + Delay between scraping pages in seconds (minimum `0`). + + + + Maximum total response size in characters (minimum `1000`). + + + + How many extra results to fetch for quality filtering — e.g. `2.5` fetches + 2.5× the requested `num_results` before scoring. Range `1.0-3.5`. + + + + Minimum quality score (0–1) required to include a result. + + + + Message returned when no quality results are found. Use `{query}` as a + placeholder for the original search term. + + + + Safe-search level. One of `"off"`, `"medium"`, `"high"`. + + +## Example + +```typescript {6-10} import { AgentBase, WebSearchSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new WebSearchSkill({ - max_results: 3, + num_results: 3, safe_search: 'high', + min_quality_score: 0.4, })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx index 6922b1826..9bf2ef0e0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx @@ -1,40 +1,38 @@ --- title: "WikipediaSearchSkill" slug: /reference/typescript/agents/skills/wikipedia-search -description: Search Wikipedia for article summaries and extracts. +description: Search Wikipedia for article summaries. No API key required. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Search Wikipedia for article summaries and extracts. No API key required. +Search Wikipedia for information about a topic and return article summaries. +Uses Node's native `fetch` with a 10-second timeout. No API key required. **Class:** `WikipediaSearchSkill` -**Tools:** `search_wikipedia` +**Tools:** `search_wiki` **Env vars:** None - - Wikipedia language edition to search (e.g., `"en"`, `"fr"`, `"de"`). + + Maximum number of Wikipedia articles to return (range `1-5`). - - Maximum number of search results to consider. + + Custom message returned when no articles match the query. - - Maximum length of returned content in characters. - +## Example -```typescript {6-9} +```typescript {6-8} import { AgentBase, WikipediaSearchSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new WikipediaSearchSkill({ - language: 'en', - max_results: 1, + num_results: 2, })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx index 6cdc4b270..8b6fb3597 100644 --- a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx @@ -19,6 +19,13 @@ method for discovering available numbers and uses PUT for updates. Access via `client.phoneNumbers` on a [`RestClient`][restclient] instance. + +**Idiomatic deviation:** `create()` and `update()` accept an untyped body +object (`Record`) rather than narrow per-field types. This +mirrors Python's `**kwargs`-style flexibility. Response payloads follow the +same typing. + + ```typescript {9} import { RestClient } from "@signalwire/sdk"; diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/rest-error.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/rest-error.mdx index 15757fa3c..8cd7c7bc0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/rest/rest-error.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/rest/rest-error.mdx @@ -9,6 +9,8 @@ Custom error class for REST API errors. Extends JavaScript's built-in `Error` class. Thrown when an HTTP request to the SignalWire REST API returns a non-success status code. The `name` property is always `"RestError"`. +Also exported as `SignalWireRestError` to match the Python SDK class name. + ```typescript {1} import { RestError } from '@signalwire/sdk'; ``` @@ -19,8 +21,10 @@ import { RestError } from '@signalwire/sdk'; HTTP status code returned by the API (e.g., `404`, `422`, `500`). - - Raw response body from the API. +"} toc={true}> + Response body from the API. Parsed as JSON when the response was valid + JSON; otherwise the raw text. Matches the Python SDK's + `SignalWireRestError.body` behavior. diff --git a/fern/products/server-sdks/sdk-source-sync.json b/fern/products/server-sdks/sdk-source-sync.json index 3d6076acd..020813ab4 100644 --- a/fern/products/server-sdks/sdk-source-sync.json +++ b/fern/products/server-sdks/sdk-source-sync.json @@ -12,8 +12,8 @@ "repository": "https://github.com/signalwire/signalwire-typescript.git", "local_path": "temp/signalwire-typescript", "status": "active", - "synced_commit": "f7144ab40505f365e554332e891b38b3a5e2f670", - "synced_at": "2026-04-08" + "synced_commit": "ba6d5b1f1c68065bb378ab9c1a79c4a08da107e1", + "synced_at": "2026-04-21" }, "go": { "repository": "https://github.com/signalwire/signalwire-go.git", diff --git a/fern/products/server-sdks/server-sdks.yml b/fern/products/server-sdks/server-sdks.yml index ffdc5d163..d6eaedb2f 100644 --- a/fern/products/server-sdks/server-sdks.yml +++ b/fern/products/server-sdks/server-sdks.yml @@ -21,44 +21,35 @@ navigation: title: Deploy - tab: reference - layout: - - folder: ./pages/reference/python/core - title: Core - - folder: ./pages/reference/python/agents - title: Agents - - folder: ./pages/reference/python/relay - title: RELAY - - folder: ./pages/reference/python/rest - title: REST Client - # variants: - # - title: Python - # icon: brands fa-python - # default: true - # layout: - # - folder: ./pages/reference/python/core - # title: Core - # collapsed: false - # - folder: ./pages/reference/python/agents - # title: Agents - # collapsed: false - # - folder: ./pages/reference/python/relay - # title: RELAY - # collapsed: false - # - folder: ./pages/reference/python/rest - # title: REST Client - # collapsed: false - # - title: TypeScript - # icon: brands fa-typescript - # layout: - # - folder: ./pages/reference/typescript/core - # title: Core - # collapsed: false - # - folder: ./pages/reference/typescript/agents - # title: Agents - # collapsed: false - # - folder: ./pages/reference/typescript/relay - # title: RELAY - # collapsed: false - # - folder: ./pages/reference/typescript/rest - # title: REST Client - # collapsed: false + variants: + - title: Python + icon: brands fa-python + default: true + layout: + - folder: ./pages/reference/python/core + title: Core + collapsed: false + - folder: ./pages/reference/python/agents + title: Agents + collapsed: false + - folder: ./pages/reference/python/relay + title: RELAY + collapsed: false + - folder: ./pages/reference/python/rest + title: REST Client + collapsed: false + - title: TypeScript + icon: brands fa-js + layout: + - folder: ./pages/reference/typescript/core + title: Core + collapsed: false + - folder: ./pages/reference/typescript/agents + title: Agents + collapsed: false + - folder: ./pages/reference/typescript/relay + title: RELAY + collapsed: false + - folder: ./pages/reference/typescript/rest + title: REST Client + collapsed: false From 5f8093b3c8baca4d28c8b1f5ac30f06467ea60c3 Mon Sep 17 00:00:00 2001 From: august l-r Date: Wed, 22 Apr 2026 15:57:05 +0000 Subject: [PATCH 02/21] tracker --- .../typescript-sdk-audit-tracker.md | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 fern/products/server-sdks/typescript-sdk-audit-tracker.md diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md new file mode 100644 index 000000000..9d89c1ebb --- /dev/null +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -0,0 +1,206 @@ +# TypeScript SDK Audit Tracker + +## SDK Identity + +- **Language:** TypeScript +- **Package name:** `@signalwire/sdk` +- **Version:** 2.0.0 +- **Main import:** `import { RestClient } from '@signalwire/sdk';` +- **Source repo:** https://github.com/signalwire/signalwire-typescript +- **Local path:** `temp/signalwire-typescript` +- **Source commit:** `ba6d5b1f1c68065bb378ab9c1a79c4a08da107e1` (2026-04-21) +- **Prior synced commit:** `f7144ab40505f365e554332e891b38b3a5e2f670` (2026-04-08) +- **Delta:** 132 commits — alignment sweep + skills infra refactor + v2.0.0 tag + +## Audit Scope (this run) + +REST namespace (`pages/reference/typescript/rest/**`). ~384 MDX files across +22 namespaces. + +## Full Inventory — REST + +Order: largest class first. + +| Status | Namespace | Files | Source | +|--------|-----------|-------|--------| +| AUDITED -- NO ISSUES | `fabric/` | 112 | `src/rest/namespaces/fabric.ts` | +| AUDITED -- NO ISSUES | `compat/` | 91 | `src/rest/namespaces/compat.ts` | +| AUDITED -- NO ISSUES | `video/` | 38 | `src/rest/namespaces/video.ts` | +| AUDITED -- NO ISSUES | `calling/` | 38 | `src/rest/namespaces/calling.ts` | +| AUDITED -- NO ISSUES | `registry/` | 15 | `src/rest/namespaces/registry.ts` | +| AUDITED -- NO ISSUES | `logs/` | 13 | `src/rest/namespaces/logs.ts` | +| AUDITED -- NO ISSUES | `number-groups/` | 10 | `src/rest/namespaces/number-groups.ts` | +| AUDITED -- NO ISSUES | `datasphere/` | 10 | `src/rest/namespaces/datasphere.ts` | +| AUDITED -- NO ISSUES | `queues/` | 9 | `src/rest/namespaces/queues.ts` | +| AUDITED -- NO ISSUES | `verified-callers/` | 8 | `src/rest/namespaces/verified-callers.ts` | +| AUDITED -- NO ISSUES | `phone-numbers/` | 7 | `src/rest/namespaces/phone-numbers.ts` | +| AUDITED -- NO ISSUES | `addresses/` | 5 | `src/rest/namespaces/addresses.ts` | +| AUDITED -- NO ISSUES | `short-codes/` | 4 | `src/rest/namespaces/short-codes.ts` | +| AUDITED -- NO ISSUES | `recordings/` | 4 | `src/rest/namespaces/recordings.ts` | +| AUDITED -- NO ISSUES | `project/` | 4 | `src/rest/namespaces/project.ts` | +| AUDITED -- NO ISSUES | `mfa/` | 4 | `src/rest/namespaces/mfa.ts` | +| AUDITED -- NO ISSUES | `sip-profile/` | 3 | `src/rest/namespaces/sip-profile.ts` | +| AUDITED -- NO ISSUES | `pubsub/` | 2 | `src/rest/namespaces/pubsub.ts` | +| AUDITED -- NO ISSUES | `lookup/` | 2 | `src/rest/namespaces/lookup.ts` | +| AUDITED -- NO ISSUES | `imported-numbers/` | 2 | `src/rest/namespaces/imported-numbers.ts` | +| AUDITED -- NO ISSUES | `chat/` | 2 | `src/rest/namespaces/chat.ts` | +| AUDITED -- NO ISSUES | `client/` | 1 | `src/rest/index.ts` | +| AUDITED -- NO ISSUES | root (`overview.mdx`, `rest-error.mdx`) | 2 | `src/rest/RestError.ts` | + +## Findings Log + +_(One line per finding and per fix. Format: `[path/to/file.mdx] PRIORITY type: description`)_ + +### fabric/ + +- `[fabric/index.mdx]` NO ISSUES — 16 sub-resource list matches source; PATCH/PUT note verified. +- `[fabric/ai-agents/*]` NO ISSUES — all 7 files (index + 6 methods) verified against `FabricResource` extending `CrudWithAddresses`; endpoint paths, HTTP methods, and example signatures match source. +- `[fabric/call-flows/*]` NO ISSUES — all 9 files verified against `CallFlowsResource` (extends `FabricResourcePUT`). PUT update confirmed. Singular `/call_flow/{id}/addresses` + `/versions` + POST `/versions` paths match source. +- `[fabric/subscribers/*]` NO ISSUES — all 12 files verified against `SubscribersResource`. PUT update, PATCH on `updateSipEndpoint`, and all 5 SIP-endpoint method paths match source. +- `[fabric/conference-rooms/*]` NO ISSUES — 7 files verified against `ConferenceRoomsResource`. Singular `/conference_room/{id}/addresses` override confirmed. +- `[fabric/cxml-applications/*]` NO ISSUES — 6 files verified against `CxmlApplicationsResource`. No `create.mdx` (source's `create()` throws). PUT update confirmed. +- `[fabric/swml-scripts/*]` NO ISSUES — 7 files verified. PUT update, basePath `/swml_scripts` confirmed. +- `[fabric/relay-applications/*]` NO ISSUES — 7 files verified. PUT, basePath `/relay_applications` confirmed. +- `[fabric/sip-endpoints/*]` NO ISSUES — 7 files verified. PUT, basePath `/sip_endpoints` confirmed. Index correctly cross-links to subscribers nested variant. +- `[fabric/cxml-scripts/*]` NO ISSUES — 7 files verified. PUT, basePath `/cxml_scripts` confirmed. +- `[fabric/freeswitch-connectors/*]` NO ISSUES — 7 files verified. PUT, basePath `/freeswitch_connectors` confirmed. +- `[fabric/swml-webhooks/*]` NO ISSUES — 7 files verified. PATCH, basePath `/swml_webhooks` confirmed. +- `[fabric/sip-gateways/*]` NO ISSUES — 7 files verified. PATCH, basePath `/sip_gateways` confirmed. +- `[fabric/cxml-webhooks/*]` NO ISSUES — 7 files verified. PATCH, basePath `/cxml_webhooks` confirmed. +- `[fabric/resources/*]` NO ISSUES — 7 files verified against `GenericResources`. 6 methods (list, get, delete, listAddresses, assignPhoneRoute, assignDomainApplication) all match source paths. +- `[fabric/addresses.mdx]` NO ISSUES — single-page read-only resource (list + get) matches `FabricAddresses`. +- `[fabric/tokens/*]` NO ISSUES — 6 files verified against `FabricTokens`. All 5 token endpoints match source paths (note singular `/subscriber/invites`). + +### compat/ + +- `[compat/index.mdx]` NO ISSUES — 12-card CardGroup matches `CompatNamespace` source. URL structure `/2010-04-01/Accounts/{AccountSid}/` correctly documented. +- `[compat/accounts/*]` NO ISSUES — 5 files verified against `CompatAccounts` (non-AccountSid-scoped basePath `/Accounts`). list/create/get/update; POST update. +- `[compat/applications/*]` NO ISSUES — 6 files verified against `CompatApplications` (CrudResource + POST update). +- `[compat/calls/*]` NO ISSUES — 10 files verified against `CompatCalls`. CRUD + 4 sub-resource methods (startRecording, updateRecording, startStream, stopStream) all POST with correct paths. +- `[compat/conferences/*]` NO ISSUES — 14 files verified against `CompatConferences`. No create (source has none). 13 methods across CRUD, participants (4), recordings (4), streams (2) all match. +- `[compat/faxes/*]` NO ISSUES — 9 files verified against `CompatFaxes`. CRUD + media sub-resources (list/get/delete) match source. +- `[compat/laml-bins/*]` NO ISSUES — 6 files verified against `CompatLamlBins` (CrudResource + POST update). +- `[compat/messages/*]` NO ISSUES — 9 files verified against `CompatMessages`. CRUD + media sub-resources match. +- `[compat/phone-numbers/*]` NO ISSUES — 10 files verified against `CompatPhoneNumbers`. 9 methods incl. `importNumber` → `/ImportedPhoneNumbers`, and `searchLocal`/`searchTollFree`/`listAvailableCountries` → `/AvailablePhoneNumbers` path-replacement all match source. +- `[compat/queues/*]` NO ISSUES — 9 files verified against `CompatQueues`. CRUD + member sub-resources match. +- `[compat/recordings/*]` NO ISSUES — 4 files verified against `CompatRecordings` (read-only list/get/delete). +- `[compat/tokens/*]` NO ISSUES — 4 files verified against `CompatTokens`. `update` correctly documented as PATCH (unique exception vs all other compat updates which are POST). +- `[compat/transcriptions/*]` NO ISSUES — 4 files verified against `CompatTranscriptions` (read-only list/get/delete). + +### video/ + +- `[video/index.mdx]` NO ISSUES — 7-card CardGroup matches `VideoNamespace` source. +- `[video/rooms/*]` NO ISSUES — 8 files verified against `VideoRooms` (CrudResource with PUT update + listStreams + createStream). +- `[video/room-tokens/*]` NO ISSUES — 2 files verified against `VideoRoomTokens` (create only). +- `[video/room-sessions/*]` NO ISSUES — 6 files verified against `VideoRoomSessions` (list, get, listEvents, listMembers, listRecordings). +- `[video/room-recordings/*]` NO ISSUES — 5 files verified against `VideoRoomRecordings` (list, get, delete, listEvents). +- `[video/conferences/*]` NO ISSUES — 9 files verified against `VideoConferences` (CrudResource with PUT update + listConferenceTokens + listStreams + createStream). +- `[video/conference-tokens/*]` NO ISSUES — 3 files verified against `VideoConferenceTokens` (get, reset). +- `[video/streams/*]` NO ISSUES — 4 files verified against `VideoStreams` (get, update with PUT, delete). + +### calling/ + +- `[calling/index.mdx]` NO ISSUES — 14-section CardGroup totals 37 methods, matching `CallingNamespace` source. +- `[calling/*]` (37 method files) NO ISSUES — every file audited: all dispatch POST `/api/calling/calls`, signatures match source (`(params)` for `dial`/`update`, `(callId, params)` for the other 35). `sendFaxStop` and `receiveFaxStop` doc notes that initiation happens via the Relay client are correct. + +### registry/ + +- `[registry/index.mdx]` NO ISSUES — 4-resource CardGroup matches `RegistryNamespace`. Beta-path note documented. +- `[registry/brands/*]` NO ISSUES — 6 files verified against `RegistryBrands` (list, create, get, listCampaigns, createCampaign). +- `[registry/campaigns/*]` NO ISSUES — 6 files verified against `RegistryCampaigns` (get, update with PUT, listNumbers, listOrders, createOrder). +- `[registry/orders.mdx]` NO ISSUES — single-page for `RegistryOrders` (get only). +- `[registry/numbers.mdx]` NO ISSUES — single-page for `RegistryNumbers` (delete only). + +### logs/ + +- `[logs/index.mdx]` NO ISSUES — 4-sub-resource CardGroup matches `LogsNamespace`. +- `[logs/messages/*]` NO ISSUES — 3 files (list, get) verified against `MessageLogs` (`/api/messaging/logs`). +- `[logs/voice/*]` NO ISSUES — 4 files (list, get, listEvents) verified against `VoiceLogs` (`/api/voice/logs`). +- `[logs/fax/*]` NO ISSUES — 3 files (list, get) verified against `FaxLogs` (`/api/fax/logs`). +- `[logs/conferences/*]` NO ISSUES — 2 files (list only) verified against `ConferenceLogs` (`/api/logs/conferences`). Doc correctly notes no `get()` exists. + +### number-groups/ + +- `[number-groups/*]` NO ISSUES — 10 files verified against `NumberGroupsResource` (CrudResource PUT + listMemberships + addMembership + getMembership + deleteMembership). Top-level `/number_group_memberships/{id}` endpoint for get/delete correctly documented with Note. + +### datasphere/ + +- `[datasphere/*]` NO ISSUES — 10 files verified against `DatasphereDocuments` (CrudResource PATCH + search + listChunks + getChunk + deleteChunk). Flat folder layout; all examples correctly use `client.datasphere.documents.*`. + +### queues/ + +- `[queues/*]` NO ISSUES — 9 files verified against `QueuesResource` (CrudResource PUT + listMembers + getMember + getNextMember). + +### verified-callers/ + +- `[verified-callers/*]` NO ISSUES — 8 files verified against `VerifiedCallersResource` (CrudResource PUT + redialVerification + submitVerification). Verification sub-resource paths `/verified_caller_ids/{id}/verification` (POST redial, PUT submit) confirmed. + +### phone-numbers/ + +- `[phone-numbers/*]` NO ISSUES — 7 files verified against `PhoneNumbersResource` (CrudResource PUT + search). Index carries idiomatic-deviation note for Python-kwargs-style bodies. Search endpoint correctly maps to `/phone_numbers/search` GET. + +### addresses/ + +- `[addresses/*]` NO ISSUES — 5 files verified against `AddressesResource` (list, create, get, delete; no update). Index correctly notes absence of update. + +### short-codes/ + +- `[short-codes/*]` NO ISSUES — 4 files verified against `ShortCodesResource` (list, get, update with PUT; no create/delete). Index correctly notes pre-provisioned status. + +### recordings/ + +- `[recordings/*]` NO ISSUES — 4 files verified against `RecordingsResource` (list, get, delete; no create/update). + +### project/ + +- `[project/*]` NO ISSUES — 4 files verified against `ProjectTokens`. `update` correctly uses PATCH. + +### mfa/ + +- `[mfa/*]` NO ISSUES — 4 files verified against `MfaResource` (sms, call, verify). Sub-resource paths `/mfa/sms`, `/mfa/call`, `/mfa/{id}/verify` match source. + +### sip-profile/ + +- `[sip-profile/*]` NO ISSUES — 3 files verified against `SipProfileResource` (singleton get + PUT update). + +### pubsub/ + +- `[pubsub/*]` NO ISSUES — 2 files verified against `PubSubResource` (createToken only). Endpoint `/api/pubsub/tokens` POST matches source. + +### lookup/ + +- `[lookup/*]` NO ISSUES — 2 files verified against `LookupResource` (phoneNumber only). Endpoint `/api/relay/rest/lookup/phone_number/{e164}` matches source. + +### imported-numbers/ + +- `[imported-numbers/*]` NO ISSUES — 2 files verified against `ImportedNumbersResource` (create only). Endpoint `/api/relay/rest/imported_phone_numbers` POST matches. + +### chat/ + +- `[chat/*]` NO ISSUES — 2 files verified against `ChatResource` (createToken only). Endpoint `/api/chat/tokens` POST matches. + +### client/ + +- `[client/index.mdx]` NO ISSUES — Constructor params (project, token, host) and all 20 namespace `ParamField` entries match `RestClient` source exactly (fabric, calling, phoneNumbers, addresses, queues, recordings, numberGroups, verifiedCallers, sipProfile, lookup, shortCodes, importedNumbers, mfa, registry, datasphere, video, logs, project, pubsub, chat, compat). + +### REST root + +- `[rest/overview.mdx]` NO ISSUES — 10-card CardGroup covers major namespaces; `RestError` example accurate. +- `[rest/rest-error.mdx]` NO ISSUES — `body: string | Record` and `SignalWireRestError` alias both correctly documented (updated from prior session). + +--- + +## REST audit summary + +**All 384 MDX files across 22 REST namespaces audited clean** against source commit `ba6d5b1`. No discrepancies found. Every documented method, endpoint path, HTTP verb, and example signature matches the TypeScript source exactly. + +Key verified behaviors: +- Fabric `FabricResource` (4 classes) use PATCH default update; `FabricResourcePUT` (9 classes) overrides to PUT. +- `cxml-applications` correctly omits `create.mdx` (source `create()` throws). +- `conference-rooms` + `call-flows` `listAddresses` use singular `conference_room` / `call_flow` path (source override). +- `subscribers.updateSipEndpoint` correctly uses PATCH while its outer `update` uses PUT. +- Compat `tokens.update` uniquely uses PATCH (all other compat updates use POST). +- `RegistryCampaigns.update` uses PUT (source override on BaseResource). +- `NumberGroups.getMembership` / `deleteMembership` correctly document the top-level `/number_group_memberships/{id}` endpoint (not nested). +- Calling namespace: all 37 commands dispatch POST `/api/calling/calls`; signature shape `(params)` for `dial`/`update`, `(callId, params)` for the rest. + From 716a9acefe5d2d8a5d074b25738266785921751e Mon Sep 17 00:00:00 2001 From: august l-r Date: Wed, 22 Apr 2026 23:53:49 +0000 Subject: [PATCH 03/21] docs(ts-sdk): align agents reference with source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit sweep against signalwire-typescript@ba6d5b1. Covers agent-base, agent-server, prefabs, skills, swaig-function, swml-builder, swml-service, and all 7 configuration sub-classes (session-manager, schema-utils, prompt-manager, config-loader, serverless-adapter, ssl-config, auth-handler). Notable fixes: - session-manager/debug-token: wrong return shape (flat camelCase |null) vs nested DebugTokenResult with snake_case components/status - session-manager/get-session-metadata: typed `| undefined` but src uses `?? {}` — never undefined - auth-handler/middleware: `optional` param entirely undocumented - set-global-data / update-global-data: claimed "replace" but src uses safeAssign (merge) - on-function-call: Warning said hook can't intercept but src uses hookResult to short-circuit - swml-builder/say: doc claimed method didn't exist (src 195 defines it) - skills/google-maps, native-vector-search, play-background-file: wrong/missing tool names and config - Multiple stub pages fleshed out (reset-contexts, set-pronunciations, validate-tool-token, et al.) Tracker updated with per-class status and P4 coverage gaps for follow-up (config-loader mergeWithEnv/getSection, auth-handler verify* + expressMiddleware, swml-service ~14 undocumented methods). --- .../agents/agent-base/add-internal-filler.mdx | 14 +- .../agents/agent-base/add-pattern-hint.mdx | 5 + .../agent-base/auto-map-sip-usernames.mdx | 49 +- .../agent-base/clear-swaig-query-params.mdx | 35 +- .../agents/agent-base/define-tool.mdx | 15 +- .../agents/agent-base/define-typed-tool.mdx | 4 +- .../agents/agent-base/enable-debug-routes.mdx | 27 +- .../agent-base/get-basic-auth-credentials.mdx | 6 +- .../agents/agent-base/get-prompt-pom.mdx | 29 +- .../typescript/agents/agent-base/index.mdx | 28 +- .../agents/agent-base/on-function-call.mdx | 15 +- .../agents/agent-base/on-swml-request.mdx | 16 +- .../agent-base/register-swaig-function.mdx | 11 +- .../agent-base/remove-skill-by-name.mdx | 28 +- .../agents/agent-base/render-swml.mdx | 7 + .../agents/agent-base/reset-contexts.mdx | 31 +- .../typescript/agents/agent-base/run.mdx | 14 +- .../typescript/agents/agent-base/serve.mdx | 20 +- .../agent-base/set-function-includes.mdx | 36 +- .../agents/agent-base/set-global-data.mdx | 14 +- .../agent-base/set-internal-fillers.mdx | 40 +- .../agents/agent-base/set-prompt-pom.mdx | 37 +- .../agents/agent-base/set-pronunciations.mdx | 25 +- .../agents/agent-base/update-global-data.mdx | 10 +- .../agents/agent-base/validate-tool-token.mdx | 24 +- .../typescript/agents/agent-server/index.mdx | 27 +- .../agents/agent-server/routing-callback.mdx | 66 ++ .../typescript/agents/agent-server/run.mdx | 10 +- .../agents/agent-server/sip-routing.mdx | 116 +++ .../agents/agent-server/static-files.mdx | 4 +- .../agents/agent-server/unregister.mdx | 6 +- .../configuration/auth-handler/index.mdx | 8 +- .../configuration/auth-handler/middleware.mdx | 14 +- .../configuration/config-loader/index.mdx | 16 +- .../configuration/config-loader/search.mdx | 42 +- .../configuration/schema-utils/index.mdx | 6 + .../session-manager/debug-token.mdx | 101 ++- .../session-manager/get-session-metadata.mdx | 11 +- .../configuration/session-manager/index.mdx | 9 + .../session-manager/set-session-metadata.mdx | 32 +- .../agents/configuration/ssl-config/index.mdx | 9 + .../context-builder/context/add-step.mdx | 3 + .../context/set-initial-step.mdx | 2 +- .../context-builder/context/set-isolated.mdx | 11 +- .../context-builder/create-simple-context.mdx | 39 + .../agents/context-builder/index.mdx | 4 + .../agents/context-builder/reset.mdx | 5 +- .../step/add-gather-question.mdx | 15 + .../agents/context-builder/step/set-end.mdx | 16 +- .../context-builder/step/set-functions.mdx | 31 +- .../agents/context-builder/validate.mdx | 7 +- .../agents/function-result/execute-swml.mdx | 7 +- .../function-result/join-conference.mdx | 10 +- .../typescript/agents/function-result/tap.mdx | 6 +- .../reference/typescript/agents/helpers.mdx | 34 + .../agents/livewire/agent-session/index.mdx | 57 +- .../agents/livewire/agent-session/start.mdx | 8 +- .../typescript/agents/livewire/signals.mdx | 37 +- .../reference/typescript/agents/overview.mdx | 2 +- .../typescript/agents/prefabs/index.mdx | 8 +- .../agents/prefabs/receptionist-agent.mdx | 4 +- .../agents/prefabs/survey-agent.mdx | 2 + .../agents/skills/api-ninjas-trivia.mdx | 19 +- .../typescript/agents/skills/ask-claude.mdx | 3 +- .../agents/skills/datasphere-serverless.mdx | 19 +- .../typescript/agents/skills/datasphere.mdx | 8 +- .../typescript/agents/skills/datetime.mdx | 2 +- .../typescript/agents/skills/google-maps.mdx | 33 +- .../typescript/agents/skills/index.mdx | 28 +- .../typescript/agents/skills/joke.mdx | 8 +- .../typescript/agents/skills/mcp-gateway.mdx | 5 +- .../agents/skills/native-vector-search.mdx | 164 ++++- .../agents/skills/play-background-file.mdx | 76 +- .../typescript/agents/skills/spider.mdx | 20 +- .../agents/skills/swml-transfer.mdx | 18 +- .../typescript/agents/skills/weather-api.mdx | 23 +- .../typescript/agents/skills/web-search.mdx | 7 +- .../agents/skills/wikipedia-search.mdx | 5 +- .../agents/swaig-function/execute.mdx | 4 +- .../agents/swaig-function/index.mdx | 6 +- .../agents/swaig-function/validate-args.mdx | 54 ++ .../typescript/agents/swml-builder/index.mdx | 23 +- .../typescript/agents/swml-builder/reset.mdx | 2 +- .../typescript/agents/swml-builder/say.mdx | 56 +- .../agents/swml-service/get-builder.mdx | 6 +- .../typescript/agents/swml-service/index.mdx | 72 +- .../typescript/agents/swml-service/run.mdx | 38 +- .../typescript-sdk-audit-tracker.md | 678 ++++++++++++++++++ 88 files changed, 2394 insertions(+), 308 deletions(-) create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-server/routing-callback.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/agent-server/sip-routing.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/context-builder/create-simple-context.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/validate-args.mdx diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-internal-filler.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-internal-filler.mdx index 89b3a3d15..ed57076c3 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-internal-filler.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-internal-filler.mdx @@ -1,19 +1,27 @@ --- title: "addInternalFiller" slug: /reference/typescript/agents/agent-base/add-internal-filler -description: Add filler phrases for a specific SWAIG function and language. +description: Add filler phrases for a specific native SWAIG function and language. max-toc-depth: 3 --- [ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base -Add filler phrases spoken while a specific SWAIG function is executing. The AI +Add filler phrases spoken while a specific native SWAIG function is executing. The AI randomly selects from the list each time the function is invoked. + +Only a fixed set of native function names accept fillers: `hangup`, `check_time`, +`wait_for_user`, `wait_seconds`, `adjust_response_latency`, `next_step`, +`change_context`, `get_visual_input`, `get_ideal_strategy`. Passing any other name +logs a warning and is silently ignored by the runtime. + + ## **Parameters** - Name of the SWAIG function these fillers apply to (e.g., `"next_step"`, `"check_time"`). + One of the supported native function names (e.g., `"next_step"`, `"check_time"`). + Unknown names log a warning and are ignored. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-pattern-hint.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-pattern-hint.mdx index 5837f4a45..ce0bc0e14 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-pattern-hint.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/add-pattern-hint.mdx @@ -18,6 +18,10 @@ consistent misrecognitions or normalizing variations. + + Descriptive label for the hint (surfaced to the ASR alongside the pattern). + + Regular expression pattern to match. @@ -44,6 +48,7 @@ const agent = new AgentBase({ name: 'support', route: '/support' }); agent.setPromptText('You are a helpful assistant.'); // Correct common ASR misrecognition agent.addPatternHint({ + hint: 'SignalWire brand name', pattern: 'signal\\s*wire|signal\\s*wired', replace: 'SignalWire', ignoreCase: true, diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx index 4b45ca454..99b13c537 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/auto-map-sip-usernames.mdx @@ -1,13 +1,54 @@ --- title: "autoMapSipUsernames" slug: /reference/typescript/agents/agent-base/auto-map-sip-usernames -description: Auto-register the agent's route as the default SIP username target. +description: Automatically register common SIP usernames derived from the agent's name and route. max-toc-depth: 3 --- -Auto-register the agent's route as the default SIP username routing target. -Port of Python's `auto_map_sip_usernames()`. +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base +[enable-sip-routing]: /docs/server-sdks/reference/typescript/agents/agent-base/enable-sip-routing +[register-sip-username]: /docs/server-sdks/reference/typescript/agents/agent-base/register-sip-username + +Automatically register SIP usernames based on the agent's `name` and `route` +properties. Convenience method that derives common username variations so callers +can reach the agent via SIP without manual registration. + +The method registers: +- A lowercase, alphanumeric-only version of the agent name (e.g., `"supportagent"`) +- A lowercase, alphanumeric-only version of the route when different from the name +- A vowel-stripped abbreviation of the name when the cleaned name is longer than + 3 characters and the stripped result is longer than 2 characters + + +[`enableSipRouting()`][enable-sip-routing] calls this method automatically when +invoked without arguments. You only need to call `autoMapSipUsernames()` directly +to trigger it after disabling auto-mapping. + + +## **Parameters** + +None. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'Support Agent', route: '/support' }); +agent.setPromptText('You are a support assistant.'); +agent.autoMapSipUsernames(); +// Registers: "supportagent", "support", "spprtgnt" +await agent.serve(); +``` + +To register specific usernames instead, use +[`registerSipUsername()`][register-sip-username]: + +```typescript {2-3} +agent.registerSipUsername('helpdesk'); +agent.registerSipUsername('support'); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx index f07743a17..2ebde3100 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/clear-swaig-query-params.mdx @@ -1,12 +1,41 @@ --- title: "clearSwaigQueryParams" slug: /reference/typescript/agents/agent-base/clear-swaig-query-params -description: Remove every SWAIG query-param override set on the agent. +description: Remove all SWAIG query parameters from the agent. max-toc-depth: 3 --- -Remove every SWAIG query-param override set via `addSwaigQueryParams`. +[add-swaig-query-params]: /docs/server-sdks/reference/typescript/agents/agent-base/add-swaig-query-params +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base + +Clear all query parameters previously added with +[`addSwaigQueryParams()`][add-swaig-query-params]. After calling this method, +SWAIG webhook URLs will no longer include any extra query parameters. + +## **Parameters** + +None. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Examples** + +### Reset params in dynamic config + +```typescript {9} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +agent.setPromptText('You are a helpful assistant.'); + +agent.setDynamicConfigCallback((queryParams, bodyParams, headers, agentCopy) => { + // Start fresh each request to avoid stale params + agentCopy.clearSwaigQueryParams(); + const tier = queryParams.tier ?? 'free'; + agentCopy.addSwaigQueryParams({ tier }); +}); + +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-tool.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-tool.mdx index 04f2ab425..bec3e3dc4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-tool.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-tool.mdx @@ -53,8 +53,8 @@ instead. return a [`FunctionResult`][functionresult]. - - Whether to require token validation on tool calls. + + Whether to require token validation on tool calls. Recommended for production. "} toc={true}> @@ -73,6 +73,17 @@ instead. List of required parameter names from the JSON Schema. + + + External webhook URL. When set, the tool is treated as externally-hosted and + the tool call is forwarded to this URL instead of being dispatched to a local + handler. + + +"} toc={true}> + Additional fields merged into the SWAIG function definition. Equivalent to + Python's `**swaig_fields` kwargs (e.g., `meta_data`). + ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-typed-tool.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-typed-tool.mdx index ced64b153..b19976d55 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-typed-tool.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/define-typed-tool.mdx @@ -47,8 +47,8 @@ the args object. object. Parameter names must match the JSON Schema property names. - - Whether to require token validation on tool calls. + + Whether to require token validation on tool calls. Recommended for production. "} toc={true}> diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx index 42c80ffe5..2c8d56c04 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/enable-debug-routes.mdx @@ -1,13 +1,32 @@ --- title: "enableDebugRoutes" slug: /reference/typescript/agents/agent-base/enable-debug-routes -description: Expose the agent's debug HTTP endpoints. +description: Enable debug and testing routes on the agent's HTTP server. max-toc-depth: 3 --- -Expose the agent's debug HTTP endpoints on the Hono server. Use in -development to inspect live state; avoid in production. +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base + +Enable debug routes on the agent's Hono server for development and testing. In +the TypeScript SDK, debug routes (health, ready, debug_events) are automatically +registered in `getApp()`; this method exists as a no-op stub for API parity with +the Python SDK. + +## **Parameters** + +None. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'dev-agent', route: '/dev' }); +agent.setPromptText('You are a helpful assistant.'); +agent.enableDebugRoutes(); +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-basic-auth-credentials.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-basic-auth-credentials.mdx index ae5ae2c0d..a3c02db67 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-basic-auth-credentials.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-basic-auth-credentials.mdx @@ -13,8 +13,8 @@ includes a source label indicating where the credentials came from. When `true`, the returned tuple includes a third element indicating the credential source: `"provided"` (set explicitly), `"environment"` (from `SWML_BASIC_AUTH_USER` - / `SWML_BASIC_AUTH_PASSWORD` environment variables), or `"generated"` (auto-generated - at startup). + / `SWML_BASIC_AUTH_PASSWORD` environment variables), or `"auto-generated"` + (auto-generated at startup). ## **Returns** @@ -46,7 +46,7 @@ import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); const [user, password, source] = agent.getBasicAuthCredentials(true); -if (source === 'generated') { +if (source === 'auto-generated') { console.log(`Auto-generated credentials: ${user}:${password}`); console.log('Set SWML_BASIC_AUTH_USER and SWML_BASIC_AUTH_PASSWORD to use your own.'); } diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx index d33f791c1..9fb248efd 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/get-prompt-pom.mdx @@ -5,10 +5,31 @@ description: Return the current prompt as a POM (Prompt Object Model) array. max-toc-depth: 3 --- -Return the current prompt as a POM (Prompt Object Model) array — the -structured, section-based representation. Returns `null` when the agent is -configured with a raw text prompt (`usePom: false`). +[set-prompt-pom]: /docs/server-sdks/reference/typescript/agents/agent-base/set-prompt-pom +[prompt-add-section]: /docs/server-sdks/reference/typescript/agents/agent-base/prompt-add-section + +Return the current prompt as a POM (Prompt Object Model) array — the structured, +section-based representation built via [`setPromptPom()`][set-prompt-pom] or +[`promptAddSection()`][prompt-add-section]. Returns `null` when the agent is +configured with a raw text prompt (`usePom: false`) or when no sections have been +added. + +## **Parameters** + +None. ## **Returns** -`Record[] | null` +`Record[] | null` -- Array of POM section data objects, or +`null` if not in POM mode or POM is empty. + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'support', route: '/support' }); +agent.promptAddSection('Role', { body: 'You are a support agent.' }); +const sections = agent.getPromptPom(); +console.log(sections); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx index 36a689ba3..41c3038bf 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/index.mdx @@ -69,7 +69,7 @@ const agent = new AgentBase({ plain text prompts only. - + Expiration time in seconds for SWAIG function authentication tokens. @@ -109,6 +109,32 @@ const agent = new AgentBase({ Suppress SDK log output. Useful in testing or when integrating with external logging. + + When `true`, register the `/post_prompt_override` route allowing external callers to + replace the post-prompt text at runtime. + + + + When `true`, register the `/check_for_input` route allowing external callers to inject + input checks at runtime. + + + + Path to a JSON configuration file. When provided, its `service` section supplies + defaults for `name`, `route`, `host`, and `port`. Constructor arguments still take + precedence over file values. + + + + Path to a custom SWML JSON Schema file used for validation. Falls back to the built-in + schema when omitted. + + + + Enable SWML schema validation on rendered documents. Can also be disabled via + `SWML_SKIP_SCHEMA_VALIDATION` env var. + + ## **Properties** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-function-call.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-function-call.mdx index 57d6865e8..51c376673 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-function-call.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-function-call.mdx @@ -11,11 +11,12 @@ Pre-execution hook called before each SWAIG function is executed. The default implementation is a no-op. Override this method in a subclass to intercept tool calls for logging, metrics, or custom dispatch logic. - -This is a **pre-execution hook only** — it does not replace the function dispatch. -The tool handler still executes regardless of what this method does. If you need -to block execution, throw an error from this hook. - + +Return a result object from this hook to **short-circuit** default execution — +the returned value is sent as the function response and the registered tool +handler is skipped. Return `void` / `undefined` to let the normal dispatch +proceed. + ## **Parameters** @@ -34,7 +35,9 @@ to block execution, throw an error from this hook. ## **Returns** -`void | Promise` +`Record | void | Promise | void>` -- +Return a result object to short-circuit default execution; return `void` / +`undefined` to proceed normally. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-swml-request.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-swml-request.mdx index 4069cb7ee..138ae222e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-swml-request.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/on-swml-request.mdx @@ -21,9 +21,23 @@ prompts based on request metadata, or logging request details. `caller_id_number`, `caller_id_name`, and any custom SIP headers. + + Optional callback path from the request body (`callback_path` field), when + the request was triggered via a callback URL. + + + + The raw Hono request context (`c`), providing access to headers, query + parameters, and the underlying HTTP request. + + ## **Returns** -`void | Promise` +`Record | void | Promise | void>` -- +Return a modifications object to merge into the AI verb config before +rendering. `global_data` is deep-merged; all other keys override AI config +fields directly. Return `void` / `undefined` to render without +modifications. For most per-request customization scenarios, prefer diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/register-swaig-function.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/register-swaig-function.mdx index 3b73f4bd3..6b6664519 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/register-swaig-function.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/register-swaig-function.mdx @@ -26,8 +26,8 @@ accepts pre-built objects rather than taking a handler callback. ## **Example** -```typescript {17} -import { AgentBase, DataMap } from '@signalwire/sdk'; +```typescript {15} +import { AgentBase, DataMap, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'plant-agent', route: '/plants' }); agent.setPromptText('You are a helpful plant care assistant.'); @@ -37,10 +37,9 @@ const plantTool = new DataMap('get_plant_info') .description('Get care information for a plant') .parameter('plantId', 'string', 'Plant ID', { required: true }) .webhook('GET', 'https://api.plants.example.com/plants/${args.plantId}') - .output({ - response: 'The plant ${args.plantId} needs ${response.water_schedule} watering.', - action: [{ say: 'Here is the plant care information.' }], - }); + .output(new FunctionResult( + 'The plant ${args.plantId} needs ${response.water_schedule} watering.', + )); // Register the DataMap as a SWAIG function agent.registerSwaigFunction(plantTool.toSwaigFunction()); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx index 9df8bc28b..24a8335d5 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/remove-skill-by-name.mdx @@ -1,19 +1,37 @@ --- title: "removeSkillByName" slug: /reference/typescript/agents/agent-base/remove-skill-by-name -description: Remove every skill instance matching a given skill name. +description: Remove a skill from the agent by skill name. max-toc-depth: 3 --- -Remove every skill instance whose `skillName` matches the given name. -`cleanup()` is invoked on each instance before removal. +[remove-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/remove-skill +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base + +Remove the first loaded skill whose name matches `skillName`. Provides name-based +removal for parity with Python's `remove_skill(skill_name)`. Use +[`removeSkill()`][remove-skill] when you need to remove a specific instance by +its `instanceId`. ## **Parameters** - Skill name to match. + Skill name to match. Only the first matching instance is removed. ## **Returns** -`Promise` — `true` if at least one instance was removed. +`Promise` -- `true` if a matching skill was found and removed, `false` +otherwise. + +## **Example** + +```typescript {6} +import { AgentBase, DateTimeSkill, MathSkill } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +await agent.addSkill(new DateTimeSkill()); +await agent.addSkill(new MathSkill()); +await agent.removeSkillByName('math'); +console.log(agent.listSkills().map((s) => s.name)); // ["datetime"] +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/render-swml.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/render-swml.mdx index 5dcc894d0..c90195aab 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/render-swml.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/render-swml.mdx @@ -16,6 +16,13 @@ debugging. Optional call ID to use for session tokens. Auto-generated if omitted. +"} toc={true}> + Optional object (typically returned from + [`onSwmlRequest()`](/docs/server-sdks/reference/typescript/agents/agent-base/on-swml-request)) + merged into the AI verb config before rendering. `global_data` is deep-merged; + all other keys override AI config fields directly. + + ## **Returns** `string` -- The rendered SWML document as a JSON string. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx index 6dd42bb9d..a750f6e01 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/reset-contexts.mdx @@ -5,13 +5,36 @@ description: Clear every context defined on this agent's ContextBuilder. max-toc-depth: 3 --- +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [ref-ctxbuilder]: /docs/server-sdks/reference/typescript/agents/context-builder +[define-contexts]: /docs/server-sdks/reference/typescript/agents/agent-base/define-contexts Remove every context defined on this agent's internal -[`ContextBuilder`][ref-ctxbuilder], returning the builder to its initial -state. Use this inside a dynamic-config callback to rebuild contexts per -request. +[`ContextBuilder`][ref-ctxbuilder], returning the builder to its initial state. +Convenience wrapper around [`defineContexts()`][define-contexts]`.reset()`. Use +this inside a dynamic-config callback when you need to rebuild contexts from +scratch for a specific request. + +## **Parameters** + +None. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {6} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'intake', route: '/intake' }); + +agent.setDynamicConfigCallback((queryParams, bodyParams, headers, agentCopy) => { + agentCopy.resetContexts(); + const ctx = agentCopy.defineContexts().addContext('default'); + ctx.addStep('greeting').setText('Greet the caller.'); +}); + +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/run.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/run.mdx index d53253a9d..80983d07f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/run.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/run.mdx @@ -12,7 +12,19 @@ for requests. ## **Parameters** -None. + + Optional host and port overrides. + + + + + Host to bind the server to. Falls back to the constructor's `host` option. + + + + Port to listen on. Falls back to the constructor's `port` option. + + ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/serve.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/serve.mdx index 2ea00ec3d..07bef5cef 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/serve.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/serve.mdx @@ -26,7 +26,25 @@ TypeScript SDK. ## **Parameters** -None. + + Optional host and port overrides. + + + + + Host to bind the server to. Falls back to the constructor's `host` option. + + + + Port to listen on. Falls back to the constructor's `port` option. + + + + +When the `SWAIG_CLI_MODE` environment variable is set to `"true"`, `serve()` +returns immediately without starting the server. This lets the `swaig-test` +CLI load the agent's configuration without binding a port. + ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx index 7413dcca9..67cbb320a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-function-includes.mdx @@ -5,17 +5,45 @@ description: Replace the agent's SWAIG function-includes list. max-toc-depth: 3 --- +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [ref-add-include]: /docs/server-sdks/reference/typescript/agents/agent-base/add-function-include -Replace the agent's SWAIG function-includes list in one call. Use -[`addFunctionInclude`][ref-add-include] to append a single include instead. +Replace the agent's SWAIG function-includes list in a single call. Each +include pulls a remote SWAIG function definition into the agent's toolset. Use +[`addFunctionInclude()`][ref-add-include] to append a single include instead +of replacing the list. + + +Entries without a `url` or without an array `functions` field are silently +filtered out. + ## **Parameters** - Ordered list of function-include entries. + Ordered list of function-include entries. Each entry must provide `url` and + an array of `functions` names; an optional `meta_data` object is passed to + the remote server. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +agent.setPromptText('You are a helpful assistant.'); +agent.setFunctionIncludes([ + { url: 'https://tools.example.com/swaig', functions: ['lookup_order'] }, + { + url: 'https://analytics.example.com/swaig', + functions: ['log_event'], + meta_data: { api_key: 'secret' }, + }, +]); +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-global-data.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-global-data.mdx index f34128232..4b59e607a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-global-data.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-global-data.mdx @@ -1,13 +1,23 @@ --- title: "setGlobalData" slug: /reference/typescript/agents/agent-base/set-global-data -description: Replace the global data object available to the AI throughout a conversation. +description: Merge key-value pairs into the global data object available to the AI throughout a conversation. max-toc-depth: 3 --- [ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base -Replace the entire global data object available to the AI throughout the conversation. +Merge key-value pairs into the `global_data` object available to the AI +throughout the conversation. Matches Python's `set_global_data`, which calls +`.update()` on the internal dict — existing keys are preserved; incoming keys +overwrite on collision. Skills and other callers can each contribute keys +without clobbering one another. + + +Despite the `set` prefix, this method **merges** rather than replaces. There is +no built-in "clear" method; construct a new agent if you need an empty +`global_data` object. + ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx index 5b9330e24..ffb177ae1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-internal-fillers.mdx @@ -5,29 +5,49 @@ description: Set every internal-filler entry in one call. max-toc-depth: 3 --- -Set every internal-filler entry on the agent in one call. Unknown filler -names (not in the SWML schema's supported set) are rejected with a warning. +[add-internal-filler]: /docs/server-sdks/reference/typescript/agents/agent-base/add-internal-filler +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base + +Set every internal-filler entry on the agent in a single call. Internal fillers +are short phrases the agent speaks (via TTS) while a native SWAIG function is +running, so the caller doesn't hear dead air during transitions or background +work. Use [`addInternalFiller()`][add-internal-filler] to add a single entry +instead. + + +Filler names outside the SWML schema's supported set are logged as a warning +and silently ignored by the runtime. Supported names: `hangup`, `check_time`, +`wait_for_user`, `wait_seconds`, `adjust_response_latency`, `next_step`, +`change_context`, `get_visual_input`, `get_ideal_strategy`. + ## **Parameters** >"} required={true} toc={true}> - Outer key: filler name (e.g. `"pre_speech"`). Inner key: language code - (e.g. `"en-US"`). Value: array of filler phrases. + Outer key: native SWAIG function name (e.g. `"next_step"`). Inner key: + language code (e.g. `"en-US"`). Value: array of filler phrases played + randomly while that function executes. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. ## **Example** -```typescript {1-9} +```typescript {5-14} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); +agent.setPromptText('You are a helpful assistant.'); agent.setInternalFillers({ - pre_speech: { - 'en-US': ['one moment', 'let me check'], + next_step: { + 'en-US': ['Moving to the next step...', 'Great, let us continue...'], + es: ['Pasando al siguiente paso...'], }, - summary: { - 'en-US': ['so to summarize', 'in short'], + check_time: { + 'en-US': ['Let me check the time...'], }, }); +await agent.serve(); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx index 9e1b44223..8bbc64251 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-prompt-pom.mdx @@ -5,15 +5,46 @@ description: Replace the agent's prompt with the supplied POM sections. max-toc-depth: 3 --- +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base +[prompt-add-section]: /docs/server-sdks/reference/typescript/agents/agent-base/prompt-add-section +[get-prompt-pom]: /docs/server-sdks/reference/typescript/agents/agent-base/get-prompt-pom + Replace the agent's prompt with the supplied POM (Prompt Object Model) array. -Requires the agent to be constructed with `usePom: true` — throws otherwise. +Existing sections are cleared before the new ones are applied, so this is the +batch equivalent of calling [`promptAddSection()`][prompt-add-section] for +every entry. The shape must match what [`getPromptPom()`][get-prompt-pom] +returns. + + +Requires the agent to be constructed with `usePom: true`. Throws `Error("usePom must be true to use setPromptPom")` otherwise. + ## **Parameters** []"} required={true} toc={true}> - Ordered array of POM section objects. + Ordered array of POM section objects. Each section supports `title` (string), + `body` (string), `bullets` (string[]), `numbered` (boolean), + `numberedBullets` (boolean), and `subsections` (array of + `{ title, body?, bullets? }`). ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'support', route: '/support', usePom: true }); + +agent.setPromptPom([ + { title: 'Role', body: 'You are a support agent for Acme Corp.' }, + { + title: 'Guidelines', + bullets: ['Greet by name', 'Never share internal pricing'], + }, +]); +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx index d656adf81..d360443db 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/set-pronunciations.mdx @@ -5,19 +5,36 @@ description: Replace the agent's pronunciation rules in a single call. max-toc-depth: 3 --- +[ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [ref-add-pronunciation]: /docs/server-sdks/reference/typescript/agents/agent-base/add-pronunciation Replace every pronunciation rule on the agent with the provided array. Use -[`addPronunciation`][ref-add-pronunciation] to add a single rule without +[`addPronunciation()`][ref-add-pronunciation] to append a single rule without replacing the list. ## **Parameters** - Ordered list of pronunciation rules. Each rule maps a spelled-out token to - its phonetic replacement. + Ordered list of pronunciation rules. Each rule has `replace` (the spelled-out + token), `with` (the phonetic replacement), and an optional + `ignoreCase` boolean. ## **Returns** -`this` — the agent for method chaining. +[`AgentBase`][ref-agentbase] -- Returns `this` for method chaining. + +## **Example** + +```typescript {5-9} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'support', route: '/support' }); +agent.setPromptText('You are a helpful assistant.'); +agent.setPronunciations([ + { replace: 'SignalWire', with: 'signal wire' }, + { replace: 'SWML', with: 'swim el' }, + { replace: 'SWAIG', with: 'swayg' }, +]); +await agent.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/update-global-data.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/update-global-data.mdx index 88f534223..392d61cd4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/update-global-data.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/update-global-data.mdx @@ -8,10 +8,12 @@ max-toc-depth: 3 [set-global-data]: /docs/server-sdks/reference/typescript/agents/agent-base/set-global-data [ref-agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base -Merge additional entries into the existing global data object. Unlike -[`setGlobalData()`][set-global-data] which replaces, this method merges so that -multiple callers (skills, dynamic config callbacks, etc.) can each contribute keys -without overwriting each other. +Merge additional entries into the existing `global_data` object. Functionally +equivalent to [`setGlobalData()`][set-global-data] — both methods call +`.update()` on the internal dict so multiple callers (skills, dynamic config +callbacks, etc.) can each contribute keys without overwriting each other. +`updateGlobalData()` is the idiomatically named variant for call sites that +want to make the merge semantics explicit. ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx index e3a7472e1..cd03deb9f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-base/validate-tool-token.mdx @@ -5,9 +5,19 @@ description: Validate a per-tool HMAC token attached to a SWAIG function call. max-toc-depth: 3 --- -Validate a per-tool HMAC token attached to a SWAIG function call. Delegates -to `SessionManager.validateToolToken` after short-circuiting for tools -registered without `secure: true`. +[define-tool]: /docs/server-sdks/reference/typescript/agents/agent-base/define-tool + +Validate a per-tool HMAC token attached to an incoming SWAIG function call. +Returns `false` for unknown tools, short-circuits to `true` for tools +registered without [`secure: true`][define-tool], and otherwise delegates to +`SessionManager.validateToolToken`. Raw-dict descriptors (e.g. `DataMap` +output) are always treated as secure. + + +Called automatically by the SWAIG dispatch path before a tool handler runs. +You rarely need to invoke it directly; it is exposed for custom dispatch logic +and test harnesses. + ## **Parameters** @@ -16,13 +26,15 @@ registered without `secure: true`. - HMAC token to validate. + HMAC token to validate. Missing tokens on secure tools return `false`. - Call ID the token is bound to. + Call ID the token is bound to. Empty strings are forwarded unchanged and + rejected by the underlying validator. ## **Returns** -`boolean` — `true` when the token is valid for the given function and call. +`boolean` -- `true` when the token is valid for the given function and call, +or when the tool is registered as non-secure. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/index.mdx index 7218568da..c11dcbdf9 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/index.mdx @@ -11,14 +11,17 @@ max-toc-depth: 3 [getagent]: /docs/server-sdks/reference/typescript/agents/agent-server/get-agent [getagents]: /docs/server-sdks/reference/typescript/agents/agent-server/get-agents [register]: /docs/server-sdks/reference/typescript/agents/agent-server/register +[registerglobalroutingcallback]: /docs/server-sdks/reference/typescript/agents/agent-server/routing-callback [run]: /docs/server-sdks/reference/typescript/agents/agent-server/run [servestaticfiles]: /docs/server-sdks/reference/typescript/agents/agent-server/static-files +[setupsiprouting]: /docs/server-sdks/reference/typescript/agents/agent-server/sip-routing [unregister]: /docs/server-sdks/reference/typescript/agents/agent-server/unregister `AgentServer` hosts multiple [`AgentBase`][agentbase] instances on a single Hono HTTP server. Each agent registers at its own URL route, and the server -provides unified health monitoring and static file serving. Use `AgentServer` when you -have several related agents (sales, support, billing) that share the same deployment. +provides unified health monitoring, SIP-based routing, and static file serving. +Use `AgentServer` when you have several related agents (sales, support, billing) +that share the same deployment. For a single agent, use [`AgentBase.serve()`][agentbase-serve] or [`AgentBase.run()`][agentbase-run] instead. @@ -45,6 +48,10 @@ const server = new AgentServer({ host: '0.0.0.0', port: 3000 }); Port the server listens on. Also reads from the `PORT` environment variable. + + + Logging level: `'debug'`, `'info'`, `'warn'`, or `'error'`. Lowercased and applied globally via `setGlobalLogLevel`. + ## **Properties** @@ -57,6 +64,10 @@ const server = new AgentServer({ host: '0.0.0.0', port: 3000 }); The port the server listens on. + + The logging level for the server (read-only). + + ## **Methods** @@ -66,21 +77,27 @@ const server = new AgentServer({ host: '0.0.0.0', port: 3000 }); Return all registered agents as a Map. + + Get the fully configured Hono application. + Register an agent at a URL route on the server. + + Register a routing callback across all agents for custom request routing. + Start the multi-agent HTTP server. Serve static files from a directory alongside agent routes. + + Configure SIP-based routing to direct calls to specific agents by username. + Remove an agent from the server's registry by route. - - Get the fully configured Hono application. - ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/routing-callback.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/routing-callback.mdx new file mode 100644 index 000000000..f67addf05 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/routing-callback.mdx @@ -0,0 +1,66 @@ +--- +title: "registerGlobalRoutingCallback" +slug: /reference/typescript/agents/agent-server/routing-callback +description: Register a routing callback across all agents for custom request routing. +max-toc-depth: 3 +--- + +[setup-sip-routing]: /docs/server-sdks/reference/typescript/agents/agent-server/sip-routing + +Register a custom routing callback on every registered agent at the specified path. +When a request arrives at that path on any agent, the callback is invoked to determine +whether to redirect the request to a different agent route. + +Use this alongside or instead of [`setupSipRouting()`][setup-sip-routing] when you +need custom routing logic — for example, routing based on request body content, +tenant IDs, or feature flags. + + +The callback is also applied to agents registered **after** this method is called. +The server stores each callback internally so new agents automatically receive it. + + +## **Parameters** + + + A function that receives the parsed request body and returns a route string + (e.g., `"/sales"`) to redirect the request, or `null` / `undefined` to let the + current agent handle it. May return a `Promise` for asynchronous routing decisions. + Signature: `(body: Record) => string | null | undefined | Promise`. + + + + The URL path where the callback is triggered (e.g., `"/route"`). Leading slashes are + added and trailing slashes are stripped automatically. + + +## **Returns** + +`void` + +## **Example** + +```typescript {21} +import { AgentBase, AgentServer } from '@signalwire/sdk'; + +function routeByLanguage(body: Record): string | undefined { + const lang = (body['lang'] as string | undefined) ?? 'en'; + if (lang.startsWith('es')) return '/spanish-agent'; + if (lang.startsWith('fr')) return '/french-agent'; + return undefined; +} + +const english = new AgentBase({ name: 'english', route: '/english-agent' }); +english.setPromptText('You are a helpful assistant. Respond in English.'); +const spanish = new AgentBase({ name: 'spanish', route: '/spanish-agent' }); +spanish.setPromptText('You are a helpful assistant. Respond in Spanish.'); +const french = new AgentBase({ name: 'french', route: '/french-agent' }); +french.setPromptText('You are a helpful assistant. Respond in French.'); + +const server = new AgentServer({ port: 3000 }); +server.register(english); +server.register(spanish); +server.register(french); +server.registerGlobalRoutingCallback(routeByLanguage, '/route'); +await server.run(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/run.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/run.mdx index 803b69ca7..684fbb7ec 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/run.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/run.mdx @@ -6,7 +6,9 @@ max-toc-depth: 3 --- Start the HTTP server and begin listening for requests. Uses `@hono/node-server` -to serve the Hono application with all registered agents. +to serve the Hono application with all registered agents. Handles server mode only — +for serverless deployments (AWS Lambda, Google Cloud Functions, Azure Functions), +use `ServerlessAdapter` instead. ## **Parameters** @@ -28,6 +30,12 @@ use `getApp()` to retrieve the underlying Hono app and pass its `fetch` handler your own `@hono/node-server` `serve()` call instead of using `run()`. + +When the environment variable `SWAIG_CLI_MODE=true` is set (used by the `swaig-test` +CLI tool), `run()` returns immediately without starting the server so only the agent +configuration is loaded. + + ## **Example** ```typescript {8} diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/sip-routing.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/sip-routing.mdx new file mode 100644 index 000000000..a8dbe99ab --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/sip-routing.mdx @@ -0,0 +1,116 @@ +--- +title: "setupSipRouting" +slug: /reference/typescript/agents/agent-server/sip-routing +description: Configure SIP-based routing to direct calls to specific agents by username. +max-toc-depth: 3 +--- + +Enable SIP-based routing across all registered agents. When a SIP call arrives, the server +extracts the username from the SIP address and routes the request to the matching agent. + +With `autoMap` enabled, the server automatically creates username-to-route mappings from +each agent's name and route path. You can add explicit mappings with +[`registerSipUsername()`](#manual-username-registration). + + +Call this method **after** registering agents. Agents registered after `setupSipRouting()` +also receive SIP routing automatically. + + +## **Parameters** + + + The URL path where SIP routing requests are handled. Each registered agent receives a + routing callback at this path. + + + + Automatically generate SIP username mappings from agent names and route paths. For example, + an agent named `"sales-agent"` at route `"/sales"` gets two mappings: + - `"salesagent"` (agent name, lowercase alphanumeric and underscores only) + - `"sales"` (route path without leading slash) + + +## **Returns** + +`void` + + +Calling `setupSipRouting()` more than once logs a warning and returns early. +SIP routing can only be configured once per server. + + +--- + +## **registerSipUsername** + +Create an explicit mapping from a SIP username to an agent route. The username is +stored lowercase for case-insensitive matching. Routes are normalized: leading `/` +is added if missing and trailing slashes are stripped. + + +SIP routing must be enabled via `setupSipRouting()` before calling this method. +If routing is not enabled, a warning is logged and the call is a no-op. + + +## **Parameters** + + + The SIP username to map (e.g., `"sales-team"`). Matched case-insensitively. + + + + The target agent route (e.g., `"/sales"`). A warning is logged if the route + does not correspond to a registered agent. + + +## **Returns** + +`void` + +## **Examples** + +### SIP routing with auto-mapping + +```typescript {13} +import { AgentBase, AgentServer } from '@signalwire/sdk'; + +const sales = new AgentBase({ name: 'sales', route: '/sales' }); +sales.setPromptText('You are a sales assistant.'); +const support = new AgentBase({ name: 'support', route: '/support' }); +support.setPromptText('You are a support assistant.'); + +const server = new AgentServer({ port: 3000 }); +server.register(sales); +server.register(support); + +server.setupSipRouting('/sip', true); +server.registerSipUsername('help-desk', '/support'); + +await server.run(); +``` + +With this configuration, SIP calls are routed as follows: + +| SIP Address | Resolves To | +|-------------|-------------| +| `sip:sales@example.com` | `/sales` (auto-mapped from route) | +| `sip:salesagent@example.com` | `/sales` (auto-mapped from agent name) | +| `sip:help-desk@example.com` | `/support` (manual mapping) | + +### Manual username registration + +```typescript {10-12} +import { AgentBase, AgentServer } from '@signalwire/sdk'; + +const sales = new AgentBase({ name: 'sales', route: '/sales' }); +sales.setPromptText('You are a sales assistant.'); + +const server = new AgentServer({ port: 3000 }); +server.register(sales); +server.setupSipRouting('/sip'); +server.registerSipUsername('sales-team', '/sales'); +server.registerSipUsername('tech-support', '/support'); +server.registerSipUsername('accounts', '/billing'); +await server.run(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/static-files.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/static-files.mdx index 4ec6bcab1..69075931a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/static-files.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/static-files.mdx @@ -19,8 +19,8 @@ an admin dashboard or a configuration UI. (resolved via `path.resolve()` at registration time). - - URL path prefix for static files. + + URL path prefix for static files. Trailing slashes are stripped; `'/'` serves from the root. ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/unregister.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/unregister.mdx index 729f4b5e9..79d177e25 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/unregister.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/agent-server/unregister.mdx @@ -22,7 +22,8 @@ internal registry used by `getAgents()` and the root listing endpoint. ## **Returns** -`void` +`boolean` -- `true` if an agent was registered at that route and was removed, +`false` if no agent was found at the route. ## **Example** @@ -33,5 +34,6 @@ const server = new AgentServer({ port: 3000 }); const agent = new AgentBase({ name: 'sales', route: '/sales' }); server.register(agent); -server.unregister('/sales'); +const removed = server.unregister('/sales'); +console.log(removed); // true ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx index 3c53253bb..5e40e8d2d 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx @@ -37,7 +37,13 @@ const auth = new AuthHandler({ - API key matched against the `X-Api-Key` header. + API key matched against the `X-Api-Key` header (or the custom header named + by `config.apiKeyHeader`). + + + + Custom header name to use for API key lookup instead of the default + `X-Api-Key`. Lookup is case-insensitive. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/middleware.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/middleware.mdx index be3b340ac..9068ff511 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/middleware.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/middleware.mdx @@ -7,11 +7,16 @@ max-toc-depth: 3 Create a Hono-compatible middleware function that validates incoming requests against the configured auth methods. Unauthorized requests receive a -`401 Unauthorized` JSON response. +`401 Unauthorized` JSON response by default; pass `optional: true` to let them +pass through without blocking. ## **Parameters** -None. + + When `true`, unauthenticated requests are allowed through instead of being + rejected with a 401. Useful for routes that expose richer data to + authenticated callers but still serve unauthenticated traffic. + ## **Returns** @@ -29,8 +34,11 @@ const auth = new AuthHandler({ }); const app = new Hono(); -// Protect all routes +// Protect all routes — unauthorized returns 401 app.use('*', auth.middleware()); app.get('/', (c) => c.json({ status: 'ok' })); + +// Or allow unauthenticated access through +app.use('/public/*', auth.middleware(true)); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx index 3992e2df0..469e34dda 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx @@ -27,9 +27,19 @@ const port = config.get('server.port', 3000); ## **Constructor** - - Path to a JSON config file to load on construction. If omitted, use - [`load()`][load] or [`loadFromObject()`][loadfromobject] later. + + Path(s) to a JSON config file to load on construction. A single string is + loaded directly; an array is searched in order and the first existing file + is loaded (mirroring the Python SDK's ordered-search behaviour). If no file + in the array exists, the paths are recorded but no error is thrown. If + omitted, use [`load()`][load] or [`loadFromObject()`][loadfromobject] later. + + +## **Properties** + + + The ordered list of config file paths passed to the constructor or searched + during loading. Returns a defensive copy. ## **Methods** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/search.mdx index 2640bd63b..26a6dbbc2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/search.mdx @@ -5,10 +5,28 @@ description: "Search for a config file in standard locations and load it if foun max-toc-depth: 3 --- -Static method that searches for a config file in standard locations: the -current working directory, `./config/`, and `~/.signalwire/`. Returns a -loaded `ConfigLoader` if found, or `null` if the file does not exist in -any search path. +Static method that searches for a config file across service-specific paths, +caller-supplied directories, and default standard locations. Returns a loaded +`ConfigLoader` as soon as the first existing file is found, or `null` if none +of the candidates exist. + +Default search paths (joined with `filename`, in order): + +- `${cwd}/${filename}` +- `${cwd}/config/${filename}` +- `$HOME/.signalwire/${filename}` +- `${cwd}/.swml/${filename}` +- `$HOME/.swml/${filename}` +- `/etc/swml/${filename}` + +When `serviceName` is provided, two service-specific variants are checked +*before* any other path: + +- `${cwd}/${serviceName}_${filename}` +- `${cwd}/.swml/${serviceName}_${filename}` + +When `additionalPaths` is provided, those directories are checked (joined +with `filename`) after the service-specific variants but before the defaults. ## **Parameters** @@ -16,16 +34,28 @@ any search path. The config file name to search for (e.g., `"config.json"`). + + Extra directories to search before the default locations. Each directory + is joined with `filename` to form a candidate path. + + + + Optional service name. When provided, adds `${serviceName}_${filename}` + variants to the front of the search order so a service can override the + generic config file. + + ## **Returns** -`ConfigLoader | null` -- A loaded ConfigLoader instance, or `null` if not found. +`ConfigLoader | null` -- A loaded ConfigLoader instance, or `null` if no +candidate path exists. ## **Example** ```typescript {3} import { ConfigLoader } from '@signalwire/sdk'; -const config = ConfigLoader.search('agent-config.json'); +const config = ConfigLoader.search('agent-config.json', ['/etc/myapp'], 'myservice'); if (config) { console.log('Config found at:', config.getFilePath()); console.log('Port:', config.get('server.port', 3000)); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/schema-utils/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/schema-utils/index.mdx index 49f9b8cee..9c623a873 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/schema-utils/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/schema-utils/index.mdx @@ -33,6 +33,12 @@ console.log(result.valid, result.errors); Maximum number of cached validation results before LRU eviction. + + + Path to a custom JSON Schema file. When omitted, the bundled `schema.json` + is used. Mirrors the Python SDK's `schema_path` parameter. A load failure + falls back to the bundled schema silently. + ## **Methods** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/debug-token.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/debug-token.mdx index 30cef9e47..9f2a9e74b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/debug-token.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/debug-token.mdx @@ -1,12 +1,21 @@ --- title: "debugToken" slug: /reference/typescript/agents/configuration/session-manager/debug-token -description: "Decode token components for debugging without validating the signature." +description: "Decode token components for inspection without validating the signature." max-toc-depth: 3 --- -Decode token components for debugging without validating the signature. Useful -for inspecting token contents and checking expiration. +Decode token components for inspection without validating the signature. Useful +for debugging token contents and checking expiration. + + + `debugToken` returns diagnostic data only when + [`debugMode`](/docs/server-sdks/reference/typescript/agents/configuration/session-manager#properties) + is `true`. With `debugMode: false` (the default), it returns + `{ valid_format: false, error: "debug mode not enabled" }` — matching the + Python SDK's behavior. Enable `debugMode` at runtime only when you need to + inspect tokens. + ## **Parameters** @@ -16,19 +25,93 @@ for inspecting token contents and checking expiration. ## **Returns** -`{ callId: string; functionName: string; expiry: number; nonce: string; signature: string; expired: boolean } | null` --- The decoded token fields and expiration status, or `null` if malformed. +`DebugTokenResult` — a nested object with the following optional fields: + + + `true` when the token decoded into five dot-separated parts; `false` otherwise. + + + + Present only when `valid_format` is `true`. + + + + + Call ID extracted from the token. Truncated to 8 characters followed by `...` + when longer than 8 characters. + + + + Function name encoded in the token. + + + + Token expiry as a Unix timestamp string. + + + + ISO 8601 string representation of the expiry, or `null` when the expiry + component did not parse as a number. + + + + The random nonce component of the token. + + + + Token signature. Truncated to 8 characters followed by `...` when longer than + 8 characters. + + + + + Present only when `valid_format` is `true`. + + + + + Current Unix timestamp in seconds. + + + + `true` if expired, `false` if still valid, `null` if the expiry component + did not parse. + + + + Seconds remaining until expiry, or `0` when expired, or `null` when expiry + did not parse. + + + + + Only populated when `valid_format` is `false` because the decoded token had + an unexpected number of dot-separated parts. + + + + Length of the raw token string. Populated when `valid_format` is `false`. + + + + Set to `"debug mode not enabled"` when `debugMode` is `false`, or to the + caught error message when decoding failed. + ## **Example** -```typescript {5} +```typescript {4,6} import { SessionManager } from '@signalwire/sdk'; const sm = new SessionManager(); +sm.debugMode = true; // enable before calling debugToken const token = sm.generateToken('get_weather', 'call-abc123'); const info = sm.debugToken(token); -if (info) { - console.log('Function:', info.functionName); - console.log('Expired:', info.expired); + +if (info.valid_format) { + console.log('Function:', info.components!.function); + console.log('Expired:', info.status!.is_expired); +} else { + console.log('Error:', info.error); } ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/get-session-metadata.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/get-session-metadata.mdx index e01fdcc81..e374f96a2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/get-session-metadata.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/get-session-metadata.mdx @@ -5,7 +5,8 @@ description: "Retrieve metadata associated with a session." max-toc-depth: 3 --- -Retrieve metadata associated with a session. +Retrieve metadata associated with a session. Always returns an object — +callers can check truthiness or iterate keys without a null guard. ## **Parameters** @@ -15,8 +16,9 @@ Retrieve metadata associated with a session. ## **Returns** -`Record | undefined` -- The metadata record, or `undefined` -if no metadata exists for this session. +`Record` -- The metadata record for the session, or an empty +object (`{}`) when no metadata has been stored. This matches the Python SDK's +`get_session_metadata` behavior. ## **Example** @@ -28,4 +30,7 @@ sm.setSessionMetadata('session-1', { caller: 'John', topic: 'billing' }); const meta = sm.getSessionMetadata('session-1'); console.log(meta); // { caller: "John", topic: "billing" } + +const missing = sm.getSessionMetadata('unknown-session'); +console.log(missing); // {} ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/index.mdx index c162a0c7d..80e8f6676 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/index.mdx @@ -28,6 +28,15 @@ const valid = sm.validateToken('call-123', 'get_weather', token); HMAC signing secret. A random 32-byte key is generated if omitted. +## **Properties** + + + When `true`, [`debugToken`](/docs/server-sdks/reference/typescript/agents/configuration/session-manager/debug-token) + decodes token internals for inspection. When `false`, `debugToken` returns + `{ error: "debug mode not enabled" }`. Set this to `true` at runtime only when + you need to inspect token contents. + + ## **Methods** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/set-session-metadata.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/set-session-metadata.mdx index dc03fcae6..078b41565 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/set-session-metadata.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/session-manager/set-session-metadata.mdx @@ -6,7 +6,19 @@ max-toc-depth: 3 --- Merge metadata into a session, creating the entry if it does not exist. -Automatically triggers cleanup when the metadata map exceeds 1000 entries. +Automatically triggers [`cleanup`](/docs/server-sdks/reference/typescript/agents/configuration/session-manager/cleanup) +when the metadata map exceeds 1000 entries. + + + Two call signatures are supported for Python SDK compatibility: + + - **Bulk merge (TS-native):** `setSessionMetadata(sessionId, metadata)` — merges + every key in the `metadata` object into the session, returning `void`. + - **Single key/value (Python-compatible):** `setSessionMetadata(sessionId, key, value)` + — sets a single key, returning `true` for parity with Python. + + Both forms merge into any existing metadata; they do not replace. + ## **Parameters** @@ -14,21 +26,31 @@ Automatically triggers cleanup when the metadata map exceeds 1000 entries. The session identifier. - - Key-value pairs to merge into the session metadata. + + A metadata record to merge into the session (bulk-merge form), or a single + `string` key (three-argument form). + + + + The value to set when `metadataOrKey` is a `string` key. Only used by the + three-argument form. ## **Returns** -`void` +`void` for the bulk-merge form; `boolean` (`true`) for the three-argument, +Python-compatible form. ## **Example** -```typescript {4-5} +```typescript {4-5,8} import { SessionManager } from '@signalwire/sdk'; const sm = new SessionManager(); sm.setSessionMetadata('session-1', { caller: 'John' }); sm.setSessionMetadata('session-1', { topic: 'billing' }); // Metadata is now { caller: "John", topic: "billing" } + +sm.setSessionMetadata('session-1', 'priority', 'high'); +// Metadata is now { caller: "John", topic: "billing", priority: "high" } ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/ssl-config/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/ssl-config/index.mdx index 0ea7e6eac..3e02afb5c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/ssl-config/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/ssl-config/index.mdx @@ -24,6 +24,15 @@ import { SslConfig } from '@signalwire/sdk'; const ssl = new SslConfig({ certPath: './cert.pem', keyPath: './key.pem' }); ``` +## **Constructor** + + + Optional SSL configuration overrides. Any field omitted falls back to the + corresponding `SWML_SSL_*` environment variable. Accepts the same keys as + the [`Properties`](#properties) section below (`enabled`, `certPath`, + `keyPath`, `domain`, `hsts`, `hstsMaxAge`). + + ## **Properties** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/add-step.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/add-step.mdx index ef8eab658..3f2dbeef0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/add-step.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/add-step.mdx @@ -11,6 +11,9 @@ Add a new step to this context. When called with only `name`, the returned Step can be configured via method chaining. When an options object is provided, the step is fully configured in one call. +Throws an `Error` if the step name already exists in this context or if the +maximum steps per context limit (100) is exceeded. + ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx index dd66e2075..a10140a2c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-initial-step.mdx @@ -27,7 +27,7 @@ must exist in this context or validation throws. ## **Example** -```typescript {6} +```typescript {7} import { ContextBuilder } from '@signalwire/sdk'; const builder = new ContextBuilder(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-isolated.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-isolated.mdx index 578c20a12..05da1891c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-isolated.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/context/set-isolated.mdx @@ -8,7 +8,16 @@ max-toc-depth: 3 [ref-context]: /docs/server-sdks/reference/typescript/agents/context-builder/context Set whether this context is isolated from other contexts' conversation history. -When `true`, conversation history from other contexts is not carried over. +When `true`, entering this context via `change_context` wipes the conversation +array — the model starts fresh with only this context's system prompt and step +instructions, with no memory of prior turns. + + +If the context also has a reset configured (`setConsolidate(true)` or +`setFullReset(true)`), the wipe is skipped in favor of the reset behavior. +Use reset with `setConsolidate(true)` to summarize prior history into a +single message instead of dropping it entirely. + ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/create-simple-context.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/create-simple-context.mdx new file mode 100644 index 000000000..7a3600b77 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/create-simple-context.mdx @@ -0,0 +1,39 @@ +--- +title: "createSimpleContext" +slug: /reference/typescript/agents/context-builder/create-simple-context +description: Helper function to create a standalone Context without a ContextBuilder. +max-toc-depth: 3 +--- + +[context]: /docs/server-sdks/reference/typescript/agents/context-builder/context +[contextbuilder]: /docs/server-sdks/reference/typescript/agents/context-builder + +Helper function that creates a standalone [`Context`][context] object without +requiring a [`ContextBuilder`][contextbuilder]. Useful for quick prototyping or +when you need a single context outside of the builder pattern. + + +This is a module-level function, not a method on `ContextBuilder`. Import it +directly: `import { createSimpleContext } from '@signalwire/sdk';`. + + +## **Parameters** + + + Context name. Defaults to `"default"`, which is the required name for + single-context agents. + + +## **Returns** + +[`Context`][context] -- A new Context object ready for adding steps. + +## **Example** + +```typescript {3} +import { createSimpleContext } from '@signalwire/sdk'; + +const ctx = createSimpleContext(); +ctx.addStep('greet').setText('Welcome the caller and ask how you can help.'); +ctx.addStep('farewell').setText('Thank the caller and end the conversation.'); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx index 28030739e..9505087a3 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/index.mdx @@ -9,6 +9,7 @@ max-toc-depth: 3 [step]: /docs/server-sdks/reference/typescript/agents/context-builder/step [agentbase]: /docs/server-sdks/reference/typescript/agents/agent-base [addcontext]: /docs/server-sdks/reference/typescript/agents/context-builder/add-context +[createsimplecontext]: /docs/server-sdks/reference/typescript/agents/context-builder/create-simple-context [getcontext]: /docs/server-sdks/reference/typescript/agents/context-builder/get-context [todict]: /docs/server-sdks/reference/typescript/agents/context-builder/to-dict [validate]: /docs/server-sdks/reference/typescript/agents/context-builder/validate @@ -47,6 +48,9 @@ automatically. Validate the entire context configuration tree. + + Helper function to create a standalone Context without a ContextBuilder. + --- diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx index 96c905f16..f212ed3c5 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/reset.mdx @@ -18,8 +18,9 @@ scratch for a specific request, rather than mutating the shared builder. ## **Example** ```typescript {3} -agent.onRequest((req, builder) => { - if (req.query.tenant === 'billing') { +agent.setDynamicConfigCallback((queryParams, bodyParams, headers, ephemeralAgent) => { + if (queryParams['tenant'] === 'billing') { + const builder = (ephemeralAgent as any).defineContexts(); builder.reset(); builder.addContext('default') .addStep('greeting') diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/add-gather-question.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/add-gather-question.mdx index 5ed2155e1..6b9d2ae1f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/add-gather-question.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/add-gather-question.mdx @@ -12,6 +12,21 @@ Add a question to this step's gather_info configuration. [`setGatherInfo()`][set-gather-info] must be called before this method. + +**Gather mode locks function access.** While the model is asking gather +questions, the runtime forcibly deactivates all of the step's other +functions. The only callable tools during a gather question are: + +- `gather_submit` (the native answer-submission tool) +- Whatever names you list in this question's `functions` option + +`next_step` and `change_context` are also filtered out — the model +cannot navigate away until the gather completes. If a question needs +to call out to a tool (e.g. validate an email, geocode a ZIP), list +that tool name in this question's `functions`. Functions listed here +are active only for this question. + + ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-end.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-end.mdx index 466cf2e22..1eb4b8189 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-end.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-end.mdx @@ -1,18 +1,28 @@ --- title: "setEnd" slug: /reference/typescript/agents/context-builder/step/set-end -description: Set whether the conversation should end after this step completes. +description: Mark this step as terminal for the step flow. max-toc-depth: 3 --- [ref-step]: /docs/server-sdks/reference/typescript/agents/context-builder/step -Set whether the conversation should end after this step completes. +Mark this step as terminal for the step flow. After the step executes, step +mode exits entirely — the steps list, current step index, valid steps, and +valid contexts are all cleared. The agent keeps running under the base system +prompt and context-level prompt, with no more step instructions injected and +no `next_step` tool offered. + + +`setEnd(true)` does **not** end the conversation or hang up the call. To +actually end the call, call a hangup tool from a SWAIG handler or define a +hangup hook. + ## **Parameters** - Whether to end the conversation after this step. + `true` to exit step mode after this step executes. ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-functions.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-functions.mdx index 4848e5fff..c408641ce 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-functions.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/step/set-functions.mdx @@ -7,13 +7,38 @@ max-toc-depth: 3 [ref-step]: /docs/server-sdks/reference/typescript/agents/context-builder/step -Set which SWAIG functions are available during this step. Restricting functions -per step prevents the AI from calling irrelevant tools. +Set which non-internal functions are callable while this step is active. +Restricting functions per step prevents the AI from calling irrelevant tools +and keeps the per-step active set small — LLM tool selection accuracy +degrades noticeably past ~7–8 simultaneously-active tools per call. + + +**Step toolsets inherit from the previous step.** If you do not call +`setFunctions()` on a step, it inherits whichever function set was active on +the previous step (or the previous context's last step). The server-side +runtime only resets the active set when a step explicitly declares its +`functions` field. This is the most common source of bugs in multi-step +agents — forgetting `setFunctions()` on a later step lets the previous +step's tools leak through. Best practice: call `setFunctions()` explicitly +on every step that should have a different toolset than the previous one. + + + +Internal functions (`startup_hook`, `hangup_hook`, `gather_submit`, etc.) +are always protected and cannot be deactivated by this whitelist. The +native navigation tools `next_step` and `change_context` are injected +automatically when `setValidSteps()` / `setValidContexts()` is set; they +are not affected by this list and do not need to appear in it. + ## **Parameters** - Either `"none"` to disable all functions, or a list of function names to allow. + One of: + - `string[]` — whitelist of function names allowed in this step. Functions + not in the list become inactive. + - `[]` — explicit disable-all (no user functions callable). + - `"none"` — synonym for `[]`, same effect. ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/validate.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/validate.mdx index d63876572..5a4d975fe 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/validate.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/context-builder/validate.mdx @@ -13,8 +13,13 @@ Checks performed: - At least one context exists. - A single context is named `"default"`. - Every context has at least one step. +- Each context's `initial_step` (if set) references a real step in that context. - All context-level `valid_contexts` references point to contexts that exist in the builder. -- All `gather_info` `completion_action` targets point to valid steps. +- All step-level `valid_steps` references point to real step names (or the literal `"next"`) in the same context. +- All step-level `valid_contexts` references point to contexts that exist in the builder. +- All `gather_info` question keys are unique within a single step. +- All `gather_info` `completion_action` targets point to `"next_step"` or a real step in the same context. +- No user-defined SWAIG tool collides with the reserved native tool names (`next_step`, `change_context`, `gather_submit`). ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/execute-swml.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/execute-swml.mdx index bc037f610..bec43194d 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/execute-swml.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/execute-swml.mdx @@ -25,10 +25,11 @@ convenience methods. ## **Parameters** - - SWML content in one of two formats: + | { toDict(): Record }"} required={true} toc={true}> + SWML content in one of three formats: - `string` -- raw SWML JSON text (parsed via `JSON.parse`; invalid JSON is wrapped as `{ raw_swml: content }`) - - `Record` -- SWML data structure (spread into the action) + - `Record` -- SWML data structure (shallow-copied into the action) + - An object exposing a `toDict()` method (e.g., a `SwmlBuilder` instance) -- the returned dictionary is used as the SWML payload diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx index 5fa58c039..c704a9d59 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/join-conference.mdx @@ -29,7 +29,7 @@ used internally. Passing any non-default parameter triggers the full object form Join the conference muted. - + Beep configuration for join/leave notifications. - `"true"` -- beep on both enter and exit @@ -52,7 +52,7 @@ used internally. Passing any non-default parameter triggers the full object form When omitted, default hold music is used. - + Maximum number of participants. @@ -97,7 +97,7 @@ used internally. Passing any non-default parameter triggers the full object form URL to receive conference status event webhooks. - + HTTP method for status callbacks. - `"GET"` -- send status callbacks as GET requests @@ -108,14 +108,14 @@ used internally. Passing any non-default parameter triggers the full object form URL to receive recording status event webhooks. - + HTTP method for recording status callbacks. - `"GET"` -- send recording status callbacks as GET requests - `"POST"` -- send recording status callbacks as POST requests - + Space-separated list of recording events to report. - `"in-progress"` -- recording is currently in progress diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/tap.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/tap.mdx index 22cb36d46..fd511f45b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/function-result/tap.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/function-result/tap.mdx @@ -29,7 +29,7 @@ WebSocket (`wss://`, `ws://`) and RTP (`rtp://`) destinations. specific tap. If omitted, a default ID is generated. - + Audio direction to tap. - `"speak"` -- what the party says @@ -37,14 +37,14 @@ WebSocket (`wss://`, `ws://`) and RTP (`rtp://`) destinations. - `"both"` -- both directions - + Audio codec for the stream. - `"PCMU"` -- G.711 mu-law - `"PCMA"` -- G.711 A-law - + Packetization time in milliseconds for RTP streams. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/helpers.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/helpers.mdx index b914e2ef1..de4db6f17 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/helpers.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/helpers.mdx @@ -370,6 +370,40 @@ console.log(redactUrl('https://admin:secret@example.com/api')); --- +## **validateUrl** + +Validate that a URL is safe to fetch — rejects URLs whose hostname resolves to +a private or reserved IP range (loopback, RFC1918, link-local, IPv6 private). +Never throws; returns `false` on failure. + +## **Parameters** + + + The URL to validate. + + + + When `true`, skip the private-IP check. + + +## **Returns** + +`Promise` -- `true` if the URL is safe to fetch, `false` otherwise. + +## **Example** + +```typescript {3} +import { validateUrl } from '@signalwire/sdk'; + +const ok = await validateUrl('https://api.example.com/endpoint'); +console.log(ok); // true + +const bad = await validateUrl('http://127.0.0.1:8080/admin'); +console.log(bad); // false +``` + +--- + ## **MAX_SKILL_INPUT_LENGTH** Maximum allowed input length for skill handler arguments (characters). Value: `1000`. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/index.mdx index 2f9dea278..1e5ba37be 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/index.mdx @@ -39,44 +39,83 @@ new AgentSession(options?: { llm?: any; vad?: any; turnDetection?: any; + tools?: FunctionTool[]; + mcpServers?: unknown; userData?: UserData; - voiceOptions?: Partial; + allowInterruptions?: boolean; + minInterruptionDuration?: number; + minEndpointingDelay?: number; + maxEndpointingDelay?: number; + maxToolSteps?: number; + preemptiveGeneration?: boolean; }) ``` - + STT provider instance. Accepted for API compatibility; SignalWire handles speech recognition automatically. Logs an informational message on first use. - + TTS provider instance. Accepted for API compatibility; SignalWire handles text-to-speech automatically. Logs an informational message on first use. - + LLM provider or model string. If provided, the model name is extracted (stripping any provider prefix like `"openai/"`) and set on the underlying SignalWire agent. - + VAD provider instance. Accepted for API compatibility; SignalWire handles voice activity detection automatically. - + Turn detection configuration. Accepted for API compatibility; SignalWire handles turn detection automatically. + + Optional additional tools merged with the agent's tools when `start()` is called. + + + + Accepted for LiveKit parity. MCP servers are not yet supported in LiveWire — + logs a one-time advisory and has no effect. + + Arbitrary data attached to the session. Accessible from tool handlers via [`RunContext.userData`][runcontext]. - - Voice configuration (`voice`, `engine`, `language`) passed through to the - SignalWire AI config. + + Forwarded to the SignalWire AI params when the session starts. + + + + Accepted for LiveKit parity. Forwarded to the SignalWire AI params when the + session starts. + + + + Minimum endpointing delay in seconds. Forwarded to the SignalWire AI params + when the session starts. + + + + Maximum endpointing delay in seconds. Forwarded to the SignalWire AI params + when the session starts. + + + + Accepted for LiveKit parity. SignalWire handles tool-execution depth + automatically — logs a one-time advisory if set to a non-default value. + + + + Accepted for LiveKit parity. Stored on the session but not currently used. ## **Properties** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/start.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/start.mdx index 746095448..a841d2651 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/start.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/agent-session/start.mdx @@ -16,7 +16,7 @@ AI model parameter. ## **Signature** ```typescript {1} -async start(params: { agent: Agent; room?: any }): Promise +async start(params: { agent: Agent; room?: any; record?: boolean }): Promise ``` ## **Parameters** @@ -25,10 +25,14 @@ async start(params: { agent: Agent; room?: any }): Promise The [`Agent`][agent] instance to bind to this session. - + A room instance. Accepted for API compatibility with LiveKit. + + Whether to record the session. Accepted for API compatibility with LiveKit. + + ## **Returns** `Promise` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/signals.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/signals.mdx index 849fd3a71..b787579a4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/livewire/signals.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/livewire/signals.mdx @@ -125,17 +125,38 @@ Factory function that creates an `AgentHandoff` instance. ## **ChatContext** -A minimal empty class mirroring the LiveKit `ChatContext`. Exists for API -compatibility. On SignalWire, conversation history is managed by the platform. +A minimal class mirroring the LiveKit `ChatContext`. Stores an in-memory list +of chat messages. On SignalWire, the platform manages conversation history +for the active call — this class exists so that existing livekit-agents code +that references `ChatContext` compiles without errors, and so callers can +stage messages in prewarm code. -```typescript {3} +```typescript {4} import { llm } from '@signalwire/sdk/livewire'; const chat = new llm.ChatContext(); +chat.append({ role: 'system', text: 'You are a helpful agent.' }); ``` - -`ChatContext` has no methods or properties in the LiveWire implementation. It is an -empty stub provided solely so that existing livekit-agents code that references -`ChatContext` compiles without errors. - +### Properties + + + Appended chat messages. Each entry is stored as `{ role, content }`. + + +### append + +```typescript {1} +append(options: { role?: string; text?: string }): this +``` + +Append a message to `messages`. The stored entry uses `content` (not `text`) +as the body key — `text` is renamed to match the on-wire message shape. + + + The message role (`"user"`, `"assistant"`, `"system"`, etc.). + + + + The message content. + diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/overview.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/overview.mdx index 73dbf95c4..8eeb991bb 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/overview.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/overview.mdx @@ -1,7 +1,7 @@ --- title: "Agents" sidebar-title: Overview -subtitle: "TypeScript API reference for AgentBase, SWMLService, SWAIG functions, skills, contexts, LiveWire, search, and more" +subtitle: "TypeScript API reference for AgentBase, SWMLService, SWAIG functions, skills, contexts, LiveWire, and more" slug: /reference/typescript/agents description: "Core framework for building AI-powered voice agents." max-toc-depth: 3 diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/index.mdx index a999d4c83..238209883 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/index.mdx @@ -25,11 +25,11 @@ import { | Prefab | Purpose | Built-in Tools | |--------|---------|----------------| -| [ConciergeAgent](/docs/server-sdks/reference/typescript/agents/prefabs/concierge-agent) | Multi-department routing with knowledge base | `list_departments`, `get_department_info`, `transfer_to_department` | +| [ConciergeAgent](/docs/server-sdks/reference/typescript/agents/prefabs/concierge-agent) | Venue concierge with services, amenities, and hours | `check_availability`, `get_directions` | | [FAQBotAgent](/docs/server-sdks/reference/typescript/agents/prefabs/faq-bot-agent) | Answer questions using keyword matching | `search_faq`, `escalate` (optional) | -| [InfoGathererAgent](/docs/server-sdks/reference/typescript/agents/prefabs/info-gatherer-agent) | Collect named fields from a caller | `save_field`, `get_status` | -| [ReceptionistAgent](/docs/server-sdks/reference/typescript/agents/prefabs/receptionist-agent) | Front-desk check-in, directory, and transfers | `get_department_list`, `transfer_to_department`, `check_in_visitor` (optional) | -| [SurveyAgent](/docs/server-sdks/reference/typescript/agents/prefabs/survey-agent) | Conduct surveys with branching and scoring | `answer_question`, `get_current_question`, `get_survey_progress` | +| [InfoGathererAgent](/docs/server-sdks/reference/typescript/agents/prefabs/info-gatherer-agent) | Collect answers to a list of questions | `start_questions`, `submit_answer` | +| [ReceptionistAgent](/docs/server-sdks/reference/typescript/agents/prefabs/receptionist-agent) | Front-desk check-in, directory, and transfers | `collect_caller_info`, `transfer_call`, `check_in_visitor` (optional) | +| [SurveyAgent](/docs/server-sdks/reference/typescript/agents/prefabs/survey-agent) | Conduct surveys with branching and scoring | `validate_response`, `log_response`, `answer_question`, `get_current_question`, `get_survey_progress` | Each prefab also has a corresponding factory function (e.g., `createConciergeAgent()`) that creates and returns a configured instance. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx index d95decbc7..436fbfc1c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/receptionist-agent.mdx @@ -65,8 +65,8 @@ const agent = new ReceptionistAgent({ /* ReceptionistConfig */ }); | Tool | Description | |------|-------------| -| `get_department_list` | List all departments with descriptions and numbers. | -| `transfer_call` | Dial a department's number and transfer the caller. | +| `collect_caller_info` | Collect the caller's name and reason for calling; stored in `global_data.caller_info`. | +| `transfer_call` | Dial a department's number and transfer the caller. The `department` param is an enum of the configured department names. | | `check_in_visitor` | Record a visitor check-in (only when `checkInEnabled` is `true`). | diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx index a9f29de6a..835c9ce00 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/prefabs/survey-agent.mdx @@ -72,6 +72,8 @@ const agent = new SurveyAgent({ /* SurveyConfig */ }); | Tool | Description | Parameters | |------|-------------|------------| +| `validate_response` | Validate a response against the question's type and rules without advancing | `question_id` (string), `response` (string) | +| `log_response` | Log a validated response to the session without scoring or advancing | `question_id` (string), `response` (string) | | `answer_question` | Record the caller's answer, validate it, apply scoring, and advance to the next question | `question_id` (string), `answer` (string) | | `get_current_question` | Get the current question that should be asked | (none) | | `get_survey_progress` | Get progress stats: questions answered, total score, and answer history | (none) | diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/api-ninjas-trivia.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/api-ninjas-trivia.mdx index a5baba854..4f9657d66 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/api-ninjas-trivia.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/api-ninjas-trivia.mdx @@ -10,21 +10,34 @@ Fetch trivia questions from the API Ninjas service with optional category filter **Class:** `ApiNinjasTriviaSkill` -**Tools:** `get_trivia` +**Tools:** Configurable via `tool_name` (default `get_trivia`) **Env vars:** `API_NINJAS_KEY` +**Multi-instance:** Yes — each instance must use a distinct `tool_name`. + + + Custom name for the SWAIG trivia tool. Set a distinct value per instance when + registering multiple `ApiNinjasTriviaSkill` instances on the same agent. + + API Ninjas API key. Falls back to the `API_NINJAS_KEY` environment variable. - - Default trivia category if none is specified by the user. Available categories: + + Subset of trivia categories to enable. Defaults to all 14 supported categories. + Values outside the allowed set are filtered out. Available categories: `artliterature`, `language`, `sciencenature`, `general`, `fooddrink`, `peopleplaces`, `geography`, `historyholidays`, `entertainment`, `toysgames`, `music`, `mathematics`, `religionmythology`, `sportsleisure`. + + Default trivia category if none is specified by the user. Must be one of the + enabled `categories`. + + Whether to include the answer in the response. When `false`, the AI receives the answer privately so it can quiz the user. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/ask-claude.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/ask-claude.mdx index 87e15f084..d3e0d112c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/ask-claude.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/ask-claude.mdx @@ -16,7 +16,8 @@ sub-tasks that benefit from a dedicated AI query. **Env vars:** `ANTHROPIC_API_KEY` - Anthropic API key. Falls back to the `ANTHROPIC_API_KEY` environment variable. + Anthropic API key. The handler reads the `ANTHROPIC_API_KEY` environment + variable at request time; a config value is not used as a fallback. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx index 1943abce2..0f1ec392b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere-serverless.mdx @@ -21,24 +21,27 @@ time, so the same parameters are required here as on DataSphereSkill. **Tools:** Custom per instance via `tool_name` (default `search_knowledge`), registered as a DataMap-style SWAIG function. -**Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_TOKEN` +**Env vars:** None. `space_name`, `project_id`, and `token` must be supplied as +config values — the serverless build path reads config only, not environment +variables. **Multi-instance:** yes - - Custom tool name for this instance. + + Custom tool name for this instance. Required when registering multiple + instances on the same agent. - SignalWire space name. + SignalWire space name (e.g., `"mycompany"` from `mycompany.signalwire.com`). - SignalWire project ID. Falls back to `SIGNALWIRE_PROJECT_ID`. + SignalWire project ID. - SignalWire API token. Falls back to `SIGNALWIRE_TOKEN`. + SignalWire API token. @@ -71,7 +74,9 @@ registered as a DataMap-style SWAIG function. - Message returned when no results match the query. + Message returned when no results match the query. Supports a `{query}` + placeholder that is substituted with the user's query text at registration + time. ## Example diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx index 0e0e43be9..ecfd89854 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx @@ -20,8 +20,9 @@ required — `setup()` fails closed if any are missing. **Multi-instance:** yes - - Custom tool name for this DataSphere instance. + + Custom tool name for this DataSphere instance. Required when registering + multiple instances on the same agent. @@ -67,7 +68,8 @@ required — `setup()` fails closed if any are missing. - Message returned when no results match the query. + Message returned when no results match the query. Supports a `{query}` + placeholder that is substituted with the user's query text. ## Example diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datetime.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datetime.mdx index f78f35e36..21e7b6edd 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datetime.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datetime.mdx @@ -11,7 +11,7 @@ Get the current date and time with optional timezone support. **Class:** `DateTimeSkill` -**Tools:** `get_datetime` +**Tools:** `get_current_time`, `get_current_date` **Env vars:** None diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/google-maps.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/google-maps.mdx index 0da4bd17c..45e058a4f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/google-maps.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/google-maps.mdx @@ -6,21 +6,42 @@ description: Get driving/walking/transit directions and search for places using [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Get driving/walking/transit directions and search for places using Google Maps APIs. +Get driving/walking/transit directions, find places, geocode addresses, and +compute routes by coordinates using Google Maps APIs. **Class:** `GoogleMapsSkill` -**Tools:** `get_directions`, `find_place` +**Tools:** `compute_route`, `lookup_address`, `geocode_address`, +`compute_route_by_coords` (each tool name is configurable). -**Env vars:** `GOOGLE_MAPS_API_KEY` +**Env vars:** `GOOGLE_MAPS_API_KEY` (required — the tool handlers read this +directly and do not fall back to an `api_key` config value). - Google Maps API key with Directions and Places APIs enabled. - Falls back to the `GOOGLE_MAPS_API_KEY` environment variable. + Schema-level declaration for the Google Maps API key. The tool handlers read + the `GOOGLE_MAPS_API_KEY` environment variable at request time; a config + value is not used as a fallback. - Default travel mode: `"driving"`, `"walking"`, `"bicycling"`, or `"transit"`. + Default travel mode for `compute_route`: `"driving"`, `"walking"`, + `"bicycling"`, or `"transit"`. + + + + Custom name for the route computation tool. + + + + Custom name for the address / place lookup tool. + + + + Custom name for the address-to-coordinates geocode tool. + + + + Custom name for the coordinate-based route computation tool. ```typescript {6-8} diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx index 72cfd6578..5bc3957d5 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/index.mdx @@ -29,7 +29,7 @@ await agent.addSkill(new DateTimeSkill()); // Skill with parameters await agent.addSkill(new WebSearchSkill({ - max_results: 5, + num_results: 5, safe_search: 'high', })); @@ -40,21 +40,21 @@ agent.run(); | Skill | Class | Tools | Env Vars Required | Multi-Instance | |-------|-------|-------|-------------------|----------------| -| [`datetime`](/docs/server-sdks/reference/typescript/agents/skills/datetime) | `DateTimeSkill` | 1 | No | No | +| [`datetime`](/docs/server-sdks/reference/typescript/agents/skills/datetime) | `DateTimeSkill` | 2 | No | No | | [`math`](/docs/server-sdks/reference/typescript/agents/skills/math) | `MathSkill` | 1 | No | No | | [`joke`](/docs/server-sdks/reference/typescript/agents/skills/joke) | `JokeSkill` | 1 | No | No | | [`weather_api`](/docs/server-sdks/reference/typescript/agents/skills/weather-api) | `WeatherApiSkill` | 1 | Yes | No | -| [`web_search`](/docs/server-sdks/reference/typescript/agents/skills/web-search) | `WebSearchSkill` | 1 | Yes | No | +| [`web_search`](/docs/server-sdks/reference/typescript/agents/skills/web-search) | `WebSearchSkill` | 1 | Yes | Yes | | [`wikipedia_search`](/docs/server-sdks/reference/typescript/agents/skills/wikipedia-search) | `WikipediaSearchSkill` | 1 | No | No | -| [`google_maps`](/docs/server-sdks/reference/typescript/agents/skills/google-maps) | `GoogleMapsSkill` | 2 | Yes | No | -| [`play_background_file`](/docs/server-sdks/reference/typescript/agents/skills/play-background-file) | `PlayBackgroundFileSkill` | 2 | No | No | -| [`swml_transfer`](/docs/server-sdks/reference/typescript/agents/skills/swml-transfer) | `SwmlTransferSkill` | 1-2 | No | No | +| [`google_maps`](/docs/server-sdks/reference/typescript/agents/skills/google-maps) | `GoogleMapsSkill` | 4 | Yes | No | +| [`play_background_file`](/docs/server-sdks/reference/typescript/agents/skills/play-background-file) | `PlayBackgroundFileSkill` | 1-3 | No | Yes | +| [`swml_transfer`](/docs/server-sdks/reference/typescript/agents/skills/swml-transfer) | `SwmlTransferSkill` | 1-2 | No | Yes | | [`datasphere`](/docs/server-sdks/reference/typescript/agents/skills/datasphere) | `DataSphereSkill` | 1 | Yes | Yes | | [`datasphere_serverless`](/docs/server-sdks/reference/typescript/agents/skills/datasphere-serverless) | `DataSphereServerlessSkill` | 1 | Yes | Yes | | [`native_vector_search`](/docs/server-sdks/reference/typescript/agents/skills/native-vector-search) | `NativeVectorSearchSkill` | 1 | No | Yes | -| [`info_gatherer`](/docs/server-sdks/reference/typescript/agents/skills/info-gatherer) | `InfoGathererSkill` | 2 | No | No | -| [`api_ninjas_trivia`](/docs/server-sdks/reference/typescript/agents/skills/api-ninjas-trivia) | `ApiNinjasTriviaSkill` | 1 | Yes | No | -| [`spider`](/docs/server-sdks/reference/typescript/agents/skills/spider) | `SpiderSkill` | 1 | Yes | No | +| [`info_gatherer`](/docs/server-sdks/reference/typescript/agents/skills/info-gatherer) | `InfoGathererSkill` | 2 | No | Yes | +| [`api_ninjas_trivia`](/docs/server-sdks/reference/typescript/agents/skills/api-ninjas-trivia) | `ApiNinjasTriviaSkill` | 1 | Yes | Yes | +| [`spider`](/docs/server-sdks/reference/typescript/agents/skills/spider) | `SpiderSkill` | 3 | No | Yes | | [`ask_claude`](/docs/server-sdks/reference/typescript/agents/skills/ask-claude) | `AskClaudeSkill` | 1 | Yes | No | | [`claude_skills`](/docs/server-sdks/reference/typescript/agents/skills/claude-skills) | `ClaudeSkillsSkill` | Dynamic | No | Yes | | [`custom_skills`](/docs/server-sdks/reference/typescript/agents/skills/custom-skills) | `CustomSkillsSkill` | Dynamic | No | No | @@ -70,13 +70,13 @@ parameter is not provided directly. import { WebSearchSkill } from '@signalwire/sdk'; // Direct configuration -const skill = new WebSearchSkill({ max_results: 5, safe_search: 'high' }); +const skill = new WebSearchSkill({ num_results: 5, safe_search: 'high' }); // Environment variable fallback (api_key falls back to GOOGLE_SEARCH_API_KEY, // search_engine_id falls back to GOOGLE_SEARCH_CX) process.env.GOOGLE_SEARCH_API_KEY = 'YOUR_KEY'; process.env.GOOGLE_SEARCH_CX = 'YOUR_ENGINE_ID'; -const skillWithEnv = new WebSearchSkill({ max_results: 5 }); +const skillWithEnv = new WebSearchSkill({ num_results: 5 }); ``` ### SWAIG Field Overrides @@ -112,11 +112,13 @@ agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new DataSphereSkill({ tool_name: 'search_products', - max_results: 3, + document_id: 'doc_products', + count: 3, })); await agent.addSkill(new DataSphereSkill({ tool_name: 'search_policies', - max_results: 5, + document_id: 'doc_policies', + count: 5, })); agent.run(); diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/joke.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/joke.mdx index 060fdf28a..f12d37c47 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/joke.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/joke.mdx @@ -12,11 +12,15 @@ categories. No external API required. **Class:** `JokeSkill` -**Tools:** `tell_joke` +**Tools:** `tell_joke` (configurable via `tool_name`) **Env vars:** None -No custom parameters. This skill inherits only the [base parameters][base-parameters]. + + Custom name for the joke tool. Overrides the default SWAIG function name. + + +Plus the [base parameters][base-parameters] (`swaig_fields`, `skip_prompt`). ```typescript {5} import { AgentBase, JokeSkill } from '@signalwire/sdk'; diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx index 153087531..0207ac481 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/mcp-gateway.mdx @@ -55,8 +55,9 @@ cloud-metadata endpoints are rejected. Requests use retry semantics with Gateway session timeout in seconds. - - Prefix prepended to each SWAIG function name registered from the gateway. + + Prefix prepended to each SWAIG function name registered from the gateway + (e.g., `mcp_todo_add_todo`). diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx index 32d9e776b..aee1db3c4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/native-vector-search.mdx @@ -1,33 +1,35 @@ --- title: "NativeVectorSearchSkill" slug: /reference/typescript/agents/skills/native-vector-search -description: Vector + keyword document search against a local .swsearch index or remote search server. +description: Vector + keyword document search against a local .swsearch index, an in-memory document array, or a remote search server. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Search documents using vector similarity and keyword matching. Supports two -backends: +Search documents using vector similarity and keyword matching. Supports three +modes: +- **In-memory (TF-IDF)** — supply a `documents` array in config; the skill + tokenizes and indexes at startup (TypeScript-specific fast path). - **Local (SQLite)** — point `index_file` at a `.swsearch` index, or set `build_index: true` and `source_dir` to index at startup. - **Remote (network)** — point `remote_url` at a search server and optionally - name the index via `index_name`. - -The remote mode enforces an SSRF guard before each request and uses a 5-second -health-check timeout. + name the index via `index_name`. Validated by the SSRF guard before each + request; health check uses a 5-second timeout. **Class:** `NativeVectorSearchSkill` -**Tools:** `search_documents` (default — `tool_name` override supported) +**Tools:** `search_knowledge` (default — `tool_name` override supported) **Env vars:** None -**Multi-instance:** yes +**Multi-instance:** yes (distinguished by `tool_name` + `index_file`) + +## Core Parameters - - Custom tool name for this instance. Set when registering multiple - NativeVectorSearch instances on the same agent. + + Custom tool name for this skill instance. Required when registering multiple + instances on the same agent. @@ -35,8 +37,7 @@ health-check timeout. - When `true`, the skill builds an in-process index at startup from - `source_dir`. + Whether to build the index from source files at startup. @@ -45,54 +46,139 @@ health-check timeout. - URL of the remote search server (network mode). Validated by the SSRF guard. + URL of a remote search server (network mode). Validated by the SSRF guard — + private, loopback, and cloud-metadata endpoints are rejected. + + + + Name of the index on a remote server. Only used with `remote_url`. - - Name of the index on the remote server (network mode only). + + In-memory array of documents to index (TypeScript-specific). Each entry has + `id` (string), `text` (string), optional `metadata` (object), and optional + `tags` (string[]). +## Search Parameters + - Number of results to return (range `1-20`). + Number of search results to return (range `1-20`). - Minimum similarity score (0.0 — no limit, 1.0 — exact match). + Minimum similarity score for results (`0.0` — no limit, `1.0` — exact match). + + Manual keyword weight in the hybrid TF-IDF + keyword score + (range `0.0-1.0`). Overrides the automatic default of `0.3`. + + + + Embedding model for remote/SQLite modes. Shortcuts: `"mini"` (fastest, + 384 dims), `"base"` or `"large"` (768 dims). Full model names also accepted. + + +## Content Parameters + - Tag filter applied to search queries. + Tag filter applied to search queries. Only documents carrying at least one + matching tag are returned. - Tags applied to every indexed document at build time. + Tags applied to every document at index-build time. - File extensions to include when building an index. + File extensions to include when building an index from `source_dir`. - Glob patterns excluded from index builds. Defaults include `**/node_modules/**`, - `**/.git/**`, `**/dist/**`, `**/build/**`. + Glob patterns excluded from index builds. Defaults include + `**/node_modules/**`, `**/.git/**`, `**/dist/**`, `**/build/**`. - - Message returned when no results match. Supports `{query}` placeholder. - Defaults to `"No information found for '{query}'"`. + + Maximum total response size in characters (distributed across all results). - - Prefix prepended to the search response. +## Response Parameters + + + Message returned when no results match. Supports a `{query}` placeholder + that is substituted with the user's query text. - - Suffix appended to the search response. + + Text prepended to the search response. -## Example — local index + + Text appended to the search response. + -```typescript {6-10} + + Optional callback to transform the final response. Receives + `{ response, agent, query, results, args, count, skill }` and must return a + string. + + + + Description of the search tool presented to the AI. + + + + Additional speech recognition hints for the tool. + + +## NLP Parameters + + + NLP backend for query processing: `"basic"`, `"spacy"`, or `"nltk"`. + **Deprecated** — use `query_nlp_backend` and `index_nlp_backend` instead. + + + + NLP backend for query expansion: `"basic"`, `"spacy"`, or `"nltk"`. + + + + NLP backend for indexing: `"basic"`, `"spacy"`, or `"nltk"`. + + +## Backend Parameters + + + Storage backend for local database mode: `"sqlite"` or `"pgvector"`. Ignored + when `remote_url` is set. SQLite and pgvector backends require native + Python-only dependencies; configurations written for the Python SDK remain + valid but the TypeScript SDK only exercises the in-memory (`documents`) and + remote (`remote_url`) paths. + + + + PostgreSQL connection string. Required when `backend="pgvector"`. + + + + PostgreSQL collection name. Required when `backend="pgvector"`. + + +## Other Parameters + + + Enable verbose logging during indexing and search. + + + + Overwrite existing pgvector collection when building the index. + + +## Example — in-memory documents + +```typescript {6-16} import { AgentBase, NativeVectorSearchSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'kb-bot', route: '/kb' }); @@ -100,8 +186,13 @@ agent.setPromptText('Answer questions from the knowledge base.'); await agent.addSkill(new NativeVectorSearchSkill({ tool_name: 'search_kb', - index_file: './kb.swsearch', - count: 5, + documents: [ + { id: 'faq-1', text: 'Hours are 9am to 5pm Monday to Friday.', tags: ['hours'] }, + { id: 'faq-2', text: 'Returns are accepted within 30 days.', tags: ['returns'] }, + ], + count: 3, + similarity_threshold: 0.1, + keyword_weight: 0.5, })); agent.run(); @@ -109,11 +200,12 @@ agent.run(); ## Example — remote server -```typescript {6-9} +```typescript {6-10} await agent.addSkill(new NativeVectorSearchSkill({ remote_url: 'https://search.internal.example.com', index_name: 'support-kb', count: 3, similarity_threshold: 0.4, + tags: ['public'], })); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/play-background-file.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/play-background-file.mdx index aec5930cf..6860da72c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/play-background-file.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/play-background-file.mdx @@ -1,40 +1,94 @@ --- title: "PlayBackgroundFileSkill" slug: /reference/typescript/agents/skills/play-background-file -description: Control background audio playback during calls. +description: Control background audio/video playback during calls. Supports pre-configured file list or free-form URL playback. --- [add-skill]: /docs/server-sdks/reference/typescript/agents/agent-base/add-skill -Control background audio playback during calls. Play hold music, ambient sounds, -or any audio file using SWML playback actions. +Control background audio/video playback during calls using SWML playback +actions. Two configuration modes are supported: + +- **Pre-configured mode (matches Python)** — supply `files` and the skill + emits a single tool whose `action` enum includes `start_` for each + configured file plus `stop`. +- **Free-form mode (TypeScript-specific)** — omit `files` and supply + `default_file_url` and/or `allowed_domains`. The skill emits two tools, + `play_background` and `stop_background`, which accept arbitrary URLs (with + optional domain allowlist). **Class:** `PlayBackgroundFileSkill` -**Tools:** `play_background`, `stop_background` +**Tools (pre-configured mode):** `play_background_file` (configurable via +`tool_name`) + +**Tools (free-form mode):** `play_background`, `stop_background` **Env vars:** None +**Multi-instance:** yes — set a distinct `tool_name` per instance. + + + Custom name for the generated SWAIG tool in pre-configured mode. Required + when registering multiple instances on the same agent. + + + + Array of pre-configured file entries that become selectable via the tool's + `action` enum. When supplied (and non-empty), the skill runs in + pre-configured mode; when omitted or empty, the skill falls back to + free-form mode. + + Each entry has: + + - `key` (string, required) — unique identifier (alphanumeric, underscores, + hyphens); mapped to `start_` in the `action` enum. + - `description` (string, required) — human-readable description shown to + the AI. + - `url` (string, required) — URL of the audio/video file. + - `wait` (boolean, optional, default `false`) — whether to wait for the + file to finish playing. + + - Default audio file URL to use when no URL is specified by the caller. - When set, the `file_url` parameter becomes optional on the `play_background` tool. + Default audio file URL for free-form mode. When set, the `file_url` + parameter on the `play_background` tool becomes optional. - List of allowed domains for audio file URLs. If set, only URLs from these - domains are accepted. + Allowlist of domains for audio file URLs in free-form mode. When set, only + URLs whose hostname matches or is a subdomain of one of these entries are + accepted. -```typescript {6-9} +## Example — pre-configured files + +```typescript {6-14} import { AgentBase, PlayBackgroundFileSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant', route: '/assistant' }); agent.setPromptText('You are a helpful assistant.'); await agent.addSkill(new PlayBackgroundFileSkill({ - default_file_url: 'https://example.com/hold-music.mp3', - allowed_domains: ['example.com', 'cdn.example.com'], + tool_name: 'play_testimonial', + files: [ + { + key: 'massey', + description: 'Customer success story from Massey Energy', + url: 'https://example.com/massey.mp4', + wait: true, + }, + ], })); agent.run(); ``` + +## Example — free-form URL + +```typescript {6-9} +await agent.addSkill(new PlayBackgroundFileSkill({ + default_file_url: 'https://example.com/hold-music.mp3', + allowed_domains: ['example.com', 'cdn.example.com'], +})); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx index f563167d1..9e860304b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/spider.mdx @@ -12,11 +12,21 @@ from any public URL, optionally following links up to a bounded depth. Uses **Class:** `SpiderSkill` -**Tools:** `scrape_url` +**Tools:** `scrape_url`, `crawl_site`, `extract_structured_data` (each is +prefixed with `_` when `tool_name` is set). **Required packages:** `cheerio` -**Env vars:** None +**Env vars:** `SWML_ALLOW_PRIVATE_URLS=true` relaxes the SSRF guard for local +testing. + +**Multi-instance:** yes — set a distinct `tool_name` per instance. + + + Prefix prepended to each emitted tool name (e.g., `tool_name="news"` gives + `news_scrape_url`, `news_crawl_site`, `news_extract_structured_data`). + Required when registering multiple instances on the same agent. + Delay between requests in seconds (minimum `0`). @@ -38,9 +48,11 @@ from any public URL, optionally following links up to a bounded depth. Uses Maximum crawl depth. `0` restricts to a single page; range `0-5`. - + Content extraction method. One of `"fast_text"`, `"clean_text"`, - `"full_text"`, `"html"`, `"markdown"`, `"structured"`, `"custom"`. + `"full_text"`, `"html"`, `"markdown"`, `"structured"`, `"custom"`. Only + `fast_text`, `markdown`, and `structured` are wired through the handlers + in the TypeScript port; the others fall back to `fast_text`. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx index f38b77879..13737117a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/swml-transfer.mdx @@ -14,16 +14,20 @@ closed otherwise. **Class:** `SwmlTransferSkill` -**Tools:** `transfer_call` (always registered) +**Tools:** `transfer_call` always; `list_transfer_destinations` additionally +registered when at least one entry is supplied in `patterns`. **Env vars:** None -"} required={true} toc={true}> +**Multi-instance:** yes — set a distinct `tool_name` per instance. + +"} toc={true}> Python-style map of transfer configs keyed by regex pattern (or name). Each entry includes either `url` or `address` (not both), plus optional `message`, `return_message`, `post_process`, `final`, and `from_addr`. Either `transfers` or `patterns` must be provided; both may be combined. + `setup()` fails closed when neither is configured. @@ -42,23 +46,23 @@ closed otherwise. patterns are configured. - + Name of the transfer tool exposed to the AI. - + Description for the transfer tool shown to the AI. - + Name of the parameter that accepts the transfer type. - + Description for the transfer-type parameter. - + Message spoken when no pattern matches. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/weather-api.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/weather-api.mdx index 6b6ac063a..8de889e13 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/weather-api.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/weather-api.mdx @@ -8,19 +8,32 @@ description: Get current weather conditions for any location using the OpenWeath Get current weather conditions for any location using the OpenWeatherMap API. + +**Provider note:** This skill uses OpenWeatherMap +(`api.openweathermap.org/data/2.5/weather`), not WeatherAPI.com. An +OpenWeatherMap API key is required — a WeatherAPI.com key will not work. +Obtain a key at https://openweathermap.org/api. + + **Class:** `WeatherApiSkill` -**Tools:** `get_weather` +**Tools:** `get_weather` (configurable via `tool_name`) **Env vars:** `WEATHER_API_KEY` - OpenWeatherMap API key. Falls back to the `WEATHER_API_KEY` environment variable. + OpenWeatherMap API key. Falls back to the `WEATHER_API_KEY` environment + variable when the config value is not supplied. + + + + Custom name for the generated weather tool. - - Temperature units: `"metric"` (Celsius), `"imperial"` (Fahrenheit), or - `"standard"` (Kelvin). + + Temperature units. Preferred values: `"metric"` (Celsius), `"imperial"` + (Fahrenheit), or `"standard"` (Kelvin). Python SDK aliases are also + accepted: `"celsius"` → `"metric"`, `"fahrenheit"` → `"imperial"`. ```typescript {6-8} diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx index dcedc2ee4..632662a3c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/web-search.mdx @@ -12,11 +12,14 @@ content, and returns only the highest-quality matches to the AI. **Class:** `WebSearchSkill` -**Tools:** `web_search` +**Tools:** `web_search` (configurable via `tool_name`) **Env vars:** `GOOGLE_SEARCH_API_KEY`, `GOOGLE_SEARCH_ENGINE_ID` (legacy `GOOGLE_SEARCH_CX` is still accepted) +**Multi-instance:** yes — instance key combines `search_engine_id` and +`tool_name`. + Google Custom Search API key. Falls back to the `GOOGLE_SEARCH_API_KEY` environment variable. @@ -59,7 +62,7 @@ content, and returns only the highest-quality matches to the AI. placeholder for the original search term. - + Safe-search level. One of `"off"`, `"medium"`, `"high"`. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx index 9bf2ef0e0..1555060ac 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/wikipedia-search.mdx @@ -20,7 +20,10 @@ Uses Node's native `fetch` with a 10-second timeout. No API key required. - Custom message returned when no articles match the query. + Custom message returned when no articles match the query. Supports a + `{query}` placeholder that is substituted with the user's query text. + Defaults to a generic "couldn't find any Wikipedia articles for '{query}'" + fallback. ## Example diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/execute.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/execute.mdx index 8784d79f8..2f4213585 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/execute.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/execute.mdx @@ -34,7 +34,7 @@ or a plain string. All formats are normalized to a result dictionary. ## **Example** -```typescript {20} +```typescript {19} import { SwaigFunction, FunctionResult } from '@signalwire/sdk'; const func = new SwaigFunction({ @@ -55,5 +55,5 @@ const func = new SwaigFunction({ const result = await func.execute({ account_id: "12345" }); console.log(result); -// { response: "Account 12345 is active.", action: [] } +// { response: "Account 12345 is active." } ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/index.mdx index b68d3afba..6b94b12e8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/index.mdx @@ -14,6 +14,7 @@ max-toc-depth: 3 [swml-swaig-functions-reference]: /docs/swml/reference/ai/swaig/functions [execute]: /docs/server-sdks/reference/typescript/agents/swaig-function/execute [toswaig]: /docs/server-sdks/reference/typescript/agents/swaig-function/to-swaig +[validateargs]: /docs/server-sdks/reference/typescript/agents/swaig-function/validate-args SwaigFunction wraps a function as a SWAIG (SignalWire AI Gateway) tool that the AI can invoke during a conversation. It manages the function's name, @@ -166,13 +167,16 @@ type SwaigHandler = ( ## **Methods** - + Execute the tool with the given arguments. Convert the tool to a SWAIG-compatible dictionary for SWML. + + Validate arguments against the parameter JSON Schema. + --- diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/validate-args.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/validate-args.mdx new file mode 100644 index 000000000..4be47d05e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swaig-function/validate-args.mdx @@ -0,0 +1,54 @@ +--- +title: "validateArgs" +slug: /reference/typescript/agents/swaig-function/validate-args +description: Validate arguments against the parameter JSON Schema. +max-toc-depth: 3 +--- + +Validate arguments against the parameter JSON Schema. Uses +[Ajv](https://ajv.js.org/) to compile and run the schema. When the function +has no parameters declared (empty schema), validation is skipped and the +arguments are treated as valid — matching the Python SDK's early-return +behavior. + +## **Parameters** + + + Arguments to validate. + + +## **Returns** + +`[boolean, string[]]` -- A tuple of `[isValid, errors]`. When no validation is +needed (empty schema), returns `[true, []]`. Error strings include the +offending property path where available (e.g., `"'account_id' is a required +property"`). + +## **Example** + +```typescript {18,22} +import { SwaigFunction, FunctionResult } from '@signalwire/sdk'; + +const fn = new SwaigFunction({ + name: 'lookup_account', + handler: async () => new FunctionResult('ok'), + description: 'Look up account status', + parameters: { + type: 'object', + properties: { + account_id: { type: 'string', description: 'Account ID' }, + }, + required: ['account_id'], + }, +}); + +// Valid arguments +const [ok1, errs1] = fn.validateArgs({ account_id: '12345' }); +console.log(`Valid: ${ok1}, Errors: ${JSON.stringify(errs1)}`); +// Valid: true, Errors: [] + +// Missing required argument +const [ok2, errs2] = fn.validateArgs({}); +console.log(`Valid: ${ok2}, Errors: ${JSON.stringify(errs2)}`); +// Valid: false, Errors: ["must have required property 'account_id'"] +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx index 844f9cedc..0e3f8a604 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx @@ -37,11 +37,28 @@ SwmlBuilder constructs [SWML][swml] documents programmatically. See the ## **Constructor** ```typescript {1} -const builder = new SwmlBuilder(); +const builder = new SwmlBuilder(opts?); ``` -The constructor takes no parameters. It initializes an empty SWML document and -installs dynamic verb methods from the bundled schema. +Initializes an empty SWML document and installs dynamic verb methods from the +bundled schema. All constructor options are optional. + +### SwmlBuilderOptions + + }"} toc={true}> + Seed the builder with an existing document instead of creating an empty one. + Enables document injection — mirrors the Python SDK's `SWMLService` injection pattern. + + + + Explicit override for verb schema validation. Defaults to `true` unless + `SWML_SKIP_SCHEMA_VALIDATION=true` is set in the environment. + + + + Path to a custom SWML schema JSON file. When set, the builder uses a + per-instance `SchemaUtils` loaded from this path instead of the bundled schema. + ## **Dynamic Verb Methods** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/reset.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/reset.mdx index 4a8ff0aae..00edb2d83 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/reset.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/reset.mdx @@ -13,7 +13,7 @@ This method takes no parameters. ## **Returns** -`void` +`this` -- The builder instance for method chaining. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx index f84f33aa2..0dfec3621 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx @@ -1,30 +1,56 @@ --- title: "say" slug: /reference/typescript/agents/swml-builder/say -description: The say method does not exist on SwmlBuilder. +description: Add a play verb with a say: prefix for text-to-speech. max-toc-depth: 3 --- [play]: /docs/server-sdks/reference/typescript/agents/swml-builder/play -[addverb]: /docs/server-sdks/reference/typescript/agents/swml-builder/add-verb - -`say` is **not** a method on `SwmlBuilder`. The SWML schema does not define a `say` -verb, so no dynamic method is generated for it. - +Convenience wrapper that appends a `play` verb with a `say:`-prefixed URL for +text-to-speech. Equivalent to calling `builder.play({ url: 'say:${text}', ... })` +but exposes the TTS options as typed arguments. -To produce text-to-speech output, use the [`play()`][play] verb with a `say:` URL -prefix, or pass the `say:` URL directly via [`addVerb()`][addverb]: +## **Parameters** -```typescript {7} + + Text the agent should speak. The method prepends `say:` to produce the + final URL passed to the underlying [`play`][play] verb. + + + + Optional TTS parameters. + + + + + Voice name for the TTS engine. Maps to `say_voice` in the emitted SWML. + + + + Language code (e.g., `"en-US"`). Maps to `say_language` in the emitted SWML. + + + + Gender for TTS voice selection. Maps to `say_gender` in the emitted SWML. + + + + Volume adjustment in dB (−40 to 40). Maps to `volume` on the play verb. + + + +## **Returns** + +`this` -- The builder instance for method chaining. + +## **Example** + +```typescript {5} import { SwmlBuilder } from '@signalwire/sdk'; const builder = new SwmlBuilder(); builder.answer(); - -// Use the play verb with a say: URL prefix for text-to-speech -builder.play({ url: 'say:Hello, welcome to our service.' }); - -// Or use addVerb directly -builder.addVerb('play', { url: 'say:Goodbye!' }); +builder.say('Welcome to our service.', { voice: 'rime.spore', language: 'en-US' }); +builder.hangup(); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-builder.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-builder.mdx index 04fce69ae..100e8d047 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-builder.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-builder.mdx @@ -20,7 +20,7 @@ This method takes no parameters. ```typescript {4} import { SWMLService } from '@signalwire/sdk'; -const sWMLService = new SWMLService(); -const result = sWMLService.getBuilder(); -console.log(result); +const service = new SWMLService({ name: 'my-ivr' }); +const builder = service.getBuilder(); +builder.addVerb('answer', {}); ``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx index afce27a36..d394fea59 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx @@ -29,24 +29,47 @@ See the [SWML reference][swml-reference] for the full document specification. ## **Constructor** - - Optional configuration object. + + Configuration object. - - Service display name used in logging and startup messages. + + Service display name used in logging and startup messages. Required to + match the Python SDK, where `name` is a positional required parameter. HTTP route path where the service is accessible. + + Host the HTTP server binds to. + + + + Port the HTTP server binds to. Defaults to the `PORT` environment variable, + falling back to `3000`. + + Basic auth credentials as `[username, password]`. Unlike `AgentBase`, `SWMLService` does not fall back to environment variables — credentials must be provided explicitly. + + + Path to a JSON Schema file for verb validation. + + + + Path to a security configuration file for SSL, CORS, and host allowlist settings. + + + + Enable schema validation. Can also be disabled via the + `SWML_SKIP_SCHEMA_VALIDATION=true` environment variable. + ## **Properties** @@ -59,6 +82,47 @@ See the [SWML reference][swml-reference] for the full document specification. HTTP route path where this service is accessible. + + Host address the HTTP server binds to. + + + + Port the HTTP server binds to. + + + + Structured logger bound to this service name. Exposed for subclass access. + + + + Unified security configuration loaded from environment variables and optional + config file. Controls SSL, CORS, and host allowlist settings. + + + + Whether SSL/HTTPS is enabled. Mirrors `security.sslEnabled`. + + + + Path to the SSL certificate file. + + + + Path to the SSL private key file. + + + + Domain name for SSL certificates. + + + + Schema validation utilities for SWML documents. + + + + Registry of custom verb handlers for specialized SWML verb processing. + + ## **Methods** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/run.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/run.mdx index 066ad7bf9..92d02deed 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/run.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/run.mdx @@ -7,15 +7,45 @@ max-toc-depth: 3 Start the HTTP server to serve the SWML document. + +Returns immediately when `SWAIG_CLI_MODE=true` is set, so the CLI testing +tool can load the service without opening a port. + + ## **Parameters** - - Hostname to bind to. + + Hostname to bind to. Defaults to the `host` passed to the constructor, or `"0.0.0.0"`. + + + + Port number to listen on. Defaults to the `port` passed to the constructor, + which itself falls back to the `PORT` environment variable or `3000`. + + + + Optional SSL/TLS overrides. Each field falls back to the matching value on + the service instance. + + + + + Path to the SSL certificate file. When both `sslCert` and `sslKey` are + resolved and `sslEnabled` is `true`, the server runs over HTTPS. + + + + Path to the SSL private key file. + + + + Override whether SSL/HTTPS is enabled for this run. - - Port number to listen on. Falls back to the `PORT` environment variable. + + Domain name associated with the SSL certificate. + ## **Returns** diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md index 9d89c1ebb..e156f8753 100644 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -190,6 +190,684 @@ _(One line per finding and per fix. Format: `[path/to/file.mdx] PRIORITY type: d --- +--- + +## Agents Audit (in progress) + +**Scope:** `pages/reference/typescript/agents/agent-base/**` — pilot of 82 files +against `src/AgentBase.ts` at commit `ba6d5b1`. + +**Source file:** `temp/signalwire-typescript/src/AgentBase.ts` (2489 lines) +**AgentOptions type:** `temp/signalwire-typescript/src/types.ts:6-70` + +### agent-base/ progress — 82/82 AUDITED + FIXED + +| # | File | Status | Notes | +|---|------|--------|-------| +| 1 | `index.mdx` | FIXED | `tokenExpirySecs` default 900→3600 (source line 196); added 5 missing constructor params: `enablePostPromptOverride`, `checkForInputOverride`, `configFile`, `schemaPath`, `schemaValidation`. CardGroup verified: 81 cards = 81 method files. | +| 2 | `add-answer-verb.mdx` | clean | signature `(config?)` line 1306 | +| 3 | `add-function-include.mdx` | clean | `(url, functions, metaData?)` line 758; meta_data mapping ok | +| 4 | `add-hint.mdx` | clean | line 499 | +| 5 | `add-hints.mdx` | clean | line 509 | +| 6 | `add-internal-filler.mdx` | FIXED | Added `` restricting to 9 supported native function names (`SUPPORTED_INTERNAL_FILLER_NAMES` at line 651); clarified description (was "specific SWAIG function" — misleading) | +| 7 | `add-language.mdx` | clean | LanguageConfig has 7 fields incl. `functionFillers`; SWML key mappings (speech_model, function_fillers) correct | +| 8 | `add-mcp-server.mdx` | clean | `(url, opts?)` with headers/resources/resourceVars; `resource_vars` mapping ok | +| 9 | `add-pattern-hint.mdx` | FIXED | Added missing required `opts.hint` param (source line 520 requires 4 fields) + updated example | +| 10 | `add-post-ai-verb.mdx` | clean | line 1328 | +| 11 | `add-pre-answer-verb.mdx` | clean | line 1296 | +| 12 | `add-pronunciation.mdx` | clean | matches PronunciationRule (types.ts:91) | +| 13 | `add-skill.mdx` | clean | async, fails-closed behavior verified against source lines 1375-1425 | +| 14 | `add-skill-by-name.mdx` | clean | line 1440 | +| 15 | `add-swaig-query-params.mdx` | clean | merge-not-replace via `safeAssign` line 1512 confirmed | +| 16 | `as-router.mdx` | clean | line 2360 | +| 17 | `auto-map-sip-usernames.mdx` | FIXED | Rewrote from stub — added overview (3-bullet behavior list), `` about `enableSipRouting()` auto-calling, full example. Ported from Python counterpart. | +| 18 | `clear-post-ai-verbs.mdx` | clean | line 1355 | +| 19 | `clear-post-answer-verbs.mdx` | clean | line 1346 | +| 20 | `clear-pre-answer-verbs.mdx` | clean | line 1337 | +| 21 | `clear-swaig-query-params.mdx` | FIXED | Rewrote from stub — added ref links, Parameters None, Returns, full dynamic-config example (src line 1520 `this.swaigQueryParams = {}`) | +| 22 | `define-contexts.mdx` | clean | `(contexts?: ContextBuilder \| Record)` line 464; plain-dict quirk (dict ignored, new ContextBuilder) correctly documented | +| 23 | `define-tool.mdx` | FIXED | Added missing `opts.webhookUrl` + `opts.extraFields` params (src lines 1131-1133); added `default="false"` to `opts.secure` (SwaigFunction.ts:143) | +| 24 | `define-tools.mdx` | clean | `protected defineTools(): void` line 256; "not called automatically" note matches src comment | +| 25 | `define-typed-tool.mdx` | FIXED | Added `default="false"` to `opts.secure` (aligns with defineTool / SwaigFunction.ts:143) | +| 26 | `enable-debug-events.mdx` | clean | `(level=1)` line 803; `debug_webhook_url` wiring at 1887 confirmed | +| 27 | `enable-debug-routes.mdx` | FIXED | Rewrote misleading desc — source line 1551 is a no-op stub; debug routes auto-registered in `getApp()`. Added Parameters None + Example + ref link, parity-with-Python note | +| 28 | `enable-mcp-server.mdx` | clean | line 950 `_mcpServerEnabled = true`; `/mcp` JSON-RPC 2.0 endpoint accurate | +| 29 | `enable-sip-routing.mdx` | clean | `(autoMap=true, path='/sip')` line 817; autoMap triggers `autoMapSipUsernames()` | +| 30 | `extract-sip-username.mdx` | clean | static method line 912; strips `sip:`/`sips:` prefix + `@domain`; returns null if no `call.to` | +| 31 | `get-app.mdx` | clean | `getApp(): Hono` line 2004; lazy init of Hono app | +| 32 | `get-basic-auth-credentials.mdx` | FIXED | Source `"auto-generated"` not `"generated"` (line 2484); fixed both occurrences | +| 33 | `get-full-url.mdx` | clean | line 1635; proxy base takes precedence, optional basic-auth embed | +| 34 | `get-mcp-servers.mdx` | clean | line 961; read-only spread copy | +| 35 | `get-name.mdx` | clean | line 1364 | +| 36 | `get-post-prompt.mdx` | clean | line 422 | +| 37 | `get-prompt.mdx` | clean | line 394 | +| 38 | `get-prompt-pom.mdx` | FIXED | Added Parameters None + Example + ref links (line 410; returns null when POM empty or non-POM mode) | +| 39 | `get-registered-tools.mdx` | clean | line 1216 | +| 40 | `get-tool.mdx` | clean | line 1237 | +| 41 | `handle-mcp-request.mdx` | clean | line 994; methods: initialize, notifications/initialized, tools/list, tools/call, ping | +| 42 | `has-skill.mdx` | clean | line 1470 | +| 43 | `is-mcp-server-enabled.mdx` | clean | line 956 | +| 44 | `list-skills.mdx` | clean | line 1461 | +| 45 | `manual-set-proxy-url.mdx` | clean | line 1532; strips trailing slashes, clears env-source flag | +| 46 | `native-functions.mdx` | clean | documents `setNativeFunctions` (line 640) + ctor `nativeFunctions` option | +| 47 | `on-debug-event.mdx` | clean | line 1705 no-op hook; invoked at line 2262 on /debug_events | +| 48 | `on-function-call.mdx` | FIXED | Wrong Warning — hook CAN short-circuit dispatch (src 2213 uses returned hookResult). Replaced with Note; fixed Returns type to include `Record` | +| 49 | `on-summary.mdx` | clean | line 1673; invoked at 2246 post-prompt path | +| 50 | `on-swml-request.mdx` | FIXED | Doc missing `callbackPath` + `context` params (src 1693); Returns was `void\|Promise` but source returns optional modifications object (merged into AI config) | +| 51 | `prompt-add-section.mdx` | clean | line 341 | +| 52 | `prompt-add-subsection.mdx` | clean | line 376 | +| 53 | `prompt-add-to-section.mdx` | clean | line 361 | +| 54 | `prompt-has-section.mdx` | clean | line 386 | +| 55 | `register-sip-username.mdx` | clean | line 832 (username lowercased) | +| 56 | `register-swaig-function.mdx` | FIXED | DataMap example called `.output()` with plain object; source expects FunctionResult (DataMap.ts:302). Rewrote example + updated line highlight | +| 57 | `remove-skill.mdx` | clean | line 1453; async by instance ID | +| 58 | `remove-skill-by-name.mdx` | FIXED | Rewrote — old doc claimed "removes every instance" + mentioned nonexistent `cleanup()`. Source (line 1484) removes FIRST match only. Added ref link to `removeSkill`, full Example | +| 59 | `render-swml.mdx` | FIXED | Added missing `modifications` parameter (src 1754; `global_data` deep-merged, rest override AI config) | +| 60 | `reset-contexts.mdx` | FIXED | Stub → added Parameters None, Returns, Example; ref links to defineContexts/ContextBuilder | +| 61 | `run.mdx` | FIXED | Doc said Parameters None; source (line 2391) takes `opts?: { host?; port? }`. Added Indent of opts fields | +| 62 | `serve.mdx` | FIXED | Same missing `opts` params as run.mdx (src 2368); added Note about `SWAIG_CLI_MODE` env var early-return (src 2370) | +| 63 | `set-dynamic-config-callback.mdx` | clean | line 1501 | +| 64 | `set-function-includes.mdx` | FIXED | Stub → added Note about silent filtering (src 772 filters entries without url/functions array), full Example with meta_data, ref link | +| 65 | `set-global-data.mdx` | FIXED | **Wrong description** — claimed "Replace the entire global data object" but src (line 621) uses `safeAssign` → merges, matching Python `.update()` semantics. Rewrote desc + added Note explaining the `set` prefix is misleading | +| 66 | `set-internal-fillers.mdx` | FIXED | Example used invalid filler names `pre_speech`, `summary` (not in `SUPPORTED_INTERNAL_FILLER_NAMES`). Rewrote example with valid names (`next_step`, `check_time`) + added Note listing all 9 supported names | +| 67 | `set-languages.mdx` | clean | line 555 | +| 68 | `set-param.mdx` | clean | line 592 | +| 69 | `set-params.mdx` | clean | line 602; merges via safeAssign | +| 70 | `set-post-prompt.mdx` | clean | line 330 | +| 71 | `set-post-prompt-llm-params.mdx` | clean | line 793 | +| 72 | `set-post-prompt-url.mdx` | clean | line 1625 | +| 73 | `set-prompt-llm-params.mdx` | clean | line 783 | +| 74 | `set-prompt-pom.mdx` | FIXED | Stub → added Warning about `usePom: true` throw (src line 440), detailed ParamField sub-field list, Example. Ref links to promptAddSection + getPromptPom | +| 75 | `set-prompt-text.mdx` | clean | line 320 | +| 76 | `set-pronunciations.mdx` | FIXED | Stub → added full ParamField describing PronunciationRule shape (replace/with/ignoreCase per types.ts:91), Example | +| 77 | `set-web-hook-url.mdx` | clean | line 1615 | +| 78 | `setup-graceful-shutdown.mdx` | clean | static line 2440; SIGTERM/SIGINT, default timeout 5000 | +| 79 | `update-global-data.mdx` | FIXED | Doc claimed `setGlobalData()` replaces; both methods identical (safeAssign). Reworded to say functionally equivalent to setGlobalData | +| 80 | `validate-basic-auth.mdx` | clean | line 1715; Warning re: middleware not calling hook confirmed (no `this.validateBasicAuth` refs in src) | +| 81 | `validate-tool-token.mdx` | FIXED | Stub → added Note about automatic dispatch-path invocation, full ParamField list with src-accurate edge cases (empty callId forwarded, missing token on secure → false, non-SwaigFunction treated as secure) | + +### agent-base/ summary + +82/82 files audited. 20 fixes applied across resume (files 21-82); 12 FIXED in +this session: + +- **Missing/wrong params:** define-tool (webhookUrl, extraFields), render-swml + (modifications), on-swml-request (callbackPath, context), run + serve (opts) +- **Wrong behavioral claims:** on-function-call (hook CAN intercept), + set-global-data (merges, doesn't replace), update-global-data (describes + set-global-data as replace), remove-skill-by-name (first match, not every + instance) +- **Wrong defaults/literals:** define-tool secure default (false), + define-typed-tool secure default, get-basic-auth-credentials source label + (`"auto-generated"` not `"generated"`) +- **Broken example code:** register-swaig-function (.output() needs + FunctionResult, not plain object), set-internal-fillers (used invalid + filler names) +- **Stub pages:** clear-swaig-query-params, enable-debug-routes, + get-prompt-pom, reset-contexts, set-function-includes, set-prompt-pom, + set-pronunciations, validate-tool-token + +### agent-server/ — AUDITED + FIXED (10/10) + +**Source:** `temp/signalwire-typescript/src/AgentServer.ts` (415 lines) + +| # | File | Status | Notes | +|---|------|--------|-------| +| 1 | `index.mdx` | FIXED | Added missing `opts.logLevel` ctor param + `logLevel` property; added 3 missing CardGroup entries (setupSipRouting, registerGlobalRoutingCallback pages; registerSipUsername combined into sip-routing page per Python pattern); added SIP-routing mention to overview | +| 2 | `get-agent.mdx` | clean | `getAgent(route)` line 169; Map.get lookup | +| 3 | `get-agents.mdx` | clean | `getAgents(): Map` line 160 (returns internal ref — note unnecessary) | +| 4 | `get-app.mdx` | clean | `getApp(): Hono` line 362; root listing only mounted if no agent at `/` (line 371) | +| 5 | `register.mdx` | clean | `register(agent, route?)` line 110; throws on duplicate route, mounts agent.getApp() | +| 6 | `run.mdx` | FIXED | Added `SWAIG_CLI_MODE=true` early-return note (line 395) + ServerlessAdapter note for serverless mode | +| 7 | `static-files.mdx` | FIXED | Wrong default `/static` → `/` (source line 180); updated route ParamField | +| 8 | `unregister.mdx` | FIXED | Wrong return type `void` → `boolean` (source line 150 returns Map.delete result) | +| 9 | `sip-routing.mdx` | CREATED | Covers both `setupSipRouting` + `registerSipUsername` (Python pattern). Ported descriptions, params, examples from Python counterpart | +| 10 | `routing-callback.mdx` | CREATED | `registerGlobalRoutingCallback(callbackFn, path)` line 316. RoutingCallback type `(body) => string \| null \| undefined \| Promise<...>` (no Request arg in TS, unlike Python). Corrected "powers setupSipRouting" claim — TS uses `agent.enableSipRouting()` directly, not this method | + +### agent-server/ summary + +10 pages. 5 fixes + 2 new pages. Index CardGroup now has 9 entries matching 9 +method pages (10 public methods with registerSipUsername combined into sip-routing). + +### function-result/ — AUDITED + FIXED (50/50) + +**Source:** `temp/signalwire-typescript/src/FunctionResult.ts` (866 lines) + +49 public methods + index. All files match source. 3 fixes: + +| File | Status | Notes | +|------|--------|-------| +| `index.mdx` | clean | Properties (response, action, postProcess), 49 CardGroup entries. Matches Python reference | +| `execute-swml.mdx` | FIXED | swmlContent type was missing third accepted form `{ toDict(): Record }` (source line 308, 316-317). Added form + description | +| `join-conference.mdx` | FIXED | 5 missing defaults: `beep='true'`, `maxParticipants=250`, `statusCallbackMethod='POST'`, `recordingStatusCallbackMethod='POST'`, `recordingStatusCallbackEvent='completed'` (source lines 619-653 use these as comparison values) | +| `tap.mdx` | FIXED | 3 missing defaults: `direction='both'`, `codec='PCMU'`, `rtpPtime=20` (source lines 544-546 compare against these) | +| All other 46 files | clean | set-response, set-post-process, add-action, add-actions, to-dict, connect, hangup, hold, swml-transfer, say, wait-for-user, stop, play-background-file, stop-background-file, record-call, stop-record-call, stop-tap, update-global-data, remove-global-data, set-metadata, remove-metadata, swml-change-step, swml-change-context, switch-context, swml-user-event, simulate-user-input, toggle-functions, enable-functions-on-timeout, add-dynamic-hints, clear-dynamic-hints, set-end-of-speech-timeout, set-speech-event-timeout, update-settings, enable-extensive-data, replace-in-history, send-sms, pay, create-payment-prompt, create-payment-action, create-payment-parameter, sip-refer, join-room, execute-swml (after fix), execute-rpc, rpc-dial, rpc-ai-message, rpc-ai-unhold | + +### context-builder/ root — AUDITED + FIXED (14/14 root files) + +**Source:** `temp/signalwire-typescript/src/ContextBuilder.ts` (1150 lines) +**Classes:** ContextBuilder, Context, Step, GatherInfo, GatherQuestion + free function `createSimpleContext` + +Root-level ContextBuilder class (public methods only: addContext, getContext, reset, toDict, validate, + `createSimpleContext` helper). + +| File | Status | Notes | +|------|--------|-------| +| `index.mdx` | FIXED | Added `createSimpleContext` card (source line 1148 exports helper; Python docs it; TS was missing) | +| `add-context.mdx` | clean | `addContext(name)` line 963; throws on duplicate/max-contexts | +| `create-simple-context.mdx` | CREATED | `createSimpleContext(name='default')` free function — matches Python counterpart | +| `gather-classes.mdx` | clean | GatherQuestion + GatherInfo docs combined per Python pattern | +| `get-context.mdx` | clean | `getContext(name): Context \| undefined` line 979 | +| `get-questions.mdx` | clean | `GatherInfo.getQuestions()` line 121 — public, no Python counterpart (TS extra but matches source) | +| `reset.mdx` | FIXED | **Broken example** — used nonexistent `agent.onRequest(...)`. TS uses `setDynamicConfigCallback((queryParams, bodyParams, headers, agent) => {...})`. Rewrote example | +| `to-dict.mdx` | clean | `toDict()` line 1131 calls `validate()` then serializes | +| `validate.mdx` | FIXED | Missing 5 of 10 documented checks — added `initial_step` validation, step-level `valid_steps` and `valid_contexts` validation, gather_info duplicate-key validation, reserved native tool name collision check | +| `get-completion-action.mdx` | clean (@internal) | Matches source `GatherInfo.getCompletionAction()` line 129 — marked @internal in source but has doc page. Doc labels "internal method" honestly | +| `get-gather-info.mdx` | clean (@internal) | Matches `Step.getGatherInfo()` line 383 — same pattern | +| `get-step-order.mdx` | clean (@internal) | Matches `Context.getStepOrder()` line 813 | +| `get-steps.mdx` | clean (@internal) | Matches `Context.getSteps()` line 808 | +| `get-valid-contexts.mdx` | clean (@internal) | Matches `Context.getValidContexts()` line 823 | + +**Structural drift (P4):** TS has 5 doc pages for @internal getters (Context.getStepOrder/getSteps/getValidContexts, Step.getGatherInfo, GatherInfo.getCompletionAction) that Python doesn't document. Factually accurate but likely unintended exposure. Candidate for deletion or marking as "internal" in future cleanup. + +**Coverage gap (P4):** `Context.toDict()` (source line 854) has no doc page — Python also doesn't have it. Treating as intentional omission (serialization internals not part of user-facing API). + +### context-builder/context/ subclass — AUDITED + FIXED (23/23) + +- `context/index.mdx` clean — CardGroup has 22 entries matching 22 method files. `name` property documented. TS has `set-initial-step.mdx` that Python doesn't (legitimate — source line 670). +- 22 method files audited against `Context` class in `ContextBuilder.ts`. 3 fixes: + - `add-step.mdx` FIXED — added throws note (src 542-545 throws on duplicate name / max 100 exceeded); Python has same note. + - `set-initial-step.mdx` FIXED — highlight `{6}`→`{7}` to point at setInitialStep call, not addStep. + - `set-isolated.mdx` FIXED — added Note about reset override exception (src JSDoc 683-687: `consolidate`/`fullReset` skip the wipe). +- Other 19 files clean: add-bullets, add-enter-filler, add-exit-filler, add-section, add-system-bullets, add-system-section, get-step, move-step, remove-step, set-consolidate, set-enter-fillers, set-exit-fillers, set-full-reset, set-post-prompt, set-prompt, set-system-prompt, set-user-prompt, set-valid-contexts, set-valid-steps. +- Coverage: Context public methods `getInitialStep`, `renderPrompt`, `renderSections`, `renderSystemPrompt`, `toDict` (src 818/827/833/839/854) have no doc pages — rendering/serialization internals; Python omits too. Intentional. + +### context-builder/step/ subclass — AUDITED + FIXED (18/18) + +- `step/index.mdx` clean — constructor `(name: string)`, `name` public property, 17-method CardGroup matches source (addBullets, addGatherQuestion, addSection, clearSections, setEnd, setFunctions, setGatherInfo, setResetConsolidate, setResetFullReset, setResetSystemPrompt, setResetUserPrompt, setSkipToNextStep, setSkipUserTurn, setStepCriteria, setText, setValidContexts, setValidSteps). +- 17 method files audited against `Step` class in `ContextBuilder.ts`. 3 fixes: + - `add-gather-question.mdx` FIXED — added Note about gather-mode function-lock behavior (src JSDoc 347-361): only `gather_submit` + per-question `functions` callable while asking; `next_step`/`change_context` filtered. + - `set-end.mdx` FIXED — TS doc description was misleading ("ends the conversation"). Source JSDoc (lines 290-303) is explicit: `end=true` exits step mode only, does NOT hang up. Rewrote description + added Warning. + - `set-functions.mdx` FIXED — added Warning about step inheritance behavior (src JSDoc 233-246): step inherits previous step's functions unless `setFunctions()` is explicitly called, most common bug source; added Note on internal-function protection; added full param form list (`string[]`, `[]`, `"none"`). +- Other 14 files clean: add-bullets, add-section, clear-sections, set-gather-info, set-reset-consolidate, set-reset-full-reset, set-reset-system-prompt, set-reset-user-prompt, set-skip-to-next-step, set-skip-user-turn, set-step-criteria, set-text, set-valid-contexts, set-valid-steps. +- Coverage: Step public methods `getGatherInfo` (383), `getStepValidContexts` (399), `getValidSteps` (391), `renderText` (453 private), `toDict` (473) have no doc pages — internals; Python omits too. + +### overview + helpers (2 files) — AUDITED + FIXED + +- `overview.mdx` FIXED — removed "search" from subtitle (TS has no search module in source). P4 coverage gap logged: WebService card + doc page missing (src: `WebService.ts`); CLI/Search/MCP/BedrockAgent refs in Python overview correctly absent from TS (those modules don't exist in TS source). +- `helpers.mdx` FIXED — added `validateUrl` section (exported from SecurityUtils.ts:146 but doc was missing it). All 14 other exports verified against source. + +### prefabs/ — AUDITED + FIXED (6/6) + +**Source:** `temp/signalwire-typescript/src/prefabs/` + +- `index.mdx` FIXED — tool table had wrong names for ConciergeAgent, InfoGathererAgent, ReceptionistAgent, SurveyAgent. Corrected against source tool registrations. +- `concierge-agent.mdx` clean — ConciergeConfig (9 fields) matches src 15-35. Tools not listed in page (acceptable, matches Python depth). +- `faq-bot-agent.mdx` clean — FAQBotConfig (9 fields), FAQEntry (4 fields), 2 tools (`search_faq` always, `escalate` conditional on `escalationNumber`) all verified. +- `info-gatherer-agent.mdx` clean — InfoGathererConfig (5 fields), InfoGathererQuestion (3 fields), 2 tools (`start_questions`, `submit_answer`), `setQuestionCallback` method all verified. +- `receptionist-agent.mdx` FIXED — tool table had wrong name `get_department_list`; source has `collect_caller_info` (src 208). Noted `department` enum constraint on transfer_call (src 251). +- `survey-agent.mdx` FIXED — tool table missing 2 tools (`validate_response` at src 387, `log_response` at src 419); doc only listed 3 of 5. + +### swaig-function/ — AUDITED + FIXED (4/4) + +**Source:** `temp/signalwire-typescript/src/SwaigFunction.ts` (277 lines) + +- `index.mdx` FIXED — Added `validate-args` card + link ref (CardGroup was missing it; TS source has public `validateArgs` method at line 186). Options interface (12 fields) and class properties (13 fields) all verified against src. +- `execute.mdx` FIXED — Highlight `{20}`→`{19}` (pointed at console.log, should be the `execute()` call). Corrected output comment: `toDict()` omits `action` when array is empty (src 855-857). +- `to-swaig.mdx` clean — `toSwaig(baseUrl, token?, callId?)` matches src 257; TS lacks Python's `include_auth` param (legitimate drift). +- `validate-args.mdx` CREATED — ported from Python counterpart; src 186-205 (Ajv-based validation, early-returns `[true, []]` on empty schema). + +### swml-service/ — AUDITED + FIXED (7/7) + +**Source:** `temp/signalwire-typescript/src/SWMLService.ts` (717 lines) + +- `index.mdx` FIXED — added 5 missing constructor options (host, port, schemaPath, configFile, schemaValidation); fixed `name` to required={true} (src 158 — required in non-deprecated overload); expanded Properties from 2 to 12 to match source (host, port, log, security, sslEnabled, sslCertPath, sslKeyPath, domain, schemaUtils, verbRegistry added). +- `add-verb.mdx` clean — `addVerb(name, config): this` delegates to swmlBuilder (src 389). Return type drift vs Python (TS fluent `this`, Python `bool`) is legitimate. +- `get-app.mdx` clean — `getApp(): Hono` (src 631-633). +- `get-builder.mdx` FIXED — example used empty-arg `new SWMLService()` (deprecated overload). Changed to `{ name: 'my-ivr' }` + demonstrates actual builder use. +- `render-swml.mdx` clean — delegates to swmlBuilder.getDocument() (src 435). Version 1.0.0 output confirmed against SwmlBuilder.ts:92. +- `run.mdx` FIXED — added `SWAIG_CLI_MODE=true` early-return note (src 663); added full `opts` param with `sslCert`/`sslKey`/`sslEnabled`/`domain` (src 656-661); fixed host/port default descriptions. +- `set-on-request-callback.mdx` clean — `OnRequestCallback` type (src 138-142) matches doc description. + +**Coverage gap (P4):** TS source has ~20 public methods on SWMLService; only 6 method pages exist. Python documents 15. Missing TS pages: addSection, addVerbToSection, asRouter, extractSipUsername, getBasicAuthCredentials, getDocument, manualSetProxyUrl, onRequest, registerRoutingCallback, registerVerbHandler, renderDocument, resetDocument, serve, stop. Large follow-up scope. + +### pom-builder/ — AUDITED -- NO ISSUES (9/9) + +**Source:** `temp/signalwire-typescript/src/PomBuilder.ts` (450+ lines) + +All 9 files clean — `index.mdx`, `add-section.mdx` (src 225), `add-subsection.mdx` (src 286), `add-to-section.mdx` (src 263), `find-section.mdx` (src 325), `get-section.mdx` (src 316), `has-section.mdx` (src 307), `render-markdown.mdx` (src 401), `to-dict.mdx` (src 366). All signatures, nested Indent params, and highlights verified against source. + +**Coverage gap (P4):** TS source has 13 public methods on PomBuilder; 8 documented. Missing: `renderXml` (422), `toJson` (374), `reset` (213), `addPomAsSubsection` (344), `fromSections` (383, static). Python docs `render` (unified Markdown/XML) and `toJson` — TS splits rendering. Also missing: PomSection class page (exposed via `getSection`/`findSection`). Overview line "can render to Markdown format" should be updated to "Markdown or XML" once renderXml page exists. + +### data-map/ — AUDITED -- NO ISSUES (19/19) + +**Source:** `temp/signalwire-typescript/src/DataMap.ts` (455 lines) + +All 19 files clean. Instance methods verified: `purpose` (132), `description` (146, alias), `parameter` (175), `expression` (203), `webhook` (229), `webhookExpressions` (253), `body` (264), `params` (275), `foreach` (286), `output` (302), `fallbackOutput` (313), `errorKeys` (323), `globalErrorKeys` (337), `enableEnvExpansion` (90), `setAllowedEnvPrefixes` (104, instance), `registerWithAgent` (347), `toSwaigFunction` (356). Helper functions: `createSimpleApiTool` (402), `createExpressionTool` (432). Index CardGroup has 18 entries matching 17 methods + helper-functions. + +Every "throws if no webhook" claim on `body`/`output`/`params`/`foreach`/`webhookExpressions`/`errorKeys` verified against source. Nested Indent ParamFields used correctly. All highlight line numbers verified. Variable substitution table matches documented patterns. + +### livewire/ — AUDITED + FIXED (14/14) + +**Source:** `temp/signalwire-typescript/src/livewire/index.ts` (947 lines) + +- `index.mdx` clean — compat layer description, namespace aliases (voice/llm/cli/inference) verified against src 920/937/945/884. +- `agent/index.mdx` clean — Agent class (src 121-211) with 13 constructor options + 4 properties. +- `agent-session/index.mdx` FIXED — removed fabricated `voiceOptions` (not in source); added 8 missing real options (`tools`, `mcpServers`, `allowInterruptions`, `minInterruptionDuration`, `minEndpointingDelay`, `maxEndpointingDelay`, `maxToolSteps`, `preemptiveGeneration`) with correct defaults from src 341-346. +- `agent-session/start.mdx` FIXED — added missing `record?: boolean` option (src 387). +- `agent-session/say.mdx` clean — queuing semantics (src 467-475) correctly documented. +- `agent-session/generate-reply.mdx` clean — src 478-482. +- `agent-session/interrupt.mdx` clean — no-op (src 485-487). +- `agent-session/update-agent.mdx` clean — src 490-496. +- `function-tool.mdx` clean — `tool()` factory + `FunctionTool` interface (src 526-549, 109-114). +- `job-context.mdx` clean — JobContext (src 612-635), JobProcess (594-596), Room (603-605). +- `plugins.mdx` clean — 5 plugin stubs + 3 inference classes match src 827-913. +- `run-app.mdx` clean — runApp (src 666-705) + defineAgent (645-650). +- `run-context.mdx` clean — RunContext (src 282-299). Minor: constructor has optional 2nd arg (`speechHandle`, `functionCall`) not documented — accepted. +- `signals.mdx` FIXED — ChatContext section falsely claimed "empty stub with no methods or properties" but src 927-934 defines `messages` property and `append(options)` method. Rewrote with actual Properties + append method docs. + +### configuration/ — AUDITED + FIXED (64/64) + +**Source:** `temp/signalwire-typescript/src/{AuthHandler,ConfigLoader,PromptManager,SchemaUtils,ServerlessAdapter,SessionManager,SslConfig,Logger}.ts` + +- `index.mdx` clean — 9-card CardGroup matches 7 sub-class folders + `environment-variables.mdx` + `logging.mdx`. Layered config priority (constructor > env > config file > defaults) documented correctly. +- `environment-variables.mdx` spot-checked — structural content solid (Server, Auth, SSL sections with defaults); full deep verify against source pending. +- `logging.mdx` spot-checked — Logger/getLogger/setGlobalLogLevel API described; full deep verify against Logger.ts pending. + +All 7 configuration sub-classes fully audited in session 4. See per-class +sections below for details. + +### configuration/auth-handler/ — AUDITED + FIXED (6/6) + +**Source:** `temp/signalwire-typescript/src/AuthHandler.ts` (256 lines) + +- `index.mdx` FIXED — Missing `config.apiKeyHeader` field (src 20, 71). + Added with default `'X-Api-Key'` and case-insensitive lookup note. +- `has-api-key-auth.mdx` clean — `hasApiKeyAuth(): boolean` (src 245). +- `has-basic-auth.mdx` clean — `hasBasicAuth(): boolean` (src 253). +- `has-bearer-auth.mdx` clean — `hasBearerAuth(): boolean` (src 237). +- `middleware.mdx` FIXED — Missing `optional = false` param (src 163). Added + ParamField, updated description, added second example demonstrating the + permissive mode. +- `validate.mdx` clean — `validate(headers): Promise` (src 59); 4-way + auth order verified (Bearer/APIKey/Basic/Custom) + allowUnauthenticated + fallback correctly documented. + +**Coverage gap (P4):** 5 public methods not documented — `verifyBasicAuth` +(src 124), `verifyBearerToken` (src 139), `verifyApiKey` (src 153), +`expressMiddleware` (src 186), `getAuthInfo` (src 206). These are useful +standalone verification helpers and framework adapters. Follow-up session +recommended to add pages. + +### configuration/ssl-config/ — AUDITED + FIXED (7/7) + +**Source:** `temp/signalwire-typescript/src/SslConfig.ts` (118 lines) + +- `index.mdx` FIXED — Added missing `## Constructor` section (opts: SslOptions) + with cross-reference to Properties. 6 properties already documented with + env-var fallbacks; 6-card CardGroup matches methods. +- `get-cert.mdx` clean — `getCert(): string | null` (src 71); null when + certPath unset or file missing. +- `get-key.mdx` clean — `getKey(): string | null` (src 80). +- `get-hsts-header.mdx` clean — `getHstsHeader(): string | null` (src 89); + null when HSTS or SSL disabled (src 90); format + `max-age=${hstsMaxAge}; includeSubDomains`. +- `get-server-options.mdx` clean — `getServerOptions(): { cert, key } | null` + (src 98); null when either file missing. +- `hsts-middleware.mdx` clean — `hstsMiddleware()` Hono middleware (src 109). +- `is-configured.mdx` clean — `isConfigured(): boolean` (src 61); requires + SSL enabled AND both cert/key files exist on disk (src 62-64). + +### configuration/serverless-adapter/ — AUDITED -- NO ISSUES (8/8) + +**Source:** `temp/signalwire-typescript/src/ServerlessAdapter.ts` (221 lines) + +All 8 files clean. `index.mdx` covers ctor `platform='auto'` (src 53) with 5 +valid enum values + 7-card CardGroup. Methods verified: +- `detectPlatform` (src 61) — 4 platform env-var checks + default fallback. +- `getPlatform` (src 73). +- `handleRequest` (src 83) — event normalization, URL building, Hono routing. +- `generateUrl` (src 134) — per-platform URL construction + env-var defaults + for region/project/functionName/stage/apiId all documented. +- `createLambdaHandler` (src 171, static). +- `createGcfHandler` (src 181, static). +- `createAzureHandler` (src 204, static). + +### configuration/config-loader/ — AUDITED + FIXED (9/9) + +**Source:** `temp/signalwire-typescript/src/ConfigLoader.ts` (447 lines) + +- `index.mdx` FIXED — Ctor param was `filePath: string`; source (src 33) is + `filePaths?: string | string[]`. Fixed to document both forms + ordered + array search behavior. Added `Properties` section with `configPaths` + getter (src 56-57). +- `get.mdx` clean — `get(path, defaultValue?): T` (src 182); prototype- + pollution blocklist verified (src 184-186). +- `get-all.mdx` clean — `getAll(): Record` (src 247); + shallow copy via spread. +- `get-file-path.mdx` clean — `getFilePath(): string | null` (src 263); + null when loaded from object (src 430). +- `has.mdx` clean — `has(path): boolean` (src 229). +- `load.mdx` clean — `load(filePath): this` (src 65); throws on missing file + (src 67-69); interpolates env vars. +- `load-from-object.mdx` clean — `loadFromObject(obj): this` (src 428); + sets filePath to null. +- `search.mdx` FIXED — Doc was missing `additionalPaths` + `serviceName` + params (src 88). Only listed 3 of 6 default search paths. Rewrote + Parameters to cover all three args, added full 6-path default list from + `_buildSearchPaths` (src 147-174), documented service-specific variants + + additionalPaths precedence. +- `set.mdx` clean — `set(path, value): this` (src 205); prototype-pollution + blocklist verified (src 207-209). + +**Coverage gap (P4):** 8 public methods not documented — `static findConfigFile` +(src 109), `getConfig` alias (src 255), `getConfigFile` alias (src 271), +`hasConfig` (src 289), `getSection` (src 298), `substituteVars` (src 316), +`mergeWithEnv` (src 367), `interpolateEnvVars` (src 439). Significant surface +missing especially `mergeWithEnv` + `getSection` which are core to runtime +config loading. Follow-up session recommended. + +### configuration/prompt-manager/ — AUDITED -- NO ISSUES (10/10) + +**Source:** `temp/signalwire-typescript/src/PromptManager.ts` (133 lines) + +All 10 files clean. `index.mdx` covers ctor `usePom=true` (src 20) + 9-card +CardGroup matching 9 public methods. Method files verified: `setPromptText` +(src 31), `setPostPrompt` (39), `addSection` (48, full 5-field opts: body/ +bullets/numbered/numberedBullets/subsections), `addToSection` (70, opts: +body/bullet/bullets), `addSubsection` (87, opts: body/bullets), `hasSection` +(104, `pom?.hasSection ?? false`), `getPrompt` (112, rawText-over-POM +precedence), `getPostPrompt` (122), `getPomBuilder` (130). Nested Indent +blocks used correctly. getPrompt precedence (`rawText !== null` first, then +POM markdown) verified against src 113-115. + +### configuration/schema-utils/ — AUDITED + FIXED (10/10) + +**Source:** `temp/signalwire-typescript/src/SchemaUtils.ts` (361 lines) + +- `index.mdx` FIXED — Added missing `opts.schemaPath` ctor option (src 47, 50). + Env-var fallback for `opts.skipValidation` correctly documented. 9-card + CardGroup matches 9 public methods. +- `clear-cache.mdx` clean — `clearCache(): void` (src 341). +- `get-cache-size.mdx` clean — `getCacheSize(): number` (src 349). +- `get-verb-description.mdx` clean — `getVerbDescription(verbName): string` + (src 158); empty string when missing (`?? ''`). +- `get-verb-names.mdx` clean — `getVerbNames(): string[]` (src 124). +- `get-verb-properties.mdx` clean — `getVerbProperties(verbName): Record` + (src 134); returns `{}` when not found. +- `get-verb-required-properties.mdx` clean — `getVerbRequiredProperties(verbName): string[]` + (src 147). +- `has-verb.mdx` clean — `hasVerb(verbName): boolean` (src 168). +- `validate.mdx` clean — `validate(swml: string | Record): ValidationResult` + (src 231); 4 doc-level checks (top-level keys, version, sections, AI verb + structure) + LRU cache all verified. +- `validate-verb.mdx` clean — `validateVerb(verbName, config): ValidationResult` + (src 181); signature and "checks verb exists + required properties" prose + verified against src 188-220. + +### configuration/session-manager/ — AUDITED + FIXED (11/11) + +**Source:** `temp/signalwire-typescript/src/SessionManager.ts` (311 lines) + +- `index.mdx` FIXED — Added `Properties` section documenting `debugMode` + public mutable flag (src 42). Constructor params `tokenExpirySecs`/`secretKey` + already accurate. CardGroup covers 10 public methods; `activateSession`/ + `endSession` intentionally omitted (legacy no-ops for Python parity). +- `cleanup.mdx` clean — `cleanup(maxAgeMs?): void` (src 272); default + `tokenExpirySecs * 1000` documented; iterates timestamps, deletes stale. +- `create-session.mdx` clean — `createSession(callId?): string` (src 62); + returns `callId` or `randomBytes(16).toString('base64url')`. +- `create-tool-token.mdx` clean — alias for generateToken (src 92). +- `debug-token.mdx` FIXED — Major rewrite. Wrong return type (doc had flat + camelCase fields + `| null`; source `DebugTokenResult` is nested with + snake_case `components.call_id` / `status.is_expired` and never returns null, + src 12-30). Missing `debugMode` requirement (src 170-172: returns + `{ valid_format: false, error: "debug mode not enabled" }` when disabled). + Added Warning box, documented all nested fields including 8-char truncation + of `call_id`/`signature` (src 201, 206), fixed example to enable debugMode + and use correct field paths. +- `delete-session-metadata.mdx` clean — `deleteSessionMetadata(sessionId): boolean` + (src 308); returns `Map.delete` result. +- `generate-token.mdx` clean — token format + `${callId}.${functionName}.${expiry}.${nonce}.${signature}` then base64url + (src 74-81). +- `get-session-metadata.mdx` FIXED — Wrong return type `Record | undefined`. + Source (src 234) uses `?? {}` and never returns undefined; JSDoc at 227-228 + explicitly documents this Python-compat behavior. Updated return type, + added note, extended example showing empty-object return for unknown session. +- `set-session-metadata.mdx` FIXED — Missing the three-argument + `setSessionMetadata(sessionId, key, value)` overload (src 249, 250-259). + Added Info box covering both signatures, documented `metadataOrKey` + `value` + params, clarified return-type split (`void` bulk vs `boolean` single), added + 3-arg example. +- `validate-token.mdx` clean — `validateToken(callId, functionName, token): boolean` + (src 103); 6 distinct checks verified (format/callId/function/expiry/signature/callIdMatch). +- `validate-tool-token.mdx` clean — reordered alias (src 156). + +Significant follow-up scope — recommend new session. + +### skills/ — AUDITED + FIXED (20/20) + +**Source:** `temp/signalwire-typescript/src/skills/builtin/*.ts` (20 skills) + +**Prior session deep audit (4):** +- `index.mdx` FIXED — tool counts: `datetime` 1→2, `google_maps` 2→4. +- `datetime.mdx` FIXED — tool name `get_datetime`→`get_current_time`+`get_current_date`. +- `joke.mdx` FIXED — added missing `tool_name` param (default `tell_joke`). +- `math.mdx` clean. + +**This session deep audit (17):** + +| File | Status | Notes | +|------|--------|-------| +| `api-ninjas-trivia.mdx` | FIXED | Added missing `tool_name` (default `get_trivia`) + `categories` params; added multi-instance note. | +| `ask-claude.mdx` | FIXED | Corrected `api_key` description — handler reads `ANTHROPIC_API_KEY` directly (ask_claude.ts:136), not as config fallback. TS-only skill (no Python counterpart). | +| `claude-skills.mdx` | clean | All 13 params match src; matches Python doc. | +| `custom-skills.mdx` | clean | TS-only skill; Python doc of same filename documents different concept — legitimate divergence. | +| `datasphere.mdx` | FIXED | Added `{query}` placeholder note on `no_results_message`; normalized `default={'"..."'}`→`default="..."`; noted tool_name required for multi-instance. | +| `datasphere-serverless.mdx` | FIXED | Removed false env-fallback claims — the serverless DataMap build path (`buildDataMapFunction` 193-197) reads config-only, not env. Added `{query}` note. | +| `google-maps.mdx` | FIXED | Major rewrite: doc had wrong tools `get_directions, find_place`; source has 4 tools `compute_route`, `lookup_address`, `geocode_address`, `compute_route_by_coords`. Added 4 `*_tool_name` params. Corrected `api_key` description — handlers read `GOOGLE_MAPS_API_KEY` env directly. | +| `info-gatherer.mdx` | clean | 3 params match src; prefix-based multi-instance verified. | +| `mcp-gateway.mdx` | FIXED | Normalized `tool_prefix` default style. Auth token env fallback verified working (unlike some other skills). | +| `native-vector-search.mdx` | FIXED | Major rewrite: doc had wrong tool default `search_documents` (source: `search_knowledge`). Added 10 missing params (`max_content_length`, `keyword_weight`, `model_name`, `response_format_callback`, `description`, `hints`, 3 NLP backends, `backend`, pgvector `connection_string`/`collection_name`, `verbose`, `overwrite`, `documents`). Restructured to mirror Python's section layout. | +| `play-background-file.mdx` | FIXED | Rewrite: doc only covered free-form mode (`play_background` + `stop_background`). Added pre-configured mode (`` single tool with `action` enum of `start_`/`stop`). Added missing `tool_name` + `files` params. | +| `spider.mdx` | FIXED | Doc said "Tools: scrape_url" but source has 3: `scrape_url`, `crawl_site`, `extract_structured_data`. Added tool_name prefix param. Noted `SWML_ALLOW_PRIVATE_URLS=true` SSRF bypass. Noted that only `fast_text`/`markdown`/`structured` extract_types are wired; others fall back. | +| `swml-transfer.mdx` | FIXED | Added `list_transfer_destinations` tool (registered when `patterns` configured). Removed `required={true}` from `transfers` (either `transfers` or `patterns` required). Normalized default styles. Multi-instance note. | +| `weather-api.mdx` | FIXED | Added OpenWeatherMap-vs-WeatherAPI.com provider note (TS uses OpenWeatherMap despite SKILL_DESCRIPTION text). Corrected `units` default `"metric"`→`"fahrenheit"` (src 107). Added `tool_name` param. Documented `celsius`/`fahrenheit` Python aliases. | +| `web-search.mdx` | FIXED | Added multi-instance note (instance key combines `search_engine_id` + `tool_name`). Normalized `safe_search` default style. Noted tool_name configurability. | +| `wikipedia-search.mdx` | FIXED | Added `{query}` placeholder note on `no_results_message`. | +| `index.mdx` | FIXED | 5 multi-instance table corrections: `web_search`, `play_background_file`, `swml_transfer`, `api_ninjas_trivia`, `spider`, `info_gatherer` all `SUPPORTS_MULTIPLE_INSTANCES=true`. `spider` env-required `Yes`→`No`; tool count 1→3. `play_background_file` tool count 2→1-3 (mode-dependent). Code example `max_results`→`num_results` for `WebSearchSkill`; DataSphere example fixed to use `count` + `document_id` instead of `num_results`. | + +### skills/ summary + +17 files deep-audited this session, 14 fixed + 3 clean. 3 major rewrites +(`google-maps`, `native-vector-search`, `play-background-file`). Systematic +drift patterns encountered and fixed: +1. **Missing `tool_name` params** on 4 multi-instance-capable skills. +2. **Wrong env-fallback claims** on 2 skills whose handlers read `process.env` + directly, bypassing the declared config param. +3. **`{query}` placeholder** undocumented on 3 `no_results_message` fields + despite source implementing it. +4. **Default-value style inconsistency** (`default={'"x"'}`) normalized on 6 + ParamFields to match the project convention (`default="x"`). +5. **Index summary table** had 6 wrong multi-instance flags and 2 wrong tool + counts; source had diverged since last table review. + +### skill-registry/ — AUDITED -- NO ISSUES (16/16) + +**Source:** `temp/signalwire-typescript/src/skills/SkillRegistry.ts` (367 lines) + +All 16 files clean. `index.mdx` documents 15-card CardGroup + `size` getter (src 357). Methods verified: `getInstance` (src 72, static), `register` (95), `create` (157), `has` (184), `unregister` (144), `lock` (132), `listRegistered` (192), `addSearchPath` (218), `getSearchPaths` (228), `discoverFromDirectory` (238), `discoverAll` (294), `getSkillSchema` (310), `getAllSkillsSchema` (328), `listAllSkillSources` (347), `clear` (364). `SWML_SKILL_DISCOVERY_ENABLED=true` requirement on `discoverFromDirectory` correctly documented. + +**Coverage gap (P4):** `getSkillClass` (175), `listSkills` (202), `resetInstance` (82 static, test helper) not documented. + +### skill-manager/ — AUDITED -- NO ISSUES (17/17) + +**Source:** `temp/signalwire-typescript/src/skills/SkillManager.ts` (416 lines) + +All 17 files clean. `index.mdx` documents `size` getter + 16-card CardGroup. Methods verified: `addSkill` (src 70), `loadSkill` (236), `loadSkillByName` (266), `removeSkill` (144), `removeSkillByName` (174), `hasSkill` (192), `hasSkillByKey` (214), `listSkillKeys` (306), `getSkill` (315), `listSkills` (329), `getAllTools` (341), `getAllPromptSections` (353), `getAllHints` (365), `getMergedGlobalData` (377), `getLoadedSkillEntries` (397), `clear` (408). + +**Coverage gap (P4):** `loadedSkills` getter (src 55) not documented as a property. + +### skill-base/ — AUDITED -- NO ISSUES (16/16) + +**Source:** `temp/signalwire-typescript/src/skills/SkillBase.ts` (590+ lines) + +All 16 files clean. Static constants (`SKILL_NAME`, `SKILL_DESCRIPTION`, `SKILL_VERSION`, `REQUIRED_PACKAGES`, `REQUIRED_ENV_VARS`, `SUPPORTS_MULTIPLE_INSTANCES`) + 4 instance properties + 15-card method group all verified against src 90-550. Files: `index.mdx`, `setup.mdx` (src 278), `cleanup.mdx` (434), `get-tools.mdx` (297), `get-data-map-tools.mdx` (337), `get-prompt-sections.mdx` (347), `get-hints.mdx` (367), `get-global-data.mdx` (375), `get-instance-key.mdx` (392), `get-skill-namespace.mdx` (405), `get-skill-data.mdx` (415), `update-skill-data.mdx` (427), `is-initialized.mdx` (472), `mark-initialized.mdx` (479), `validate-env-vars.mdx` (451), `get-parameter-schema.mdx` (148). + +**Coverage gap (P4):** 7 public methods undocumented — `getAgent` (226), `setAgent` (499), `getConfig` (489, mentioned inline in index), `defineTool` (316, inline), `hasAllEnvVars` (509, inline), `hasAllPackages` (544, inline), `validatePackages` (522). + +### swml-builder/ — AUDITED + FIXED (12/12) + +**Source:** `temp/signalwire-typescript/src/SwmlBuilder.ts` (258 lines) + +- `index.mdx` FIXED — Constructor section claimed "takes no parameters" but `SwmlBuilder` accepts `opts?: SwmlBuilderOptions` (src 18-30). Added 3 options: `initialDocument`, `enableValidation`, `schemaPath`. +- `add-verb.mdx` clean — src 161-172 returns `void`; throws on validation failure. +- `add-verb-to-section.mdx` clean — src 180-185; auto-creates section. +- `ai.mdx` / `answer.mdx` / `hangup.mdx` / `play.mdx` clean — dynamic verb methods auto-installed from schema (src 111-148), return `this` for chaining. +- `get-document.mdx` clean — src 227-229. +- `get-schema-utils.mdx` clean — src 99-104 (static singleton). +- `render-document.mdx` clean — src 245-247 (JSON.stringify). +- `reset.mdx` FIXED — return type was `void`; source src 150 returns `this` for chaining. +- `say.mdx` FIXED (P0) — Doc falsely claimed `say` is not a method on SwmlBuilder. Source src 195 defines public `say(text, opts?): this` convenience method that emits `play` with `say:` prefix. Completely rewrote page with params (text, voice, language, gender, volume) to mirror Python doc. + +**Coverage gap (P4):** Source has `build()` (237), `render()` (255), `document` getter (78), `setValidation` (87), `addSection` (216) also public but undocumented. `build`/`render` are Python-compat aliases for `getDocument`/`renderDocument` respectively. + +--- + +## Agents audit session summary + +**Session 1 (prior):** +- agent-base (82/82), agent-server (10/10), function-result (50/50), + context-builder root (14/14), context-builder/context/index (1/23) — 167 files, 10 fixes, 3 new pages. + +**Session 2 (this session — 2026-04-22):** + +Audited in full + depth: +- context-builder/context (22/22) — 3 fixes +- context-builder/step (18/18) — 3 fixes +- overview + helpers (2/2) — 2 fixes +- prefabs (6/6) — 4 fixes +- swaig-function (4/4) — 3 fixes + 1 new page (validate-args) +- swml-service (7/7) — 4 fixes +- pom-builder (9/9) — 0 fixes +- swml-builder (12/12) — 3 fixes (incl. P0 say) +- data-map (19/19) — 0 fixes +- livewire (14/14) — 4 fixes +- skill-base (16/16) — 0 fixes +- skill-manager (17/17) — 0 fixes +- skill-registry (16/16) — 0 fixes + +Partial audit: +- skills (3/20 deep + 17 spot) — 3 fixes; systematic P1 gap flagged +- configuration (3/64) — deferred + +**Totals this session:** ~165 files audited, 29 fixes applied, 1 new page created (validate-args). +**Cumulative across sessions:** ~332 files audited, 39 fixes, 4 new pages. + +**Remaining:** 17 skills pages (deep audit) + 61 configuration sub-class files = ~78 files. Follow-up session needed. + +--- + +## Agents audit session 3 summary (2026-04-22) + +Focused on skills deep-audit — the partial audit flagged in session 2. + +Audited: skills (17/17 remaining + index re-verify) — 14 fixes across 17 +files, 3 major rewrites (google-maps, native-vector-search, play-background-file). + +**Totals this session:** 17 files audited, 15 fixes applied. +**Cumulative across sessions:** ~349 files audited, 54 fixes, 4 new pages. + +**Remaining:** 61 configuration sub-class files (auth-handler 6, config-loader +9, prompt-manager 10, schema-utils 10, serverless-adapter 8, session-manager +11, ssl-config 7). Follow-up session needed. + +--- + +## Agents audit session 4 summary (2026-04-22) + +Focused on the 61 configuration sub-class files flagged for session 4 in +session 3. All 7 configuration sub-classes completed. + +Audited this session: +- configuration/session-manager (11/11) — 4 fixes +- configuration/schema-utils (10/10) — 1 fix +- configuration/prompt-manager (10/10) — 0 fixes +- configuration/config-loader (9/9) — 2 fixes +- configuration/serverless-adapter (8/8) — 0 fixes +- configuration/ssl-config (7/7) — 1 fix +- configuration/auth-handler (6/6) — 2 fixes + +**Totals this session:** 61 files audited, 10 fixes applied, 0 new pages. +**Cumulative across sessions:** ~410 files audited, 64 fixes, 4 new pages. + +**Notable finds this session:** + +- **P0 fixes:** + - `session-manager/debug-token.mdx` — Return type was flat camelCase with + `| null`; source `DebugTokenResult` is nested with snake_case + `components.call_id` / `status.is_expired`, never null, and only works + when `debugMode=true` (returns an error object otherwise). Fixed with + full interface docs + Warning box + corrected example. + - `session-manager/get-session-metadata.mdx` — Return type + `Record | undefined`. Source (src 234) uses `?? {}` and + never returns undefined. JSDoc at 227-228 explicitly documents this as + Python-compat behavior. Callers would have added null guards that never + fire. + - `auth-handler/middleware.mdx` — Params listed "None" but signature is + `middleware(optional = false)`. Doc hid a real boolean option. +- **Missing ctor params/overloads:** + - `session-manager/set-session-metadata.mdx` — 3-arg + `setSessionMetadata(sessionId, key, value)` overload (src 249) was + entirely undocumented despite being the Python-compat path. + - `schema-utils/index.mdx` — `opts.schemaPath` ctor option (src 47, 50) + missing; mirrors Python's `schema_path` argument. + - `config-loader/index.mdx` — Ctor declared `filePath: string` but source + accepts `filePaths?: string | string[]` with ordered-array search + behavior (src 33-48). Array form critical for multi-env deployments. + - `config-loader/search.mdx` — Missing `additionalPaths` + `serviceName` + params (src 88); only listed 3 of 6 default search paths. + - `auth-handler/index.mdx` — `config.apiKeyHeader` (src 20, default + `'X-Api-Key'`) undocumented. + - `ssl-config/index.mdx` — Whole `## Constructor` section missing; added + opts: SslOptions reference. +- **Missing properties on index pages:** + - `session-manager/index.mdx` — `debugMode` public mutable flag (src 42) + and its effect on `debugToken` behavior undocumented. + - `config-loader/index.mdx` — `configPaths` getter (src 56) missing. + +**Significant coverage gaps (P4) flagged for future session:** +- `config-loader/`: 8 public methods undocumented — `findConfigFile`, + `getConfig` (alias), `getConfigFile` (alias), `hasConfig`, `getSection`, + `substituteVars`, `mergeWithEnv`, `interpolateEnvVars`. `mergeWithEnv` + + `getSection` are core to runtime config loading. +- `auth-handler/`: 5 public methods undocumented — `verifyBasicAuth`, + `verifyBearerToken`, `verifyApiKey`, `expressMiddleware`, `getAuthInfo`. + +**Configuration namespace now fully audited:** +7/7 sub-classes: auth-handler, config-loader, prompt-manager, schema-utils, +serverless-adapter, session-manager, ssl-config. 64 total files (61 audited +this session + 3 spot-checked in session 2: configuration/index, +environment-variables, logging). + +**Notable finds this session:** +- **P0 fixes:** + - `native-vector-search.mdx` wrong tool default `search_documents` — source is `search_knowledge` (src 363/405). + - `google-maps.mdx` completely wrong tool names (`get_directions`/`find_place` vs actual `compute_route`/`lookup_address` + 2 more). + - `play-background-file.mdx` missed the entire pre-configured-files mode (a whole separate tool registration path). +- **False env-fallback claims** on `ask-claude` and `datasphere-serverless`. The `env_var` field in `ParameterSchemaEntry` is schema-declarative only — SkillBase does not auto-hydrate env into config. Skills that want env fallback must call `process.env['X']` in their handler, and several did not despite declaring `env_var`. Docs must match the handler's actual behavior, not the schema declaration. +- **Multi-instance table drift** — 6 rows had wrong `Multi-Instance` flags in the index table because prior audits updated individual skill pages but not the summary table. +- **Systematic style normalization** — 6 ParamField `default={'"..."'}` occurrences cleaned up to `default="..."` for consistency. + +**Notable finds this session:** +- **P0 fixes:** swml-builder/say.mdx (doc falsely claimed method doesn't exist), skills/datetime.mdx (wrong tool name), skill-base/set-end.mdx (doc said "ends call" but source explicitly says it doesn't), skills/index table tool counts. +- **Fabricated content removed:** livewire/agent-session/index.mdx had fabricated `voiceOptions` param; livewire/signals.mdx ChatContext falsely claimed empty stub. +- **Significant missing info:** swml-service/index.mdx was missing 5 constructor options + 10 properties; swml-builder/index.mdx had wrong "takes no parameters" constructor claim; step/set-functions missing crucial inheritance warning; helpers.mdx missing validateUrl. +- **Doc→source drift in prefabs:** receptionist + survey had wrong tool names in index table. +- **Systematic skills drift:** tool names and custom `tool_name` parameters frequently missing/wrong across the 20 skill pages. + +--- + ## REST audit summary **All 384 MDX files across 22 REST namespaces audited clean** against source commit `ba6d5b1`. No discrepancies found. Every documented method, endpoint path, HTTP verb, and example signature matches the TypeScript source exactly. From f155c6da497030b7225ef513fd86d40e2cca91ee Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 12:04:02 +0000 Subject: [PATCH 04/21] relay --- .../relay/actions/ai-action/index.mdx | 2 +- .../relay/actions/ai-action/stop.mdx | 2 +- .../relay/actions/collect-action/index.mdx | 2 +- .../collect-action/start-input-timers.mdx | 2 +- .../relay/actions/collect-action/stop.mdx | 2 +- .../relay/actions/collect-action/volume.mdx | 2 +- .../relay/actions/detect-action/index.mdx | 4 +- .../relay/actions/detect-action/stop.mdx | 2 +- .../relay/actions/fax-action/index.mdx | 2 +- .../relay/actions/fax-action/stop.mdx | 2 +- .../typescript/relay/actions/index.mdx | 6 +- .../relay/actions/pay-action/index.mdx | 2 +- .../relay/actions/pay-action/stop.mdx | 2 +- .../relay/actions/play-action/index.mdx | 2 +- .../relay/actions/play-action/pause.mdx | 2 +- .../relay/actions/play-action/resume.mdx | 2 +- .../relay/actions/play-action/stop.mdx | 2 +- .../relay/actions/play-action/volume.mdx | 2 +- .../relay/actions/record-action/index.mdx | 2 +- .../relay/actions/record-action/pause.mdx | 2 +- .../relay/actions/record-action/resume.mdx | 2 +- .../relay/actions/record-action/stop.mdx | 2 +- .../standalone-collect-action/index.mdx | 4 +- .../start-input-timers.mdx | 4 +- .../standalone-collect-action/stop.mdx | 4 +- .../relay/actions/stream-action/index.mdx | 2 +- .../relay/actions/stream-action/stop.mdx | 2 +- .../relay/actions/tap-action/index.mdx | 2 +- .../relay/actions/tap-action/stop.mdx | 2 +- .../relay/actions/transcribe-action/index.mdx | 2 +- .../relay/actions/transcribe-action/stop.mdx | 2 +- .../typescript/relay/call/ai-hold.mdx | 2 +- .../typescript/relay/call/ai-message.mdx | 2 +- .../typescript/relay/call/ai-unhold.mdx | 2 +- .../reference/typescript/relay/call/ai.mdx | 2 +- .../typescript/relay/call/amazon-bedrock.mdx | 2 +- .../typescript/relay/call/answer.mdx | 2 +- .../typescript/relay/call/bind-digit.mdx | 2 +- .../relay/call/clear-digit-bindings.mdx | 2 +- .../typescript/relay/call/collect.mdx | 2 +- .../typescript/relay/call/connect.mdx | 2 +- .../typescript/relay/call/denoise-stop.mdx | 2 +- .../typescript/relay/call/denoise.mdx | 2 +- .../typescript/relay/call/detect.mdx | 2 +- .../typescript/relay/call/disconnect.mdx | 2 +- .../reference/typescript/relay/call/echo.mdx | 2 +- .../typescript/relay/call/hangup.mdx | 2 +- .../reference/typescript/relay/call/hold.mdx | 2 +- .../reference/typescript/relay/call/index.mdx | 2 +- .../typescript/relay/call/join-conference.mdx | 2 +- .../typescript/relay/call/join-room.mdx | 2 +- .../relay/call/leave-conference.mdx | 2 +- .../typescript/relay/call/leave-room.mdx | 2 +- .../typescript/relay/call/live-transcribe.mdx | 2 +- .../typescript/relay/call/live-translate.mdx | 2 +- .../reference/typescript/relay/call/on.mdx | 2 +- .../reference/typescript/relay/call/pass.mdx | 2 +- .../reference/typescript/relay/call/pay.mdx | 2 +- .../relay/call/play-and-collect.mdx | 2 +- .../reference/typescript/relay/call/play.mdx | 6 +- .../typescript/relay/call/queue-enter.mdx | 2 +- .../typescript/relay/call/queue-leave.mdx | 2 +- .../typescript/relay/call/receive-fax.mdx | 2 +- .../typescript/relay/call/record.mdx | 2 +- .../reference/typescript/relay/call/refer.mdx | 2 +- .../typescript/relay/call/send-digits.mdx | 2 +- .../typescript/relay/call/send-fax.mdx | 2 +- .../typescript/relay/call/stream.mdx | 2 +- .../reference/typescript/relay/call/tap.mdx | 2 +- .../typescript/relay/call/transcribe.mdx | 2 +- .../typescript/relay/call/transfer.mdx | 2 +- .../typescript/relay/call/unhold.mdx | 2 +- .../typescript/relay/call/user-event.mdx | 2 +- .../typescript/relay/call/wait-for-ended.mdx | 2 +- .../typescript/relay/call/wait-for.mdx | 2 +- .../typescript/relay/client/connect.mdx | 2 +- .../typescript/relay/client/dial.mdx | 12 +- .../typescript/relay/client/disconnect.mdx | 6 +- .../typescript/relay/client/execute.mdx | 2 +- .../typescript/relay/client/index.mdx | 47 +++++- .../typescript/relay/client/on-call.mdx | 5 +- .../typescript/relay/client/on-message.mdx | 5 +- .../typescript/relay/client/receive.mdx | 4 +- .../reference/typescript/relay/client/run.mdx | 2 +- .../typescript/relay/client/send-message.mdx | 24 +-- .../typescript/relay/client/unreceive.mdx | 2 +- .../reference/typescript/relay/constants.mdx | 9 + .../reference/typescript/relay/events.mdx | 80 ++++----- .../typescript/relay/message/index.mdx | 22 +-- .../reference/typescript/relay/message/on.mdx | 6 +- .../typescript/relay/message/wait.mdx | 11 +- .../typescript/relay/relay-error.mdx | 4 +- .../products/server-sdks/sdk-source-sync.json | 2 +- .../typescript-sdk-audit-tracker.md | 154 ++++++++++++++++++ 94 files changed, 383 insertions(+), 182 deletions(-) diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/index.mdx index e98e70c2b..f2cff576e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/index.mdx @@ -40,7 +40,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/stop.mdx index 8923a6a8d..5253c3a8e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/ai-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/index.mdx index ce002ce70..1ecd31ba7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/index.mdx @@ -51,7 +51,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/start-input-timers.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/start-input-timers.mdx index afa425996..57d467a12 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/start-input-timers.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/start-input-timers.mdx @@ -19,7 +19,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/stop.mdx index b96fcf521..6ea448271 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/volume.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/volume.mdx index e7d1dc205..b500a5600 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/volume.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/collect-action/volume.mdx @@ -24,7 +24,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/index.mdx index cf1390913..b82c1fa9a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/index.mdx @@ -42,7 +42,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -53,7 +53,7 @@ client.onCall(async (call) => { params: { initialTimeout: 5.0 }, }); - const event = await action.wait(10000); + const event = await action.wait(10); const detectResult = event.params.detect ?? {}; console.log(`Detected: ${JSON.stringify(detectResult)}`); }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/stop.mdx index a3a53c736..33a044d94 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/detect-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/index.mdx index 9e75bf73d..fea90037d 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/index.mdx @@ -37,7 +37,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/stop.mdx index 6604751e6..de28ca74c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/fax-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/index.mdx index 73a9686c2..7c2cc59b8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/index.mdx @@ -40,7 +40,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -89,8 +89,8 @@ All action classes share these properties and methods. Await the action's completion and return the terminal event. - Maximum milliseconds to wait. `undefined` waits indefinitely. Throws an `Error` - if exceeded. + Maximum seconds to wait (matches Python SDK convention). `undefined` waits + indefinitely. Throws an `Error` if exceeded. ## **Subclasses** diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/index.mdx index 2e51e62fb..4789cfef1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/index.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/stop.mdx index 2f1d0d957..ddb255f97 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/pay-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/index.mdx index 1d1f3e28b..32c705686 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/index.mdx @@ -47,7 +47,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/pause.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/pause.mdx index 546468abb..c2401a3e8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/pause.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/pause.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/resume.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/resume.mdx index 30c7da640..b8762d419 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/resume.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/resume.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/stop.mdx index 0d66f6e71..72e157a0c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/volume.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/volume.mdx index acdd55445..66cddd4a6 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/volume.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/play-action/volume.mdx @@ -24,7 +24,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/index.mdx index 0c57a017c..289fcab5a 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/index.mdx @@ -43,7 +43,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/pause.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/pause.mdx index 48287e77d..0b011e6ba 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/pause.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/pause.mdx @@ -25,7 +25,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/resume.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/resume.mdx index d7d859952..54ded3ef7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/resume.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/resume.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/stop.mdx index ba5069fdf..e631e1efb 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/record-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/index.mdx index afbd9c4c3..1ae453042 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/index.mdx @@ -40,14 +40,14 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); client.onCall(async (call) => { await call.answer(); const action = await call.collect({ - speech: { endSilenceTimeout: 2.0 }, + speech: { end_silence_timeout: 2.0 }, initialTimeout: 10.0, startInputTimers: false, }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/start-input-timers.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/start-input-timers.mdx index 075893f1a..1044536a6 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/start-input-timers.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/start-input-timers.mdx @@ -19,14 +19,14 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); client.onCall(async (call) => { await call.answer(); const action = await call.collect({ - speech: { endSilenceTimeout: 2.0 }, + speech: { end_silence_timeout: 2.0 }, initialTimeout: 10.0, startInputTimers: false, }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/stop.mdx index 686236937..72e1457ed 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/standalone-collect-action/stop.mdx @@ -18,14 +18,14 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); client.onCall(async (call) => { await call.answer(); const action = await call.collect({ - speech: { endSilenceTimeout: 2.0 }, + speech: { end_silence_timeout: 2.0 }, initialTimeout: 10.0, startInputTimers: false, }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/index.mdx index bac6492cf..e6749f04f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/index.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/stop.mdx index 09a7be483..4bc681c7e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/stream-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/index.mdx index 88b419c59..f48a7603b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/index.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/stop.mdx index 6e2daffea..b0c8f47df 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/tap-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/index.mdx index 0e1ec9c4d..60979e5b2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/index.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/stop.mdx index cc4aab71f..4702ef656 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/actions/transcribe-action/stop.mdx @@ -18,7 +18,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-hold.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-hold.mdx index 0a4eb1dbb..bdd47b9d2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-hold.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-hold.mdx @@ -37,7 +37,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-message.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-message.mdx index a9aa669db..599ba6512 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-message.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-message.mdx @@ -49,7 +49,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-unhold.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-unhold.mdx index e1db38470..d146a25ca 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-unhold.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai-unhold.mdx @@ -26,7 +26,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai.mdx index 5a143ea46..05ae64379 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/ai.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/ai.mdx @@ -125,7 +125,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/amazon-bedrock.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/amazon-bedrock.mdx index 8a039b52c..16827e0d4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/amazon-bedrock.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/amazon-bedrock.mdx @@ -48,7 +48,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/answer.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/answer.mdx index 8cbdbdb86..5cf4b7d55 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/answer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/answer.mdx @@ -31,7 +31,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/bind-digit.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/bind-digit.mdx index 0a3fa0368..cec98a77c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/bind-digit.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/bind-digit.mdx @@ -51,7 +51,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/clear-digit-bindings.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/clear-digit-bindings.mdx index 1ccedcd62..af76730ea 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/clear-digit-bindings.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/clear-digit-bindings.mdx @@ -25,7 +25,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/collect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/collect.mdx index b19efe4b7..b62ee4794 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/collect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/collect.mdx @@ -102,7 +102,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/connect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/connect.mdx index 8af3ab1a6..6efe2f9a8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/connect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/connect.mdx @@ -68,7 +68,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise-stop.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise-stop.mdx index eb704eec0..6d8ad85f7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise-stop.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise-stop.mdx @@ -22,7 +22,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise.mdx index 033035569..7471a83ee 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/denoise.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/detect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/detect.mdx index 4214eabb7..3c2eab6b9 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/detect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/detect.mdx @@ -66,7 +66,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/disconnect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/disconnect.mdx index b787105fa..716c27ec7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/disconnect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/disconnect.mdx @@ -28,7 +28,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/echo.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/echo.mdx index 5fd035b88..1a55fed92 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/echo.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/echo.mdx @@ -38,7 +38,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/hangup.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/hangup.mdx index d9b5e09c6..3be827d3d 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/hangup.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/hangup.mdx @@ -30,7 +30,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/hold.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/hold.mdx index 50af87005..73366fb40 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/hold.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/hold.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/index.mdx index c8ebd081a..2117f7d01 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/index.mdx @@ -251,7 +251,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx index 7320aa1ee..04512f580 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-conference.mdx @@ -120,7 +120,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-room.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-room.mdx index 2a408a8d7..a402ef37c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/join-room.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/join-room.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-conference.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-conference.mdx index e76d23907..9e5d3471e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-conference.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-conference.mdx @@ -24,7 +24,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-room.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-room.mdx index 717979e49..71a12e07f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-room.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/leave-room.mdx @@ -20,7 +20,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/live-transcribe.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/live-transcribe.mdx index 491316131..1e785989c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/live-transcribe.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/live-transcribe.mdx @@ -50,7 +50,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/live-translate.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/live-translate.mdx index 8f165f5f8..804a9f77b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/live-translate.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/live-translate.mdx @@ -46,7 +46,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/on.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/on.mdx index e361639c6..71791eec8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/on.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/on.mdx @@ -37,7 +37,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/pass.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/pass.mdx index b3aa859dc..1e84028d1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/pass.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/pass.mdx @@ -24,7 +24,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/pay.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/pay.mdx index 173279c32..d2f7b61b8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/pay.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/pay.mdx @@ -114,7 +114,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/play-and-collect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/play-and-collect.mdx index 6652fd44f..6e19287d1 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/play-and-collect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/play-and-collect.mdx @@ -102,7 +102,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/play.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/play.mdx index 72c61a3d6..96553cf40 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/play.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/play.mdx @@ -72,7 +72,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -92,7 +92,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -117,7 +117,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-enter.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-enter.mdx index 880120143..9ff196035 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-enter.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-enter.mdx @@ -42,7 +42,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-leave.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-leave.mdx index da89c7f4a..ea82ffe1f 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-leave.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/queue-leave.mdx @@ -44,7 +44,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/receive-fax.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/receive-fax.mdx index 583133663..e89488575 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/receive-fax.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/receive-fax.mdx @@ -40,7 +40,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/record.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/record.mdx index 9688e8e29..9943bcad6 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/record.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/record.mdx @@ -92,7 +92,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/refer.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/refer.mdx index 60e77a373..4483db735 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/refer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/refer.mdx @@ -49,7 +49,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/send-digits.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/send-digits.mdx index 44cf6dbfc..5652b9cf8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/send-digits.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/send-digits.mdx @@ -37,7 +37,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/send-fax.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/send-fax.mdx index 413ab49d8..3c6f810ce 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/send-fax.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/send-fax.mdx @@ -51,7 +51,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/stream.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/stream.mdx index c9ff2aab0..c30ef8d10 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/stream.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/stream.mdx @@ -82,7 +82,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/tap.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/tap.mdx index 89f4850ca..ed15f70b4 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/tap.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/tap.mdx @@ -75,7 +75,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/transcribe.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/transcribe.mdx index 45d502da2..954dd6c09 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/transcribe.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/transcribe.mdx @@ -51,7 +51,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/transfer.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/transfer.mdx index d01735232..f8b7b3ffd 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/transfer.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/transfer.mdx @@ -26,7 +26,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/unhold.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/unhold.mdx index e323dfa80..359ed2988 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/unhold.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/unhold.mdx @@ -29,7 +29,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/user-event.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/user-event.mdx index b4e8f6359..3bf3eee65 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/user-event.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/user-event.mdx @@ -29,7 +29,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for-ended.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for-ended.mdx index f8418542d..9b57c37a7 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for-ended.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for-ended.mdx @@ -28,7 +28,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for.mdx index b3d1dc1a6..1942950e0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/call/wait-for.mdx @@ -38,7 +38,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/connect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/connect.mdx index 733ff7f86..63ffa6328 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/connect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/connect.mdx @@ -34,7 +34,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/dial.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/dial.mdx index 676c5681a..0b13d9d01 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/dial.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/dial.mdx @@ -73,9 +73,9 @@ Throws `RelayError` if the dial fails or if no answer is received within the limit is reached. - - How long in milliseconds to wait for the dial to complete (answer or failure) before - throwing a timeout error. + + How long in seconds to wait for the dial to complete (answer or failure) before + throwing a timeout error. Matches the Python SDK convention. @@ -92,7 +92,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -122,7 +122,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -144,7 +144,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/disconnect.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/disconnect.mdx index f37bde983..06014a1e9 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/disconnect.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/disconnect.mdx @@ -34,7 +34,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -42,8 +42,8 @@ await client.connect(); // Do work ... const message = await client.sendMessage({ - to: '+15559876543', - from: '+15551234567', + toNumber: '+15559876543', + fromNumber: '+15551234567', body: 'Hello!', }); await message.wait(); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/execute.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/execute.mdx index 57d15b54d..d71770f96 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/execute.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/execute.mdx @@ -54,7 +54,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/index.mdx index 6806d5b0c..e200fa6a0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/index.mdx @@ -32,23 +32,30 @@ token. Credentials can be passed directly or read from environment variables. - API token for authentication. Set via constructor or `SIGNALWIRE_TOKEN` environment variable. + API token for authentication. Set via constructor or `SIGNALWIRE_API_TOKEN` environment variable. - JWT token for alternative authentication. Read from the `SIGNALWIRE_JWT_TOKEN` environment variable. + JWT token for alternative authentication. Set via constructor or `SIGNALWIRE_JWT_TOKEN` environment variable. When provided, `project` and `token` are not required. - + SignalWire space hostname (e.g., `your-space.signalwire.com`). Set via constructor or `SIGNALWIRE_SPACE` - environment variable. Defaults to `relay.signalwire.com`. + environment variable. - + List of contexts to subscribe to for inbound call and message events. + + Maximum number of concurrent inbound calls the client will track. Calls + arriving beyond this limit are dropped with a log warning. Set via constructor + or `RELAY_MAX_ACTIVE_CALLS` environment variable. Constructor-only -- not + accessible as a public attribute after initialization. + + Server-assigned protocol string from the connect response. Read-only. Used internally for session resumption on reconnect. @@ -89,6 +96,34 @@ token. Credentials can be passed directly or read from environment variables. +## **Async Disposable** + +`RelayClient` implements `Symbol.asyncDispose`, so it can be used with the +`await using` statement for scoped connections. The client disconnects +automatically when the scope exits. + +```typescript {4-5} +import { RelayClient } from '@signalwire/sdk'; + +async function main() { + await using client = new RelayClient({ + project: process.env.SIGNALWIRE_PROJECT_ID!, + token: process.env.SIGNALWIRE_API_TOKEN!, + contexts: ['default'], + }); + await client.connect(); + const call = await client.dial([ + [{ type: 'phone', params: { to_number: '+15559876543', from_number: '+15551234567' } }], + ]); + // Automatically disconnects on exit +} + +await main(); +``` + +For environments without `await using` support, use try/finally with +`disconnect()`. + ## **Example** ```typescript {3} @@ -96,7 +131,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/on-call.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/on-call.mdx index cd2759b6a..08a6c7ae5 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/on-call.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/on-call.mdx @@ -24,7 +24,8 @@ the previous handler. ## **Returns** -`void` +`CallHandler` — the same handler, returned to support decorator-style usage +(e.g., TypeScript 5 decorators or manual composition). ## **Example** @@ -33,7 +34,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/on-message.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/on-message.mdx index db73d25e8..df22c25cf 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/on-message.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/on-message.mdx @@ -24,7 +24,8 @@ replaces the previous handler. ## **Returns** -`void` +`MessageHandler` — the same handler, returned to support decorator-style usage +(e.g., TypeScript 5 decorators or manual composition). ## **Example** @@ -33,7 +34,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/receive.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/receive.mdx index dfd31d7bf..86df595bf 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/receive.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/receive.mdx @@ -42,7 +42,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['sales'] }); @@ -62,7 +62,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['sales'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/run.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/run.mdx index 27d77aa51..2dcceb745 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/run.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/run.mdx @@ -39,7 +39,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/send-message.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/send-message.mdx index 08166655c..df104b97e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/send-message.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/send-message.mdx @@ -19,11 +19,11 @@ with text and attached media. ## **Parameters** - + Destination phone number in E.164 format (e.g., `"+15559876543"`). - + Sender phone number in E.164 format. Must be a number owned by your SignalWire project. @@ -68,21 +68,21 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15559876543', - from: '+15551234567', + toNumber: '+15559876543', + fromNumber: '+15551234567', body: 'Hello from SignalWire RELAY!', }); console.log(`Message ID: ${message.messageId}`); // Wait for delivery confirmation -const result = await message.wait(30_000); +const result = await message.wait(30); console.log(`Final state: ${message.state}`); await client.disconnect(); @@ -95,15 +95,15 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15559876543', - from: '+15551234567', + toNumber: '+15559876543', + fromNumber: '+15551234567', body: 'Check out this image!', media: ['https://example.com/photo.jpg'], }); @@ -118,15 +118,15 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15559876543', - from: '+15551234567', + toNumber: '+15559876543', + fromNumber: '+15551234567', body: 'Important notification', onCompleted: (event) => { console.log(`Message delivered: ${JSON.stringify(event.params)}`); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/client/unreceive.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/client/unreceive.mdx index ac756bc77..363a292ac 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/client/unreceive.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/client/unreceive.mdx @@ -35,7 +35,7 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['sales', 'support', 'billing'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx index dc24dc32a..71da401a8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx @@ -18,6 +18,15 @@ The `@signalwire/sdk` package exports string and numeric constants used throughout the RELAY namespace for call states, end reasons, connect states, event types, message states, media operation states, and protocol settings. + +Only `CALL_STATE_*`, `CONNECT_STATE_*`, `EVENT_CALL_*`, `EVENT_MESSAGING_*`, +`EVENT_CONFERENCE`, `EVENT_CALLING_ERROR`, and `MESSAGE_STATE_*` are re-exported +from the `@signalwire/sdk` entry point. The remaining constants listed below +(protocol, JSON-RPC method names, end reasons, play/record/detect/room states, +reconnect tuning) are internal reference values for the RELAY protocol -- +documented here for completeness but not importable from the package root. + + ```typescript {2-7} import { CALL_STATE_ANSWERED, diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/events.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/events.mdx index 78820d405..1c30d1600 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/events.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/events.mdx @@ -33,7 +33,7 @@ import { RelayClient, CallStateEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -206,11 +206,11 @@ Handlers for this event receive a `CallStateEvent` with the following properties #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, CallStateEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -296,11 +296,11 @@ Handlers for this event receive a `PlayEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, PlayEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -359,11 +359,11 @@ Handlers for this event receive a `RecordEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, RecordEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -420,11 +420,11 @@ Handlers for this event receive a `CollectEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, CollectEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -470,11 +470,11 @@ Handlers for this event receive a `ConnectEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, ConnectEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -518,11 +518,11 @@ Handlers for this event receive a `DetectEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, DetectEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -562,11 +562,11 @@ Handlers for this event receive a `FaxEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, FaxEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -614,11 +614,11 @@ Handlers for this event receive a `TapEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, TapEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -665,11 +665,11 @@ Handlers for this event receive a `StreamEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, StreamEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -706,11 +706,11 @@ Handlers for this event receive a `SendDigitsEvent` with the following propertie #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, SendDigitsEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -779,11 +779,11 @@ Handlers for this event receive a `ReferEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, ReferEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -818,11 +818,11 @@ Handlers for this event receive a `HoldEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, HoldEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -855,11 +855,11 @@ Handlers for this event receive a `DenoiseEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, DenoiseEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -899,11 +899,11 @@ Handlers for this event receive a `PayEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, PayEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -936,11 +936,11 @@ Handlers for this event receive an `EchoEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, EchoEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -995,11 +995,11 @@ Handlers for this event receive a `QueueEvent` with the following properties: #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, QueueEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -1040,11 +1040,11 @@ Handlers for this event receive a `ConferenceEvent` with the following propertie #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, ConferenceEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -1099,11 +1099,11 @@ Handlers for this event receive a `TranscribeEvent` with the following propertie #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, TranscribeEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -1140,11 +1140,11 @@ Handlers for this event receive a `CallingErrorEvent` with the following propert #### Example ```typescript {14} -import { RelayClient } from '@signalwire/sdk'; +import { RelayClient, CallingErrorEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); @@ -1279,7 +1279,7 @@ import { RelayClient, MessageStateEvent } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/message/index.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/message/index.mdx index af35dc75e..9934cf294 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/message/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/message/index.mdx @@ -27,20 +27,20 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15551234567', - from: '+15559876543', + toNumber: '+15551234567', + fromNumber: '+15559876543', body: 'Hello from SignalWire!', }); // Wait for delivery confirmation -const result = await message.wait(30_000); +const result = await message.wait(30); console.log(`Final state: ${message.state}`); await client.disconnect(); @@ -142,15 +142,15 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15551234567', - from: '+15559876543', + toNumber: '+15551234567', + fromNumber: '+15559876543', body: 'Order confirmed', }); @@ -171,20 +171,20 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15551234567', - from: '+15559876543', + toNumber: '+15551234567', + fromNumber: '+15559876543', body: 'Your verification code is 123456', }); try { - const event = await message.wait(30_000); + const event = await message.wait(30); if (message.state === 'delivered') { console.log('Message delivered successfully'); } else { diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/message/on.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/message/on.mdx index 3cc650117..9b044d22c 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/message/on.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/message/on.mdx @@ -29,15 +29,15 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15551234567', - from: '+15559876543', + toNumber: '+15551234567', + fromNumber: '+15559876543', body: 'Order confirmed', }); diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/message/wait.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/message/wait.mdx index 12620b8cc..aaeee2be8 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/message/wait.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/message/wait.mdx @@ -18,7 +18,8 @@ reach a terminal state within the given duration. ## **Parameters** - Maximum number of milliseconds to wait. `undefined` waits indefinitely. + Maximum seconds to wait (matches Python SDK convention). `undefined` waits + indefinitely. ## **Returns** @@ -33,20 +34,20 @@ import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'] }); await client.connect(); const message = await client.sendMessage({ - to: '+15551234567', - from: '+15559876543', + toNumber: '+15551234567', + fromNumber: '+15559876543', body: 'Your verification code is 123456', }); try { - const event = await message.wait(30_000); + const event = await message.wait(30); if (message.state === 'delivered') { console.log('Message delivered successfully'); } else { diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/relay-error.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/relay-error.mdx index 6db8ebc34..0d66deb98 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/relay-error.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/relay-error.mdx @@ -14,7 +14,7 @@ import { RelayError } from '@signalwire/sdk'; ## **Properties** - + Numeric error code returned by the RELAY server. @@ -35,7 +35,7 @@ import { RelayClient, RelayError } from '@signalwire/sdk'; const client = new RelayClient({ project: process.env.SIGNALWIRE_PROJECT_ID!, - token: process.env.SIGNALWIRE_TOKEN!, + token: process.env.SIGNALWIRE_API_TOKEN!, contexts: ['default'], }); diff --git a/fern/products/server-sdks/sdk-source-sync.json b/fern/products/server-sdks/sdk-source-sync.json index 020813ab4..d5085ec2b 100644 --- a/fern/products/server-sdks/sdk-source-sync.json +++ b/fern/products/server-sdks/sdk-source-sync.json @@ -13,7 +13,7 @@ "local_path": "temp/signalwire-typescript", "status": "active", "synced_commit": "ba6d5b1f1c68065bb378ab9c1a79c4a08da107e1", - "synced_at": "2026-04-21" + "synced_at": "2026-04-23" }, "go": { "repository": "https://github.com/signalwire/signalwire-go.git", diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md index e156f8753..c55ee2010 100644 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -882,3 +882,157 @@ Key verified behaviors: - `NumberGroups.getMembership` / `deleteMembership` correctly document the top-level `/number_group_memberships/{id}` endpoint (not nested). - Calling namespace: all 37 commands dispatch POST `/api/calling/calls`; signature shape `(params)` for `dial`/`update`, `(callId, params)` for the rest. +--- + +## Relay Audit (in progress — 2026-04-22 session 5) + +**Scope:** `pages/reference/typescript/relay/**` — 91 MDX files against +`src/relay/**` at commit `ba6d5b1`. + +**Source files:** +- `src/relay/RelayClient.ts` (1036 lines) → `relay/client/` +- `src/relay/Call.ts` (854 lines) → `relay/call/` +- `src/relay/Message.ts` (148 lines) → `relay/message/` +- `src/relay/Action.ts` (314 lines) → `relay/actions/*/` (11 subclasses) +- `src/relay/RelayError.ts` (14 lines) → `relay/relay-error.mdx` +- `src/relay/RelayEvent.ts` (892 lines) → `relay/events.mdx` +- `src/relay/constants.ts` (132 lines) → `relay/constants.mdx` +- `src/relay/index.ts` + `types.ts` + `Deferred.ts` → internal + +### Full Inventory — Relay + +| Status | Namespace | Files | Source | +|--------|-----------|-------|--------| +| AUDITED -- NO ISSUES | `call/` | 45 | `src/relay/Call.ts` | +| AUDITED + FIXED | `actions/` | 31 | `src/relay/Action.ts` (base) | +| AUDITED + FIXED | `client/` | 10 | `src/relay/RelayClient.ts` | +| AUDITED + FIXED | `message/` | 3 | `src/relay/Message.ts` | +| AUDITED + FIXED | root (overview, relay-error, constants, events) | 4 | various | + +### Findings Log + +#### call/ (45 files) — AUDITED -- NO ISSUES + +- `[call/index.mdx]` clean — 9 properties + 44-card CardGroup match src Call.ts line 40-48, 107-835. Content drift vs Python: only legitimate (type syntax, casing, example idioms). Behavioral: "created automatically by RelayClient" ✓ line 1-5; "JSON-RPC via WebSocket" ✓ line 83-85; "long-running ops return Action" ✓ line 208. +- `[call/on.mdx]` clean — `on(eventType, handler): void` (src 107). EventHandler type matches. Behavioral: handlers pushed to `_listeners`, invoked on dispatch (src 140-147). +- `[call/wait-for.mdx]` clean — `waitFor(eventType, predicate?, timeout?)` (src 151). One-shot handler removed in finally block (src 179-185). Throws on timeout (src 170). +- `[call/wait-for-ended.mdx]` clean — `waitForEnded(timeout?)` (src 190). Resolves on `_ended` deferred, set when state === 'ended' (src 122-123). +- `[call/answer.mdx]` clean — `answer(extra?)` (src 247). `extra` intentional pass-through omission (matches Python parity). +- `[call/hangup.mdx]` clean — `hangup(reason = 'hangup')` (src 252). Reason default + enum values documented. +- `[call/pass.mdx]` clean — `pass()` no args (src 257). Delegates to `_execute('pass')`. +- `[call/play.mdx]` clean — `play(media, options)` with 5 options (src 264). PlayAction has stop/pause/resume/volume + wait. All 3 example highlights verified. +- `[call/record.mdx]` clean — `record(audio?, options)` (src 286). Nested audio.* params correctly documented with Indent. +- `[call/play-and-collect.mdx]` clean — `playAndCollect(media, collect, options)` (src 303). Nested collect.digits/speech Indents correct. +- `[call/collect.mdx]` clean — `collect(options)` 9 options (src 324). All documented incl. digits/speech nested. +- `[call/connect.mdx]` clean — `connect(devices, options)` 5 options (src 351). +- `[call/disconnect.mdx]` clean — `disconnect()` no args (src 371). +- `[call/send-digits.mdx]` clean — `sendDigits(digits, controlId?)` (src 378). +- `[call/detect.mdx]` clean — `detect(detect, options)` 3 options (src 386). DetectAction resolves on first detection event (src 169-175). +- `[call/refer.mdx]` clean — `refer(device, options)` (src 404). device.type/params nested. +- `[call/pay.mdx]` clean — `pay(paymentConnectorUrl, options)` 18 options (src 416). All documented. +- `[call/send-fax.mdx]` clean — `sendFax(document, options)` 4 options (src 469). +- `[call/receive-fax.mdx]` clean — `receiveFax(options)` 2 options (src 487). +- `[call/tap.mdx]` clean — `tap(tap, device, options)` (src 502). Nested tap + device Indents. +- `[call/stream.mdx]` clean — `stream(url, options)` 8 options (src 519). +- `[call/transfer.mdx]` clean — `transfer(dest, extra?)` (src 549). `extra` pass-through (Python parity). +- `[call/join-conference.mdx]` clean — `joinConference(name, options)` 19 options (src 557). +- `[call/leave-conference.mdx]` clean — `leaveConference(conferenceId, extra?)` (src 605). +- `[call/hold.mdx]` / `[call/unhold.mdx]` clean — no args (src 612/617). +- `[call/denoise.mdx]` / `[call/denoise-stop.mdx]` clean — no args (src 624/629). RPC `denoise` / `denoise.stop`. +- `[call/transcribe.mdx]` clean — `transcribe(options)` 3 options (src 636). TranscribeAction. +- `[call/echo.mdx]` clean — `echo({timeout?, statusUrl?})` (src 653). +- `[call/bind-digit.mdx]` clean — `bindDigit(digits, bindMethod, options)` 3 options (src 663). +- `[call/clear-digit-bindings.mdx]` clean — `clearDigitBindings(realm?)` (src 683). +- `[call/live-transcribe.mdx]` clean — `liveTranscribe(action, extra?)` (src 692). `extra` pass-through. +- `[call/live-translate.mdx]` clean — `liveTranslate(action, {statusUrl?})` (src 697). +- `[call/join-room.mdx]` clean — `joinRoom(name, {statusUrl?})` (src 709). +- `[call/leave-room.mdx]` clean — `leaveRoom(extra?)` (src 719). `extra` pass-through. +- `[call/ai.mdx]` clean — `ai(options)` 14 options (src 726). All documented. +- `[call/amazon-bedrock.mdx]` clean — `amazonBedrock(options)` 6 options (src 761). +- `[call/ai-message.mdx]` clean — `aiMessage(options)` 4 options (src 780). +- `[call/ai-hold.mdx]` clean — `aiHold({timeout?, prompt?})` (src 795). +- `[call/ai-unhold.mdx]` clean — `aiUnhold({prompt?})` (src 803). +- `[call/user-event.mdx]` clean — `userEvent(options)` event field (src 812). Doc correctly notes extra keys ignored. +- `[call/queue-enter.mdx]` clean — `queueEnter(queueName, {controlId?, statusUrl?})` (src 821). RPC `queue.enter`. +- `[call/queue-leave.mdx]` clean — `queueLeave(queueName, {controlId?, queueId?, statusUrl?})` (src 835). RPC `queue.leave`. + +**Coverage gap (P4):** `toString()` (src 851) not documented — intentional, internal repr. +**Content drift vs Python:** 44 method slugs + filenames match exactly. Only legitimate drift (camelCase titles, TS type syntax, example idioms). + +#### actions/ (31 files) — AUDITED + FIXED + +- `[actions/index.mdx]` FIXED (P1) — `wait(timeout)` claimed "Maximum milliseconds"; source Action.ts:91/95 is **seconds** (JSDoc: "matches Python SDK convention", line 95: `timeout * 1000` converts to ms). Fixed description to "Maximum seconds" per Python parity. +- `[actions/detect-action/index.mdx]` FIXED (P2) — example `action.wait(10000)` interpreted timeout as ms; source is seconds (10000 = 2.7 hours). Fixed to `wait(10)` matching Python counterpart. +- `[actions/standalone-collect-action/index.mdx]` FIXED (P1) — example `speech: { endSilenceTimeout: 2.0 }` — the `speech` obj is pass-through to RELAY server (Call.ts:338). RELAY server uses snake_case `end_silence_timeout`. CamelCase key would be ignored by server. Fixed. +- `[actions/standalone-collect-action/stop.mdx]` FIXED (P1) — same `endSilenceTimeout` → `end_silence_timeout` pass-through fix. +- `[actions/standalone-collect-action/start-input-timers.mdx]` FIXED (P1) — same `endSilenceTimeout` → `end_silence_timeout` pass-through fix. +- Other 26 action files clean. Per-action-class verification: + - `play-action/*` (5 files) — PlayAction src 117-137; 4 methods (stop/pause/resume/volume) all RPC `play.*`. Terminal `PLAY_STATE_FINISHED, PLAY_STATE_ERROR`. + - `record-action/*` (4 files) — RecordAction src 141-159; 3 methods (stop/pause/resume) RPC `record.*`. Terminal `RECORD_STATE_FINISHED, RECORD_STATE_NO_INPUT`. `pause(behavior?)` optional arg documented. + - `collect-action/*` (4 files) — CollectAction src 184-214; 3 methods (stop/volume/startInputTimers) RPC mix `play_and_collect.*` + `collect.start_input_timers`. Note about collect-only events (src 193-201) accurate. + - `detect-action/*` (2 files) — DetectAction src 163-180; 1 method. Note about first-detection-resolve accurate (src 169-175). + - `fax-action/*` (2 files) — FaxAction src 243-254; 1 method. RPC prefix `send_fax.stop` or `receive_fax.stop` depending on source method. + - `tap-action/*` / `stream-action/*` / `pay-action/*` / `transcribe-action/*` / `ai-action/*` — all single-stop classes, terminal states match src. + - `standalone-collect-action/*` (3 files) — terminal states match src 220. Two distinct RPC paths: `collect.stop` + `collect.start_input_timers`. + +**Systematic issue (project-wide):** Two distinct timeout-unit bugs surfaced in this audit. (1) Doc prose claimed `wait(timeout)` is ms — fixed in base Action page. (2) Example code passed `10000` assuming ms — fixed in detect-action. Worth spot-checking other SDK pages that mention wait-with-timeout, in case the unit confusion propagated. **Followup audit confirmed the pattern extended to `dialTimeout` (client/dial.mdx) and `message.wait(30_000)` (client/send-message.mdx) — also fixed.** + +#### client/ (10 files) — AUDITED + FIXED + +- `[client/index.mdx]` FIXED (P0 x 1 + drift) — + - `token` env var was `SIGNALWIRE_TOKEN`; source `RelayClient.ts:132` uses `SIGNALWIRE_API_TOKEN`. **P0 wrong env var.** + - Missing `maxActiveCalls` property (source ctor 152-158 + `_maxActiveCalls` field 118; default 1000 via `DEFAULT_MAX_ACTIVE_CALLS`; `RELAY_MAX_ACTIVE_CALLS` env fallback). Added per Python counterpart. + - `jwtToken` description was "Read from env var" only; source 133 also accepts constructor. Fixed to "Set via constructor or ...". + - `host` missing `default="relay.signalwire.com"` attribute; `contexts` missing `default="[]"`. Added to match Python. + - No "Async Disposable" section; source implements `Symbol.asyncDispose` (line 182) for `await using`. Added section with full example. +- `[client/on-call.mdx]` FIXED (P1) — Returns was `void`; source `onCall(handler: CallHandler): CallHandler` — returns the handler to support decorator usage. Fixed. +- `[client/on-message.mdx]` FIXED (P1) — same Returns-type bug as on-call; source returns `MessageHandler`. Fixed. +- `[client/connect.mdx]` clean — `connect()` no args; behavioral claims (wss://host, signalwire.connect, contexts auto-subscribe via `_authenticate` 304-306, ping loop) all verified. +- `[client/disconnect.mdx]` FIXED (P0 in example) — example used `client.sendMessage({ to, from, body })`; sendMessage options (src 437) are `toNumber`/`fromNumber`. Fixed both keys. +- `[client/execute.mdx]` clean — `(method, params): Promise` matches src 365. Warning about 30s timeout + reconnect matches REQUEST_TIMEOUT constant. +- `[client/dial.mdx]` FIXED (P0) — `options.dialTimeout` claimed `default="120000"` in milliseconds; source 401-402 uses seconds (default 120, then `* 1000` to ms internally). JSDoc line 375 confirms seconds. Fixed doc + default. +- `[client/send-message.mdx]` FIXED (P0 x 5) — (a) ParamField `to` should be `toNumber` (src 438); (b) ParamField `from` should be `fromNumber` (src 439); (c) all 3 examples used `to`/`from` as sendMessage options — would fail at runtime; (d) `await message.wait(30_000)` — Message.wait uses seconds convention (Message.ts:79/83 `timeout * 1000`). Fixed to `wait(30)`. +- `[client/receive.mdx]` clean — `receive(contexts: string[])` src 487; empty list short-circuits. +- `[client/unreceive.mdx]` clean — `unreceive(contexts: string[])` src 494. +- `[client/run.mdx]` clean — `run(): Promise` src 503. Backoff claim "1s initial, 30s max" verified against `RECONNECT_MIN_DELAY=1.0`, `RECONNECT_MAX_DELAY=30.0` (constants.ts:118-119). + +**Systematic project-wide fix:** Swept `process.env.SIGNALWIRE_TOKEN` → `SIGNALWIRE_API_TOKEN` across 91 relay `.mdx` files. This was the env-var name the SDK auto-fallback reads, and prior examples had propagated a different env-var name that wouldn't be auto-loaded. Users copying examples and setting `SIGNALWIRE_API_TOKEN` now get the SDK's expected default behavior. + +#### message/ (3 files) — AUDITED + FIXED + +- `[message/index.mdx]` FIXED (P0 in examples) — 11 properties (messageId, context, direction, fromNumber, toNumber, body, media, segments, state, reason, tags + isDone/result getters) all match Message.ts:18-28/61-70. Three example code blocks used `to`/`from` sendMessage options — wrong per source 437-439 (actual: `toNumber`/`fromNumber`). Also `message.wait(30_000)` passes 30000 seconds — wait uses seconds (Message.ts:79/83); fixed to `wait(30)`. +- `[message/on.mdx]` FIXED (P0 in example) — `on(handler): void` matches src 73; example used `to`/`from` — fixed to `toNumber`/`fromNumber`. +- `[message/wait.mdx]` FIXED (P1 + P0 in example) — (a) ParamField `timeout` claimed "milliseconds"; source 81-96 uses seconds (`timeout * 1000` internally). (b) example used `to`/`from` + `wait(30_000)`. All fixed. + +#### root/ (4 files) — AUDITED + FIXED + +- `[overview.mdx]` clean — IVR example matches Python counterpart (same `transfer(dest=phone)` pattern — accepted per Python parity even though transfer doc says context/URL). +- `[relay-error.mdx]` FIXED — `code` ParamField had `default="0"`; source RelayError.ts:9 constructor requires `code: number` (no default). Removed wrong default. Other fields (message, name) match source 6-13. +- `[constants.mdx]` FIXED — added `` clarifying only `CALL_STATE_*`, `CONNECT_STATE_*`, `EVENT_CALL_*`, `EVENT_MESSAGING_*`, `EVENT_CONFERENCE`, `EVENT_CALLING_ERROR`, `MESSAGE_STATE_*` are re-exported from `@signalwire/sdk` (verified against `src/relay/index.ts:66-107`). All other constants listed (PROTOCOL_VERSION, AGENT_STRING, DEFAULT_RELAY_HOST, METHOD_*, END_REASON_*, PLAY_STATE_*, RECORD_STATE_*, DETECT_TYPE_*, ROOM_STATE_*, RECONNECT_*, MESSAGE_TERMINAL_STATES, CALL_STATES, EVENT_AUTHORIZATION_STATE) exist in constants.ts but aren't re-exported — note prevents user confusion about import failures. Values checked individually against constants.ts and all match. +- `[events.mdx]` FIXED (P2 x 19 systematic) — RelayEvent base (eventType/params/callId/timestamp) matches src 12-40. 19 event-class examples used typed event classes in handler signatures (e.g., `(event: PlayEvent) => …`) but didn't import those classes — examples would fail TS type check as written. Used Python AST-style script to backtrack from each handler to the preceding `import { RelayClient } from '@signalwire/sdk';` and add the referenced event class. All 21 examples now import their event class correctly. + +### Relay Audit Summary + +**Total:** 93 files audited (45 call/ + 31 actions/ + 10 client/ + 3 message/ + 4 root). +**Fixes:** ~25 distinct per-file fixes + 1 systematic 91-file sweep (SIGNALWIRE_API_TOKEN) + 1 systematic 19-file sweep (event class imports). + +**Highest-impact fixes:** +1. **wait(timeout) unit confusion (seconds not ms)** — surfaced on Action.wait (prose), DetectAction example, `dialTimeout`, `message.wait` prose, and 3 example calls. Would have produced apparent hangs in user code (timeouts many orders of magnitude too long). +2. **SIGNALWIRE_API_TOKEN env var** — client/index doc claimed `SIGNALWIRE_TOKEN`; SDK falls back to `SIGNALWIRE_API_TOKEN`. Without user setting the right env var, the SDK's auto-fallback silently did nothing. +3. **sendMessage `to`/`from` vs `toNumber`/`fromNumber`** — 6 examples + 2 ParamFields incorrectly showed `to`/`from`; actual SDK options are `toNumber`/`fromNumber`. Would fail at runtime since the SDK strictly validates body/media. +4. **Event class imports missing** — 19 typed-event examples referenced classes (CallStateEvent, PlayEvent, etc.) without importing them. +5. **speech object keys in collect pass-through** — 3 files had `speech: { endSilenceTimeout: 2.0 }` (camelCase); the `speech` object is passed unchanged to the RELAY server which expects snake_case (`end_silence_timeout`). +6. **maxActiveCalls missing from client/index docs** — documented in Python, source of truth in src/RelayClient.ts:118/152-158, default 1000, env var `RELAY_MAX_ACTIVE_CALLS`. Added. +7. **Async Disposable missing** — TS `Symbol.asyncDispose` implementation (src 182) wasn't documented; Python counterpart has `async with` section. Added TS equivalent with `await using` example. +8. **on-call/on-message Returns type** — both documented `void` but source returns the handler (decorator pattern support). + +**Coverage gaps (P4) not fixed:** +- `Call.toString()` — internal repr; intentional. +- Constants doc lists constants not re-exported from `@signalwire/sdk` root — flagged via Note rather than removing. + +**Systematic patterns uncovered (for future SDK doc authoring):** +1. Timeout units must be stated explicitly in both prose AND matching examples; TS/JS conventions default to milliseconds, Python SDK convention is seconds, and TS mirrored Python — a steady source of confusion. +2. Options object pass-through (where TS SDK wraps an opaque `Record` passed to a RELAY server) must document the server-side key casing, not the TS idiomatic casing — the SDK doesn't translate. +3. Examples that show typed event handlers need explicit type imports — language-specific issue that Python doesn't have. + + From cd75b3cdc74346de0583c7e5d975eeedd05fb801 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 14:54:46 +0000 Subject: [PATCH 05/21] docs(ts-sdk): close P4 coverage gaps in agents/ reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds 48 per-method pages across 8 agent classes flagged as P4 coverage gaps in the audit tracker. Each class's index.mdx CardGroup is expanded to link the new pages. New pages follow the standard format (frontmatter → link refs → overview → params → returns → example) and note TS/Python divergences where behavior differs. Breakdown: - swml-service (14): reset-document, stop, get-document, render-document, get-basic-auth-credentials, serve, as-router, add-section, add-verb-to-section, register-verb-handler, register-routing-callback, extract-sip-username, manual-set-proxy-url, on-request - configuration/auth-handler (5): verify-basic-auth, verify-bearer-token, verify-api-key, get-auth-info, express-middleware - configuration/config-loader (8): find-config-file, get-config, get-config-file, has-config, get-section, substitute-vars, merge-with-env, interpolate-env-vars - pom-builder (5): reset, add-pom-as-subsection, to-json, from-sections, render-xml - swml-builder (5): build, render, document, set-validation, add-section - skill-base (7): get-agent, set-agent, get-config, define-tool, has-all-env-vars, has-all-packages, validate-packages - skill-registry (3): get-skill-class, list-skills, reset-instance - skill-manager (1): loaded-skills Also quotes the YAML-unsafe description in swml-builder/say.mdx (colon in "say: prefix" was breaking fern check). yarn fern-md-check: 2241 files valid. yarn fern-check: 0 errors. --- .../auth-handler/express-middleware.mdx | 60 +++++++++++++ .../auth-handler/get-auth-info.mdx | 52 +++++++++++ .../configuration/auth-handler/index.mdx | 15 ++++ .../auth-handler/verify-api-key.mdx | 45 ++++++++++ .../auth-handler/verify-basic-auth.mdx | 53 +++++++++++ .../auth-handler/verify-bearer-token.mdx | 44 +++++++++ .../config-loader/find-config-file.mdx | 54 +++++++++++ .../config-loader/get-config-file.mdx | 30 +++++++ .../config-loader/get-config.mdx | 26 ++++++ .../config-loader/get-section.mdx | 42 +++++++++ .../config-loader/has-config.mdx | 39 ++++++++ .../configuration/config-loader/index.mdx | 24 +++++ .../config-loader/interpolate-env-vars.mdx | 42 +++++++++ .../config-loader/merge-with-env.mdx | 53 +++++++++++ .../config-loader/substitute-vars.mdx | 55 ++++++++++++ .../pom-builder/add-pom-as-subsection.mdx | 52 +++++++++++ .../agents/pom-builder/from-sections.mdx | 40 +++++++++ .../typescript/agents/pom-builder/index.mdx | 15 ++++ .../agents/pom-builder/render-xml.mdx | 43 +++++++++ .../typescript/agents/pom-builder/reset.mdx | 29 ++++++ .../typescript/agents/pom-builder/to-json.mdx | 32 +++++++ .../agents/skill-base/define-tool.mdx | 79 ++++++++++++++++ .../agents/skill-base/get-agent.mdx | 40 +++++++++ .../agents/skill-base/get-config.mdx | 44 +++++++++ .../agents/skill-base/has-all-env-vars.mdx | 37 ++++++++ .../agents/skill-base/has-all-packages.mdx | 38 ++++++++ .../typescript/agents/skill-base/index.mdx | 21 +++++ .../agents/skill-base/set-agent.mdx | 42 +++++++++ .../agents/skill-base/validate-packages.mdx | 46 ++++++++++ .../typescript/agents/skill-manager/index.mdx | 3 + .../agents/skill-manager/loaded-skills.mdx | 43 +++++++++ .../agents/skill-registry/get-skill-class.mdx | 42 +++++++++ .../agents/skill-registry/index.mdx | 9 ++ .../agents/skill-registry/list-skills.mdx | 69 ++++++++++++++ .../agents/skill-registry/reset-instance.mdx | 45 ++++++++++ .../agents/swml-builder/add-section.mdx | 42 +++++++++ .../typescript/agents/swml-builder/build.mdx | 32 +++++++ .../agents/swml-builder/document.mdx | 34 +++++++ .../typescript/agents/swml-builder/index.mdx | 15 ++++ .../typescript/agents/swml-builder/render.mdx | 32 +++++++ .../typescript/agents/swml-builder/say.mdx | 2 +- .../agents/swml-builder/set-validation.mdx | 47 ++++++++++ .../agents/swml-service/add-section.mdx | 42 +++++++++ .../swml-service/add-verb-to-section.mdx | 59 ++++++++++++ .../agents/swml-service/as-router.mdx | 49 ++++++++++ .../swml-service/extract-sip-username.mdx | 54 +++++++++++ .../get-basic-auth-credentials.mdx | 47 ++++++++++ .../agents/swml-service/get-document.mdx | 48 ++++++++++ .../typescript/agents/swml-service/index.mdx | 42 +++++++++ .../swml-service/manual-set-proxy-url.mdx | 46 ++++++++++ .../agents/swml-service/on-request.mdx | 90 +++++++++++++++++++ .../register-routing-callback.mdx | 71 +++++++++++++++ .../swml-service/register-verb-handler.mdx | 63 +++++++++++++ .../agents/swml-service/render-document.mdx | 36 ++++++++ .../agents/swml-service/reset-document.mdx | 33 +++++++ .../typescript/agents/swml-service/serve.mdx | 80 +++++++++++++++++ .../typescript/agents/swml-service/stop.mdx | 38 ++++++++ .../typescript-sdk-audit-tracker.md | 79 ++++++++++++++++ 58 files changed, 2483 insertions(+), 1 deletion(-) create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/express-middleware.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/get-auth-info.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-api-key.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-basic-auth.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-bearer-token.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/find-config-file.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config-file.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-section.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/has-config.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/interpolate-env-vars.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/merge-with-env.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/substitute-vars.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/add-pom-as-subsection.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/from-sections.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/render-xml.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/reset.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/to-json.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/define-tool.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-agent.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-config.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-env-vars.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-packages.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/set-agent.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-base/validate-packages.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/loaded-skills.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-skill-class.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-skills.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/reset-instance.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/add-section.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/build.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/document.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/render.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/set-validation.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-section.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-verb-to-section.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/as-router.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/extract-sip-username.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-basic-auth-credentials.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-document.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/manual-set-proxy-url.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/on-request.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-routing-callback.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-verb-handler.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/render-document.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/reset-document.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/serve.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/agents/swml-service/stop.mdx diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/express-middleware.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/express-middleware.mdx new file mode 100644 index 000000000..1910eafe3 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/express-middleware.mdx @@ -0,0 +1,60 @@ +--- +title: "expressMiddleware" +slug: /reference/typescript/agents/configuration/auth-handler/express-middleware +description: "Create an Express/Connect-compatible middleware adapter." +max-toc-depth: 3 +--- + +[ref-middleware]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/middleware +[ref-validate]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/validate + +Create an Express/Connect-compatible middleware function that validates +incoming requests against the configured authentication methods and returns a +`401 Unauthorized` response when auth fails. Framework-agnostic equivalent of +the Python SDK's `get_fastapi_dependency`. + + +For Hono apps, use [`middleware()`][ref-middleware] instead. For standalone +validation without a framework, use [`validate()`][ref-validate] directly. + + +## **Parameters** + + + When `true`, unauthenticated requests are allowed through instead of being + rejected. Useful for progressive-auth flows where the handler downstream + decides whether to require credentials. + + +## **Returns** + +An async Express-compatible middleware: +`(req, res, next) => Promise`. + +On failed auth with `optional=false`, responds with HTTP 401 and body +`{ error: 'Unauthorized' }`. On success or when `optional=true`, calls `next()`. + +## **Example** + +```typescript {11} +import express from 'express'; +import { AuthHandler } from '@signalwire/sdk'; + +const auth = new AuthHandler({ + bearerToken: 'sk_live_abc123', +}); + +const app = express(); + +// Protect all /api/* routes +app.use('/api', auth.expressMiddleware()); + +app.get('/api/status', (req, res) => { + res.json({ ok: true }); +}); + +// Public route with optional auth +app.get('/public', auth.expressMiddleware(true), (req, res) => { + res.json({ authenticated: false }); +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/get-auth-info.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/get-auth-info.mdx new file mode 100644 index 000000000..4ce670eb4 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/get-auth-info.mdx @@ -0,0 +1,52 @@ +--- +title: "getAuthInfo" +slug: /reference/typescript/agents/configuration/auth-handler/get-auth-info +description: "Get structured metadata describing the enabled authentication methods." +max-toc-depth: 3 +--- + +Return structured metadata describing each enabled authentication method on +this handler. Useful for generating diagnostic pages, startup banners, or +developer-facing hints about which auth schemes are active. Missing entries +indicate the corresponding method is not configured. + +## **Returns** + +An object with three optional keys: + + + Present when Basic Auth is configured. Contains the configured username (the + password is never returned). + + + + Present when Bearer token auth is configured. `hint` is a human-readable + string like `"Use Authorization: Bearer "`. + + + + Present when API key auth is configured. `header` is the configured header + name (defaults to `"X-Api-Key"`). `hint` is a human-readable usage string. + + +## **Example** + +```typescript {9} +import { AuthHandler } from '@signalwire/sdk'; + +const auth = new AuthHandler({ + basicAuth: ['admin', 'secret'], + bearerToken: 'sk_live_abc123', +}); + +const info = auth.getAuthInfo(); +console.log(info); +// { +// basic: { enabled: true, username: 'admin' }, +// bearer: { enabled: true, hint: 'Use Authorization: Bearer ' } +// } + +if (info.apiKey) { + console.log(`API key expected in header ${info.apiKey.header}`); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx index 5e40e8d2d..a9ffb59c0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/index.mdx @@ -69,6 +69,21 @@ const auth = new AuthHandler({ Create a Hono-compatible middleware that rejects unauthorized requests. + + Create an Express/Connect-compatible middleware adapter. + + + Verify a username/password pair with constant-time comparison. + + + Verify a Bearer token with constant-time comparison. + + + Verify an API key with constant-time comparison. + + + Get metadata describing the enabled auth methods. + Check whether Bearer token authentication is configured. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-api-key.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-api-key.mdx new file mode 100644 index 000000000..60526bb49 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-api-key.mdx @@ -0,0 +1,45 @@ +--- +title: "verifyApiKey" +slug: /reference/typescript/agents/configuration/auth-handler/verify-api-key +description: "Verify an API key against the configured key." +max-toc-depth: 3 +--- + +[ref-validate]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/validate + +Verify an API key against the configured key. Uses a constant-time comparison +to prevent timing attacks. Returns `false` immediately when API key auth is +not configured. + + +Pass only the key value -- this method does not parse headers. For full +header-based validation (which reads the configured `apiKeyHeader`, case- +insensitive), use [`validate()`][ref-validate]. + + +## **Parameters** + + + The API key string to verify. + + +## **Returns** + +`boolean` -- `true` if the key matches; `false` if it doesn't, or if API key +auth was not configured. + +## **Example** + +```typescript {8} +import { AuthHandler } from '@signalwire/sdk'; + +const auth = new AuthHandler({ + apiKey: 'sk_live_abc123', + apiKeyHeader: 'X-Api-Key', +}); + +function authorize(headerValue: string | undefined) { + if (!headerValue) return false; + return auth.verifyApiKey(headerValue); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-basic-auth.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-basic-auth.mdx new file mode 100644 index 000000000..49727569f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-basic-auth.mdx @@ -0,0 +1,53 @@ +--- +title: "verifyBasicAuth" +slug: /reference/typescript/agents/configuration/auth-handler/verify-basic-auth +description: "Verify a username/password pair against the configured Basic Auth credentials." +max-toc-depth: 3 +--- + +[ref-validate]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/validate +[ref-middleware]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/middleware + +Verify a Basic Auth username/password pair against the configured credentials. +Uses a constant-time comparison to prevent timing attacks. Useful for custom +auth flows where you need to check credentials outside a middleware context. + + +Returns `false` immediately when Basic Auth is not configured (i.e., +`basicAuth` was not passed to the constructor). For full request validation +including Bearer and API key fallbacks, use +[`validate()`][ref-validate] or attach +[`middleware()`][ref-middleware] to your Hono app. + + +## **Parameters** + + + The username to verify. + + + + The password to verify. + + +## **Returns** + +`boolean` -- `true` if the credentials match; `false` if they don't, or if +Basic Auth was not configured. + +## **Example** + +```typescript {12} +import { AuthHandler } from '@signalwire/sdk'; + +const auth = new AuthHandler({ + basicAuth: ['admin', 'secret-password'], +}); + +function login(username: string, password: string) { + if (auth.verifyBasicAuth(username, password)) { + return { ok: true, user: username }; + } + return { ok: false }; +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-bearer-token.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-bearer-token.mdx new file mode 100644 index 000000000..48d073dff --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/auth-handler/verify-bearer-token.mdx @@ -0,0 +1,44 @@ +--- +title: "verifyBearerToken" +slug: /reference/typescript/agents/configuration/auth-handler/verify-bearer-token +description: "Verify a Bearer token against the configured token." +max-toc-depth: 3 +--- + +[ref-validate]: /docs/server-sdks/reference/typescript/agents/configuration/auth-handler/validate + +Verify a Bearer token against the configured token. Uses a constant-time +comparison to prevent timing attacks. Returns `false` immediately when Bearer +token auth is not configured. + + +Pass the raw token -- do **not** include the `"Bearer "` prefix. For full +header-based validation (including prefix parsing), use +[`validate()`][ref-validate]. + + +## **Parameters** + + + The Bearer token string to verify, without the `"Bearer "` prefix. + + +## **Returns** + +`boolean` -- `true` if the token matches; `false` if it doesn't, or if Bearer +auth was not configured. + +## **Example** + +```typescript {8} +import { AuthHandler } from '@signalwire/sdk'; + +const auth = new AuthHandler({ + bearerToken: 'sk_live_abc123', +}); + +function authorize(header: string | undefined) { + const token = header?.replace(/^Bearer\s+/i, '') ?? ''; + return auth.verifyBearerToken(token); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/find-config-file.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/find-config-file.mdx new file mode 100644 index 000000000..03139a0ab --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/find-config-file.mdx @@ -0,0 +1,54 @@ +--- +title: "findConfigFile" +slug: /reference/typescript/agents/configuration/config-loader/find-config-file +description: "Find a config file path without loading it (static helper)." +max-toc-depth: 3 +--- + +[ref-search]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/search + +Static helper that searches for a config file and returns the first match's +absolute path without loading it. Useful for detecting whether a configuration +exists before deciding whether to instantiate a `ConfigLoader`. For searching +from an instance that also loads on match, use +[`search()`][ref-search] instead. + +The search order is: + +1. `{serviceName}_config.json` (cwd) and `.swml/{serviceName}_config.json` (if `serviceName`) +2. Each path in `additionalPaths` (if provided) +3. `config.json` +4. `agent_config.json` +5. `.swml/config.json` +6. `~/.swml/config.json` +7. `/etc/swml/config.json` + +## **Parameters** + + + Service name. When provided, service-specific config filenames are checked + before defaults. + + + + Extra file paths to check between service-specific and default locations. + + +## **Returns** + +`string | null` -- absolute path of the first existing config file, or `null` +if none match. + +## **Example** + +```typescript {4} +import { ConfigLoader } from '@signalwire/sdk'; + +const path = ConfigLoader.findConfigFile('my-service'); +if (path) { + const loader = new ConfigLoader(path); + console.log(`Loaded from ${loader.getFilePath()}`); +} else { + console.log('No config file found'); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config-file.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config-file.mdx new file mode 100644 index 000000000..38fbb92ec --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config-file.mdx @@ -0,0 +1,30 @@ +--- +title: "getConfigFile" +slug: /reference/typescript/agents/configuration/config-loader/get-config-file +description: "Return the path of the loaded config file (Python-compat alias for getFilePath)." +max-toc-depth: 3 +--- + +[ref-getfilepath]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/get-file-path + +Return the absolute path of the loaded config file, or `null` when the loader +was populated via `loadFromObject()`. Python-compat alias for +[`getFilePath()`][ref-getfilepath]; the two are functionally identical. + +## **Returns** + +`string | null` -- the file path, or `null` if config was loaded from an +object. + +## **Example** + +```typescript {4} +import { ConfigLoader } from '@signalwire/sdk'; + +const loader = new ConfigLoader('config.json'); +console.log(loader.getConfigFile()); // absolute path + +const inMemory = new ConfigLoader(); +inMemory.loadFromObject({ server: { port: 3000 } }); +console.log(inMemory.getConfigFile()); // null +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config.mdx new file mode 100644 index 000000000..a608ba163 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-config.mdx @@ -0,0 +1,26 @@ +--- +title: "getConfig" +slug: /reference/typescript/agents/configuration/config-loader/get-config +description: "Return a shallow copy of the entire configuration (Python-compat alias for getAll)." +max-toc-depth: 3 +--- + +[ref-getall]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/get-all + +Return a shallow copy of the entire loaded configuration. Python-compat alias +for [`getAll()`][ref-getall]; the two are functionally identical. Use +`getConfig()` when porting from the Python SDK. + +## **Returns** + +`Record` -- a shallow copy of the top-level config object. + +## **Example** + +```typescript {4} +import { ConfigLoader } from '@signalwire/sdk'; + +const loader = new ConfigLoader('config.json'); +const config = loader.getConfig(); +console.log(Object.keys(config)); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-section.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-section.mdx new file mode 100644 index 000000000..c940899bb --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/get-section.mdx @@ -0,0 +1,42 @@ +--- +title: "getSection" +slug: /reference/typescript/agents/configuration/config-loader/get-section +description: "Get a configuration section with environment variables substituted." +max-toc-depth: 3 +--- + +[ref-substitutevars]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/substitute-vars +[ref-get]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/get + +Get an entire top-level configuration section with all +`${VAR|default}` environment-variable references substituted. Internally +calls [`substituteVars()`][ref-substitutevars] on the resolved value. + +Returns an empty object (`{}`) if the section does not exist or is not an +object. For single-value lookups, use [`get()`][ref-get] instead. + +## **Parameters** + + + The top-level section name (e.g., `"security"`, `"server"`). + + +## **Returns** + +`Record` -- the configuration section, with env-var +substitution applied; empty object if the section is missing or not an object. + +## **Example** + +```typescript {8} +import { ConfigLoader } from '@signalwire/sdk'; + +// Given config.json: +// { "server": { "host": "${HOST|0.0.0.0}", "port": "${PORT|3000}" } } + +const loader = new ConfigLoader('config.json'); + +const serverCfg = loader.getSection('server'); +console.log(serverCfg.host); // "0.0.0.0" (or HOST env var) +console.log(serverCfg.port); // 3000 (coerced to number) +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/has-config.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/has-config.mdx new file mode 100644 index 000000000..abfcf2b66 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/has-config.mdx @@ -0,0 +1,39 @@ +--- +title: "hasConfig" +slug: /reference/typescript/agents/configuration/config-loader/has-config +description: "Check whether any configuration data is loaded (file or object)." +max-toc-depth: 3 +--- + +[ref-getfilepath]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/get-file-path + +Check whether any configuration data has been loaded. Returns `true` if a file +was loaded or data was set via `loadFromObject()`. + + +**Deliberate deviation from the Python SDK.** Python's `has_config()` returns +`True` only when a *file* was loaded. The TypeScript version also returns +`true` for object-loaded data, because `loadFromObject()` is a TS-only entry +point with no Python equivalent -- treating object-loaded data as "configured" +matches the TS API surface. + +If you specifically need file-load detection, check +`loader.getFilePath() !== null` via +[`getFilePath()`][ref-getfilepath]. + + +## **Returns** + +`boolean` -- `true` if any configuration data exists (from file or object), +`false` if the loader is empty. + +## **Example** + +```typescript {4} +import { ConfigLoader } from '@signalwire/sdk'; + +const loader = new ConfigLoader('config.json'); +if (loader.hasConfig()) { + console.log('Config loaded, proceed with startup'); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx index 469e34dda..384167fab 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/index.mdx @@ -69,6 +69,30 @@ const port = config.get('server.port', 3000); Load configuration from a plain object instead of a file. + + Find a config file without loading it (static). + + + Return the full config (Python-compat alias for getAll). + + + Return the loaded file path (Python-compat alias for getFilePath). + + + Check whether any configuration data is loaded. + + + Get a top-level section with env-var substitution. + + + Recursively substitute ${VAR} references with coercion. + + + Merge config with prefixed environment variables. + + + Interpolate ${VAR} in a raw string without coercion. + ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/interpolate-env-vars.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/interpolate-env-vars.mdx new file mode 100644 index 000000000..32a0bceba --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/interpolate-env-vars.mdx @@ -0,0 +1,42 @@ +--- +title: "interpolateEnvVars" +slug: /reference/typescript/agents/configuration/config-loader/interpolate-env-vars +description: "Interpolate ${VAR|default} patterns in a raw string." +max-toc-depth: 3 +--- + +[ref-substitutevars]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/substitute-vars + +Interpolate `${VAR|default}` environment-variable references in a raw string. +Unlike [`substituteVars()`][ref-substitutevars], this method does not apply +type coercion -- the result is always a string. Missing env vars with no +default resolve to an empty string. + + +This is a TS-specific helper (no Python SDK equivalent). Use it when building +URLs, log messages, or any string output where numeric/boolean coercion would +corrupt the value. + + +## **Parameters** + + + The string containing `${VAR}` or `${VAR|default}` references. + + +## **Returns** + +`string` -- the input with all env var references resolved. + +## **Example** + +```typescript {4} +import { ConfigLoader } from '@signalwire/sdk'; + +const loader = new ConfigLoader(); +const url = loader.interpolateEnvVars( + 'https://${HOST|api.example.com}/v1/${VERSION|latest}', +); +console.log(url); +// "https://api.example.com/v1/latest" (defaults used when env vars unset) +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/merge-with-env.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/merge-with-env.mdx new file mode 100644 index 000000000..b0fb2aea5 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/merge-with-env.mdx @@ -0,0 +1,53 @@ +--- +title: "mergeWithEnv" +slug: /reference/typescript/agents/configuration/config-loader/merge-with-env +description: "Merge configuration with prefix-matched environment variables." +max-toc-depth: 3 +--- + +[ref-substitutevars]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/substitute-vars + +Merge the loaded configuration with environment variables whose names start +with a given prefix. Config file values take precedence over environment +variables -- env vars only fill in keys that are missing from the config. + +Matching env var names are: + +1. Stripped of the prefix +2. Lowercased +3. Split on `_` to produce a nested object path + +For example, with prefix `SWML_`, `SWML_SERVER_PORT=3000` produces +`{ server: { port: "3000" } }`. + + +All values inherited from env vars are written as strings (Node returns +`process.env` values as strings). Apply +[`substituteVars()`][ref-substitutevars] to the result if you need type +coercion. + + +## **Parameters** + + + Prefix for environment variables to consider. + + +## **Returns** + +`Record` -- the merged configuration (file + prefixed env +vars) with `${VAR}` substitution applied to file values. + +## **Example** + +```typescript {7} +import { ConfigLoader } from '@signalwire/sdk'; + +// Given config.json: { "server": { "host": "0.0.0.0" } } +// And env: SWML_SERVER_PORT=3000 + +const loader = new ConfigLoader('config.json'); +const merged = loader.mergeWithEnv(); +console.log(merged); +// { server: { host: "0.0.0.0", port: "3000" } } +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/substitute-vars.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/substitute-vars.mdx new file mode 100644 index 000000000..07f600a3d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/config-loader/substitute-vars.mdx @@ -0,0 +1,55 @@ +--- +title: "substituteVars" +slug: /reference/typescript/agents/configuration/config-loader/substitute-vars +description: "Recursively substitute environment variables in any value." +max-toc-depth: 3 +--- + +[ref-interpolateenvvars]: /docs/server-sdks/reference/typescript/agents/configuration/config-loader/interpolate-env-vars + +Recursively substitute `${VAR|default}` environment-variable references in any +value. Walks strings, objects, and arrays. After substitution, resulting +strings are coerced to: + +- `true` / `false` when they equal `"true"` / `"false"` (case-insensitive) +- an integer when they match `/^\d+$/` +- a float when they match `/^\d+\.\d+$/` +- otherwise left as a string + + +For raw string interpolation without type coercion, use +[`interpolateEnvVars()`][ref-interpolateenvvars] instead. + + +## **Parameters** + + + The value to process. Can be a string, object, array, or primitive. + + + + Maximum recursion depth. Throws `Error("Maximum variable substitution depth + exceeded")` when the limit is reached. + + +## **Returns** + +The input value with all environment variables substituted. Type depends on +the input and the coercion rules above. + +## **Example** + +```typescript {5} +import { ConfigLoader } from '@signalwire/sdk'; + +const loader = new ConfigLoader(); +const config = { + port: '${PORT|8080}', + debug: '${DEBUG|false}', + name: '${SERVICE_NAME|my-service}', +}; + +const resolved = loader.substituteVars(config); +console.log(resolved); +// { port: 8080, debug: false, name: "my-service" } (types coerced) +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/add-pom-as-subsection.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/add-pom-as-subsection.mdx new file mode 100644 index 000000000..38c3f1960 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/add-pom-as-subsection.mdx @@ -0,0 +1,52 @@ +--- +title: "addPomAsSubsection" +slug: /reference/typescript/agents/pom-builder/add-pom-as-subsection +description: "Append another PomBuilder's sections as subsections of a target section." +max-toc-depth: 3 +--- + +[ref-findsection]: /docs/server-sdks/reference/typescript/agents/pom-builder/find-section + +Append every top-level section of another `PomBuilder` as a subsection of a +target section in this builder. Useful for composing prompts assembled +separately into a single document. + + +Throws `Error("No section with title '' found.")` when `target` is a +string and no section with that title exists. For deeper lookups, resolve the +section yourself via [`findSection()`][ref-findsection] and pass the +`PomSection` directly. + + +## **Parameters** + + + The target section to append into. Pass a title string for top-level + sections, or a `PomSection` instance (from `findSection()`) for nested + sections. + + + + The builder whose sections should be appended. + + +## **Returns** + +`this` -- returns the builder for fluent chaining. + +## **Example** + +```typescript {11} +import { PomBuilder } from '@signalwire/sdk'; + +const subPom = new PomBuilder(); +subPom.addSection('Policy A', { body: 'Always greet by name.' }); +subPom.addSection('Policy B', { body: 'Escalate billing issues.' }); + +const main = new PomBuilder(); +main.addSection('Introduction', { body: 'You are a helpful agent.' }); +main.addSection('Policies'); + +main.addPomAsSubsection('Policies', subPom); +console.log(main.renderMarkdown()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/from-sections.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/from-sections.mdx new file mode 100644 index 000000000..65b74a542 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/from-sections.mdx @@ -0,0 +1,40 @@ +--- +title: "fromSections" +slug: /reference/typescript/agents/pom-builder/from-sections +description: "Create a new PomBuilder from an array of section data objects (static)." +max-toc-depth: 3 +--- + +[ref-tojson]: /docs/server-sdks/reference/typescript/agents/pom-builder/to-json +[ref-todict]: /docs/server-sdks/reference/typescript/agents/pom-builder/to-dict + +Static factory method that reconstructs a `PomBuilder` from an array of +`PomSectionData` objects. Use this to restore a prompt serialized via +[`toJson()`][ref-tojson] or +[`toDict()`][ref-todict]. + +## **Parameters** + + + Array of section data objects. Each must include at minimum a `title`, and + may include `body`, `bullets`, `numbered`, `numberedBullets`, and nested + `subsections`. + + +## **Returns** + +`PomBuilder` -- a new builder populated with the given sections. + +## **Example** + +```typescript {8} +import { PomBuilder } from '@signalwire/sdk'; + +const data = [ + { title: 'Intro', body: 'Welcome.' }, + { title: 'Rules', bullets: ['Be nice.', 'Stay on topic.'] }, +]; + +const pom = PomBuilder.fromSections(data); +console.log(pom.renderMarkdown()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/index.mdx index e4f3a3967..7d2495ef0 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/index.mdx @@ -49,9 +49,24 @@ can render to Markdown format. Render the POM as a Markdown string. + + Render the POM as an XML document. + Convert the POM to a list of section objects. + + Serialize all sections to a JSON string. + + + Create a new PomBuilder from section data (static). + + + Append another PomBuilder's sections as subsections. + + + Clear all sections and start over. + ## **Examples** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/render-xml.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/render-xml.mdx new file mode 100644 index 000000000..357afeba9 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/render-xml.mdx @@ -0,0 +1,43 @@ +--- +title: "renderXml" +slug: /reference/typescript/agents/pom-builder/render-xml +description: "Render all sections as a combined XML document." +max-toc-depth: 3 +--- + +[ref-rendermarkdown]: /docs/server-sdks/reference/typescript/agents/pom-builder/render-markdown + +Render all top-level sections as a single XML document wrapped in a +`` root element. Each section becomes a nested XML element with its +title as the tag text or attribute, and bullets/numbered lists rendered as +child elements. + + +The markdown variant -- [`renderMarkdown()`][ref-rendermarkdown] -- is the +default render format. Use `renderXml()` only for prompts where the +downstream LLM or template expects XML-structured input. + + +## **Returns** + +`string` -- XML document starting with `` +and wrapping all sections in a `` root. + +## **Example** + +```typescript {7} +import { PomBuilder } from '@signalwire/sdk'; + +const pom = new PomBuilder(); +pom.addSection('Intro', { body: 'Welcome.' }); +pom.addSection('Rules', { bullets: ['Be nice.', 'Stay on topic.'] }); + +console.log(pom.renderXml()); +// +// +//
+// Welcome. +//
+// ... +//
+``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/reset.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/reset.mdx new file mode 100644 index 000000000..e57a90c98 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/reset.mdx @@ -0,0 +1,29 @@ +--- +title: "reset" +slug: /reference/typescript/agents/pom-builder/reset +description: "Clear all sections and return the builder to its initial empty state." +max-toc-depth: 3 +--- + +Clear all top-level sections from the builder, returning it to an empty +initial state. Also clears the internal section lookup map used by +[`hasSection()`](/docs/server-sdks/reference/typescript/agents/pom-builder/has-section) +and +[`getSection()`](/docs/server-sdks/reference/typescript/agents/pom-builder/get-section). + +## **Returns** + +`this` -- returns the builder for fluent chaining. + +## **Example** + +```typescript {7} +import { PomBuilder } from '@signalwire/sdk'; + +const pom = new PomBuilder(); +pom.addSection('Intro', { body: 'Welcome.' }); +pom.addSection('Rules', { bullets: ['Be nice.', 'Stay on topic.'] }); + +pom.reset(); +console.log(pom.renderMarkdown()); // "" (empty) +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/to-json.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/to-json.mdx new file mode 100644 index 000000000..a1206ac7c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/pom-builder/to-json.mdx @@ -0,0 +1,32 @@ +--- +title: "toJson" +slug: /reference/typescript/agents/pom-builder/to-json +description: "Serialize all sections to a JSON string." +max-toc-depth: 3 +--- + +[ref-todict]: /docs/server-sdks/reference/typescript/agents/pom-builder/to-dict +[ref-fromsections]: /docs/server-sdks/reference/typescript/agents/pom-builder/from-sections + +Serialize all top-level sections to a JSON string. Internally calls +[`toDict()`][ref-todict] and wraps the result in `JSON.stringify()`. Use this +to persist a prompt for later restoration via +[`PomBuilder.fromSections()`][ref-fromsections]. + +## **Returns** + +`string` -- JSON-serialized array of section data. + +## **Example** + +```typescript {7} +import { PomBuilder } from '@signalwire/sdk'; + +const pom = new PomBuilder(); +pom.addSection('Intro', { body: 'Welcome.' }); +pom.addSection('Rules', { bullets: ['Be nice.', 'Stay on topic.'] }); + +const json = pom.toJson(); +// Persist, send over the wire, etc. +const restored = PomBuilder.fromSections(JSON.parse(json)); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/define-tool.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/define-tool.mdx new file mode 100644 index 000000000..706ccea10 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/define-tool.mdx @@ -0,0 +1,79 @@ +--- +title: "defineTool" +slug: /reference/typescript/agents/skill-base/define-tool +description: "Imperatively register a tool with this skill." +max-toc-depth: 3 +--- + +[ref-gettools]: /docs/server-sdks/reference/typescript/agents/skill-base/get-tools + +Imperatively register a SWAIG tool with this skill. The tool definition is +merged with the skill's `swaigFields` (explicit fields on `toolDef` take +precedence) and then appended to the internal dynamic tool list. The default +[`getTools()`][ref-gettools] implementation returns these dynamic tools at +SWML render time. + + +Use `defineTool()` from `setup()` when the tool shape depends on config +evaluated at setup time (e.g., an API key that changes the available +actions). Skills with a static tool list should override `getTools()` +directly instead. + + +## **Parameters** + + + The tool definition. Must include at minimum `name`, `description`, + `parameters`, and `handler`. + + + + + Tool name exposed to the AI. + + + + One-sentence summary the AI sees when choosing whether to call the tool. + + + + JSON-Schema-style parameter description. + + + + Async function invoked when the AI calls the tool. + + + + When `true`, the tool requires signed tokens for invocation. + + + +## **Returns** + +`void` + +## **Example** + +```typescript {9-17} +import { SkillBase, FunctionResult } from '@signalwire/sdk'; + +export class TimeSkill extends SkillBase { + static SKILL_NAME = 'time'; + static SKILL_DESCRIPTION = 'Tells the current time.'; + + async setup(): Promise { + const timezone = this.getConfig('timezone', 'UTC'); + this.defineTool({ + name: 'get_time', + description: `Get the current time in ${timezone}.`, + parameters: { type: 'object', properties: {} }, + handler: async () => { + const now = new Date().toLocaleString('en-US', { timeZone: timezone }); + return new FunctionResult().setResponse(`It's ${now}`); + }, + }); + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-agent.mdx new file mode 100644 index 000000000..097d2658e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-agent.mdx @@ -0,0 +1,40 @@ +--- +title: "getAgent" +slug: /reference/typescript/agents/skill-base/get-agent +description: "Get the agent this skill is attached to." +max-toc-depth: 3 +--- + +[ref-setagent]: /docs/server-sdks/reference/typescript/agents/skill-base/set-agent + +Get the [`AgentBase`](/docs/server-sdks/reference/typescript/agents/agent-base) +that owns this skill instance. Called internally from `setup()` and tool +handlers to interact with the agent's configuration, tools, or global data. + + +Throws `Error` when called before the skill has been attached. The +`SkillManager` calls [`setAgent()`][ref-setagent] as part of +`addSkill()`; only call `getAgent()` from `setup()` or tool handlers where +attachment is guaranteed. + + +## **Returns** + +`AgentBase` -- the owning agent. + +## **Example** + +```typescript {9} +import { SkillBase } from '@signalwire/sdk'; + +export class MySkill extends SkillBase { + static SKILL_NAME = 'my-skill'; + static SKILL_DESCRIPTION = 'An example skill'; + + async setup(): Promise { + const agent = this.getAgent(); + agent.addHint('Prefer concise answers.'); + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-config.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-config.mdx new file mode 100644 index 000000000..d9de5474c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/get-config.mdx @@ -0,0 +1,44 @@ +--- +title: "getConfig" +slug: /reference/typescript/agents/skill-base/get-config +description: "Look up a configuration value passed to the skill's constructor." +max-toc-depth: 3 +--- + +Look up a configuration value by key, with an optional default. The `config` +object is whatever was passed to the skill's constructor (typed as +`SkillConfig`, a string-keyed record). Values are returned as-is; the caller +provides the type argument for casting. + +## **Parameters** + + + The configuration key to look up. + + + + Value to return when the key is not present. The result is cast to `T`. + + +## **Returns** + +`T` -- the configured value cast to the generic type, or the default value. + +## **Example** + +```typescript {9,10} +import { SkillBase } from '@signalwire/sdk'; + +export class WeatherSkill extends SkillBase { + static SKILL_NAME = 'weather'; + static SKILL_DESCRIPTION = 'Fetches current weather for a city.'; + + async setup(): Promise { + const apiKey = this.getConfig('api_key'); + const units = this.getConfig<'metric' | 'imperial'>('units', 'metric'); + if (!apiKey) return false; + this.logger.info(`Weather skill configured in ${units} units`); + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-env-vars.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-env-vars.mdx new file mode 100644 index 000000000..a5307e5d4 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-env-vars.mdx @@ -0,0 +1,37 @@ +--- +title: "hasAllEnvVars" +slug: /reference/typescript/agents/skill-base/has-all-env-vars +description: "Check whether all required environment variables are set." +max-toc-depth: 3 +--- + +[ref-validateenvvars]: /docs/server-sdks/reference/typescript/agents/skill-base/validate-env-vars + +Convenience wrapper around +[`validateEnvVars()`][ref-validateenvvars] that returns a boolean. Mirrors the +Python SDK's `validate_env_vars() -> bool` return shape. Checks each entry in +the skill class's `REQUIRED_ENV_VARS` static array against `process.env`. + +## **Returns** + +`boolean` -- `true` if every required env var is present, `false` otherwise. + +## **Example** + +```typescript {10} +import { SkillBase } from '@signalwire/sdk'; + +export class WeatherSkill extends SkillBase { + static SKILL_NAME = 'weather'; + static SKILL_DESCRIPTION = 'Fetches current weather.'; + static REQUIRED_ENV_VARS = ['WEATHER_API_KEY']; + + async setup(): Promise { + if (!this.hasAllEnvVars()) { + this.logger.error('Missing required environment variables'); + return false; + } + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-packages.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-packages.mdx new file mode 100644 index 000000000..dc06017f1 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/has-all-packages.mdx @@ -0,0 +1,38 @@ +--- +title: "hasAllPackages" +slug: /reference/typescript/agents/skill-base/has-all-packages +description: "Check whether all required packages are importable." +max-toc-depth: 3 +--- + +[ref-validatepackages]: /docs/server-sdks/reference/typescript/agents/skill-base/validate-packages + +Convenience wrapper around +[`validatePackages()`][ref-validatepackages] that returns a boolean. Mirrors +the Python SDK's `validate_packages() -> bool` return shape. Because it +performs dynamic `import()` calls, the method is async. + +## **Returns** + +`Promise` -- `true` if every package in `REQUIRED_PACKAGES` imports +successfully, `false` otherwise. + +## **Example** + +```typescript {9} +import { SkillBase } from '@signalwire/sdk'; + +export class ScraperSkill extends SkillBase { + static SKILL_NAME = 'scraper'; + static SKILL_DESCRIPTION = 'Scrapes web pages.'; + static REQUIRED_PACKAGES = ['cheerio']; + + async setup(): Promise { + if (!(await this.hasAllPackages())) { + this.logger.error('Missing required packages'); + return false; + } + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx index 5b2a67da1..7b1bb318b 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/index.mdx @@ -158,6 +158,27 @@ constants — not from constructor arguments. Validate that required environment variables are set. + + Check whether all required env vars are present. + + + Validate that required packages can be imported. + + + Check whether all required packages are importable. + + + Look up a configuration value by key. + + + Get the agent this skill is attached to. + + + Attach the skill to an agent. + + + Imperatively register a tool with this skill. + ### defineTool (protected) diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/set-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/set-agent.mdx new file mode 100644 index 000000000..19cb6332f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/set-agent.mdx @@ -0,0 +1,42 @@ +--- +title: "setAgent" +slug: /reference/typescript/agents/skill-base/set-agent +description: "Attach the skill to an agent (called by the SkillManager)." +max-toc-depth: 3 +--- + +[ref-getagent]: /docs/server-sdks/reference/typescript/agents/skill-base/get-agent +[ref-skillmanager]: /docs/server-sdks/reference/typescript/agents/skill-manager + +Attach this skill to an [`AgentBase`](/docs/server-sdks/reference/typescript/agents/agent-base). +Called by the [`SkillManager`][ref-skillmanager] during +`agent.addSkill()` before `setup()` runs, so [`getAgent()`][ref-getagent] is +safe from within `setup()` and tool handlers. + + +Normally not called directly. If you are implementing a custom skill loader +that bypasses `addSkill()`, call this yourself before invoking `setup()`. + + +## **Parameters** + + + The agent instance that owns this skill. + + +## **Returns** + +`void` + +## **Example** + +```typescript {7} +import { AgentBase, SkillBase } from '@signalwire/sdk'; + +class InlineSkill extends SkillBase { /* ... */ } + +const agent = new AgentBase({ name: 'demo' }); +const skill = new InlineSkill(); +skill.setAgent(agent); +await skill.setup(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/validate-packages.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/validate-packages.mdx new file mode 100644 index 000000000..317776c15 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-base/validate-packages.mdx @@ -0,0 +1,46 @@ +--- +title: "validatePackages" +slug: /reference/typescript/agents/skill-base/validate-packages +description: "Validate that all required packages can be imported." +max-toc-depth: 3 +--- + +[ref-hasallpackages]: /docs/server-sdks/reference/typescript/agents/skill-base/has-all-packages + +Attempt to `import()` every package listed in the skill class's +`REQUIRED_PACKAGES` static array. Returns the list of packages that failed to +import (empty array means everything is available). Python parity: +`validate_packages()` at `core/skill_base.py:112-124`. + +Logs an error listing every missing package when the result is non-empty. + + +For a boolean check, use [`hasAllPackages()`][ref-hasallpackages]. Because +the TS version uses dynamic `import()`, this method is async. + + +## **Returns** + +`Promise` -- array of package names that failed to import. Empty when +all packages are available. + +## **Example** + +```typescript {9} +import { SkillBase } from '@signalwire/sdk'; + +export class ScraperSkill extends SkillBase { + static SKILL_NAME = 'scraper'; + static SKILL_DESCRIPTION = 'Scrapes web pages.'; + static REQUIRED_PACKAGES = ['cheerio']; + + async setup(): Promise { + const missing = await this.validatePackages(); + if (missing.length > 0) { + this.logger.error(`Install: npm install ${missing.join(' ')}`); + return false; + } + return true; + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx index da2c94506..26766dee2 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/index.mdx @@ -79,6 +79,9 @@ Most users should use `AgentBase.addSkill()`, `AgentBase.removeSkill()`, and Remove all skills. + + Read-only map of loaded skill instances (getter). + ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/loaded-skills.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/loaded-skills.mdx new file mode 100644 index 000000000..4d3d40432 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-manager/loaded-skills.mdx @@ -0,0 +1,43 @@ +--- +title: "loadedSkills" +slug: /reference/typescript/agents/skill-manager/loaded-skills +description: "Read-only view of all loaded skill instances keyed by instance key." +max-toc-depth: 3 +--- + +[ref-listskillkeys]: /docs/server-sdks/reference/typescript/agents/skill-manager/list-skill-keys +[ref-getskill]: /docs/server-sdks/reference/typescript/agents/skill-manager/get-skill + +Read-only getter exposing every loaded skill instance keyed by its instance +key (e.g., `"weather"` or `"weather#main_tool"` for multi-instance skills). +Use this to iterate or inspect loaded skills without mutating the internal +map. + +Python equivalent: `self.loaded_skills` (public `Dict[str, SkillBase]`). + + +The returned `ReadonlyMap` is a live view of the internal map, not a copy. +Iterating concurrently with `addSkill()` / `removeSkill()` can see updates +as they happen. For a snapshot of skill keys, use +[`listSkillKeys()`][ref-listskillkeys]; for a single lookup, use +[`getSkill()`][ref-getskill]. + + +## **Type** + +`ReadonlyMap` + +## **Example** + +```typescript {5} +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ name: 'demo' }); +await agent.addSkillByName('weather'); +await agent.addSkillByName('datetime'); + +const manager = agent.getSkillManager(); +for (const [key, skill] of manager.loadedSkills) { + console.log(`${key} -> ${(skill.constructor as typeof skill).SKILL_NAME}`); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-skill-class.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-skill-class.mdx new file mode 100644 index 000000000..a5fef61a8 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/get-skill-class.mdx @@ -0,0 +1,42 @@ +--- +title: "getSkillClass" +slug: /reference/typescript/agents/skill-registry/get-skill-class +description: "Look up a registered skill class by name." +max-toc-depth: 3 +--- + +[ref-create]: /docs/server-sdks/reference/typescript/agents/skill-registry/create +[ref-has]: /docs/server-sdks/reference/typescript/agents/skill-registry/has + +Look up a registered skill class by its `SKILL_NAME`. Returns the class +reference itself (not an instance); use +[`create()`][ref-create] to get an instance. Returns `undefined` if no skill +is registered under that name -- for a boolean check use +[`has()`][ref-has]. + +Matches Python's `get_skill_class(skill_name)` (`registry.py:196-203`). + +## **Parameters** + + + The registered skill name (the skill class's static `SKILL_NAME`). + + +## **Returns** + +`typeof SkillBase | undefined` -- the skill class, or `undefined` if not +registered. + +## **Example** + +```typescript {5} +import { SkillRegistry } from '@signalwire/sdk'; + +const registry = SkillRegistry.getInstance(); + +const WeatherSkill = registry.getSkillClass('weather'); +if (WeatherSkill) { + console.log(WeatherSkill.SKILL_DESCRIPTION); + console.log(WeatherSkill.REQUIRED_ENV_VARS); +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx index 8e4aef2bf..8887d2936 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/index.mdx @@ -66,6 +66,15 @@ import { SkillRegistry } from '@signalwire/sdk'; Remove all registrations. + + Look up a registered skill class by name. + + + List all registered skills with full metadata. + + + Reset the global singleton (test helper). + ## **Properties** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-skills.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-skills.mdx new file mode 100644 index 000000000..44fef9af5 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/list-skills.mdx @@ -0,0 +1,69 @@ +--- +title: "listSkills" +slug: /reference/typescript/agents/skill-registry/list-skills +description: "List all registered skills with their full metadata." +max-toc-depth: 3 +--- + +[ref-listregistered]: /docs/server-sdks/reference/typescript/agents/skill-registry/list-registered + +List every registered skill with its full metadata. Each entry includes the +name, description, version, multi-instance flag, required env vars, required +packages, and parameter schema. Use [`listRegistered()`][ref-listregistered] +for just the names. + +Matches Python's `list_skills()` shape (`registry.py:205-227`) with +TS-idiomatic camelCase keys. + +## **Returns** + +`SkillSchemaInfo[]` -- array of metadata objects. + + + Each entry has the following shape: + + + + + The skill's `SKILL_NAME`. + + + + The skill's `SKILL_DESCRIPTION`. + + + + The skill's `SKILL_VERSION`. + + + + Whether the skill supports multiple instances. + + + + Required environment variable names. + + + + Required npm package names. + + + + Parameter schema describing the config the skill accepts. + + + +## **Example** + +```typescript {4} +import { SkillRegistry } from '@signalwire/sdk'; + +const registry = SkillRegistry.getInstance(); +const skills = registry.listSkills(); +for (const s of skills) { + console.log(`${s.name} v${s.version} - ${s.description}`); + if (s.requiredEnvVars.length > 0) { + console.log(` Needs: ${s.requiredEnvVars.join(', ')}`); + } +} +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/reset-instance.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/reset-instance.mdx new file mode 100644 index 000000000..aaa181934 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skill-registry/reset-instance.mdx @@ -0,0 +1,45 @@ +--- +title: "resetInstance" +slug: /reference/typescript/agents/skill-registry/reset-instance +description: "Reset the global SkillRegistry singleton (test helper)." +max-toc-depth: 3 +--- + +[ref-getinstance]: /docs/server-sdks/reference/typescript/agents/skill-registry/get-instance + +Static helper that clears the process-wide `SkillRegistry` singleton. The next +call to [`getInstance()`][ref-getinstance] constructs a fresh registry with +no registered skills, cleared search paths, and no locked names. + + +Intended for use in test suites that need a clean registry per test case. +Calling this in production is almost always a bug -- every previously +registered skill is forgotten, and any code still holding the old instance +reference will diverge from the new one. + + +## **Returns** + +`void` + +## **Example** + +```typescript {10} +import { SkillRegistry } from '@signalwire/sdk'; + +describe('MySkill', () => { + beforeEach(() => { + SkillRegistry.resetInstance(); + const registry = SkillRegistry.getInstance(); + registry.register(MySkill); + }); + + afterAll(() => { + SkillRegistry.resetInstance(); + }); + + it('registers correctly', () => { + expect(SkillRegistry.getInstance().has('my-skill')).toBe(true); + }); +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/add-section.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/add-section.mdx new file mode 100644 index 000000000..2537f04c0 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/add-section.mdx @@ -0,0 +1,42 @@ +--- +title: "addSection" +slug: /reference/typescript/agents/swml-builder/add-section +description: "Add a new empty named section to the SWML document." +max-toc-depth: 3 +--- + +[ref-addverbtosection]: /docs/server-sdks/reference/typescript/agents/swml-builder/add-verb-to-section + +Add a new empty named section to the SWML document. Sections are named +containers for ordered lists of verbs. Every document starts with a `main` +section -- use this method to create additional sections (e.g., a `transfer` +flow). + +Silently no-ops if a section with the given name already exists. Follow up +with [`addVerbToSection()`][ref-addverbtosection] to populate the section. + +## **Parameters** + + + Name of the section to create. + + +## **Returns** + +`this` -- returns the builder for fluent chaining. + +## **Example** + +```typescript {5} +import { SwmlBuilder } from '@signalwire/sdk'; + +const builder = new SwmlBuilder(); +builder.answer(); +builder.addSection('fallback'); +builder.addVerbToSection('fallback', 'play', { + url: 'https://example.com/sorry.mp3', +}); +builder.addVerbToSection('fallback', 'hangup', {}); + +console.log(builder.renderDocument()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/build.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/build.mdx new file mode 100644 index 000000000..358cf3f5d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/build.mdx @@ -0,0 +1,32 @@ +--- +title: "build" +slug: /reference/typescript/agents/swml-builder/build +description: "Build and return the SWML document as an object (Python-compat alias for getDocument)." +max-toc-depth: 3 +--- + +[ref-getdocument]: /docs/server-sdks/reference/typescript/agents/swml-builder/get-document +[ref-render]: /docs/server-sdks/reference/typescript/agents/swml-builder/render + +Return the SWML document as a plain object. Python-compat alias for +[`getDocument()`][ref-getdocument]; the two are functionally identical. Use +`build()` when porting from the Python SDK. For a JSON string, use +[`render()`][ref-render] or `renderDocument()`. + +## **Returns** + +`Record` -- the SWML document with `version` and `sections` +keys. + +## **Example** + +```typescript {6} +import { SwmlBuilder } from '@signalwire/sdk'; + +const builder = new SwmlBuilder(); +builder.answer(); +builder.ai({ prompt: { text: 'You are a helpful assistant.' } }); + +const doc = builder.build(); +console.log(JSON.stringify(doc, null, 2)); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/document.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/document.mdx new file mode 100644 index 000000000..3155a9f1e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/document.mdx @@ -0,0 +1,34 @@ +--- +title: "document" +slug: /reference/typescript/agents/swml-builder/document +description: "Read-only accessor for the underlying SWML document." +max-toc-depth: 3 +--- + +[ref-getdocument]: /docs/server-sdks/reference/typescript/agents/swml-builder/get-document + +Read-only getter for the underlying SWML document object. Provides direct +access to the mutable document (the returned reference is the internal object, +not a copy). Equivalent to the Python SDK's `service` property on `SWMLBuilder`. + + +Prefer [`getDocument()`][ref-getdocument] when you want an explicit method +call for symmetry with other accessors. The `document` getter exists for +callers that want property-style access. + + +## **Type** + +`{ version: string; sections: Record }` + +## **Example** + +```typescript {6} +import { SwmlBuilder } from '@signalwire/sdk'; + +const builder = new SwmlBuilder(); +builder.answer(); + +console.log(builder.document.version); // "1.0.0" +console.log(builder.document.sections.main.length); // 1 +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx index 0e3f8a604..1fad956ef 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/index.mdx @@ -127,6 +127,21 @@ console.log(builder.renderDocument()); Reset the SWML document to an empty state. + + Add a new named section to the document. + + + Build and return the document (Python-compat alias for getDocument). + + + Render the document as JSON (Python-compat alias for renderDocument). + + + Property-style read-only accessor for the underlying document. + + + Enable or disable verb schema validation. + --- diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/render.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/render.mdx new file mode 100644 index 000000000..b68fa11db --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/render.mdx @@ -0,0 +1,32 @@ +--- +title: "render" +slug: /reference/typescript/agents/swml-builder/render +description: "Render the SWML document as a JSON string (Python-compat alias for renderDocument)." +max-toc-depth: 3 +--- + +[ref-renderdocument]: /docs/server-sdks/reference/typescript/agents/swml-builder/render-document +[ref-build]: /docs/server-sdks/reference/typescript/agents/swml-builder/build + +Render the SWML document as a JSON string. Python-compat alias for +[`renderDocument()`][ref-renderdocument]; the two are functionally identical. +Use `render()` when porting from the Python SDK. For the document as a plain +object, use [`build()`][ref-build] or `getDocument()`. + +## **Returns** + +`string` -- JSON-serialized SWML document. + +## **Example** + +```typescript {6} +import { SwmlBuilder } from '@signalwire/sdk'; + +const builder = new SwmlBuilder(); +builder.answer(); +builder.ai({ prompt: { text: 'You are a helpful assistant.' } }); + +const json = builder.render(); +console.log(json); +// '{"version":"1.0.0","sections":{"main":[{"answer":{}},{"ai":{...}}]}}' +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx index 0dfec3621..5b0b8b251 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/say.mdx @@ -1,7 +1,7 @@ --- title: "say" slug: /reference/typescript/agents/swml-builder/say -description: Add a play verb with a say: prefix for text-to-speech. +description: "Add a play verb with a say: prefix for text-to-speech." max-toc-depth: 3 --- diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/set-validation.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/set-validation.mdx new file mode 100644 index 000000000..598ae1553 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-builder/set-validation.mdx @@ -0,0 +1,47 @@ +--- +title: "setValidation" +slug: /reference/typescript/agents/swml-builder/set-validation +description: "Enable or disable verb schema validation at runtime." +max-toc-depth: 3 +--- + +[ref-addverb]: /docs/server-sdks/reference/typescript/agents/swml-builder/add-verb + +Toggle verb schema validation at runtime. When validation is enabled (the +default), [`addVerb()`][ref-addverb] validates each verb's config against the +schema and throws if it fails. Disable validation for performance-sensitive +call paths or when constructing verbs with custom schemas not known to the +built-in schema utilities. + + +Matches the Python `schema_validation` constructor parameter on +`AgentBase`. For SWML service validation at construct time, pass +`schemaValidation: false` to the `SwmlBuilder` constructor via +`SwmlBuilderOptions`. + + +## **Parameters** + + + `true` to enable schema validation on subsequent `addVerb()` calls, `false` + to disable. + + +## **Returns** + +`void` + +## **Example** + +```typescript {8} +import { SwmlBuilder } from '@signalwire/sdk'; + +const builder = new SwmlBuilder(); + +// Validation on (default) — throws on invalid verb +builder.answer(); + +// Disable validation for a hot path +builder.setValidation(false); +builder.addVerb('custom_verb', { unusual: 'payload' }); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-section.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-section.mdx new file mode 100644 index 000000000..2a50ebd8a --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-section.mdx @@ -0,0 +1,42 @@ +--- +title: "addSection" +slug: /reference/typescript/agents/swml-service/add-section +description: "Add a new empty section to the SWML document." +max-toc-depth: 3 +--- + +[ref-addverbtosection]: /docs/server-sdks/reference/typescript/agents/swml-service/add-verb-to-section + +Add a new empty section to the SWML document. Sections are named containers for +ordered lists of verbs. Every document starts with a `main` section. + + +Silently no-ops if a section with the given name already exists (unlike the +Python SDK which returns `False` on duplicate). Follow up with +[`addVerbToSection()`][ref-addverbtosection] to populate the section. + + +## **Parameters** + + + Name of the section to create. + + +## **Returns** + +`this` -- returns the service for fluent chaining. + +## **Example** + +```typescript {4} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'multi-section' }); +service.addSection('fallback'); +service.addVerbToSection('fallback', 'play', { + url: 'https://example.com/sorry.mp3', +}); +service.addVerbToSection('fallback', 'hangup', {}); + +console.log(service.renderDocument()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-verb-to-section.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-verb-to-section.mdx new file mode 100644 index 000000000..8b3b6ba52 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/add-verb-to-section.mdx @@ -0,0 +1,59 @@ +--- +title: "addVerbToSection" +slug: /reference/typescript/agents/swml-service/add-verb-to-section +description: "Add a SWML verb to a specific named section of the document." +max-toc-depth: 3 +--- + +[ref-addsection]: /docs/server-sdks/reference/typescript/agents/swml-service/add-section +[ref-addverb]: /docs/server-sdks/reference/typescript/agents/swml-service/add-verb + +Add a SWML verb to a specific named section of the document. If the section +does not exist, it is created automatically before the verb is appended. Throws +a validation error if schema validation is enabled and the verb config is +invalid. + + +Use [`addSection()`][ref-addsection] first to create an empty section if you +prefer explicit creation, or use this method directly and let it auto-create. +For the default `main` section, use [`addVerb()`][ref-addverb] instead. + + +## **Parameters** + + + Name of the section to add the verb to (e.g., `"main"`, `"transfer_flow"`). + + + + The SWML verb name. + + + + Configuration for the verb. Typically a `Record` object; + certain verbs like `sleep` accept a bare number. + + +## **Returns** + +`this` -- returns the service for fluent chaining. + +## **Example** + +```typescript {10} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'transfer-flow' }); + +// Build the main section +service.addVerb('answer', {}); +service.addVerb('ai', { prompt: { text: 'You are a helpful assistant' } }); + +// Build a separate transfer section +service.addVerbToSection('transfer', 'connect', { + to: '+15551234567', + from: '+15559876543', +}); + +console.log(service.renderDocument()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/as-router.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/as-router.mdx new file mode 100644 index 000000000..9c1ace64f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/as-router.mdx @@ -0,0 +1,49 @@ +--- +title: "asRouter" +slug: /reference/typescript/agents/swml-service/as-router +description: "Get the underlying Hono app (Python-compat alias for getApp)." +max-toc-depth: 3 +--- + +[ref-serve]: /docs/server-sdks/reference/typescript/agents/swml-service/serve +[ref-run]: /docs/server-sdks/reference/typescript/agents/swml-service/run +[ref-getapp]: /docs/server-sdks/reference/typescript/agents/swml-service/get-app +[ref-agentserver]: /docs/server-sdks/reference/typescript/agents/agent-server + +Return the underlying [`Hono`](https://hono.dev) app for this service. This is +a Python-compat alias for [`getApp()`][ref-getapp] -- use either name +interchangeably. Pick `asRouter()` when porting code from the Python SDK that +called `as_router()` for a FastAPI `APIRouter`. + +Use this to mount the service into an existing Hono application rather than +running a standalone server with [`run()`][ref-run] or +[`serve()`][ref-serve]. + + +Use `asRouter()` for production deployments where you want to control the +HTTP server lifecycle, or when hosting multiple services on the same Hono +instance via [`AgentServer`][ref-agentserver]. + + +## **Returns** + +`Hono` -- the configured Hono app with all routes registered (SWML document +endpoint plus any routing-callback paths). + +## **Example** + +```typescript {11} +import { Hono } from 'hono'; +import { serve } from '@hono/node-server'; +import { SWMLService } from '@signalwire/sdk'; + +const app = new Hono(); + +const service = new SWMLService({ name: 'ivr', route: '/ivr' }); +service.addVerb('answer', {}); +service.addVerb('play', { url: 'https://example.com/welcome.mp3' }); + +app.route('/ivr', service.asRouter()); + +serve({ fetch: app.fetch, port: 3000 }); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/extract-sip-username.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/extract-sip-username.mdx new file mode 100644 index 000000000..566c34e01 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/extract-sip-username.mdx @@ -0,0 +1,54 @@ +--- +title: "extractSipUsername" +slug: /reference/typescript/agents/swml-service/extract-sip-username +description: "Static utility that extracts the username portion from a SIP URI in a request body." +max-toc-depth: 3 +--- + +[ref-registerroutingcallback]: /docs/server-sdks/reference/typescript/agents/swml-service/register-routing-callback + +Static utility method that extracts the username portion from the `call.to` +field of a parsed request body. Handles three input formats: + +- `sip:username@domain` (or `sips:...`) -- strips the scheme and `@domain` + suffix, returning the username +- `tel:+1234567890` -- strips the `tel:` scheme, returning the phone number +- Plain string -- returned as-is + +Commonly paired with +[`registerRoutingCallback()`][ref-registerroutingcallback] to route SIP traffic +based on the dialed user. + +## **Parameters** + + + The parsed JSON body from an incoming request. Expected to contain a + `call.to` field with a SIP URI, TEL URI, or phone number string. + + +## **Returns** + +`string | null` -- The extracted username or phone number, or `null` if the +`call.to` field is missing or cannot be parsed. + +## **Examples** + +### Extract from SIP URI + +```typescript {4} +import { SWMLService } from '@signalwire/sdk'; + +const body = { call: { to: 'sip:sales@example.sip.signalwire.com' } }; +const username = SWMLService.extractSipUsername(body); +// "sales" +``` + +### Extract from TEL URI + +```typescript {4} +import { SWMLService } from '@signalwire/sdk'; + +const body = { call: { to: 'tel:+15551234567' } }; +const number = SWMLService.extractSipUsername(body); +// "+15551234567" +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-basic-auth-credentials.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-basic-auth-credentials.mdx new file mode 100644 index 000000000..c04ecad01 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-basic-auth-credentials.mdx @@ -0,0 +1,47 @@ +--- +title: "getBasicAuthCredentials" +slug: /reference/typescript/agents/swml-service/get-basic-auth-credentials +description: "Retrieve the HTTP Basic Auth credentials for the service." +max-toc-depth: 3 +--- + +[ref-swmlservice]: /docs/server-sdks/reference/typescript/agents/swml-service + +Retrieve the current HTTP Basic Auth credentials used by this service. Every +[`SWMLService`][ref-swmlservice] instance has auth credentials -- either +explicitly provided in the constructor, read from environment variables, or +auto-generated at startup. + +## **Parameters** + + + When `true`, returns a 3-tuple that includes the credential source as the + third element. The source is one of: + - `"provided"` -- credentials were passed through constructor options + - `"environment"` -- credentials came from `SWML_BASIC_AUTH_USER` and `SWML_BASIC_AUTH_PASSWORD` environment variables + - `"auto-generated"` -- credentials were randomly generated at startup + + +## **Returns** + +`[string, string]` -- A `[username, password]` tuple when `includeSource` is +`false` or omitted. + +`[string, string, 'provided' | 'environment' | 'auto-generated']` -- A +`[username, password, source]` tuple when `includeSource` is `true`. + +## **Example** + +```typescript {6,10} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); + +// Get credentials +const [username, password] = service.getBasicAuthCredentials(); +console.log(`Auth: ${username}:${password}`); + +// Get credentials with source information +const [user, pass, source] = service.getBasicAuthCredentials(true); +console.log(`Auth source: ${source}`); // "provided", "environment", or "auto-generated" +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-document.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-document.mdx new file mode 100644 index 000000000..18e40cbbb --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/get-document.mdx @@ -0,0 +1,48 @@ +--- +title: "getDocument" +slug: /reference/typescript/agents/swml-service/get-document +description: "Get the current SWML document as a plain object." +max-toc-depth: 3 +--- + +[ref-renderdocument]: /docs/server-sdks/reference/typescript/agents/swml-service/render-document +[ref-renderswml]: /docs/server-sdks/reference/typescript/agents/swml-service/render-swml + +Get the current SWML document as a plain JavaScript object. The returned +structure follows the standard SWML format with `version` and `sections` keys. + + +Functionally identical to [`renderSwml()`][ref-renderswml]; `getDocument()` exists +as a Python-compat alias. Use [`renderDocument()`][ref-renderdocument] when you +need a JSON string rather than an object. + + +## **Returns** + +`Record` — The current SWML document. Structure: + +```json +{ + "version": "1.0.0", + "sections": { + "main": [ + {"answer": {}}, + {"ai": {}} + ] + } +} +``` + +## **Example** + +```typescript {7} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); +service.addVerb('answer', {}); +service.addVerb('play', { url: 'https://example.com/audio.mp3' }); + +const doc = service.getDocument(); +console.log((doc as any).version); // "1.0.0" +console.log(((doc as any).sections.main as []).length); // 2 +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx index d394fea59..ca8d506ac 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/index.mdx @@ -129,21 +129,63 @@ See the [SWML reference][swml-reference] for the full document specification. Add a SWML verb to the document. + + Add a new named section to the document. + + + Add a verb to a specific named section. + + + Reset the document to an empty state. + Render the SWML document as an object. + + Get the SWML document as an object (Python-compat alias). + + + Render the SWML document as a JSON string. + Set a per-request callback for dynamic SWML generation. + + Subclass override hook for per-request SWML. + + + Register a custom verb handler. + + + Register a routing callback at a given path. + + + Extract the username from a SIP URI (static). + + + Retrieve HTTP Basic Auth credentials. + + + Manually set the proxy URL for webhook generation. + Get the Hono app for mounting or testing. + + Get the Hono app (Python-compat alias for getApp). + Get the underlying SwmlBuilder instance. Start the HTTP server. + + Start the HTTP server (Python-compat alias for run). + + + Stop the HTTP server. + ## **Example** diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/manual-set-proxy-url.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/manual-set-proxy-url.mdx new file mode 100644 index 000000000..b5f62593e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/manual-set-proxy-url.mdx @@ -0,0 +1,46 @@ +--- +title: "manualSetProxyUrl" +slug: /reference/typescript/agents/swml-service/manual-set-proxy-url +description: "Manually set the proxy URL base for webhook callback generation." +max-toc-depth: 3 +--- + +Manually set the proxy URL base used for generating webhook callback URLs. +Call this when automatic proxy detection does not work for your deployment +(e.g., behind a custom load balancer or tunneling service). + +Overrides any value auto-detected from the `SWML_PROXY_URL_BASE` environment +variable or inferred from request headers, and clears the "from env" flag so +subsequent env changes won't overwrite your explicit setting. + + +The proxy URL affects how webhook URLs are generated for SWAIG function +callbacks, post-prompt URLs, and other webhook endpoints. Without a correct +proxy URL, SignalWire cannot reach your service's webhook endpoints when +deployed behind a reverse proxy or tunnel. + + +## **Parameters** + + + The base URL to use for webhook generation (e.g., `"https://my-agent.ngrok.io"`). + Trailing slashes are stripped automatically. Empty strings are ignored. + + +## **Returns** + +`this` -- returns the service for fluent chaining. + +## **Example** + +```typescript {6} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); + +// Set proxy URL for ngrok tunnel +service.manualSetProxyUrl('https://abc123.ngrok.io'); + +service.addVerb('answer', {}); +await service.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/on-request.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/on-request.mdx new file mode 100644 index 000000000..cd7dec7d8 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/on-request.mdx @@ -0,0 +1,90 @@ +--- +title: "onRequest" +slug: /reference/typescript/agents/swml-service/on-request +description: "Subclass override hook for dynamic per-request SWML generation." +max-toc-depth: 3 +--- + +[ref-registerroutingcallback]: /docs/server-sdks/reference/typescript/agents/swml-service/register-routing-callback +[ref-setonrequestcallback]: /docs/server-sdks/reference/typescript/agents/swml-service/set-on-request-callback +[ref-swmlbuilder]: /docs/server-sdks/reference/typescript/agents/swml-builder + +Protected hook method called on every inbound SWML request, before the document +is returned to SignalWire. Override this in a subclass to inspect the request +and return a customized [`SwmlBuilder`][ref-swmlbuilder] for this request. + +Returning `null` delegates to the next handler in the chain (any callback +registered via [`setOnRequestCallback()`][ref-setonrequestcallback], or the +static builder). The default implementation returns `null`. + + +The TypeScript signature differs from the Python SDK's `on_request(request_data, +callback_path)` in two ways: + +1. TS receives query params, body params, and headers as separate arguments + instead of merged `request_data`. +2. TS returns a full [`SwmlBuilder`][ref-swmlbuilder] instance (or `null`) rather + than a dictionary of modifications to merge. This means a TS override replaces + the document entirely rather than patching it. + + +## **Parameters** + + + URL query parameters from the request. + + + + Parsed POST body. Empty object for GET requests. Typically contains call + metadata from SignalWire (e.g., `call.to`, `call.from`, `call.headers`). + + + + HTTP request headers. + + + + The routing callback path that matched this request, if any. Set when the + request arrived through a path registered via + [`registerRoutingCallback()`][ref-registerroutingcallback]; `undefined` for + requests to the main route. + + +## **Returns** + +`SwmlBuilder | null` -- a [`SwmlBuilder`][ref-swmlbuilder] whose document is +served for this request, or `null` to delegate to the next handler. + +## **Example** + +```typescript {7} +import { SWMLService, SwmlBuilder } from '@signalwire/sdk'; + +class DynamicService extends SWMLService { + constructor() { + super({ name: 'dynamic-ivr', route: '/' }); + } + + protected onRequest( + _queryParams: Record, + bodyParams: Record, + _headers: Record, + ): SwmlBuilder | null { + const call = bodyParams?.call as Record | undefined; + const caller = (call?.from as string) ?? ''; + if (caller.startsWith('+1555')) { + // Custom builder for VIP callers + const builder = new SwmlBuilder(); + builder.answer(); + builder.play({ url: 'https://example.com/vip-greeting.mp3' }); + return builder; + } + return null; // Use default document + } +} + +const service = new DynamicService(); +service.addVerb('answer', {}); +service.addVerb('play', { url: 'https://example.com/default.mp3' }); +await service.serve(); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-routing-callback.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-routing-callback.mdx new file mode 100644 index 000000000..45ffe903f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-routing-callback.mdx @@ -0,0 +1,71 @@ +--- +title: "registerRoutingCallback" +slug: /reference/typescript/agents/swml-service/register-routing-callback +description: "Register routing callbacks for dynamic request handling and SIP routing." +max-toc-depth: 3 +--- + +[ref-serve]: /docs/server-sdks/reference/typescript/agents/swml-service/serve +[ref-asrouter]: /docs/server-sdks/reference/typescript/agents/swml-service/as-router +[ref-extractsipusername]: /docs/server-sdks/reference/typescript/agents/swml-service/extract-sip-username + +Register a callback for dynamic request routing. When a request arrives at the +specified path, the callback inspects the POST body and decides whether to +route the request to a different endpoint (via HTTP 307 redirect) or let +normal SWML serving continue. Commonly used for SIP-based routing where the +destination depends on the incoming SIP URI. + +A Hono endpoint is registered immediately for the specified path, serving both +GET and POST. + + +Unlike the Python SDK, the TypeScript `RoutingCallback` receives only the +parsed request body -- not the underlying `Request` object. If you need access +to headers or URL, use `asRouter()` and install custom middleware on the Hono +app directly. + + +## **Parameters** + + + A function that receives the parsed JSON request body. Return a route string + to redirect the request (HTTP 307 preserves the POST method and body), or + `null` / `undefined` to continue with normal SWML document serving. May be + async. + + Type: `(body: Record) => string | null | undefined | Promise` + + + + The URL path where this routing endpoint is created. The path is normalized: + a leading `/` is added if missing, trailing slashes are stripped. + + +## **Returns** + +`void` + +## **Example** + +### Routing callback with SIP username + +```typescript {15} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'sip-router', route: '/' }); + +function routeSipCall(body: Record): string | null { + const username = SWMLService.extractSipUsername(body); + if (username === 'sales') return '/agents/sales'; + if (username === 'support') return '/agents/support'; + return null; // Default handling +} + +service.addVerb('answer', {}); +service.registerRoutingCallback(routeSipCall, '/sip'); + +await service.serve(); +``` + +See also [`extractSipUsername()`][ref-extractsipusername] and +[`serve()`][ref-serve] / [`asRouter()`][ref-asrouter]. diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-verb-handler.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-verb-handler.mdx new file mode 100644 index 000000000..8b4050a74 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/register-verb-handler.mdx @@ -0,0 +1,63 @@ +--- +title: "registerVerbHandler" +slug: /reference/typescript/agents/swml-service/register-verb-handler +description: "Register custom verb handlers for specialized SWML verb processing." +max-toc-depth: 3 +--- + +[ref-addverb]: /docs/server-sdks/reference/typescript/agents/swml-service/add-verb + +Register a custom verb handler for specialized validation and configuration of +a SWML verb. When a verb with a registered handler is added via +[`addVerb()`][ref-addverb], the handler's +`validateConfig()` method is used instead of generic schema validation. + + +Custom verb handlers are useful when a verb has complex validation rules that +go beyond JSON Schema checks -- for example, mutually exclusive parameters or +conditional requirements. + + +## **Parameters** + + + An object implementing the `SWMLVerbHandler` interface. Must implement three + methods: + - `getVerbName(): string` -- returns the verb name this handler manages + - `validateConfig(config): [boolean, string[]]` -- returns `[isValid, errors]` + - `buildConfig(opts): Record` -- returns a configuration object + + +## **Returns** + +`void` + +## **Example** + +```typescript {21} +import { SWMLService } from '@signalwire/sdk'; +import type { SWMLVerbHandler } from '@signalwire/sdk'; + +const customHandler: SWMLVerbHandler = { + getVerbName() { + return 'my_verb'; + }, + validateConfig(config: Record) { + const errors: string[] = []; + if (!('target' in config)) { + errors.push("Missing required field 'target'"); + } + return [errors.length === 0, errors]; + }, + buildConfig(opts: Record) { + return { target: opts.target }; + }, +}; + +const service = new SWMLService({ name: 'custom-service' }); +service.registerVerbHandler(customHandler); + +// Now addVerb will use the custom handler for validation +service.addVerb('my_verb', { target: 'https://example.com' }); +console.log(service.renderDocument()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/render-document.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/render-document.mdx new file mode 100644 index 000000000..51e2156fb --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/render-document.mdx @@ -0,0 +1,36 @@ +--- +title: "renderDocument" +slug: /reference/typescript/agents/swml-service/render-document +description: "Render the current SWML document as a JSON string." +max-toc-depth: 3 +--- + +[ref-getdocument]: /docs/server-sdks/reference/typescript/agents/swml-service/get-document +[ref-renderswml]: /docs/server-sdks/reference/typescript/agents/swml-service/render-swml + +Render the current SWML document as a JSON string. This is the serialized form +returned to SignalWire when a call requests SWML. Delegates to +`SwmlBuilder.renderDocument()` under the hood. + + +For the document as a plain object, use [`getDocument()`][ref-getdocument] or +[`renderSwml()`][ref-renderswml] instead. + + +## **Returns** + +`string` — The SWML document serialized as a JSON string. + +## **Example** + +```typescript {7} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); +service.addVerb('answer', {}); +service.addVerb('hangup', {}); + +const jsonStr = service.renderDocument(); +console.log(jsonStr); +// '{"version":"1.0.0","sections":{"main":[{"answer":{}},{"hangup":{}}]}}' +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/reset-document.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/reset-document.mdx new file mode 100644 index 000000000..52cd73a43 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/reset-document.mdx @@ -0,0 +1,33 @@ +--- +title: "resetDocument" +slug: /reference/typescript/agents/swml-service/reset-document +description: "Reset the SWML document to an empty state." +max-toc-depth: 3 +--- + +[ref-swmlservice]: /docs/server-sdks/reference/typescript/agents/swml-service + +Reset the SWML document to an empty state. Clears all sections and verbs, +leaving only an empty `main` section. Use this to rebuild the document from +scratch without creating a new [`SWMLService`][ref-swmlservice] instance. + +## **Returns** + +`this` -- returns the service for fluent chaining. + +## **Example** + +```typescript {8} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); +service.addVerb('answer', {}); +service.addVerb('play', { url: 'https://example.com/old.mp3' }); + +// Start over with a fresh document +service.resetDocument(); +service.addVerb('answer', {}); +service.addVerb('ai', { prompt: { text: 'You are a helpful assistant' } }); + +console.log(service.renderDocument()); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/serve.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/serve.mdx new file mode 100644 index 000000000..9e52d6617 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/serve.mdx @@ -0,0 +1,80 @@ +--- +title: "serve" +slug: /reference/typescript/agents/swml-service/serve +description: "Start the HTTP server (Python-compat alias for run)." +max-toc-depth: 3 +--- + +[ref-run]: /docs/server-sdks/reference/typescript/agents/swml-service/run +[ref-asrouter]: /docs/server-sdks/reference/typescript/agents/swml-service/as-router + +Start the HTTP server that serves the SWML document. This is a Python-compat +alias for [`run()`][ref-run] and forwards all +arguments unchanged. Use either name interchangeably -- pick `serve()` when +porting code from the Python SDK. + + +Returns immediately when `SWAIG_CLI_MODE=true` is set, so the CLI testing +tool can load the service without opening a port. + + + +`serve()` (and `run()`) start a `@hono/node-server` instance that runs until +explicitly stopped. For embedding into an existing application, use +[`asRouter()`][ref-asrouter] to get a mountable Hono sub-app instead. + + +## **Parameters** + + + Hostname to bind to. Defaults to the `host` passed to the constructor, or + `"0.0.0.0"`. + + + + Port number to listen on. Defaults to the `port` passed to the constructor, + which itself falls back to the `PORT` environment variable or `3000`. + + + + Optional SSL/TLS overrides. Each field falls back to the matching value on + the service instance. + + + + + Path to the SSL certificate file. + + + + Path to the SSL private key file. + + + + Override whether SSL/HTTPS is enabled for this run. + + + + Domain name associated with the SSL certificate. + + + +## **Returns** + +`Promise` -- resolves once the listener is bound. + +## **Example** + +```typescript {8} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service', route: '/swml' }); +service.addVerb('answer', {}); +service.addVerb('play', { url: 'https://example.com/welcome.mp3' }); + +// Start on default host/port (0.0.0.0:3000) +await service.serve(); + +// Or override host and port +// await service.serve('127.0.0.1', 8080); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/stop.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/stop.mdx new file mode 100644 index 000000000..052b5cbb2 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/agents/swml-service/stop.mdx @@ -0,0 +1,38 @@ +--- +title: "stop" +slug: /reference/typescript/agents/swml-service/stop +description: "Stop the HTTP server started by run() or serve()." +max-toc-depth: 3 +--- + +[ref-run]: /docs/server-sdks/reference/typescript/agents/swml-service/run +[ref-serve]: /docs/server-sdks/reference/typescript/agents/swml-service/serve + +Stop the HTTP server started by [`run()`][ref-run] or +[`serve()`][ref-serve]. Closes the underlying `@hono/node-server` +instance and releases the port. + + +Unlike the Python counterpart (which only flips an internal flag), the TypeScript +`stop()` actually closes the listener. It is safe to call when no server is +running -- it no-ops if the service hasn't been started. + + +## **Returns** + +`void` + +## **Example** + +```typescript {8} +import { SWMLService } from '@signalwire/sdk'; + +const service = new SWMLService({ name: 'my-service' }); +await service.run({ host: '0.0.0.0', port: 3000 }); + +// In a signal handler or shutdown hook: +process.on('SIGINT', () => { + service.stop(); + process.exit(0); +}); +``` diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md index c55ee2010..f2855530b 100644 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -1035,4 +1035,83 @@ Key verified behaviors: 2. Options object pass-through (where TS SDK wraps an opaque `Record` passed to a RELAY server) must document the server-side key casing, not the TS idiomatic casing — the SDK doesn't translate. 3. Examples that show typed event handlers need explicit type imports — language-specific issue that Python doesn't have. +--- + +## Coverage Gap Follow-up (2026-04-23 session 6) + +Addressed the P4 coverage gaps flagged across the agents/ audits. Created 48 +new method pages across 7 classes. All pages follow the standard format +(frontmatter → link refs → overview → params → returns → example) and were +cross-verified against the Python counterparts where available, with TS- +specific notes where behavior diverges. + +### New pages by class + +**swml-service/ (14 new)** — `reset-document`, `stop`, `get-document`, +`render-document`, `get-basic-auth-credentials`, `serve`, `as-router`, +`add-section`, `add-verb-to-section`, `register-verb-handler`, +`register-routing-callback`, `extract-sip-username`, `manual-set-proxy-url`, +`on-request`. Index CardGroup expanded from 6 to 20 cards. Notes key +TS/Python divergences: `resetDocument()` returns fluent `this` vs Python +`None`; TS `stop()` actually closes the server (Python only flips a flag); +TS `onRequest()` receives (queryParams, bodyParams, headers, callbackPath) +and returns a `SwmlBuilder` or null (vs Python's `(request_data, +callback_path)` returning a merge dict); TS `RoutingCallback` signature lacks +Python's `Request` arg. + +**configuration/auth-handler/ (5 new)** — `verify-basic-auth`, +`verify-bearer-token`, `verify-api-key`, `get-auth-info`, `express-middleware`. +TS `expressMiddleware` is the framework-agnostic equivalent of Python's +`get_fastapi_dependency`. Index CardGroup expanded from 5 to 10 cards. + +**configuration/config-loader/ (8 new)** — `find-config-file`, `get-config`, +`get-config-file`, `has-config`, `get-section`, `substitute-vars`, +`merge-with-env`, `interpolate-env-vars`. `findConfigFile` documented as +static; `interpolateEnvVars` flagged as TS-specific (no Python equivalent). +Noted deliberate `hasConfig()` divergence from Python (TS treats +object-loaded data as configured because `loadFromObject` is TS-only). Index +CardGroup expanded from 8 to 17 cards. + +**pom-builder/ (5 new)** — `reset`, `add-pom-as-subsection`, `to-json`, +`from-sections` (static), `render-xml`. Index CardGroup expanded from 8 to +13 cards. + +**swml-builder/ (5 new)** — `build`, `render`, `document` (getter), +`set-validation`, `add-section`. `build`/`render` documented as Python-compat +aliases for `getDocument`/`renderDocument`. Index CardGroup expanded from 10 +to 15 cards. + +**skill-base/ (7 new)** — `get-agent`, `set-agent`, `get-config`, +`define-tool`, `has-all-env-vars`, `has-all-packages`, `validate-packages`. +`validatePackages` noted as async (dynamic `import()`). Index CardGroup +expanded from 15 to 22 cards. + +**skill-registry/ (3 new)** — `get-skill-class`, `list-skills`, +`reset-instance` (test helper). Index CardGroup expanded from 15 to 18 +cards. + +**skill-manager/ (1 new)** — `loaded-skills` (getter). Index CardGroup +expanded from 16 to 17 cards. + +### Coverage summary + +Before: ~410 TS SDK doc files. After: ~458 files (+48 new pages). +All previously-flagged P4 coverage gaps in the tracker are now closed. Remaining +P4 notes: `Call.toString()` (intentional internal repr), unexported constants +in `relay/constants.mdx` (flagged via Note, not fixed — requires SDK change). + +### Writing patterns used + +- Every new page matches the format of existing docs (frontmatter → + link-ref list at top → overview prose → `## **Parameters**` with ParamField + entries → `## **Returns**` → `## **Example**` with highlighted line). +- Python-compat aliases (e.g., `build()`, `render()`, `getConfig()`, + `serve()`, `asRouter()`) explicitly noted with a pointer to the + non-alias method so users can pick one convention and stick with it. +- TS/Python behavioral divergences documented as `` or `` + blocks rather than buried in prose, following the convention used in the + rest of the audited docs. +- Every example uses the corrected `SIGNALWIRE_API_TOKEN` env var (from + the relay-audit sweep) — no examples reintroduce the old token name. + From b87d168c6d93bc85cb4635d7c005023f6102aba3 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 15:02:41 +0000 Subject: [PATCH 06/21] docs(ts-sdk): align agents env var reference with source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes defaults, values, and coverage in agents/configuration/ environment-variables.mdx to match what the TS SDK actually does. Corrected defaults: - SWML_MAX_REQUEST_SIZE: 10485760 -> 1048576 (description 10 MB -> 1 MB) to match AgentBase.ts:2011. - SWML_RATE_LIMIT: dropped default=60; unset means no rate limiting (AgentBase.ts:2046 only installs the middleware when the var is set). - SWML_ALLOWED_HOSTS: dropped default="*"; unset means no host check (AgentBase.ts:2033 applies the middleware only when set). - SWML_BASIC_AUTH_USER: dropped default="signalwire"; fallback is the agent's `name` (AgentBase.ts:220). - SIGNALWIRE_LOG_MODE: removed unrecognized "default" value from the accepted-values list; Logger.ts only handles off|stderr|auto. Removed env vars: - APP_URL: no references in TS SDK source (grep shows zero hits); the proxy Warning was also updated to drop the APP_URL mention. - SWML_REQUEST_TIMEOUT: AgentBase.ts:2010 reads the var but never uses the resulting value — dead code. Doc described behavior that does not exist. Added env vars (present in source, missing from docs): - SWML_TRUST_PROXY_HEADERS (AgentBase.ts:125) — trust X-Forwarded-* headers when set to "true". - SWML_CSRF_PROTECTION (AgentBase.ts:2085) — reject POSTs whose Origin is not in SWML_CORS_ORIGINS when set to "true". Example .env updated: SIGNALWIRE_LOG_MODE=default -> =auto. Datasphere skill SIGNALWIRE_TOKEN usage (skills/datasphere.mdx) is intentionally left unchanged — it matches current SDK source (skills/builtin/datasphere.ts:98). The split between skill auth (SIGNALWIRE_TOKEN) and client auth (SIGNALWIRE_API_TOKEN) exists in both the TS and Python SDKs and is not a TS-specific bug. yarn fern-md-check: 2241 valid. yarn fern-check: 0 errors. --- .../configuration/environment-variables.mdx | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/environment-variables.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/environment-variables.mdx index b402843cb..d259561cf 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/configuration/environment-variables.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/configuration/environment-variables.mdx @@ -33,8 +33,9 @@ const agent = new AgentBase({ name: 'my-agent' }); ## Authentication - + Username for HTTP Basic Authentication on all agent webhook endpoints. + When unset, the username falls back to the agent's `name`. @@ -77,17 +78,20 @@ until you update the credentials in your SignalWire dashboard. The agent uses this URL to generate correct webhook URLs in SWML documents. - - Fallback for `SWML_PROXY_URL_BASE` when that variable is not set. + + Enable proxy request debug logging. Only the string `"true"` is accepted. - - Enable proxy request debug logging. + + Trust `X-Forwarded-For`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers + for client IP detection (used by rate limiting) and auto-detection of the + public URL. Only the string `"true"` is accepted. Enable only when running + behind a reverse proxy you control. -Setting `SWML_PROXY_URL_BASE` (or `APP_URL`) overrides SSL configuration and port -settings for webhook URL generation. +Setting `SWML_PROXY_URL_BASE` overrides SSL configuration and port settings +for webhook URL generation. --- @@ -101,8 +105,10 @@ settings for webhook URL generation. ## Security - - Comma-separated list of allowed hosts. Set to specific domain(s) in production + + Comma-separated list of allowed `Host` header values. When unset, no host + check is applied. When set, requests with a `Host` header not in the list + are rejected with HTTP 403. Set to specific domain(s) in production (e.g., `"agent.example.com,api.example.com"`). @@ -111,16 +117,21 @@ settings for webhook URL generation. production. - - Maximum request body size in bytes. Default is 10 MB. + + When set to `"true"`, `POST` requests whose `Origin` header is not in + `SWML_CORS_ORIGINS` are rejected with HTTP 403. Only the string `"true"` is + accepted. - - Rate limit in requests per minute. + + Maximum request body size in bytes. Default is 1 MB. Requests exceeding this + size are rejected with HTTP 413. - - Request timeout in seconds. + + Rate limit in requests per minute per client IP. When unset, no rate limit + is applied. When set to a positive integer, clients exceeding the limit + receive HTTP 429. ## Logging @@ -131,7 +142,6 @@ settings for webhook URL generation. - `"auto"` -- automatic detection based on environment - `"off"` -- disable all logging - `"stderr"` -- log to stderr - - `"default"` -- standard logging output @@ -264,7 +274,7 @@ SWML_CORS_ORIGINS=https://app.example.com SWML_RATE_LIMIT=100 # Logging -SIGNALWIRE_LOG_MODE=default +SIGNALWIRE_LOG_MODE=auto SIGNALWIRE_LOG_LEVEL=info # RELAY / REST From 0b9ba4ac4a2f3a903dfd2ce5dda03ba3c101d268 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 15:34:18 +0000 Subject: [PATCH 07/21] docs(ts-sdk): trim relay constants to re-exported symbols relay/constants.mdx listed 76 constants; only 39 are re-exported from @signalwire/sdk. Trim doc to the exported subset, matching Python's signalwire/relay/__init__.py __all__ surface. Dropped sections (internal-only): Protocol, JSON-RPC Methods, End Reasons, Play/Record/Detect/Room States, Reconnect Settings, Authorization Event, CALL_STATES/MESSAGE_TERMINAL_STATES arrays. The about partial re-exports is no longer needed. String enum values users see at runtime (endReason, play/record/detect states) are already documented inline on events.mdx. No inbound anchor links broken. --- .../reference/typescript/relay/constants.mdx | 155 +----------------- 1 file changed, 7 insertions(+), 148 deletions(-) diff --git a/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx b/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx index 71da401a8..c029e06ae 100644 --- a/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/relay/constants.mdx @@ -1,31 +1,17 @@ --- title: "Constants" slug: /reference/typescript/relay/constants -description: "RELAY constants for call states, events, and message states." +description: "RELAY constants for call states, connect states, event types, and message states." max-toc-depth: 3 --- -[callstateevent-endreason]: /docs/server-sdks/reference/typescript/relay/events [connectevent-connectstate]: /docs/server-sdks/reference/typescript/relay/events [call-on]: /docs/server-sdks/reference/typescript/relay/call [relayevent-eventtype]: /docs/server-sdks/reference/typescript/relay/events -[message-wait]: /docs/server-sdks/reference/typescript/relay/message -[playevent-state]: /docs/server-sdks/reference/typescript/relay/events -[recordevent-state]: /docs/server-sdks/reference/typescript/relay/events -[call-detect]: /docs/server-sdks/reference/typescript/relay/call/detect -The `@signalwire/sdk` package exports string and numeric constants used -throughout the RELAY namespace for call states, end reasons, connect states, event -types, message states, media operation states, and protocol settings. - - -Only `CALL_STATE_*`, `CONNECT_STATE_*`, `EVENT_CALL_*`, `EVENT_MESSAGING_*`, -`EVENT_CONFERENCE`, `EVENT_CALLING_ERROR`, and `MESSAGE_STATE_*` are re-exported -from the `@signalwire/sdk` entry point. The remaining constants listed below -(protocol, JSON-RPC method names, end reasons, play/record/detect/room states, -reconnect tuning) are internal reference values for the RELAY protocol -- -documented here for completeness but not importable from the package root. - +The `@signalwire/sdk` package re-exports string constants for call states, +connect states, event types, and message states. Import any of them from the +package root: ```typescript {2-7} import { @@ -37,35 +23,6 @@ import { } from '@signalwire/sdk'; ``` -## Protocol - - - RELAY protocol version. Value: `{ major: 2, minor: 0, revision: 0 }`. - - - - User agent string sent during connection. Value: `"@signalwire/sdk-typescript/2.0"`. - - - - Default WebSocket host for RELAY connections. Value: `"relay.signalwire.com"`. - - -## JSON-RPC Methods - -Internal method identifiers used by the RELAY WebSocket protocol. - -| Constant | Value | -|----------|-------| -| `METHOD_SIGNALWIRE_CONNECT` | `"signalwire.connect"` | -| `METHOD_SIGNALWIRE_EVENT` | `"signalwire.event"` | -| `METHOD_SIGNALWIRE_PING` | `"signalwire.ping"` | -| `METHOD_SIGNALWIRE_DISCONNECT` | `"signalwire.disconnect"` | -| `METHOD_SIGNALWIRE_RECEIVE` | `"signalwire.receive"` | -| `METHOD_SIGNALWIRE_UNRECEIVE` | `"signalwire.unreceive"` | - ---- - ## Call States Constants representing the lifecycle states of a RELAY call. A call progresses @@ -79,29 +36,6 @@ through these states in order: `created` -> `ringing` -> `answered` -> `ending` | `CALL_STATE_ENDING` | `"ending"` | Call is in the process of ending | | `CALL_STATE_ENDED` | `"ended"` | Call has ended | - - Array of all call states in lifecycle order: - `['created', 'ringing', 'answered', 'ending', 'ended']`. - - -## End Reasons - -Constants for the reason a call ended. Available in -[`CallStateEvent.endReason`][callstateevent-endreason] when the call -reaches the `ended` state. - -| Constant | Value | Description | -|----------|-------|-------------| -| `END_REASON_HANGUP` | `"hangup"` | Normal hangup by either party | -| `END_REASON_CANCEL` | `"cancel"` | Call was cancelled before answer | -| `END_REASON_BUSY` | `"busy"` | Destination returned busy | -| `END_REASON_NO_ANSWER` | `"noAnswer"` | No answer within timeout | -| `END_REASON_DECLINE` | `"decline"` | Call was declined | -| `END_REASON_ERROR` | `"error"` | An error occurred | -| `END_REASON_ABANDONED` | `"abandoned"` | Call was abandoned (e.g., caller hung up in queue) | -| `END_REASON_MAX_DURATION` | `"max_duration"` | Call exceeded maximum allowed duration | -| `END_REASON_NOT_FOUND` | `"not_found"` | Destination not found | - --- ## Connect States @@ -120,9 +54,9 @@ Constants representing the state of a call bridge (connect) operation. Used in ## Event Types -String constants for all RELAY event types. Use these when registering event -handlers with [`Call.on()`][call-on] or when -matching against [`RelayEvent.eventType`][relayevent-eventtype]. +String constants for RELAY event types. Use these when registering event +handlers with [`Call.on()`][call-on] or when matching against +[`RelayEvent.eventType`][relayevent-eventtype]. ### Calling Events @@ -157,12 +91,6 @@ matching against [`RelayEvent.eventType`][relayevent-eventtype]. | `EVENT_MESSAGING_RECEIVE` | `"messaging.receive"` | | `EVENT_MESSAGING_STATE` | `"messaging.state"` | -### Authorization Event - -| Constant | Value | -|----------|-------| -| `EVENT_AUTHORIZATION_STATE` | `"signalwire.authorization.state"` | - --- ## Message States @@ -181,75 +109,6 @@ messages progress through: `queued` -> `initiated` -> `sent` -> `delivered` | `MESSAGE_STATE_FAILED` | `"failed"` | Message send failed | | `MESSAGE_STATE_RECEIVED` | `"received"` | Inbound message received | - - Array of terminal states that resolve a [`Message.wait()`][message-wait] call: - `['delivered', 'undelivered', 'failed']`. - - -## Play States - -Constants for audio playback operation states. Used in -[`PlayEvent.state`][playevent-state]. - -| Constant | Value | Description | -|----------|-------|-------------| -| `PLAY_STATE_PLAYING` | `"playing"` | Audio is playing | -| `PLAY_STATE_PAUSED` | `"paused"` | Playback is paused | -| `PLAY_STATE_FINISHED` | `"finished"` | Playback completed | -| `PLAY_STATE_ERROR` | `"error"` | Playback error occurred | - ---- - -## Record States - -Constants for recording operation states. Used in -[`RecordEvent.state`][recordevent-state]. - -| Constant | Value | Description | -|----------|-------|-------------| -| `RECORD_STATE_RECORDING` | `"recording"` | Recording is active | -| `RECORD_STATE_PAUSED` | `"paused"` | Recording is paused | -| `RECORD_STATE_FINISHED` | `"finished"` | Recording completed | -| `RECORD_STATE_NO_INPUT` | `"no_input"` | No audio input detected | - ---- - -## Detect Types - -Constants for detection operation types. Used in the `type` field of the -`detect` parameter passed to [`call.detect()`][call-detect]. - -| Constant | Value | Description | -|----------|-------|-------------| -| `DETECT_TYPE_MACHINE` | `"machine"` | Answering machine detection | -| `DETECT_TYPE_FAX` | `"fax"` | Fax tone detection | -| `DETECT_TYPE_DIGIT` | `"digit"` | DTMF digit detection | - ---- - -## Room States - -Constants for audio/video room join/leave states. - -| Constant | Value | Description | -|----------|-------|-------------| -| `ROOM_STATE_JOINING` | `"joining"` | Joining the room | -| `ROOM_STATE_JOIN` | `"join"` | Successfully joined | -| `ROOM_STATE_LEAVING` | `"leaving"` | Leaving the room | -| `ROOM_STATE_LEAVE` | `"leave"` | Successfully left | - ---- - -## Reconnect Settings - -Configuration constants for the WebSocket reconnection strategy. - -| Constant | Value | Description | -|----------|-------|-------------| -| `RECONNECT_MIN_DELAY` | `1.0` | Minimum delay between reconnect attempts (seconds) | -| `RECONNECT_MAX_DELAY` | `30.0` | Maximum delay between reconnect attempts (seconds) | -| `RECONNECT_BACKOFF_FACTOR` | `2.0` | Exponential backoff multiplier | - ## **Example** ```typescript {12} From 9c5a083e9608fcb481096255812c1cdda89cd5bb Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 15:34:23 +0000 Subject: [PATCH 08/21] tracker --- .../server-sdks/typescript-sdk-audit-tracker.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md index f2855530b..b24a51aef 100644 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -1008,7 +1008,7 @@ Key verified behaviors: - `[overview.mdx]` clean — IVR example matches Python counterpart (same `transfer(dest=phone)` pattern — accepted per Python parity even though transfer doc says context/URL). - `[relay-error.mdx]` FIXED — `code` ParamField had `default="0"`; source RelayError.ts:9 constructor requires `code: number` (no default). Removed wrong default. Other fields (message, name) match source 6-13. -- `[constants.mdx]` FIXED — added `` clarifying only `CALL_STATE_*`, `CONNECT_STATE_*`, `EVENT_CALL_*`, `EVENT_MESSAGING_*`, `EVENT_CONFERENCE`, `EVENT_CALLING_ERROR`, `MESSAGE_STATE_*` are re-exported from `@signalwire/sdk` (verified against `src/relay/index.ts:66-107`). All other constants listed (PROTOCOL_VERSION, AGENT_STRING, DEFAULT_RELAY_HOST, METHOD_*, END_REASON_*, PLAY_STATE_*, RECORD_STATE_*, DETECT_TYPE_*, ROOM_STATE_*, RECONNECT_*, MESSAGE_TERMINAL_STATES, CALL_STATES, EVENT_AUTHORIZATION_STATE) exist in constants.ts but aren't re-exported — note prevents user confusion about import failures. Values checked individually against constants.ts and all match. +- `[constants.mdx]` FIXED (session 6 follow-up) — trimmed to the 39 symbols actually re-exported from `@signalwire/sdk` root (verified against `src/relay/index.ts:67-107`). Dropped all internal-only sections: Protocol (PROTOCOL_VERSION/AGENT_STRING/DEFAULT_RELAY_HOST), JSON-RPC Methods, End Reasons, Play/Record/Detect/Room States, Reconnect Settings, Authorization Event, `CALL_STATES`/`MESSAGE_TERMINAL_STATES` arrays. Rationale: Python reference SDK (`signalwire/relay/__init__.py` `__all__`) exports the same subset — the un-re-exported constants are internal implementation in both SDKs and not part of the public API surface. String enum values users encounter at runtime (`endReason`, play/record/detect states, etc.) are already documented inline on `events.mdx` where they appear. Previous `` removed (no longer needed — doc surface now matches import surface). No inbound anchor links were broken (verified via grep for `constants#`). - `[events.mdx]` FIXED (P2 x 19 systematic) — RelayEvent base (eventType/params/callId/timestamp) matches src 12-40. 19 event-class examples used typed event classes in handler signatures (e.g., `(event: PlayEvent) => …`) but didn't import those classes — examples would fail TS type check as written. Used Python AST-style script to backtrack from each handler to the preceding `import { RelayClient } from '@signalwire/sdk';` and add the referenced event class. All 21 examples now import their event class correctly. ### Relay Audit Summary @@ -1027,8 +1027,10 @@ Key verified behaviors: 8. **on-call/on-message Returns type** — both documented `void` but source returns the handler (decorator pattern support). **Coverage gaps (P4) not fixed:** -- `Call.toString()` — internal repr; intentional. -- Constants doc lists constants not re-exported from `@signalwire/sdk` root — flagged via Note rather than removing. +- `Call.toString()` — internal repr; intentional (matches Python which also doesn't doc `__repr__`). + +**Previously flagged, now resolved in session 6:** +- `relay/constants.mdx` — trimmed to re-exported symbols only (matches Python `__all__` surface). **Systematic patterns uncovered (for future SDK doc authoring):** 1. Timeout units must be stated explicitly in both prose AND matching examples; TS/JS conventions default to milliseconds, Python SDK convention is seconds, and TS mirrored Python — a steady source of confusion. @@ -1097,8 +1099,12 @@ expanded from 16 to 17 cards. Before: ~410 TS SDK doc files. After: ~458 files (+48 new pages). All previously-flagged P4 coverage gaps in the tracker are now closed. Remaining -P4 notes: `Call.toString()` (intentional internal repr), unexported constants -in `relay/constants.mdx` (flagged via Note, not fixed — requires SDK change). +P4 note: `Call.toString()` (intentional internal repr — matches Python SDK +convention of not documenting `__repr__`). The earlier `relay/constants.mdx` +flag was resolved by trimming the doc to match the re-exported symbol set; +root cause was a doc-scope decision (over-documentation of internal-only +constants), not an SDK bug — Python's `signalwire/relay/__init__.py` `__all__` +exports the same public subset. ### Writing patterns used From 70979485baedea9b969362647f1ae497d7c1b660 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 16:23:36 +0000 Subject: [PATCH 09/21] docs(ts-sdk): remove temp redirects --- fern/docs.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/fern/docs.yml b/fern/docs.yml index 103466556..f5550017c 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -184,13 +184,6 @@ redirects: destination: /docs/server-sdks - source: /docs/server-sdk/:slug* destination: /docs/server-sdks - # Temporary: TypeScript SDK reference is hidden; redirect to Python equivalent. - - source: /docs/server-sdks/reference/typescript - destination: /docs/server-sdks/reference/python - permanent: false - - source: /docs/server-sdks/reference/typescript/:slug* - destination: /docs/server-sdks/reference/python/:slug* - permanent: false check: rules: From dec6b28a6f1123e5164c1f5a29617a13ec42af26 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 16:30:59 +0000 Subject: [PATCH 10/21] icon swap --- fern/products/server-sdks/server-sdks.yml | 2 +- .../typescript-sdk-audit-tracker.md | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/fern/products/server-sdks/server-sdks.yml b/fern/products/server-sdks/server-sdks.yml index d6eaedb2f..6b802f094 100644 --- a/fern/products/server-sdks/server-sdks.yml +++ b/fern/products/server-sdks/server-sdks.yml @@ -39,7 +39,7 @@ navigation: title: REST Client collapsed: false - title: TypeScript - icon: brands fa-js + icon: brands fa-typescript layout: - folder: ./pages/reference/typescript/core title: Core diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md index b24a51aef..6c1bc44bf 100644 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ b/fern/products/server-sdks/typescript-sdk-audit-tracker.md @@ -1120,4 +1120,50 @@ exports the same public subset. - Every example uses the corrected `SIGNALWIRE_API_TOKEN` env var (from the relay-audit sweep) — no examples reintroduce the old token name. +--- + +## Core audit session (2026-04-23) + +Scope: `pages/reference/typescript/core/` — 1 file (`overview.mdx`). + +### core/ — AUDITED -- NO ISSUES (1/1) + +`overview.mdx` is a nav landing page: frontmatter + shared snippet include +(`/snippets/server-sdks/reference-overview.mdx`) + 3-card CardGroup linking +to `agents/`, `relay/`, `rest/` section overviews. + +**Checks:** + +| Check | Result | +|-------|--------| +| Frontmatter title | "SignalWire TypeScript Server SDK" — language-appropriate ✓ | +| Frontmatter slug | `/reference/typescript` ✓ | +| Frontmatter description | "SDK reference overview for SignalWire Agents, RELAY, and REST APIs." ✓ | +| sidebar-title / subtitle / max-toc-depth / position | Match Python counterpart ✓ | +| Shared-snippet path | `/snippets/server-sdks/reference-overview.mdx` resolves to `fern/snippets/server-sdks/reference-overview.mdx` ✓ | +| CardGroup href -- agents | `/docs/server-sdks/reference/typescript/agents` — target overview slug `/reference/typescript/agents` exists ✓ | +| CardGroup href -- relay | `/docs/server-sdks/reference/typescript/relay` — target overview slug `/reference/typescript/relay` exists ✓ | +| CardGroup href -- rest | `/docs/server-sdks/reference/typescript/rest` — target overview slug `/reference/typescript/rest` exists ✓ | +| Content drift vs Python `core/overview.mdx` | Identical except for language-adapted title + slug. No drift. ✓ | + +**Behavioral verification for `overview.mdx`:** + +- "AI voice agents with SWML, SWAIG tools, skills, and multi-step workflows." → `src/AgentBase.ts` (SWML rendering via `SwmlBuilder`, SWAIG dispatch, `SkillManager`, multi-step `ContextBuilder`) ✓ confirmed +- "Real-time WebSocket client for call and message control." → `src/relay/RelayClient.ts` (WebSocket JSON-RPC 2.0) ✓ confirmed +- "HTTP client for phone numbers, fabric, video, logs, and more." → `src/rest/index.ts` + `src/rest/namespaces/{phone-numbers,fabric,video,logs,...}.ts` ✓ confirmed + +Shared snippet (`reference-overview.mdx`) is language-agnostic — references +`AgentBase`, `RelayClient`, `RestClient` all exist as exported symbols in +`src/index.ts`, `src/relay/RelayClient.ts`, `src/rest/index.ts` +respectively. No TS-specific drift possible in a shared snippet. + +**Fixes applied:** 0. **New pages created:** 0. + +### Cumulative totals + +~459 TS SDK doc files audited across all namespaces (agents + relay + rest + +core). Every namespace in `pages/reference/typescript/` now marked +AUDITED + FIXED or AUDITED -- NO ISSUES. + + From 3bd3081215fda500f7052c0ee300d635c1e52194 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 16:32:03 +0000 Subject: [PATCH 11/21] remove tracker --- .../typescript-sdk-audit-tracker.md | 1169 ----------------- 1 file changed, 1169 deletions(-) delete mode 100644 fern/products/server-sdks/typescript-sdk-audit-tracker.md diff --git a/fern/products/server-sdks/typescript-sdk-audit-tracker.md b/fern/products/server-sdks/typescript-sdk-audit-tracker.md deleted file mode 100644 index 6c1bc44bf..000000000 --- a/fern/products/server-sdks/typescript-sdk-audit-tracker.md +++ /dev/null @@ -1,1169 +0,0 @@ -# TypeScript SDK Audit Tracker - -## SDK Identity - -- **Language:** TypeScript -- **Package name:** `@signalwire/sdk` -- **Version:** 2.0.0 -- **Main import:** `import { RestClient } from '@signalwire/sdk';` -- **Source repo:** https://github.com/signalwire/signalwire-typescript -- **Local path:** `temp/signalwire-typescript` -- **Source commit:** `ba6d5b1f1c68065bb378ab9c1a79c4a08da107e1` (2026-04-21) -- **Prior synced commit:** `f7144ab40505f365e554332e891b38b3a5e2f670` (2026-04-08) -- **Delta:** 132 commits — alignment sweep + skills infra refactor + v2.0.0 tag - -## Audit Scope (this run) - -REST namespace (`pages/reference/typescript/rest/**`). ~384 MDX files across -22 namespaces. - -## Full Inventory — REST - -Order: largest class first. - -| Status | Namespace | Files | Source | -|--------|-----------|-------|--------| -| AUDITED -- NO ISSUES | `fabric/` | 112 | `src/rest/namespaces/fabric.ts` | -| AUDITED -- NO ISSUES | `compat/` | 91 | `src/rest/namespaces/compat.ts` | -| AUDITED -- NO ISSUES | `video/` | 38 | `src/rest/namespaces/video.ts` | -| AUDITED -- NO ISSUES | `calling/` | 38 | `src/rest/namespaces/calling.ts` | -| AUDITED -- NO ISSUES | `registry/` | 15 | `src/rest/namespaces/registry.ts` | -| AUDITED -- NO ISSUES | `logs/` | 13 | `src/rest/namespaces/logs.ts` | -| AUDITED -- NO ISSUES | `number-groups/` | 10 | `src/rest/namespaces/number-groups.ts` | -| AUDITED -- NO ISSUES | `datasphere/` | 10 | `src/rest/namespaces/datasphere.ts` | -| AUDITED -- NO ISSUES | `queues/` | 9 | `src/rest/namespaces/queues.ts` | -| AUDITED -- NO ISSUES | `verified-callers/` | 8 | `src/rest/namespaces/verified-callers.ts` | -| AUDITED -- NO ISSUES | `phone-numbers/` | 7 | `src/rest/namespaces/phone-numbers.ts` | -| AUDITED -- NO ISSUES | `addresses/` | 5 | `src/rest/namespaces/addresses.ts` | -| AUDITED -- NO ISSUES | `short-codes/` | 4 | `src/rest/namespaces/short-codes.ts` | -| AUDITED -- NO ISSUES | `recordings/` | 4 | `src/rest/namespaces/recordings.ts` | -| AUDITED -- NO ISSUES | `project/` | 4 | `src/rest/namespaces/project.ts` | -| AUDITED -- NO ISSUES | `mfa/` | 4 | `src/rest/namespaces/mfa.ts` | -| AUDITED -- NO ISSUES | `sip-profile/` | 3 | `src/rest/namespaces/sip-profile.ts` | -| AUDITED -- NO ISSUES | `pubsub/` | 2 | `src/rest/namespaces/pubsub.ts` | -| AUDITED -- NO ISSUES | `lookup/` | 2 | `src/rest/namespaces/lookup.ts` | -| AUDITED -- NO ISSUES | `imported-numbers/` | 2 | `src/rest/namespaces/imported-numbers.ts` | -| AUDITED -- NO ISSUES | `chat/` | 2 | `src/rest/namespaces/chat.ts` | -| AUDITED -- NO ISSUES | `client/` | 1 | `src/rest/index.ts` | -| AUDITED -- NO ISSUES | root (`overview.mdx`, `rest-error.mdx`) | 2 | `src/rest/RestError.ts` | - -## Findings Log - -_(One line per finding and per fix. Format: `[path/to/file.mdx] PRIORITY type: description`)_ - -### fabric/ - -- `[fabric/index.mdx]` NO ISSUES — 16 sub-resource list matches source; PATCH/PUT note verified. -- `[fabric/ai-agents/*]` NO ISSUES — all 7 files (index + 6 methods) verified against `FabricResource` extending `CrudWithAddresses`; endpoint paths, HTTP methods, and example signatures match source. -- `[fabric/call-flows/*]` NO ISSUES — all 9 files verified against `CallFlowsResource` (extends `FabricResourcePUT`). PUT update confirmed. Singular `/call_flow/{id}/addresses` + `/versions` + POST `/versions` paths match source. -- `[fabric/subscribers/*]` NO ISSUES — all 12 files verified against `SubscribersResource`. PUT update, PATCH on `updateSipEndpoint`, and all 5 SIP-endpoint method paths match source. -- `[fabric/conference-rooms/*]` NO ISSUES — 7 files verified against `ConferenceRoomsResource`. Singular `/conference_room/{id}/addresses` override confirmed. -- `[fabric/cxml-applications/*]` NO ISSUES — 6 files verified against `CxmlApplicationsResource`. No `create.mdx` (source's `create()` throws). PUT update confirmed. -- `[fabric/swml-scripts/*]` NO ISSUES — 7 files verified. PUT update, basePath `/swml_scripts` confirmed. -- `[fabric/relay-applications/*]` NO ISSUES — 7 files verified. PUT, basePath `/relay_applications` confirmed. -- `[fabric/sip-endpoints/*]` NO ISSUES — 7 files verified. PUT, basePath `/sip_endpoints` confirmed. Index correctly cross-links to subscribers nested variant. -- `[fabric/cxml-scripts/*]` NO ISSUES — 7 files verified. PUT, basePath `/cxml_scripts` confirmed. -- `[fabric/freeswitch-connectors/*]` NO ISSUES — 7 files verified. PUT, basePath `/freeswitch_connectors` confirmed. -- `[fabric/swml-webhooks/*]` NO ISSUES — 7 files verified. PATCH, basePath `/swml_webhooks` confirmed. -- `[fabric/sip-gateways/*]` NO ISSUES — 7 files verified. PATCH, basePath `/sip_gateways` confirmed. -- `[fabric/cxml-webhooks/*]` NO ISSUES — 7 files verified. PATCH, basePath `/cxml_webhooks` confirmed. -- `[fabric/resources/*]` NO ISSUES — 7 files verified against `GenericResources`. 6 methods (list, get, delete, listAddresses, assignPhoneRoute, assignDomainApplication) all match source paths. -- `[fabric/addresses.mdx]` NO ISSUES — single-page read-only resource (list + get) matches `FabricAddresses`. -- `[fabric/tokens/*]` NO ISSUES — 6 files verified against `FabricTokens`. All 5 token endpoints match source paths (note singular `/subscriber/invites`). - -### compat/ - -- `[compat/index.mdx]` NO ISSUES — 12-card CardGroup matches `CompatNamespace` source. URL structure `/2010-04-01/Accounts/{AccountSid}/` correctly documented. -- `[compat/accounts/*]` NO ISSUES — 5 files verified against `CompatAccounts` (non-AccountSid-scoped basePath `/Accounts`). list/create/get/update; POST update. -- `[compat/applications/*]` NO ISSUES — 6 files verified against `CompatApplications` (CrudResource + POST update). -- `[compat/calls/*]` NO ISSUES — 10 files verified against `CompatCalls`. CRUD + 4 sub-resource methods (startRecording, updateRecording, startStream, stopStream) all POST with correct paths. -- `[compat/conferences/*]` NO ISSUES — 14 files verified against `CompatConferences`. No create (source has none). 13 methods across CRUD, participants (4), recordings (4), streams (2) all match. -- `[compat/faxes/*]` NO ISSUES — 9 files verified against `CompatFaxes`. CRUD + media sub-resources (list/get/delete) match source. -- `[compat/laml-bins/*]` NO ISSUES — 6 files verified against `CompatLamlBins` (CrudResource + POST update). -- `[compat/messages/*]` NO ISSUES — 9 files verified against `CompatMessages`. CRUD + media sub-resources match. -- `[compat/phone-numbers/*]` NO ISSUES — 10 files verified against `CompatPhoneNumbers`. 9 methods incl. `importNumber` → `/ImportedPhoneNumbers`, and `searchLocal`/`searchTollFree`/`listAvailableCountries` → `/AvailablePhoneNumbers` path-replacement all match source. -- `[compat/queues/*]` NO ISSUES — 9 files verified against `CompatQueues`. CRUD + member sub-resources match. -- `[compat/recordings/*]` NO ISSUES — 4 files verified against `CompatRecordings` (read-only list/get/delete). -- `[compat/tokens/*]` NO ISSUES — 4 files verified against `CompatTokens`. `update` correctly documented as PATCH (unique exception vs all other compat updates which are POST). -- `[compat/transcriptions/*]` NO ISSUES — 4 files verified against `CompatTranscriptions` (read-only list/get/delete). - -### video/ - -- `[video/index.mdx]` NO ISSUES — 7-card CardGroup matches `VideoNamespace` source. -- `[video/rooms/*]` NO ISSUES — 8 files verified against `VideoRooms` (CrudResource with PUT update + listStreams + createStream). -- `[video/room-tokens/*]` NO ISSUES — 2 files verified against `VideoRoomTokens` (create only). -- `[video/room-sessions/*]` NO ISSUES — 6 files verified against `VideoRoomSessions` (list, get, listEvents, listMembers, listRecordings). -- `[video/room-recordings/*]` NO ISSUES — 5 files verified against `VideoRoomRecordings` (list, get, delete, listEvents). -- `[video/conferences/*]` NO ISSUES — 9 files verified against `VideoConferences` (CrudResource with PUT update + listConferenceTokens + listStreams + createStream). -- `[video/conference-tokens/*]` NO ISSUES — 3 files verified against `VideoConferenceTokens` (get, reset). -- `[video/streams/*]` NO ISSUES — 4 files verified against `VideoStreams` (get, update with PUT, delete). - -### calling/ - -- `[calling/index.mdx]` NO ISSUES — 14-section CardGroup totals 37 methods, matching `CallingNamespace` source. -- `[calling/*]` (37 method files) NO ISSUES — every file audited: all dispatch POST `/api/calling/calls`, signatures match source (`(params)` for `dial`/`update`, `(callId, params)` for the other 35). `sendFaxStop` and `receiveFaxStop` doc notes that initiation happens via the Relay client are correct. - -### registry/ - -- `[registry/index.mdx]` NO ISSUES — 4-resource CardGroup matches `RegistryNamespace`. Beta-path note documented. -- `[registry/brands/*]` NO ISSUES — 6 files verified against `RegistryBrands` (list, create, get, listCampaigns, createCampaign). -- `[registry/campaigns/*]` NO ISSUES — 6 files verified against `RegistryCampaigns` (get, update with PUT, listNumbers, listOrders, createOrder). -- `[registry/orders.mdx]` NO ISSUES — single-page for `RegistryOrders` (get only). -- `[registry/numbers.mdx]` NO ISSUES — single-page for `RegistryNumbers` (delete only). - -### logs/ - -- `[logs/index.mdx]` NO ISSUES — 4-sub-resource CardGroup matches `LogsNamespace`. -- `[logs/messages/*]` NO ISSUES — 3 files (list, get) verified against `MessageLogs` (`/api/messaging/logs`). -- `[logs/voice/*]` NO ISSUES — 4 files (list, get, listEvents) verified against `VoiceLogs` (`/api/voice/logs`). -- `[logs/fax/*]` NO ISSUES — 3 files (list, get) verified against `FaxLogs` (`/api/fax/logs`). -- `[logs/conferences/*]` NO ISSUES — 2 files (list only) verified against `ConferenceLogs` (`/api/logs/conferences`). Doc correctly notes no `get()` exists. - -### number-groups/ - -- `[number-groups/*]` NO ISSUES — 10 files verified against `NumberGroupsResource` (CrudResource PUT + listMemberships + addMembership + getMembership + deleteMembership). Top-level `/number_group_memberships/{id}` endpoint for get/delete correctly documented with Note. - -### datasphere/ - -- `[datasphere/*]` NO ISSUES — 10 files verified against `DatasphereDocuments` (CrudResource PATCH + search + listChunks + getChunk + deleteChunk). Flat folder layout; all examples correctly use `client.datasphere.documents.*`. - -### queues/ - -- `[queues/*]` NO ISSUES — 9 files verified against `QueuesResource` (CrudResource PUT + listMembers + getMember + getNextMember). - -### verified-callers/ - -- `[verified-callers/*]` NO ISSUES — 8 files verified against `VerifiedCallersResource` (CrudResource PUT + redialVerification + submitVerification). Verification sub-resource paths `/verified_caller_ids/{id}/verification` (POST redial, PUT submit) confirmed. - -### phone-numbers/ - -- `[phone-numbers/*]` NO ISSUES — 7 files verified against `PhoneNumbersResource` (CrudResource PUT + search). Index carries idiomatic-deviation note for Python-kwargs-style bodies. Search endpoint correctly maps to `/phone_numbers/search` GET. - -### addresses/ - -- `[addresses/*]` NO ISSUES — 5 files verified against `AddressesResource` (list, create, get, delete; no update). Index correctly notes absence of update. - -### short-codes/ - -- `[short-codes/*]` NO ISSUES — 4 files verified against `ShortCodesResource` (list, get, update with PUT; no create/delete). Index correctly notes pre-provisioned status. - -### recordings/ - -- `[recordings/*]` NO ISSUES — 4 files verified against `RecordingsResource` (list, get, delete; no create/update). - -### project/ - -- `[project/*]` NO ISSUES — 4 files verified against `ProjectTokens`. `update` correctly uses PATCH. - -### mfa/ - -- `[mfa/*]` NO ISSUES — 4 files verified against `MfaResource` (sms, call, verify). Sub-resource paths `/mfa/sms`, `/mfa/call`, `/mfa/{id}/verify` match source. - -### sip-profile/ - -- `[sip-profile/*]` NO ISSUES — 3 files verified against `SipProfileResource` (singleton get + PUT update). - -### pubsub/ - -- `[pubsub/*]` NO ISSUES — 2 files verified against `PubSubResource` (createToken only). Endpoint `/api/pubsub/tokens` POST matches source. - -### lookup/ - -- `[lookup/*]` NO ISSUES — 2 files verified against `LookupResource` (phoneNumber only). Endpoint `/api/relay/rest/lookup/phone_number/{e164}` matches source. - -### imported-numbers/ - -- `[imported-numbers/*]` NO ISSUES — 2 files verified against `ImportedNumbersResource` (create only). Endpoint `/api/relay/rest/imported_phone_numbers` POST matches. - -### chat/ - -- `[chat/*]` NO ISSUES — 2 files verified against `ChatResource` (createToken only). Endpoint `/api/chat/tokens` POST matches. - -### client/ - -- `[client/index.mdx]` NO ISSUES — Constructor params (project, token, host) and all 20 namespace `ParamField` entries match `RestClient` source exactly (fabric, calling, phoneNumbers, addresses, queues, recordings, numberGroups, verifiedCallers, sipProfile, lookup, shortCodes, importedNumbers, mfa, registry, datasphere, video, logs, project, pubsub, chat, compat). - -### REST root - -- `[rest/overview.mdx]` NO ISSUES — 10-card CardGroup covers major namespaces; `RestError` example accurate. -- `[rest/rest-error.mdx]` NO ISSUES — `body: string | Record` and `SignalWireRestError` alias both correctly documented (updated from prior session). - ---- - ---- - -## Agents Audit (in progress) - -**Scope:** `pages/reference/typescript/agents/agent-base/**` — pilot of 82 files -against `src/AgentBase.ts` at commit `ba6d5b1`. - -**Source file:** `temp/signalwire-typescript/src/AgentBase.ts` (2489 lines) -**AgentOptions type:** `temp/signalwire-typescript/src/types.ts:6-70` - -### agent-base/ progress — 82/82 AUDITED + FIXED - -| # | File | Status | Notes | -|---|------|--------|-------| -| 1 | `index.mdx` | FIXED | `tokenExpirySecs` default 900→3600 (source line 196); added 5 missing constructor params: `enablePostPromptOverride`, `checkForInputOverride`, `configFile`, `schemaPath`, `schemaValidation`. CardGroup verified: 81 cards = 81 method files. | -| 2 | `add-answer-verb.mdx` | clean | signature `(config?)` line 1306 | -| 3 | `add-function-include.mdx` | clean | `(url, functions, metaData?)` line 758; meta_data mapping ok | -| 4 | `add-hint.mdx` | clean | line 499 | -| 5 | `add-hints.mdx` | clean | line 509 | -| 6 | `add-internal-filler.mdx` | FIXED | Added `` restricting to 9 supported native function names (`SUPPORTED_INTERNAL_FILLER_NAMES` at line 651); clarified description (was "specific SWAIG function" — misleading) | -| 7 | `add-language.mdx` | clean | LanguageConfig has 7 fields incl. `functionFillers`; SWML key mappings (speech_model, function_fillers) correct | -| 8 | `add-mcp-server.mdx` | clean | `(url, opts?)` with headers/resources/resourceVars; `resource_vars` mapping ok | -| 9 | `add-pattern-hint.mdx` | FIXED | Added missing required `opts.hint` param (source line 520 requires 4 fields) + updated example | -| 10 | `add-post-ai-verb.mdx` | clean | line 1328 | -| 11 | `add-pre-answer-verb.mdx` | clean | line 1296 | -| 12 | `add-pronunciation.mdx` | clean | matches PronunciationRule (types.ts:91) | -| 13 | `add-skill.mdx` | clean | async, fails-closed behavior verified against source lines 1375-1425 | -| 14 | `add-skill-by-name.mdx` | clean | line 1440 | -| 15 | `add-swaig-query-params.mdx` | clean | merge-not-replace via `safeAssign` line 1512 confirmed | -| 16 | `as-router.mdx` | clean | line 2360 | -| 17 | `auto-map-sip-usernames.mdx` | FIXED | Rewrote from stub — added overview (3-bullet behavior list), `` about `enableSipRouting()` auto-calling, full example. Ported from Python counterpart. | -| 18 | `clear-post-ai-verbs.mdx` | clean | line 1355 | -| 19 | `clear-post-answer-verbs.mdx` | clean | line 1346 | -| 20 | `clear-pre-answer-verbs.mdx` | clean | line 1337 | -| 21 | `clear-swaig-query-params.mdx` | FIXED | Rewrote from stub — added ref links, Parameters None, Returns, full dynamic-config example (src line 1520 `this.swaigQueryParams = {}`) | -| 22 | `define-contexts.mdx` | clean | `(contexts?: ContextBuilder \| Record)` line 464; plain-dict quirk (dict ignored, new ContextBuilder) correctly documented | -| 23 | `define-tool.mdx` | FIXED | Added missing `opts.webhookUrl` + `opts.extraFields` params (src lines 1131-1133); added `default="false"` to `opts.secure` (SwaigFunction.ts:143) | -| 24 | `define-tools.mdx` | clean | `protected defineTools(): void` line 256; "not called automatically" note matches src comment | -| 25 | `define-typed-tool.mdx` | FIXED | Added `default="false"` to `opts.secure` (aligns with defineTool / SwaigFunction.ts:143) | -| 26 | `enable-debug-events.mdx` | clean | `(level=1)` line 803; `debug_webhook_url` wiring at 1887 confirmed | -| 27 | `enable-debug-routes.mdx` | FIXED | Rewrote misleading desc — source line 1551 is a no-op stub; debug routes auto-registered in `getApp()`. Added Parameters None + Example + ref link, parity-with-Python note | -| 28 | `enable-mcp-server.mdx` | clean | line 950 `_mcpServerEnabled = true`; `/mcp` JSON-RPC 2.0 endpoint accurate | -| 29 | `enable-sip-routing.mdx` | clean | `(autoMap=true, path='/sip')` line 817; autoMap triggers `autoMapSipUsernames()` | -| 30 | `extract-sip-username.mdx` | clean | static method line 912; strips `sip:`/`sips:` prefix + `@domain`; returns null if no `call.to` | -| 31 | `get-app.mdx` | clean | `getApp(): Hono` line 2004; lazy init of Hono app | -| 32 | `get-basic-auth-credentials.mdx` | FIXED | Source `"auto-generated"` not `"generated"` (line 2484); fixed both occurrences | -| 33 | `get-full-url.mdx` | clean | line 1635; proxy base takes precedence, optional basic-auth embed | -| 34 | `get-mcp-servers.mdx` | clean | line 961; read-only spread copy | -| 35 | `get-name.mdx` | clean | line 1364 | -| 36 | `get-post-prompt.mdx` | clean | line 422 | -| 37 | `get-prompt.mdx` | clean | line 394 | -| 38 | `get-prompt-pom.mdx` | FIXED | Added Parameters None + Example + ref links (line 410; returns null when POM empty or non-POM mode) | -| 39 | `get-registered-tools.mdx` | clean | line 1216 | -| 40 | `get-tool.mdx` | clean | line 1237 | -| 41 | `handle-mcp-request.mdx` | clean | line 994; methods: initialize, notifications/initialized, tools/list, tools/call, ping | -| 42 | `has-skill.mdx` | clean | line 1470 | -| 43 | `is-mcp-server-enabled.mdx` | clean | line 956 | -| 44 | `list-skills.mdx` | clean | line 1461 | -| 45 | `manual-set-proxy-url.mdx` | clean | line 1532; strips trailing slashes, clears env-source flag | -| 46 | `native-functions.mdx` | clean | documents `setNativeFunctions` (line 640) + ctor `nativeFunctions` option | -| 47 | `on-debug-event.mdx` | clean | line 1705 no-op hook; invoked at line 2262 on /debug_events | -| 48 | `on-function-call.mdx` | FIXED | Wrong Warning — hook CAN short-circuit dispatch (src 2213 uses returned hookResult). Replaced with Note; fixed Returns type to include `Record` | -| 49 | `on-summary.mdx` | clean | line 1673; invoked at 2246 post-prompt path | -| 50 | `on-swml-request.mdx` | FIXED | Doc missing `callbackPath` + `context` params (src 1693); Returns was `void\|Promise` but source returns optional modifications object (merged into AI config) | -| 51 | `prompt-add-section.mdx` | clean | line 341 | -| 52 | `prompt-add-subsection.mdx` | clean | line 376 | -| 53 | `prompt-add-to-section.mdx` | clean | line 361 | -| 54 | `prompt-has-section.mdx` | clean | line 386 | -| 55 | `register-sip-username.mdx` | clean | line 832 (username lowercased) | -| 56 | `register-swaig-function.mdx` | FIXED | DataMap example called `.output()` with plain object; source expects FunctionResult (DataMap.ts:302). Rewrote example + updated line highlight | -| 57 | `remove-skill.mdx` | clean | line 1453; async by instance ID | -| 58 | `remove-skill-by-name.mdx` | FIXED | Rewrote — old doc claimed "removes every instance" + mentioned nonexistent `cleanup()`. Source (line 1484) removes FIRST match only. Added ref link to `removeSkill`, full Example | -| 59 | `render-swml.mdx` | FIXED | Added missing `modifications` parameter (src 1754; `global_data` deep-merged, rest override AI config) | -| 60 | `reset-contexts.mdx` | FIXED | Stub → added Parameters None, Returns, Example; ref links to defineContexts/ContextBuilder | -| 61 | `run.mdx` | FIXED | Doc said Parameters None; source (line 2391) takes `opts?: { host?; port? }`. Added Indent of opts fields | -| 62 | `serve.mdx` | FIXED | Same missing `opts` params as run.mdx (src 2368); added Note about `SWAIG_CLI_MODE` env var early-return (src 2370) | -| 63 | `set-dynamic-config-callback.mdx` | clean | line 1501 | -| 64 | `set-function-includes.mdx` | FIXED | Stub → added Note about silent filtering (src 772 filters entries without url/functions array), full Example with meta_data, ref link | -| 65 | `set-global-data.mdx` | FIXED | **Wrong description** — claimed "Replace the entire global data object" but src (line 621) uses `safeAssign` → merges, matching Python `.update()` semantics. Rewrote desc + added Note explaining the `set` prefix is misleading | -| 66 | `set-internal-fillers.mdx` | FIXED | Example used invalid filler names `pre_speech`, `summary` (not in `SUPPORTED_INTERNAL_FILLER_NAMES`). Rewrote example with valid names (`next_step`, `check_time`) + added Note listing all 9 supported names | -| 67 | `set-languages.mdx` | clean | line 555 | -| 68 | `set-param.mdx` | clean | line 592 | -| 69 | `set-params.mdx` | clean | line 602; merges via safeAssign | -| 70 | `set-post-prompt.mdx` | clean | line 330 | -| 71 | `set-post-prompt-llm-params.mdx` | clean | line 793 | -| 72 | `set-post-prompt-url.mdx` | clean | line 1625 | -| 73 | `set-prompt-llm-params.mdx` | clean | line 783 | -| 74 | `set-prompt-pom.mdx` | FIXED | Stub → added Warning about `usePom: true` throw (src line 440), detailed ParamField sub-field list, Example. Ref links to promptAddSection + getPromptPom | -| 75 | `set-prompt-text.mdx` | clean | line 320 | -| 76 | `set-pronunciations.mdx` | FIXED | Stub → added full ParamField describing PronunciationRule shape (replace/with/ignoreCase per types.ts:91), Example | -| 77 | `set-web-hook-url.mdx` | clean | line 1615 | -| 78 | `setup-graceful-shutdown.mdx` | clean | static line 2440; SIGTERM/SIGINT, default timeout 5000 | -| 79 | `update-global-data.mdx` | FIXED | Doc claimed `setGlobalData()` replaces; both methods identical (safeAssign). Reworded to say functionally equivalent to setGlobalData | -| 80 | `validate-basic-auth.mdx` | clean | line 1715; Warning re: middleware not calling hook confirmed (no `this.validateBasicAuth` refs in src) | -| 81 | `validate-tool-token.mdx` | FIXED | Stub → added Note about automatic dispatch-path invocation, full ParamField list with src-accurate edge cases (empty callId forwarded, missing token on secure → false, non-SwaigFunction treated as secure) | - -### agent-base/ summary - -82/82 files audited. 20 fixes applied across resume (files 21-82); 12 FIXED in -this session: - -- **Missing/wrong params:** define-tool (webhookUrl, extraFields), render-swml - (modifications), on-swml-request (callbackPath, context), run + serve (opts) -- **Wrong behavioral claims:** on-function-call (hook CAN intercept), - set-global-data (merges, doesn't replace), update-global-data (describes - set-global-data as replace), remove-skill-by-name (first match, not every - instance) -- **Wrong defaults/literals:** define-tool secure default (false), - define-typed-tool secure default, get-basic-auth-credentials source label - (`"auto-generated"` not `"generated"`) -- **Broken example code:** register-swaig-function (.output() needs - FunctionResult, not plain object), set-internal-fillers (used invalid - filler names) -- **Stub pages:** clear-swaig-query-params, enable-debug-routes, - get-prompt-pom, reset-contexts, set-function-includes, set-prompt-pom, - set-pronunciations, validate-tool-token - -### agent-server/ — AUDITED + FIXED (10/10) - -**Source:** `temp/signalwire-typescript/src/AgentServer.ts` (415 lines) - -| # | File | Status | Notes | -|---|------|--------|-------| -| 1 | `index.mdx` | FIXED | Added missing `opts.logLevel` ctor param + `logLevel` property; added 3 missing CardGroup entries (setupSipRouting, registerGlobalRoutingCallback pages; registerSipUsername combined into sip-routing page per Python pattern); added SIP-routing mention to overview | -| 2 | `get-agent.mdx` | clean | `getAgent(route)` line 169; Map.get lookup | -| 3 | `get-agents.mdx` | clean | `getAgents(): Map` line 160 (returns internal ref — note unnecessary) | -| 4 | `get-app.mdx` | clean | `getApp(): Hono` line 362; root listing only mounted if no agent at `/` (line 371) | -| 5 | `register.mdx` | clean | `register(agent, route?)` line 110; throws on duplicate route, mounts agent.getApp() | -| 6 | `run.mdx` | FIXED | Added `SWAIG_CLI_MODE=true` early-return note (line 395) + ServerlessAdapter note for serverless mode | -| 7 | `static-files.mdx` | FIXED | Wrong default `/static` → `/` (source line 180); updated route ParamField | -| 8 | `unregister.mdx` | FIXED | Wrong return type `void` → `boolean` (source line 150 returns Map.delete result) | -| 9 | `sip-routing.mdx` | CREATED | Covers both `setupSipRouting` + `registerSipUsername` (Python pattern). Ported descriptions, params, examples from Python counterpart | -| 10 | `routing-callback.mdx` | CREATED | `registerGlobalRoutingCallback(callbackFn, path)` line 316. RoutingCallback type `(body) => string \| null \| undefined \| Promise<...>` (no Request arg in TS, unlike Python). Corrected "powers setupSipRouting" claim — TS uses `agent.enableSipRouting()` directly, not this method | - -### agent-server/ summary - -10 pages. 5 fixes + 2 new pages. Index CardGroup now has 9 entries matching 9 -method pages (10 public methods with registerSipUsername combined into sip-routing). - -### function-result/ — AUDITED + FIXED (50/50) - -**Source:** `temp/signalwire-typescript/src/FunctionResult.ts` (866 lines) - -49 public methods + index. All files match source. 3 fixes: - -| File | Status | Notes | -|------|--------|-------| -| `index.mdx` | clean | Properties (response, action, postProcess), 49 CardGroup entries. Matches Python reference | -| `execute-swml.mdx` | FIXED | swmlContent type was missing third accepted form `{ toDict(): Record }` (source line 308, 316-317). Added form + description | -| `join-conference.mdx` | FIXED | 5 missing defaults: `beep='true'`, `maxParticipants=250`, `statusCallbackMethod='POST'`, `recordingStatusCallbackMethod='POST'`, `recordingStatusCallbackEvent='completed'` (source lines 619-653 use these as comparison values) | -| `tap.mdx` | FIXED | 3 missing defaults: `direction='both'`, `codec='PCMU'`, `rtpPtime=20` (source lines 544-546 compare against these) | -| All other 46 files | clean | set-response, set-post-process, add-action, add-actions, to-dict, connect, hangup, hold, swml-transfer, say, wait-for-user, stop, play-background-file, stop-background-file, record-call, stop-record-call, stop-tap, update-global-data, remove-global-data, set-metadata, remove-metadata, swml-change-step, swml-change-context, switch-context, swml-user-event, simulate-user-input, toggle-functions, enable-functions-on-timeout, add-dynamic-hints, clear-dynamic-hints, set-end-of-speech-timeout, set-speech-event-timeout, update-settings, enable-extensive-data, replace-in-history, send-sms, pay, create-payment-prompt, create-payment-action, create-payment-parameter, sip-refer, join-room, execute-swml (after fix), execute-rpc, rpc-dial, rpc-ai-message, rpc-ai-unhold | - -### context-builder/ root — AUDITED + FIXED (14/14 root files) - -**Source:** `temp/signalwire-typescript/src/ContextBuilder.ts` (1150 lines) -**Classes:** ContextBuilder, Context, Step, GatherInfo, GatherQuestion + free function `createSimpleContext` - -Root-level ContextBuilder class (public methods only: addContext, getContext, reset, toDict, validate, + `createSimpleContext` helper). - -| File | Status | Notes | -|------|--------|-------| -| `index.mdx` | FIXED | Added `createSimpleContext` card (source line 1148 exports helper; Python docs it; TS was missing) | -| `add-context.mdx` | clean | `addContext(name)` line 963; throws on duplicate/max-contexts | -| `create-simple-context.mdx` | CREATED | `createSimpleContext(name='default')` free function — matches Python counterpart | -| `gather-classes.mdx` | clean | GatherQuestion + GatherInfo docs combined per Python pattern | -| `get-context.mdx` | clean | `getContext(name): Context \| undefined` line 979 | -| `get-questions.mdx` | clean | `GatherInfo.getQuestions()` line 121 — public, no Python counterpart (TS extra but matches source) | -| `reset.mdx` | FIXED | **Broken example** — used nonexistent `agent.onRequest(...)`. TS uses `setDynamicConfigCallback((queryParams, bodyParams, headers, agent) => {...})`. Rewrote example | -| `to-dict.mdx` | clean | `toDict()` line 1131 calls `validate()` then serializes | -| `validate.mdx` | FIXED | Missing 5 of 10 documented checks — added `initial_step` validation, step-level `valid_steps` and `valid_contexts` validation, gather_info duplicate-key validation, reserved native tool name collision check | -| `get-completion-action.mdx` | clean (@internal) | Matches source `GatherInfo.getCompletionAction()` line 129 — marked @internal in source but has doc page. Doc labels "internal method" honestly | -| `get-gather-info.mdx` | clean (@internal) | Matches `Step.getGatherInfo()` line 383 — same pattern | -| `get-step-order.mdx` | clean (@internal) | Matches `Context.getStepOrder()` line 813 | -| `get-steps.mdx` | clean (@internal) | Matches `Context.getSteps()` line 808 | -| `get-valid-contexts.mdx` | clean (@internal) | Matches `Context.getValidContexts()` line 823 | - -**Structural drift (P4):** TS has 5 doc pages for @internal getters (Context.getStepOrder/getSteps/getValidContexts, Step.getGatherInfo, GatherInfo.getCompletionAction) that Python doesn't document. Factually accurate but likely unintended exposure. Candidate for deletion or marking as "internal" in future cleanup. - -**Coverage gap (P4):** `Context.toDict()` (source line 854) has no doc page — Python also doesn't have it. Treating as intentional omission (serialization internals not part of user-facing API). - -### context-builder/context/ subclass — AUDITED + FIXED (23/23) - -- `context/index.mdx` clean — CardGroup has 22 entries matching 22 method files. `name` property documented. TS has `set-initial-step.mdx` that Python doesn't (legitimate — source line 670). -- 22 method files audited against `Context` class in `ContextBuilder.ts`. 3 fixes: - - `add-step.mdx` FIXED — added throws note (src 542-545 throws on duplicate name / max 100 exceeded); Python has same note. - - `set-initial-step.mdx` FIXED — highlight `{6}`→`{7}` to point at setInitialStep call, not addStep. - - `set-isolated.mdx` FIXED — added Note about reset override exception (src JSDoc 683-687: `consolidate`/`fullReset` skip the wipe). -- Other 19 files clean: add-bullets, add-enter-filler, add-exit-filler, add-section, add-system-bullets, add-system-section, get-step, move-step, remove-step, set-consolidate, set-enter-fillers, set-exit-fillers, set-full-reset, set-post-prompt, set-prompt, set-system-prompt, set-user-prompt, set-valid-contexts, set-valid-steps. -- Coverage: Context public methods `getInitialStep`, `renderPrompt`, `renderSections`, `renderSystemPrompt`, `toDict` (src 818/827/833/839/854) have no doc pages — rendering/serialization internals; Python omits too. Intentional. - -### context-builder/step/ subclass — AUDITED + FIXED (18/18) - -- `step/index.mdx` clean — constructor `(name: string)`, `name` public property, 17-method CardGroup matches source (addBullets, addGatherQuestion, addSection, clearSections, setEnd, setFunctions, setGatherInfo, setResetConsolidate, setResetFullReset, setResetSystemPrompt, setResetUserPrompt, setSkipToNextStep, setSkipUserTurn, setStepCriteria, setText, setValidContexts, setValidSteps). -- 17 method files audited against `Step` class in `ContextBuilder.ts`. 3 fixes: - - `add-gather-question.mdx` FIXED — added Note about gather-mode function-lock behavior (src JSDoc 347-361): only `gather_submit` + per-question `functions` callable while asking; `next_step`/`change_context` filtered. - - `set-end.mdx` FIXED — TS doc description was misleading ("ends the conversation"). Source JSDoc (lines 290-303) is explicit: `end=true` exits step mode only, does NOT hang up. Rewrote description + added Warning. - - `set-functions.mdx` FIXED — added Warning about step inheritance behavior (src JSDoc 233-246): step inherits previous step's functions unless `setFunctions()` is explicitly called, most common bug source; added Note on internal-function protection; added full param form list (`string[]`, `[]`, `"none"`). -- Other 14 files clean: add-bullets, add-section, clear-sections, set-gather-info, set-reset-consolidate, set-reset-full-reset, set-reset-system-prompt, set-reset-user-prompt, set-skip-to-next-step, set-skip-user-turn, set-step-criteria, set-text, set-valid-contexts, set-valid-steps. -- Coverage: Step public methods `getGatherInfo` (383), `getStepValidContexts` (399), `getValidSteps` (391), `renderText` (453 private), `toDict` (473) have no doc pages — internals; Python omits too. - -### overview + helpers (2 files) — AUDITED + FIXED - -- `overview.mdx` FIXED — removed "search" from subtitle (TS has no search module in source). P4 coverage gap logged: WebService card + doc page missing (src: `WebService.ts`); CLI/Search/MCP/BedrockAgent refs in Python overview correctly absent from TS (those modules don't exist in TS source). -- `helpers.mdx` FIXED — added `validateUrl` section (exported from SecurityUtils.ts:146 but doc was missing it). All 14 other exports verified against source. - -### prefabs/ — AUDITED + FIXED (6/6) - -**Source:** `temp/signalwire-typescript/src/prefabs/` - -- `index.mdx` FIXED — tool table had wrong names for ConciergeAgent, InfoGathererAgent, ReceptionistAgent, SurveyAgent. Corrected against source tool registrations. -- `concierge-agent.mdx` clean — ConciergeConfig (9 fields) matches src 15-35. Tools not listed in page (acceptable, matches Python depth). -- `faq-bot-agent.mdx` clean — FAQBotConfig (9 fields), FAQEntry (4 fields), 2 tools (`search_faq` always, `escalate` conditional on `escalationNumber`) all verified. -- `info-gatherer-agent.mdx` clean — InfoGathererConfig (5 fields), InfoGathererQuestion (3 fields), 2 tools (`start_questions`, `submit_answer`), `setQuestionCallback` method all verified. -- `receptionist-agent.mdx` FIXED — tool table had wrong name `get_department_list`; source has `collect_caller_info` (src 208). Noted `department` enum constraint on transfer_call (src 251). -- `survey-agent.mdx` FIXED — tool table missing 2 tools (`validate_response` at src 387, `log_response` at src 419); doc only listed 3 of 5. - -### swaig-function/ — AUDITED + FIXED (4/4) - -**Source:** `temp/signalwire-typescript/src/SwaigFunction.ts` (277 lines) - -- `index.mdx` FIXED — Added `validate-args` card + link ref (CardGroup was missing it; TS source has public `validateArgs` method at line 186). Options interface (12 fields) and class properties (13 fields) all verified against src. -- `execute.mdx` FIXED — Highlight `{20}`→`{19}` (pointed at console.log, should be the `execute()` call). Corrected output comment: `toDict()` omits `action` when array is empty (src 855-857). -- `to-swaig.mdx` clean — `toSwaig(baseUrl, token?, callId?)` matches src 257; TS lacks Python's `include_auth` param (legitimate drift). -- `validate-args.mdx` CREATED — ported from Python counterpart; src 186-205 (Ajv-based validation, early-returns `[true, []]` on empty schema). - -### swml-service/ — AUDITED + FIXED (7/7) - -**Source:** `temp/signalwire-typescript/src/SWMLService.ts` (717 lines) - -- `index.mdx` FIXED — added 5 missing constructor options (host, port, schemaPath, configFile, schemaValidation); fixed `name` to required={true} (src 158 — required in non-deprecated overload); expanded Properties from 2 to 12 to match source (host, port, log, security, sslEnabled, sslCertPath, sslKeyPath, domain, schemaUtils, verbRegistry added). -- `add-verb.mdx` clean — `addVerb(name, config): this` delegates to swmlBuilder (src 389). Return type drift vs Python (TS fluent `this`, Python `bool`) is legitimate. -- `get-app.mdx` clean — `getApp(): Hono` (src 631-633). -- `get-builder.mdx` FIXED — example used empty-arg `new SWMLService()` (deprecated overload). Changed to `{ name: 'my-ivr' }` + demonstrates actual builder use. -- `render-swml.mdx` clean — delegates to swmlBuilder.getDocument() (src 435). Version 1.0.0 output confirmed against SwmlBuilder.ts:92. -- `run.mdx` FIXED — added `SWAIG_CLI_MODE=true` early-return note (src 663); added full `opts` param with `sslCert`/`sslKey`/`sslEnabled`/`domain` (src 656-661); fixed host/port default descriptions. -- `set-on-request-callback.mdx` clean — `OnRequestCallback` type (src 138-142) matches doc description. - -**Coverage gap (P4):** TS source has ~20 public methods on SWMLService; only 6 method pages exist. Python documents 15. Missing TS pages: addSection, addVerbToSection, asRouter, extractSipUsername, getBasicAuthCredentials, getDocument, manualSetProxyUrl, onRequest, registerRoutingCallback, registerVerbHandler, renderDocument, resetDocument, serve, stop. Large follow-up scope. - -### pom-builder/ — AUDITED -- NO ISSUES (9/9) - -**Source:** `temp/signalwire-typescript/src/PomBuilder.ts` (450+ lines) - -All 9 files clean — `index.mdx`, `add-section.mdx` (src 225), `add-subsection.mdx` (src 286), `add-to-section.mdx` (src 263), `find-section.mdx` (src 325), `get-section.mdx` (src 316), `has-section.mdx` (src 307), `render-markdown.mdx` (src 401), `to-dict.mdx` (src 366). All signatures, nested Indent params, and highlights verified against source. - -**Coverage gap (P4):** TS source has 13 public methods on PomBuilder; 8 documented. Missing: `renderXml` (422), `toJson` (374), `reset` (213), `addPomAsSubsection` (344), `fromSections` (383, static). Python docs `render` (unified Markdown/XML) and `toJson` — TS splits rendering. Also missing: PomSection class page (exposed via `getSection`/`findSection`). Overview line "can render to Markdown format" should be updated to "Markdown or XML" once renderXml page exists. - -### data-map/ — AUDITED -- NO ISSUES (19/19) - -**Source:** `temp/signalwire-typescript/src/DataMap.ts` (455 lines) - -All 19 files clean. Instance methods verified: `purpose` (132), `description` (146, alias), `parameter` (175), `expression` (203), `webhook` (229), `webhookExpressions` (253), `body` (264), `params` (275), `foreach` (286), `output` (302), `fallbackOutput` (313), `errorKeys` (323), `globalErrorKeys` (337), `enableEnvExpansion` (90), `setAllowedEnvPrefixes` (104, instance), `registerWithAgent` (347), `toSwaigFunction` (356). Helper functions: `createSimpleApiTool` (402), `createExpressionTool` (432). Index CardGroup has 18 entries matching 17 methods + helper-functions. - -Every "throws if no webhook" claim on `body`/`output`/`params`/`foreach`/`webhookExpressions`/`errorKeys` verified against source. Nested Indent ParamFields used correctly. All highlight line numbers verified. Variable substitution table matches documented patterns. - -### livewire/ — AUDITED + FIXED (14/14) - -**Source:** `temp/signalwire-typescript/src/livewire/index.ts` (947 lines) - -- `index.mdx` clean — compat layer description, namespace aliases (voice/llm/cli/inference) verified against src 920/937/945/884. -- `agent/index.mdx` clean — Agent class (src 121-211) with 13 constructor options + 4 properties. -- `agent-session/index.mdx` FIXED — removed fabricated `voiceOptions` (not in source); added 8 missing real options (`tools`, `mcpServers`, `allowInterruptions`, `minInterruptionDuration`, `minEndpointingDelay`, `maxEndpointingDelay`, `maxToolSteps`, `preemptiveGeneration`) with correct defaults from src 341-346. -- `agent-session/start.mdx` FIXED — added missing `record?: boolean` option (src 387). -- `agent-session/say.mdx` clean — queuing semantics (src 467-475) correctly documented. -- `agent-session/generate-reply.mdx` clean — src 478-482. -- `agent-session/interrupt.mdx` clean — no-op (src 485-487). -- `agent-session/update-agent.mdx` clean — src 490-496. -- `function-tool.mdx` clean — `tool()` factory + `FunctionTool` interface (src 526-549, 109-114). -- `job-context.mdx` clean — JobContext (src 612-635), JobProcess (594-596), Room (603-605). -- `plugins.mdx` clean — 5 plugin stubs + 3 inference classes match src 827-913. -- `run-app.mdx` clean — runApp (src 666-705) + defineAgent (645-650). -- `run-context.mdx` clean — RunContext (src 282-299). Minor: constructor has optional 2nd arg (`speechHandle`, `functionCall`) not documented — accepted. -- `signals.mdx` FIXED — ChatContext section falsely claimed "empty stub with no methods or properties" but src 927-934 defines `messages` property and `append(options)` method. Rewrote with actual Properties + append method docs. - -### configuration/ — AUDITED + FIXED (64/64) - -**Source:** `temp/signalwire-typescript/src/{AuthHandler,ConfigLoader,PromptManager,SchemaUtils,ServerlessAdapter,SessionManager,SslConfig,Logger}.ts` - -- `index.mdx` clean — 9-card CardGroup matches 7 sub-class folders + `environment-variables.mdx` + `logging.mdx`. Layered config priority (constructor > env > config file > defaults) documented correctly. -- `environment-variables.mdx` spot-checked — structural content solid (Server, Auth, SSL sections with defaults); full deep verify against source pending. -- `logging.mdx` spot-checked — Logger/getLogger/setGlobalLogLevel API described; full deep verify against Logger.ts pending. - -All 7 configuration sub-classes fully audited in session 4. See per-class -sections below for details. - -### configuration/auth-handler/ — AUDITED + FIXED (6/6) - -**Source:** `temp/signalwire-typescript/src/AuthHandler.ts` (256 lines) - -- `index.mdx` FIXED — Missing `config.apiKeyHeader` field (src 20, 71). - Added with default `'X-Api-Key'` and case-insensitive lookup note. -- `has-api-key-auth.mdx` clean — `hasApiKeyAuth(): boolean` (src 245). -- `has-basic-auth.mdx` clean — `hasBasicAuth(): boolean` (src 253). -- `has-bearer-auth.mdx` clean — `hasBearerAuth(): boolean` (src 237). -- `middleware.mdx` FIXED — Missing `optional = false` param (src 163). Added - ParamField, updated description, added second example demonstrating the - permissive mode. -- `validate.mdx` clean — `validate(headers): Promise` (src 59); 4-way - auth order verified (Bearer/APIKey/Basic/Custom) + allowUnauthenticated - fallback correctly documented. - -**Coverage gap (P4):** 5 public methods not documented — `verifyBasicAuth` -(src 124), `verifyBearerToken` (src 139), `verifyApiKey` (src 153), -`expressMiddleware` (src 186), `getAuthInfo` (src 206). These are useful -standalone verification helpers and framework adapters. Follow-up session -recommended to add pages. - -### configuration/ssl-config/ — AUDITED + FIXED (7/7) - -**Source:** `temp/signalwire-typescript/src/SslConfig.ts` (118 lines) - -- `index.mdx` FIXED — Added missing `## Constructor` section (opts: SslOptions) - with cross-reference to Properties. 6 properties already documented with - env-var fallbacks; 6-card CardGroup matches methods. -- `get-cert.mdx` clean — `getCert(): string | null` (src 71); null when - certPath unset or file missing. -- `get-key.mdx` clean — `getKey(): string | null` (src 80). -- `get-hsts-header.mdx` clean — `getHstsHeader(): string | null` (src 89); - null when HSTS or SSL disabled (src 90); format - `max-age=${hstsMaxAge}; includeSubDomains`. -- `get-server-options.mdx` clean — `getServerOptions(): { cert, key } | null` - (src 98); null when either file missing. -- `hsts-middleware.mdx` clean — `hstsMiddleware()` Hono middleware (src 109). -- `is-configured.mdx` clean — `isConfigured(): boolean` (src 61); requires - SSL enabled AND both cert/key files exist on disk (src 62-64). - -### configuration/serverless-adapter/ — AUDITED -- NO ISSUES (8/8) - -**Source:** `temp/signalwire-typescript/src/ServerlessAdapter.ts` (221 lines) - -All 8 files clean. `index.mdx` covers ctor `platform='auto'` (src 53) with 5 -valid enum values + 7-card CardGroup. Methods verified: -- `detectPlatform` (src 61) — 4 platform env-var checks + default fallback. -- `getPlatform` (src 73). -- `handleRequest` (src 83) — event normalization, URL building, Hono routing. -- `generateUrl` (src 134) — per-platform URL construction + env-var defaults - for region/project/functionName/stage/apiId all documented. -- `createLambdaHandler` (src 171, static). -- `createGcfHandler` (src 181, static). -- `createAzureHandler` (src 204, static). - -### configuration/config-loader/ — AUDITED + FIXED (9/9) - -**Source:** `temp/signalwire-typescript/src/ConfigLoader.ts` (447 lines) - -- `index.mdx` FIXED — Ctor param was `filePath: string`; source (src 33) is - `filePaths?: string | string[]`. Fixed to document both forms + ordered - array search behavior. Added `Properties` section with `configPaths` - getter (src 56-57). -- `get.mdx` clean — `get(path, defaultValue?): T` (src 182); prototype- - pollution blocklist verified (src 184-186). -- `get-all.mdx` clean — `getAll(): Record` (src 247); - shallow copy via spread. -- `get-file-path.mdx` clean — `getFilePath(): string | null` (src 263); - null when loaded from object (src 430). -- `has.mdx` clean — `has(path): boolean` (src 229). -- `load.mdx` clean — `load(filePath): this` (src 65); throws on missing file - (src 67-69); interpolates env vars. -- `load-from-object.mdx` clean — `loadFromObject(obj): this` (src 428); - sets filePath to null. -- `search.mdx` FIXED — Doc was missing `additionalPaths` + `serviceName` - params (src 88). Only listed 3 of 6 default search paths. Rewrote - Parameters to cover all three args, added full 6-path default list from - `_buildSearchPaths` (src 147-174), documented service-specific variants - + additionalPaths precedence. -- `set.mdx` clean — `set(path, value): this` (src 205); prototype-pollution - blocklist verified (src 207-209). - -**Coverage gap (P4):** 8 public methods not documented — `static findConfigFile` -(src 109), `getConfig` alias (src 255), `getConfigFile` alias (src 271), -`hasConfig` (src 289), `getSection` (src 298), `substituteVars` (src 316), -`mergeWithEnv` (src 367), `interpolateEnvVars` (src 439). Significant surface -missing especially `mergeWithEnv` + `getSection` which are core to runtime -config loading. Follow-up session recommended. - -### configuration/prompt-manager/ — AUDITED -- NO ISSUES (10/10) - -**Source:** `temp/signalwire-typescript/src/PromptManager.ts` (133 lines) - -All 10 files clean. `index.mdx` covers ctor `usePom=true` (src 20) + 9-card -CardGroup matching 9 public methods. Method files verified: `setPromptText` -(src 31), `setPostPrompt` (39), `addSection` (48, full 5-field opts: body/ -bullets/numbered/numberedBullets/subsections), `addToSection` (70, opts: -body/bullet/bullets), `addSubsection` (87, opts: body/bullets), `hasSection` -(104, `pom?.hasSection ?? false`), `getPrompt` (112, rawText-over-POM -precedence), `getPostPrompt` (122), `getPomBuilder` (130). Nested Indent -blocks used correctly. getPrompt precedence (`rawText !== null` first, then -POM markdown) verified against src 113-115. - -### configuration/schema-utils/ — AUDITED + FIXED (10/10) - -**Source:** `temp/signalwire-typescript/src/SchemaUtils.ts` (361 lines) - -- `index.mdx` FIXED — Added missing `opts.schemaPath` ctor option (src 47, 50). - Env-var fallback for `opts.skipValidation` correctly documented. 9-card - CardGroup matches 9 public methods. -- `clear-cache.mdx` clean — `clearCache(): void` (src 341). -- `get-cache-size.mdx` clean — `getCacheSize(): number` (src 349). -- `get-verb-description.mdx` clean — `getVerbDescription(verbName): string` - (src 158); empty string when missing (`?? ''`). -- `get-verb-names.mdx` clean — `getVerbNames(): string[]` (src 124). -- `get-verb-properties.mdx` clean — `getVerbProperties(verbName): Record` - (src 134); returns `{}` when not found. -- `get-verb-required-properties.mdx` clean — `getVerbRequiredProperties(verbName): string[]` - (src 147). -- `has-verb.mdx` clean — `hasVerb(verbName): boolean` (src 168). -- `validate.mdx` clean — `validate(swml: string | Record): ValidationResult` - (src 231); 4 doc-level checks (top-level keys, version, sections, AI verb - structure) + LRU cache all verified. -- `validate-verb.mdx` clean — `validateVerb(verbName, config): ValidationResult` - (src 181); signature and "checks verb exists + required properties" prose - verified against src 188-220. - -### configuration/session-manager/ — AUDITED + FIXED (11/11) - -**Source:** `temp/signalwire-typescript/src/SessionManager.ts` (311 lines) - -- `index.mdx` FIXED — Added `Properties` section documenting `debugMode` - public mutable flag (src 42). Constructor params `tokenExpirySecs`/`secretKey` - already accurate. CardGroup covers 10 public methods; `activateSession`/ - `endSession` intentionally omitted (legacy no-ops for Python parity). -- `cleanup.mdx` clean — `cleanup(maxAgeMs?): void` (src 272); default - `tokenExpirySecs * 1000` documented; iterates timestamps, deletes stale. -- `create-session.mdx` clean — `createSession(callId?): string` (src 62); - returns `callId` or `randomBytes(16).toString('base64url')`. -- `create-tool-token.mdx` clean — alias for generateToken (src 92). -- `debug-token.mdx` FIXED — Major rewrite. Wrong return type (doc had flat - camelCase fields + `| null`; source `DebugTokenResult` is nested with - snake_case `components.call_id` / `status.is_expired` and never returns null, - src 12-30). Missing `debugMode` requirement (src 170-172: returns - `{ valid_format: false, error: "debug mode not enabled" }` when disabled). - Added Warning box, documented all nested fields including 8-char truncation - of `call_id`/`signature` (src 201, 206), fixed example to enable debugMode - and use correct field paths. -- `delete-session-metadata.mdx` clean — `deleteSessionMetadata(sessionId): boolean` - (src 308); returns `Map.delete` result. -- `generate-token.mdx` clean — token format - `${callId}.${functionName}.${expiry}.${nonce}.${signature}` then base64url - (src 74-81). -- `get-session-metadata.mdx` FIXED — Wrong return type `Record | undefined`. - Source (src 234) uses `?? {}` and never returns undefined; JSDoc at 227-228 - explicitly documents this Python-compat behavior. Updated return type, - added note, extended example showing empty-object return for unknown session. -- `set-session-metadata.mdx` FIXED — Missing the three-argument - `setSessionMetadata(sessionId, key, value)` overload (src 249, 250-259). - Added Info box covering both signatures, documented `metadataOrKey` + `value` - params, clarified return-type split (`void` bulk vs `boolean` single), added - 3-arg example. -- `validate-token.mdx` clean — `validateToken(callId, functionName, token): boolean` - (src 103); 6 distinct checks verified (format/callId/function/expiry/signature/callIdMatch). -- `validate-tool-token.mdx` clean — reordered alias (src 156). - -Significant follow-up scope — recommend new session. - -### skills/ — AUDITED + FIXED (20/20) - -**Source:** `temp/signalwire-typescript/src/skills/builtin/*.ts` (20 skills) - -**Prior session deep audit (4):** -- `index.mdx` FIXED — tool counts: `datetime` 1→2, `google_maps` 2→4. -- `datetime.mdx` FIXED — tool name `get_datetime`→`get_current_time`+`get_current_date`. -- `joke.mdx` FIXED — added missing `tool_name` param (default `tell_joke`). -- `math.mdx` clean. - -**This session deep audit (17):** - -| File | Status | Notes | -|------|--------|-------| -| `api-ninjas-trivia.mdx` | FIXED | Added missing `tool_name` (default `get_trivia`) + `categories` params; added multi-instance note. | -| `ask-claude.mdx` | FIXED | Corrected `api_key` description — handler reads `ANTHROPIC_API_KEY` directly (ask_claude.ts:136), not as config fallback. TS-only skill (no Python counterpart). | -| `claude-skills.mdx` | clean | All 13 params match src; matches Python doc. | -| `custom-skills.mdx` | clean | TS-only skill; Python doc of same filename documents different concept — legitimate divergence. | -| `datasphere.mdx` | FIXED | Added `{query}` placeholder note on `no_results_message`; normalized `default={'"..."'}`→`default="..."`; noted tool_name required for multi-instance. | -| `datasphere-serverless.mdx` | FIXED | Removed false env-fallback claims — the serverless DataMap build path (`buildDataMapFunction` 193-197) reads config-only, not env. Added `{query}` note. | -| `google-maps.mdx` | FIXED | Major rewrite: doc had wrong tools `get_directions, find_place`; source has 4 tools `compute_route`, `lookup_address`, `geocode_address`, `compute_route_by_coords`. Added 4 `*_tool_name` params. Corrected `api_key` description — handlers read `GOOGLE_MAPS_API_KEY` env directly. | -| `info-gatherer.mdx` | clean | 3 params match src; prefix-based multi-instance verified. | -| `mcp-gateway.mdx` | FIXED | Normalized `tool_prefix` default style. Auth token env fallback verified working (unlike some other skills). | -| `native-vector-search.mdx` | FIXED | Major rewrite: doc had wrong tool default `search_documents` (source: `search_knowledge`). Added 10 missing params (`max_content_length`, `keyword_weight`, `model_name`, `response_format_callback`, `description`, `hints`, 3 NLP backends, `backend`, pgvector `connection_string`/`collection_name`, `verbose`, `overwrite`, `documents`). Restructured to mirror Python's section layout. | -| `play-background-file.mdx` | FIXED | Rewrite: doc only covered free-form mode (`play_background` + `stop_background`). Added pre-configured mode (`` single tool with `action` enum of `start_`/`stop`). Added missing `tool_name` + `files` params. | -| `spider.mdx` | FIXED | Doc said "Tools: scrape_url" but source has 3: `scrape_url`, `crawl_site`, `extract_structured_data`. Added tool_name prefix param. Noted `SWML_ALLOW_PRIVATE_URLS=true` SSRF bypass. Noted that only `fast_text`/`markdown`/`structured` extract_types are wired; others fall back. | -| `swml-transfer.mdx` | FIXED | Added `list_transfer_destinations` tool (registered when `patterns` configured). Removed `required={true}` from `transfers` (either `transfers` or `patterns` required). Normalized default styles. Multi-instance note. | -| `weather-api.mdx` | FIXED | Added OpenWeatherMap-vs-WeatherAPI.com provider note (TS uses OpenWeatherMap despite SKILL_DESCRIPTION text). Corrected `units` default `"metric"`→`"fahrenheit"` (src 107). Added `tool_name` param. Documented `celsius`/`fahrenheit` Python aliases. | -| `web-search.mdx` | FIXED | Added multi-instance note (instance key combines `search_engine_id` + `tool_name`). Normalized `safe_search` default style. Noted tool_name configurability. | -| `wikipedia-search.mdx` | FIXED | Added `{query}` placeholder note on `no_results_message`. | -| `index.mdx` | FIXED | 5 multi-instance table corrections: `web_search`, `play_background_file`, `swml_transfer`, `api_ninjas_trivia`, `spider`, `info_gatherer` all `SUPPORTS_MULTIPLE_INSTANCES=true`. `spider` env-required `Yes`→`No`; tool count 1→3. `play_background_file` tool count 2→1-3 (mode-dependent). Code example `max_results`→`num_results` for `WebSearchSkill`; DataSphere example fixed to use `count` + `document_id` instead of `num_results`. | - -### skills/ summary - -17 files deep-audited this session, 14 fixed + 3 clean. 3 major rewrites -(`google-maps`, `native-vector-search`, `play-background-file`). Systematic -drift patterns encountered and fixed: -1. **Missing `tool_name` params** on 4 multi-instance-capable skills. -2. **Wrong env-fallback claims** on 2 skills whose handlers read `process.env` - directly, bypassing the declared config param. -3. **`{query}` placeholder** undocumented on 3 `no_results_message` fields - despite source implementing it. -4. **Default-value style inconsistency** (`default={'"x"'}`) normalized on 6 - ParamFields to match the project convention (`default="x"`). -5. **Index summary table** had 6 wrong multi-instance flags and 2 wrong tool - counts; source had diverged since last table review. - -### skill-registry/ — AUDITED -- NO ISSUES (16/16) - -**Source:** `temp/signalwire-typescript/src/skills/SkillRegistry.ts` (367 lines) - -All 16 files clean. `index.mdx` documents 15-card CardGroup + `size` getter (src 357). Methods verified: `getInstance` (src 72, static), `register` (95), `create` (157), `has` (184), `unregister` (144), `lock` (132), `listRegistered` (192), `addSearchPath` (218), `getSearchPaths` (228), `discoverFromDirectory` (238), `discoverAll` (294), `getSkillSchema` (310), `getAllSkillsSchema` (328), `listAllSkillSources` (347), `clear` (364). `SWML_SKILL_DISCOVERY_ENABLED=true` requirement on `discoverFromDirectory` correctly documented. - -**Coverage gap (P4):** `getSkillClass` (175), `listSkills` (202), `resetInstance` (82 static, test helper) not documented. - -### skill-manager/ — AUDITED -- NO ISSUES (17/17) - -**Source:** `temp/signalwire-typescript/src/skills/SkillManager.ts` (416 lines) - -All 17 files clean. `index.mdx` documents `size` getter + 16-card CardGroup. Methods verified: `addSkill` (src 70), `loadSkill` (236), `loadSkillByName` (266), `removeSkill` (144), `removeSkillByName` (174), `hasSkill` (192), `hasSkillByKey` (214), `listSkillKeys` (306), `getSkill` (315), `listSkills` (329), `getAllTools` (341), `getAllPromptSections` (353), `getAllHints` (365), `getMergedGlobalData` (377), `getLoadedSkillEntries` (397), `clear` (408). - -**Coverage gap (P4):** `loadedSkills` getter (src 55) not documented as a property. - -### skill-base/ — AUDITED -- NO ISSUES (16/16) - -**Source:** `temp/signalwire-typescript/src/skills/SkillBase.ts` (590+ lines) - -All 16 files clean. Static constants (`SKILL_NAME`, `SKILL_DESCRIPTION`, `SKILL_VERSION`, `REQUIRED_PACKAGES`, `REQUIRED_ENV_VARS`, `SUPPORTS_MULTIPLE_INSTANCES`) + 4 instance properties + 15-card method group all verified against src 90-550. Files: `index.mdx`, `setup.mdx` (src 278), `cleanup.mdx` (434), `get-tools.mdx` (297), `get-data-map-tools.mdx` (337), `get-prompt-sections.mdx` (347), `get-hints.mdx` (367), `get-global-data.mdx` (375), `get-instance-key.mdx` (392), `get-skill-namespace.mdx` (405), `get-skill-data.mdx` (415), `update-skill-data.mdx` (427), `is-initialized.mdx` (472), `mark-initialized.mdx` (479), `validate-env-vars.mdx` (451), `get-parameter-schema.mdx` (148). - -**Coverage gap (P4):** 7 public methods undocumented — `getAgent` (226), `setAgent` (499), `getConfig` (489, mentioned inline in index), `defineTool` (316, inline), `hasAllEnvVars` (509, inline), `hasAllPackages` (544, inline), `validatePackages` (522). - -### swml-builder/ — AUDITED + FIXED (12/12) - -**Source:** `temp/signalwire-typescript/src/SwmlBuilder.ts` (258 lines) - -- `index.mdx` FIXED — Constructor section claimed "takes no parameters" but `SwmlBuilder` accepts `opts?: SwmlBuilderOptions` (src 18-30). Added 3 options: `initialDocument`, `enableValidation`, `schemaPath`. -- `add-verb.mdx` clean — src 161-172 returns `void`; throws on validation failure. -- `add-verb-to-section.mdx` clean — src 180-185; auto-creates section. -- `ai.mdx` / `answer.mdx` / `hangup.mdx` / `play.mdx` clean — dynamic verb methods auto-installed from schema (src 111-148), return `this` for chaining. -- `get-document.mdx` clean — src 227-229. -- `get-schema-utils.mdx` clean — src 99-104 (static singleton). -- `render-document.mdx` clean — src 245-247 (JSON.stringify). -- `reset.mdx` FIXED — return type was `void`; source src 150 returns `this` for chaining. -- `say.mdx` FIXED (P0) — Doc falsely claimed `say` is not a method on SwmlBuilder. Source src 195 defines public `say(text, opts?): this` convenience method that emits `play` with `say:` prefix. Completely rewrote page with params (text, voice, language, gender, volume) to mirror Python doc. - -**Coverage gap (P4):** Source has `build()` (237), `render()` (255), `document` getter (78), `setValidation` (87), `addSection` (216) also public but undocumented. `build`/`render` are Python-compat aliases for `getDocument`/`renderDocument` respectively. - ---- - -## Agents audit session summary - -**Session 1 (prior):** -- agent-base (82/82), agent-server (10/10), function-result (50/50), - context-builder root (14/14), context-builder/context/index (1/23) — 167 files, 10 fixes, 3 new pages. - -**Session 2 (this session — 2026-04-22):** - -Audited in full + depth: -- context-builder/context (22/22) — 3 fixes -- context-builder/step (18/18) — 3 fixes -- overview + helpers (2/2) — 2 fixes -- prefabs (6/6) — 4 fixes -- swaig-function (4/4) — 3 fixes + 1 new page (validate-args) -- swml-service (7/7) — 4 fixes -- pom-builder (9/9) — 0 fixes -- swml-builder (12/12) — 3 fixes (incl. P0 say) -- data-map (19/19) — 0 fixes -- livewire (14/14) — 4 fixes -- skill-base (16/16) — 0 fixes -- skill-manager (17/17) — 0 fixes -- skill-registry (16/16) — 0 fixes - -Partial audit: -- skills (3/20 deep + 17 spot) — 3 fixes; systematic P1 gap flagged -- configuration (3/64) — deferred - -**Totals this session:** ~165 files audited, 29 fixes applied, 1 new page created (validate-args). -**Cumulative across sessions:** ~332 files audited, 39 fixes, 4 new pages. - -**Remaining:** 17 skills pages (deep audit) + 61 configuration sub-class files = ~78 files. Follow-up session needed. - ---- - -## Agents audit session 3 summary (2026-04-22) - -Focused on skills deep-audit — the partial audit flagged in session 2. - -Audited: skills (17/17 remaining + index re-verify) — 14 fixes across 17 -files, 3 major rewrites (google-maps, native-vector-search, play-background-file). - -**Totals this session:** 17 files audited, 15 fixes applied. -**Cumulative across sessions:** ~349 files audited, 54 fixes, 4 new pages. - -**Remaining:** 61 configuration sub-class files (auth-handler 6, config-loader -9, prompt-manager 10, schema-utils 10, serverless-adapter 8, session-manager -11, ssl-config 7). Follow-up session needed. - ---- - -## Agents audit session 4 summary (2026-04-22) - -Focused on the 61 configuration sub-class files flagged for session 4 in -session 3. All 7 configuration sub-classes completed. - -Audited this session: -- configuration/session-manager (11/11) — 4 fixes -- configuration/schema-utils (10/10) — 1 fix -- configuration/prompt-manager (10/10) — 0 fixes -- configuration/config-loader (9/9) — 2 fixes -- configuration/serverless-adapter (8/8) — 0 fixes -- configuration/ssl-config (7/7) — 1 fix -- configuration/auth-handler (6/6) — 2 fixes - -**Totals this session:** 61 files audited, 10 fixes applied, 0 new pages. -**Cumulative across sessions:** ~410 files audited, 64 fixes, 4 new pages. - -**Notable finds this session:** - -- **P0 fixes:** - - `session-manager/debug-token.mdx` — Return type was flat camelCase with - `| null`; source `DebugTokenResult` is nested with snake_case - `components.call_id` / `status.is_expired`, never null, and only works - when `debugMode=true` (returns an error object otherwise). Fixed with - full interface docs + Warning box + corrected example. - - `session-manager/get-session-metadata.mdx` — Return type - `Record | undefined`. Source (src 234) uses `?? {}` and - never returns undefined. JSDoc at 227-228 explicitly documents this as - Python-compat behavior. Callers would have added null guards that never - fire. - - `auth-handler/middleware.mdx` — Params listed "None" but signature is - `middleware(optional = false)`. Doc hid a real boolean option. -- **Missing ctor params/overloads:** - - `session-manager/set-session-metadata.mdx` — 3-arg - `setSessionMetadata(sessionId, key, value)` overload (src 249) was - entirely undocumented despite being the Python-compat path. - - `schema-utils/index.mdx` — `opts.schemaPath` ctor option (src 47, 50) - missing; mirrors Python's `schema_path` argument. - - `config-loader/index.mdx` — Ctor declared `filePath: string` but source - accepts `filePaths?: string | string[]` with ordered-array search - behavior (src 33-48). Array form critical for multi-env deployments. - - `config-loader/search.mdx` — Missing `additionalPaths` + `serviceName` - params (src 88); only listed 3 of 6 default search paths. - - `auth-handler/index.mdx` — `config.apiKeyHeader` (src 20, default - `'X-Api-Key'`) undocumented. - - `ssl-config/index.mdx` — Whole `## Constructor` section missing; added - opts: SslOptions reference. -- **Missing properties on index pages:** - - `session-manager/index.mdx` — `debugMode` public mutable flag (src 42) - and its effect on `debugToken` behavior undocumented. - - `config-loader/index.mdx` — `configPaths` getter (src 56) missing. - -**Significant coverage gaps (P4) flagged for future session:** -- `config-loader/`: 8 public methods undocumented — `findConfigFile`, - `getConfig` (alias), `getConfigFile` (alias), `hasConfig`, `getSection`, - `substituteVars`, `mergeWithEnv`, `interpolateEnvVars`. `mergeWithEnv` + - `getSection` are core to runtime config loading. -- `auth-handler/`: 5 public methods undocumented — `verifyBasicAuth`, - `verifyBearerToken`, `verifyApiKey`, `expressMiddleware`, `getAuthInfo`. - -**Configuration namespace now fully audited:** -7/7 sub-classes: auth-handler, config-loader, prompt-manager, schema-utils, -serverless-adapter, session-manager, ssl-config. 64 total files (61 audited -this session + 3 spot-checked in session 2: configuration/index, -environment-variables, logging). - -**Notable finds this session:** -- **P0 fixes:** - - `native-vector-search.mdx` wrong tool default `search_documents` — source is `search_knowledge` (src 363/405). - - `google-maps.mdx` completely wrong tool names (`get_directions`/`find_place` vs actual `compute_route`/`lookup_address` + 2 more). - - `play-background-file.mdx` missed the entire pre-configured-files mode (a whole separate tool registration path). -- **False env-fallback claims** on `ask-claude` and `datasphere-serverless`. The `env_var` field in `ParameterSchemaEntry` is schema-declarative only — SkillBase does not auto-hydrate env into config. Skills that want env fallback must call `process.env['X']` in their handler, and several did not despite declaring `env_var`. Docs must match the handler's actual behavior, not the schema declaration. -- **Multi-instance table drift** — 6 rows had wrong `Multi-Instance` flags in the index table because prior audits updated individual skill pages but not the summary table. -- **Systematic style normalization** — 6 ParamField `default={'"..."'}` occurrences cleaned up to `default="..."` for consistency. - -**Notable finds this session:** -- **P0 fixes:** swml-builder/say.mdx (doc falsely claimed method doesn't exist), skills/datetime.mdx (wrong tool name), skill-base/set-end.mdx (doc said "ends call" but source explicitly says it doesn't), skills/index table tool counts. -- **Fabricated content removed:** livewire/agent-session/index.mdx had fabricated `voiceOptions` param; livewire/signals.mdx ChatContext falsely claimed empty stub. -- **Significant missing info:** swml-service/index.mdx was missing 5 constructor options + 10 properties; swml-builder/index.mdx had wrong "takes no parameters" constructor claim; step/set-functions missing crucial inheritance warning; helpers.mdx missing validateUrl. -- **Doc→source drift in prefabs:** receptionist + survey had wrong tool names in index table. -- **Systematic skills drift:** tool names and custom `tool_name` parameters frequently missing/wrong across the 20 skill pages. - ---- - -## REST audit summary - -**All 384 MDX files across 22 REST namespaces audited clean** against source commit `ba6d5b1`. No discrepancies found. Every documented method, endpoint path, HTTP verb, and example signature matches the TypeScript source exactly. - -Key verified behaviors: -- Fabric `FabricResource` (4 classes) use PATCH default update; `FabricResourcePUT` (9 classes) overrides to PUT. -- `cxml-applications` correctly omits `create.mdx` (source `create()` throws). -- `conference-rooms` + `call-flows` `listAddresses` use singular `conference_room` / `call_flow` path (source override). -- `subscribers.updateSipEndpoint` correctly uses PATCH while its outer `update` uses PUT. -- Compat `tokens.update` uniquely uses PATCH (all other compat updates use POST). -- `RegistryCampaigns.update` uses PUT (source override on BaseResource). -- `NumberGroups.getMembership` / `deleteMembership` correctly document the top-level `/number_group_memberships/{id}` endpoint (not nested). -- Calling namespace: all 37 commands dispatch POST `/api/calling/calls`; signature shape `(params)` for `dial`/`update`, `(callId, params)` for the rest. - ---- - -## Relay Audit (in progress — 2026-04-22 session 5) - -**Scope:** `pages/reference/typescript/relay/**` — 91 MDX files against -`src/relay/**` at commit `ba6d5b1`. - -**Source files:** -- `src/relay/RelayClient.ts` (1036 lines) → `relay/client/` -- `src/relay/Call.ts` (854 lines) → `relay/call/` -- `src/relay/Message.ts` (148 lines) → `relay/message/` -- `src/relay/Action.ts` (314 lines) → `relay/actions/*/` (11 subclasses) -- `src/relay/RelayError.ts` (14 lines) → `relay/relay-error.mdx` -- `src/relay/RelayEvent.ts` (892 lines) → `relay/events.mdx` -- `src/relay/constants.ts` (132 lines) → `relay/constants.mdx` -- `src/relay/index.ts` + `types.ts` + `Deferred.ts` → internal - -### Full Inventory — Relay - -| Status | Namespace | Files | Source | -|--------|-----------|-------|--------| -| AUDITED -- NO ISSUES | `call/` | 45 | `src/relay/Call.ts` | -| AUDITED + FIXED | `actions/` | 31 | `src/relay/Action.ts` (base) | -| AUDITED + FIXED | `client/` | 10 | `src/relay/RelayClient.ts` | -| AUDITED + FIXED | `message/` | 3 | `src/relay/Message.ts` | -| AUDITED + FIXED | root (overview, relay-error, constants, events) | 4 | various | - -### Findings Log - -#### call/ (45 files) — AUDITED -- NO ISSUES - -- `[call/index.mdx]` clean — 9 properties + 44-card CardGroup match src Call.ts line 40-48, 107-835. Content drift vs Python: only legitimate (type syntax, casing, example idioms). Behavioral: "created automatically by RelayClient" ✓ line 1-5; "JSON-RPC via WebSocket" ✓ line 83-85; "long-running ops return Action" ✓ line 208. -- `[call/on.mdx]` clean — `on(eventType, handler): void` (src 107). EventHandler type matches. Behavioral: handlers pushed to `_listeners`, invoked on dispatch (src 140-147). -- `[call/wait-for.mdx]` clean — `waitFor(eventType, predicate?, timeout?)` (src 151). One-shot handler removed in finally block (src 179-185). Throws on timeout (src 170). -- `[call/wait-for-ended.mdx]` clean — `waitForEnded(timeout?)` (src 190). Resolves on `_ended` deferred, set when state === 'ended' (src 122-123). -- `[call/answer.mdx]` clean — `answer(extra?)` (src 247). `extra` intentional pass-through omission (matches Python parity). -- `[call/hangup.mdx]` clean — `hangup(reason = 'hangup')` (src 252). Reason default + enum values documented. -- `[call/pass.mdx]` clean — `pass()` no args (src 257). Delegates to `_execute('pass')`. -- `[call/play.mdx]` clean — `play(media, options)` with 5 options (src 264). PlayAction has stop/pause/resume/volume + wait. All 3 example highlights verified. -- `[call/record.mdx]` clean — `record(audio?, options)` (src 286). Nested audio.* params correctly documented with Indent. -- `[call/play-and-collect.mdx]` clean — `playAndCollect(media, collect, options)` (src 303). Nested collect.digits/speech Indents correct. -- `[call/collect.mdx]` clean — `collect(options)` 9 options (src 324). All documented incl. digits/speech nested. -- `[call/connect.mdx]` clean — `connect(devices, options)` 5 options (src 351). -- `[call/disconnect.mdx]` clean — `disconnect()` no args (src 371). -- `[call/send-digits.mdx]` clean — `sendDigits(digits, controlId?)` (src 378). -- `[call/detect.mdx]` clean — `detect(detect, options)` 3 options (src 386). DetectAction resolves on first detection event (src 169-175). -- `[call/refer.mdx]` clean — `refer(device, options)` (src 404). device.type/params nested. -- `[call/pay.mdx]` clean — `pay(paymentConnectorUrl, options)` 18 options (src 416). All documented. -- `[call/send-fax.mdx]` clean — `sendFax(document, options)` 4 options (src 469). -- `[call/receive-fax.mdx]` clean — `receiveFax(options)` 2 options (src 487). -- `[call/tap.mdx]` clean — `tap(tap, device, options)` (src 502). Nested tap + device Indents. -- `[call/stream.mdx]` clean — `stream(url, options)` 8 options (src 519). -- `[call/transfer.mdx]` clean — `transfer(dest, extra?)` (src 549). `extra` pass-through (Python parity). -- `[call/join-conference.mdx]` clean — `joinConference(name, options)` 19 options (src 557). -- `[call/leave-conference.mdx]` clean — `leaveConference(conferenceId, extra?)` (src 605). -- `[call/hold.mdx]` / `[call/unhold.mdx]` clean — no args (src 612/617). -- `[call/denoise.mdx]` / `[call/denoise-stop.mdx]` clean — no args (src 624/629). RPC `denoise` / `denoise.stop`. -- `[call/transcribe.mdx]` clean — `transcribe(options)` 3 options (src 636). TranscribeAction. -- `[call/echo.mdx]` clean — `echo({timeout?, statusUrl?})` (src 653). -- `[call/bind-digit.mdx]` clean — `bindDigit(digits, bindMethod, options)` 3 options (src 663). -- `[call/clear-digit-bindings.mdx]` clean — `clearDigitBindings(realm?)` (src 683). -- `[call/live-transcribe.mdx]` clean — `liveTranscribe(action, extra?)` (src 692). `extra` pass-through. -- `[call/live-translate.mdx]` clean — `liveTranslate(action, {statusUrl?})` (src 697). -- `[call/join-room.mdx]` clean — `joinRoom(name, {statusUrl?})` (src 709). -- `[call/leave-room.mdx]` clean — `leaveRoom(extra?)` (src 719). `extra` pass-through. -- `[call/ai.mdx]` clean — `ai(options)` 14 options (src 726). All documented. -- `[call/amazon-bedrock.mdx]` clean — `amazonBedrock(options)` 6 options (src 761). -- `[call/ai-message.mdx]` clean — `aiMessage(options)` 4 options (src 780). -- `[call/ai-hold.mdx]` clean — `aiHold({timeout?, prompt?})` (src 795). -- `[call/ai-unhold.mdx]` clean — `aiUnhold({prompt?})` (src 803). -- `[call/user-event.mdx]` clean — `userEvent(options)` event field (src 812). Doc correctly notes extra keys ignored. -- `[call/queue-enter.mdx]` clean — `queueEnter(queueName, {controlId?, statusUrl?})` (src 821). RPC `queue.enter`. -- `[call/queue-leave.mdx]` clean — `queueLeave(queueName, {controlId?, queueId?, statusUrl?})` (src 835). RPC `queue.leave`. - -**Coverage gap (P4):** `toString()` (src 851) not documented — intentional, internal repr. -**Content drift vs Python:** 44 method slugs + filenames match exactly. Only legitimate drift (camelCase titles, TS type syntax, example idioms). - -#### actions/ (31 files) — AUDITED + FIXED - -- `[actions/index.mdx]` FIXED (P1) — `wait(timeout)` claimed "Maximum milliseconds"; source Action.ts:91/95 is **seconds** (JSDoc: "matches Python SDK convention", line 95: `timeout * 1000` converts to ms). Fixed description to "Maximum seconds" per Python parity. -- `[actions/detect-action/index.mdx]` FIXED (P2) — example `action.wait(10000)` interpreted timeout as ms; source is seconds (10000 = 2.7 hours). Fixed to `wait(10)` matching Python counterpart. -- `[actions/standalone-collect-action/index.mdx]` FIXED (P1) — example `speech: { endSilenceTimeout: 2.0 }` — the `speech` obj is pass-through to RELAY server (Call.ts:338). RELAY server uses snake_case `end_silence_timeout`. CamelCase key would be ignored by server. Fixed. -- `[actions/standalone-collect-action/stop.mdx]` FIXED (P1) — same `endSilenceTimeout` → `end_silence_timeout` pass-through fix. -- `[actions/standalone-collect-action/start-input-timers.mdx]` FIXED (P1) — same `endSilenceTimeout` → `end_silence_timeout` pass-through fix. -- Other 26 action files clean. Per-action-class verification: - - `play-action/*` (5 files) — PlayAction src 117-137; 4 methods (stop/pause/resume/volume) all RPC `play.*`. Terminal `PLAY_STATE_FINISHED, PLAY_STATE_ERROR`. - - `record-action/*` (4 files) — RecordAction src 141-159; 3 methods (stop/pause/resume) RPC `record.*`. Terminal `RECORD_STATE_FINISHED, RECORD_STATE_NO_INPUT`. `pause(behavior?)` optional arg documented. - - `collect-action/*` (4 files) — CollectAction src 184-214; 3 methods (stop/volume/startInputTimers) RPC mix `play_and_collect.*` + `collect.start_input_timers`. Note about collect-only events (src 193-201) accurate. - - `detect-action/*` (2 files) — DetectAction src 163-180; 1 method. Note about first-detection-resolve accurate (src 169-175). - - `fax-action/*` (2 files) — FaxAction src 243-254; 1 method. RPC prefix `send_fax.stop` or `receive_fax.stop` depending on source method. - - `tap-action/*` / `stream-action/*` / `pay-action/*` / `transcribe-action/*` / `ai-action/*` — all single-stop classes, terminal states match src. - - `standalone-collect-action/*` (3 files) — terminal states match src 220. Two distinct RPC paths: `collect.stop` + `collect.start_input_timers`. - -**Systematic issue (project-wide):** Two distinct timeout-unit bugs surfaced in this audit. (1) Doc prose claimed `wait(timeout)` is ms — fixed in base Action page. (2) Example code passed `10000` assuming ms — fixed in detect-action. Worth spot-checking other SDK pages that mention wait-with-timeout, in case the unit confusion propagated. **Followup audit confirmed the pattern extended to `dialTimeout` (client/dial.mdx) and `message.wait(30_000)` (client/send-message.mdx) — also fixed.** - -#### client/ (10 files) — AUDITED + FIXED - -- `[client/index.mdx]` FIXED (P0 x 1 + drift) — - - `token` env var was `SIGNALWIRE_TOKEN`; source `RelayClient.ts:132` uses `SIGNALWIRE_API_TOKEN`. **P0 wrong env var.** - - Missing `maxActiveCalls` property (source ctor 152-158 + `_maxActiveCalls` field 118; default 1000 via `DEFAULT_MAX_ACTIVE_CALLS`; `RELAY_MAX_ACTIVE_CALLS` env fallback). Added per Python counterpart. - - `jwtToken` description was "Read from env var" only; source 133 also accepts constructor. Fixed to "Set via constructor or ...". - - `host` missing `default="relay.signalwire.com"` attribute; `contexts` missing `default="[]"`. Added to match Python. - - No "Async Disposable" section; source implements `Symbol.asyncDispose` (line 182) for `await using`. Added section with full example. -- `[client/on-call.mdx]` FIXED (P1) — Returns was `void`; source `onCall(handler: CallHandler): CallHandler` — returns the handler to support decorator usage. Fixed. -- `[client/on-message.mdx]` FIXED (P1) — same Returns-type bug as on-call; source returns `MessageHandler`. Fixed. -- `[client/connect.mdx]` clean — `connect()` no args; behavioral claims (wss://host, signalwire.connect, contexts auto-subscribe via `_authenticate` 304-306, ping loop) all verified. -- `[client/disconnect.mdx]` FIXED (P0 in example) — example used `client.sendMessage({ to, from, body })`; sendMessage options (src 437) are `toNumber`/`fromNumber`. Fixed both keys. -- `[client/execute.mdx]` clean — `(method, params): Promise` matches src 365. Warning about 30s timeout + reconnect matches REQUEST_TIMEOUT constant. -- `[client/dial.mdx]` FIXED (P0) — `options.dialTimeout` claimed `default="120000"` in milliseconds; source 401-402 uses seconds (default 120, then `* 1000` to ms internally). JSDoc line 375 confirms seconds. Fixed doc + default. -- `[client/send-message.mdx]` FIXED (P0 x 5) — (a) ParamField `to` should be `toNumber` (src 438); (b) ParamField `from` should be `fromNumber` (src 439); (c) all 3 examples used `to`/`from` as sendMessage options — would fail at runtime; (d) `await message.wait(30_000)` — Message.wait uses seconds convention (Message.ts:79/83 `timeout * 1000`). Fixed to `wait(30)`. -- `[client/receive.mdx]` clean — `receive(contexts: string[])` src 487; empty list short-circuits. -- `[client/unreceive.mdx]` clean — `unreceive(contexts: string[])` src 494. -- `[client/run.mdx]` clean — `run(): Promise` src 503. Backoff claim "1s initial, 30s max" verified against `RECONNECT_MIN_DELAY=1.0`, `RECONNECT_MAX_DELAY=30.0` (constants.ts:118-119). - -**Systematic project-wide fix:** Swept `process.env.SIGNALWIRE_TOKEN` → `SIGNALWIRE_API_TOKEN` across 91 relay `.mdx` files. This was the env-var name the SDK auto-fallback reads, and prior examples had propagated a different env-var name that wouldn't be auto-loaded. Users copying examples and setting `SIGNALWIRE_API_TOKEN` now get the SDK's expected default behavior. - -#### message/ (3 files) — AUDITED + FIXED - -- `[message/index.mdx]` FIXED (P0 in examples) — 11 properties (messageId, context, direction, fromNumber, toNumber, body, media, segments, state, reason, tags + isDone/result getters) all match Message.ts:18-28/61-70. Three example code blocks used `to`/`from` sendMessage options — wrong per source 437-439 (actual: `toNumber`/`fromNumber`). Also `message.wait(30_000)` passes 30000 seconds — wait uses seconds (Message.ts:79/83); fixed to `wait(30)`. -- `[message/on.mdx]` FIXED (P0 in example) — `on(handler): void` matches src 73; example used `to`/`from` — fixed to `toNumber`/`fromNumber`. -- `[message/wait.mdx]` FIXED (P1 + P0 in example) — (a) ParamField `timeout` claimed "milliseconds"; source 81-96 uses seconds (`timeout * 1000` internally). (b) example used `to`/`from` + `wait(30_000)`. All fixed. - -#### root/ (4 files) — AUDITED + FIXED - -- `[overview.mdx]` clean — IVR example matches Python counterpart (same `transfer(dest=phone)` pattern — accepted per Python parity even though transfer doc says context/URL). -- `[relay-error.mdx]` FIXED — `code` ParamField had `default="0"`; source RelayError.ts:9 constructor requires `code: number` (no default). Removed wrong default. Other fields (message, name) match source 6-13. -- `[constants.mdx]` FIXED (session 6 follow-up) — trimmed to the 39 symbols actually re-exported from `@signalwire/sdk` root (verified against `src/relay/index.ts:67-107`). Dropped all internal-only sections: Protocol (PROTOCOL_VERSION/AGENT_STRING/DEFAULT_RELAY_HOST), JSON-RPC Methods, End Reasons, Play/Record/Detect/Room States, Reconnect Settings, Authorization Event, `CALL_STATES`/`MESSAGE_TERMINAL_STATES` arrays. Rationale: Python reference SDK (`signalwire/relay/__init__.py` `__all__`) exports the same subset — the un-re-exported constants are internal implementation in both SDKs and not part of the public API surface. String enum values users encounter at runtime (`endReason`, play/record/detect states, etc.) are already documented inline on `events.mdx` where they appear. Previous `` removed (no longer needed — doc surface now matches import surface). No inbound anchor links were broken (verified via grep for `constants#`). -- `[events.mdx]` FIXED (P2 x 19 systematic) — RelayEvent base (eventType/params/callId/timestamp) matches src 12-40. 19 event-class examples used typed event classes in handler signatures (e.g., `(event: PlayEvent) => …`) but didn't import those classes — examples would fail TS type check as written. Used Python AST-style script to backtrack from each handler to the preceding `import { RelayClient } from '@signalwire/sdk';` and add the referenced event class. All 21 examples now import their event class correctly. - -### Relay Audit Summary - -**Total:** 93 files audited (45 call/ + 31 actions/ + 10 client/ + 3 message/ + 4 root). -**Fixes:** ~25 distinct per-file fixes + 1 systematic 91-file sweep (SIGNALWIRE_API_TOKEN) + 1 systematic 19-file sweep (event class imports). - -**Highest-impact fixes:** -1. **wait(timeout) unit confusion (seconds not ms)** — surfaced on Action.wait (prose), DetectAction example, `dialTimeout`, `message.wait` prose, and 3 example calls. Would have produced apparent hangs in user code (timeouts many orders of magnitude too long). -2. **SIGNALWIRE_API_TOKEN env var** — client/index doc claimed `SIGNALWIRE_TOKEN`; SDK falls back to `SIGNALWIRE_API_TOKEN`. Without user setting the right env var, the SDK's auto-fallback silently did nothing. -3. **sendMessage `to`/`from` vs `toNumber`/`fromNumber`** — 6 examples + 2 ParamFields incorrectly showed `to`/`from`; actual SDK options are `toNumber`/`fromNumber`. Would fail at runtime since the SDK strictly validates body/media. -4. **Event class imports missing** — 19 typed-event examples referenced classes (CallStateEvent, PlayEvent, etc.) without importing them. -5. **speech object keys in collect pass-through** — 3 files had `speech: { endSilenceTimeout: 2.0 }` (camelCase); the `speech` object is passed unchanged to the RELAY server which expects snake_case (`end_silence_timeout`). -6. **maxActiveCalls missing from client/index docs** — documented in Python, source of truth in src/RelayClient.ts:118/152-158, default 1000, env var `RELAY_MAX_ACTIVE_CALLS`. Added. -7. **Async Disposable missing** — TS `Symbol.asyncDispose` implementation (src 182) wasn't documented; Python counterpart has `async with` section. Added TS equivalent with `await using` example. -8. **on-call/on-message Returns type** — both documented `void` but source returns the handler (decorator pattern support). - -**Coverage gaps (P4) not fixed:** -- `Call.toString()` — internal repr; intentional (matches Python which also doesn't doc `__repr__`). - -**Previously flagged, now resolved in session 6:** -- `relay/constants.mdx` — trimmed to re-exported symbols only (matches Python `__all__` surface). - -**Systematic patterns uncovered (for future SDK doc authoring):** -1. Timeout units must be stated explicitly in both prose AND matching examples; TS/JS conventions default to milliseconds, Python SDK convention is seconds, and TS mirrored Python — a steady source of confusion. -2. Options object pass-through (where TS SDK wraps an opaque `Record` passed to a RELAY server) must document the server-side key casing, not the TS idiomatic casing — the SDK doesn't translate. -3. Examples that show typed event handlers need explicit type imports — language-specific issue that Python doesn't have. - ---- - -## Coverage Gap Follow-up (2026-04-23 session 6) - -Addressed the P4 coverage gaps flagged across the agents/ audits. Created 48 -new method pages across 7 classes. All pages follow the standard format -(frontmatter → link refs → overview → params → returns → example) and were -cross-verified against the Python counterparts where available, with TS- -specific notes where behavior diverges. - -### New pages by class - -**swml-service/ (14 new)** — `reset-document`, `stop`, `get-document`, -`render-document`, `get-basic-auth-credentials`, `serve`, `as-router`, -`add-section`, `add-verb-to-section`, `register-verb-handler`, -`register-routing-callback`, `extract-sip-username`, `manual-set-proxy-url`, -`on-request`. Index CardGroup expanded from 6 to 20 cards. Notes key -TS/Python divergences: `resetDocument()` returns fluent `this` vs Python -`None`; TS `stop()` actually closes the server (Python only flips a flag); -TS `onRequest()` receives (queryParams, bodyParams, headers, callbackPath) -and returns a `SwmlBuilder` or null (vs Python's `(request_data, -callback_path)` returning a merge dict); TS `RoutingCallback` signature lacks -Python's `Request` arg. - -**configuration/auth-handler/ (5 new)** — `verify-basic-auth`, -`verify-bearer-token`, `verify-api-key`, `get-auth-info`, `express-middleware`. -TS `expressMiddleware` is the framework-agnostic equivalent of Python's -`get_fastapi_dependency`. Index CardGroup expanded from 5 to 10 cards. - -**configuration/config-loader/ (8 new)** — `find-config-file`, `get-config`, -`get-config-file`, `has-config`, `get-section`, `substitute-vars`, -`merge-with-env`, `interpolate-env-vars`. `findConfigFile` documented as -static; `interpolateEnvVars` flagged as TS-specific (no Python equivalent). -Noted deliberate `hasConfig()` divergence from Python (TS treats -object-loaded data as configured because `loadFromObject` is TS-only). Index -CardGroup expanded from 8 to 17 cards. - -**pom-builder/ (5 new)** — `reset`, `add-pom-as-subsection`, `to-json`, -`from-sections` (static), `render-xml`. Index CardGroup expanded from 8 to -13 cards. - -**swml-builder/ (5 new)** — `build`, `render`, `document` (getter), -`set-validation`, `add-section`. `build`/`render` documented as Python-compat -aliases for `getDocument`/`renderDocument`. Index CardGroup expanded from 10 -to 15 cards. - -**skill-base/ (7 new)** — `get-agent`, `set-agent`, `get-config`, -`define-tool`, `has-all-env-vars`, `has-all-packages`, `validate-packages`. -`validatePackages` noted as async (dynamic `import()`). Index CardGroup -expanded from 15 to 22 cards. - -**skill-registry/ (3 new)** — `get-skill-class`, `list-skills`, -`reset-instance` (test helper). Index CardGroup expanded from 15 to 18 -cards. - -**skill-manager/ (1 new)** — `loaded-skills` (getter). Index CardGroup -expanded from 16 to 17 cards. - -### Coverage summary - -Before: ~410 TS SDK doc files. After: ~458 files (+48 new pages). -All previously-flagged P4 coverage gaps in the tracker are now closed. Remaining -P4 note: `Call.toString()` (intentional internal repr — matches Python SDK -convention of not documenting `__repr__`). The earlier `relay/constants.mdx` -flag was resolved by trimming the doc to match the re-exported symbol set; -root cause was a doc-scope decision (over-documentation of internal-only -constants), not an SDK bug — Python's `signalwire/relay/__init__.py` `__all__` -exports the same public subset. - -### Writing patterns used - -- Every new page matches the format of existing docs (frontmatter → - link-ref list at top → overview prose → `## **Parameters**` with ParamField - entries → `## **Returns**` → `## **Example**` with highlighted line). -- Python-compat aliases (e.g., `build()`, `render()`, `getConfig()`, - `serve()`, `asRouter()`) explicitly noted with a pointer to the - non-alias method so users can pick one convention and stick with it. -- TS/Python behavioral divergences documented as `` or `` - blocks rather than buried in prose, following the convention used in the - rest of the audited docs. -- Every example uses the corrected `SIGNALWIRE_API_TOKEN` env var (from - the relay-audit sweep) — no examples reintroduce the old token name. - ---- - -## Core audit session (2026-04-23) - -Scope: `pages/reference/typescript/core/` — 1 file (`overview.mdx`). - -### core/ — AUDITED -- NO ISSUES (1/1) - -`overview.mdx` is a nav landing page: frontmatter + shared snippet include -(`/snippets/server-sdks/reference-overview.mdx`) + 3-card CardGroup linking -to `agents/`, `relay/`, `rest/` section overviews. - -**Checks:** - -| Check | Result | -|-------|--------| -| Frontmatter title | "SignalWire TypeScript Server SDK" — language-appropriate ✓ | -| Frontmatter slug | `/reference/typescript` ✓ | -| Frontmatter description | "SDK reference overview for SignalWire Agents, RELAY, and REST APIs." ✓ | -| sidebar-title / subtitle / max-toc-depth / position | Match Python counterpart ✓ | -| Shared-snippet path | `/snippets/server-sdks/reference-overview.mdx` resolves to `fern/snippets/server-sdks/reference-overview.mdx` ✓ | -| CardGroup href -- agents | `/docs/server-sdks/reference/typescript/agents` — target overview slug `/reference/typescript/agents` exists ✓ | -| CardGroup href -- relay | `/docs/server-sdks/reference/typescript/relay` — target overview slug `/reference/typescript/relay` exists ✓ | -| CardGroup href -- rest | `/docs/server-sdks/reference/typescript/rest` — target overview slug `/reference/typescript/rest` exists ✓ | -| Content drift vs Python `core/overview.mdx` | Identical except for language-adapted title + slug. No drift. ✓ | - -**Behavioral verification for `overview.mdx`:** - -- "AI voice agents with SWML, SWAIG tools, skills, and multi-step workflows." → `src/AgentBase.ts` (SWML rendering via `SwmlBuilder`, SWAIG dispatch, `SkillManager`, multi-step `ContextBuilder`) ✓ confirmed -- "Real-time WebSocket client for call and message control." → `src/relay/RelayClient.ts` (WebSocket JSON-RPC 2.0) ✓ confirmed -- "HTTP client for phone numbers, fabric, video, logs, and more." → `src/rest/index.ts` + `src/rest/namespaces/{phone-numbers,fabric,video,logs,...}.ts` ✓ confirmed - -Shared snippet (`reference-overview.mdx`) is language-agnostic — references -`AgentBase`, `RelayClient`, `RestClient` all exist as exported symbols in -`src/index.ts`, `src/relay/RelayClient.ts`, `src/rest/index.ts` -respectively. No TS-specific drift possible in a shared snippet. - -**Fixes applied:** 0. **New pages created:** 0. - -### Cumulative totals - -~459 TS SDK doc files audited across all namespaces (agents + relay + rest + -core). Every namespace in `pages/reference/typescript/` now marked -AUDITED + FIXED or AUDITED -- NO ISSUES. - - - From 1d2b16fe93bcde10328aed6714c9061337b75633 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 20:21:56 +0000 Subject: [PATCH 12/21] =?UTF-8?q?docs(ts-sdk):=20guides=20audit=20pilot=20?= =?UTF-8?q?=E2=80=94=20getting-started?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uncomment TS tabs, fix signalwire-agents → @signalwire/sdk, normalize defineTool parameters to valid JSON Schema across getting-started/{overview,installation,quickstart,dev-environment}. Pilot for wider 51-file guides sweep. Findings at docs/temp/guides-audit/getting-started/findings.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../guides/getting-started/dev-environment.mdx | 2 -- .../guides/getting-started/installation.mdx | 12 ++++++------ .../pages/guides/getting-started/overview.mdx | 14 +++++++------- .../guides/getting-started/quickstart.mdx | 18 ++++++------------ 4 files changed, 19 insertions(+), 27 deletions(-) diff --git a/fern/products/server-sdks/pages/guides/getting-started/dev-environment.mdx b/fern/products/server-sdks/pages/guides/getting-started/dev-environment.mdx index 62ebb7524..d8b9cb15b 100644 --- a/fern/products/server-sdks/pages/guides/getting-started/dev-environment.mdx +++ b/fern/products/server-sdks/pages/guides/getting-started/dev-environment.mdx @@ -32,7 +32,6 @@ my-agent-project/ └── main.py # Entry point ``` -{/* ```text my-agent-project/ @@ -48,7 +47,6 @@ my-agent-project/ └── tsconfig.json ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/getting-started/installation.mdx b/fern/products/server-sdks/pages/guides/getting-started/installation.mdx index 206a8423e..14eda8393 100644 --- a/fern/products/server-sdks/pages/guides/getting-started/installation.mdx +++ b/fern/products/server-sdks/pages/guides/getting-started/installation.mdx @@ -30,13 +30,15 @@ max-toc-depth: 3 pip install signalwire-sdk ``` -{/* ```bash -npm install signalwire-agents +npm install @signalwire/sdk ``` + + +`@signalwire/sdk` is published as an ES module only (no CommonJS build). Your project must use ESM — add `"type": "module"` to your `package.json`, use `.mjs` file extensions, or use a bundler/transpiler that supports ESM. `import` syntax works; `require('@signalwire/sdk')` does not work in Node older than 22 without the `--experimental-require-module` flag. + -*/} {/* @@ -108,13 +110,11 @@ dotnet add package SignalWire.Sdk python -c "from signalwire import AgentBase; print('SDK installed successfully!')" ``` -{/* ```bash -node -e "const { AgentBase } = require('signalwire-agents'); console.log('SDK installed successfully!')" +node --input-type=module -e "import { AgentBase } from '@signalwire/sdk'; console.log('SDK installed successfully!');" ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/getting-started/overview.mdx b/fern/products/server-sdks/pages/guides/getting-started/overview.mdx index 487770f8f..b95d009cc 100644 --- a/fern/products/server-sdks/pages/guides/getting-started/overview.mdx +++ b/fern/products/server-sdks/pages/guides/getting-started/overview.mdx @@ -172,16 +172,14 @@ class MyAgent(AgentBase): # Configure your agent here ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); // Configure your agent here ``` -*/} {/* @@ -282,17 +280,20 @@ def lookup_customer(args, raw_data=None): ) ``` -{/* ```typescript agent.defineTool({ name: 'lookup_customer', description: 'Look up a customer by phone number', parameters: { - phone_number: { type: 'string', description: 'Phone number' } + type: 'object', + properties: { + phone_number: { type: 'string', description: 'Phone number' }, + }, + required: ['phone_number'], }, handler: (args) => { - const customer = database.find(args.phone_number); + const customer = database.find(args.phone_number as string); return new FunctionResult( `Customer: ${customer.name}, Account: ${customer.id}` ); @@ -300,7 +301,6 @@ agent.defineTool({ }); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx b/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx index b59369fc1..f906008d5 100644 --- a/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx +++ b/fern/products/server-sdks/pages/guides/getting-started/quickstart.mdx @@ -63,13 +63,12 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript #!/usr/bin/env npx tsx // my_first_agent.ts - A simple voice AI agent -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-first-agent' }); @@ -96,7 +95,6 @@ console.log('Server running at: http://localhost:3000'); agent.run(); ``` -*/} {/* @@ -498,13 +496,12 @@ if __name__ == "__main__": ``` -{/* ```typescript #!/usr/bin/env npx tsx // my_first_agent_with_function.ts - Agent with custom function -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-first-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -517,7 +514,7 @@ agent.promptAddSection('Role', { agent.defineTool({ name: 'tell_joke', description: 'Tell a joke to the caller', - parameters: {}, + parameters: { type: 'object', properties: {} }, handler: () => { const jokes = [ 'Why do programmers prefer dark mode? Because light attracts bugs!', @@ -533,7 +530,6 @@ agent.run(); ``` -*/} {/* @@ -928,12 +924,11 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript #!/usr/bin/env npx tsx // complete_first_agent.ts - Complete agent example with multiple features -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'complete-agent', autoAnswer: true, recordCall: false }); @@ -955,14 +950,14 @@ agent.promptAddSection('Style', { agent.defineTool({ name: 'get_current_time', description: 'Get the current time', - parameters: {}, + parameters: { type: 'object', properties: {} }, handler: () => new FunctionResult(`The current time is ${new Date().toLocaleTimeString()}`), }); agent.defineTool({ name: 'tell_joke', description: 'Tell a random joke', - parameters: {}, + parameters: { type: 'object', properties: {} }, handler: () => { const jokes = [ 'Why do programmers prefer dark mode? Because light attracts bugs!', @@ -977,7 +972,6 @@ console.log('Complete First Agent running at http://localhost:3000'); agent.run(); ``` -*/} {/* From 9b4603b1182773690440322206968153a373775e Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 21:18:14 +0000 Subject: [PATCH 13/21] =?UTF-8?q?docs(ts-sdk):=20guides=20audit=20full=20s?= =?UTF-8?q?weep=20=E2=80=94=2038=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uncomment TS tabs, swap signalwire-agents → @signalwire/sdk, and fix TS-specific drift across guides/{build-ai-agents,deploy,make-and-receive-calls, manage-resources}/. Key fixes: - Pkg name: signalwire-agents → @signalwire/sdk across every TS tab. - Unwrap {/* ... */} around TypeScript blocks (other-language tabs stay commented per release scope). - Subpath imports removed (@signalwire/sdk has no subpath exports). - defineTool parameters: flat maps and empty {} → full JSON Schema { type: 'object', properties: {...}, required: [...] }. - addSkill('name', opts) → addSkillByName('name', opts); config keys switched to snake_case (Python parity; read via this.getConfig). - SkillBase contract: setup(agent) → async setup(): Promise; registerTools() removed; declare tools in setup() via this.defineTool. - FunctionResult.connect / swmlTransfer / stopRecordCall: options-object calls → positional args (src/FunctionResult.ts:112/134/520). - addLanguage(name, code, voice) positional → { name, code, voice } object. - promptAddSection('Role', 'body') positional → ('Role', { body }). - LanguageConfig fillers / functionFillers: flat arrays → Record shapes. - RelayClient / RestClient ctor: projectId/apiToken/spaceName → project/token/host. - onSummary: misused as agent.onSummary(cb) → subclass override pattern. - Serverless: agent.handleRequest(event, ctx) → agent.runServerless(...) or ServerlessAdapter.createGcfHandler/createAzureHandler(agent.getApp()). - ESM-only notes added to deploy overview/production/docker/serverless; node entry switched to .mjs for PM2/systemd/Lambda patterns. - Loader: npx ts-node → npx tsx in testing + deploy overview (matches getting-started pilot). - _render_swml() prose made language-agnostic (renderSwml in TS). - recordCall 'mp4' format scoped to Python (TS type is 'wav' | 'mp3'). - InfoGathererAgent questions: keyName/questionText → key_name/question_text (snake_case per src/prefabs/InfoGathererAgent.ts:17-22). - SUPPORTS_MULTIPLE → SUPPORTS_MULTIPLE_INSTANCES in custom-skills table. - skillRegistry.addSkillDirectory → SkillRegistry.getInstance(). discoverFromDirectory. Out of scope (flagged in findings): - Authoring new TS tabs where Python-only examples don't port cleanly (security SSL, search-knowledge pgvector, cgi-mode Node CGI). - Large per-skill parameter-table drift in builtin-skills.mdx (needs separate per-skill source-verification pass). Findings under docs/temp/guides-audit//findings.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../guides/build-ai-agents/adding-skills.mdx | 10 ++-- .../guides/build-ai-agents/agent-base.mdx | 10 ++-- .../guides/build-ai-agents/ai-parameters.mdx | 4 +- .../guides/build-ai-agents/architecture.mdx | 16 +++--- .../guides/build-ai-agents/builtin-skills.mdx | 2 +- .../guides/build-ai-agents/call-flow.mdx | 12 ++--- .../guides/build-ai-agents/call-recording.mdx | 4 +- .../guides/build-ai-agents/call-transfer.mdx | 14 +++-- .../guides/build-ai-agents/concierge.mdx | 6 +-- .../build-ai-agents/contexts-workflows.mdx | 4 +- .../guides/build-ai-agents/custom-skills.mdx | 27 +++++----- .../pages/guides/build-ai-agents/datamap.mdx | 7 +-- .../build-ai-agents/defining-functions.mdx | 13 +++-- .../pages/guides/build-ai-agents/faq-bot.mdx | 6 +-- .../pages/guides/build-ai-agents/hints.mdx | 8 ++- .../guides/build-ai-agents/info-gatherer.mdx | 12 ++--- .../guides/build-ai-agents/lifecycle.mdx | 28 ++++++---- .../guides/build-ai-agents/mcp-gateway.mdx | 2 +- .../guides/build-ai-agents/multi-agent.mdx | 4 +- .../guides/build-ai-agents/prompts-pom.mdx | 4 +- .../guides/build-ai-agents/receptionist.mdx | 6 +-- .../build-ai-agents/results-actions.mdx | 8 ++- .../build-ai-agents/search-knowledge.mdx | 2 +- .../guides/build-ai-agents/skill-config.mdx | 6 +-- .../build-ai-agents/state-management.mdx | 22 ++++---- .../build-ai-agents/static-vs-dynamic.mdx | 10 ++-- .../pages/guides/build-ai-agents/survey.mdx | 6 +-- .../pages/guides/build-ai-agents/swaig.mdx | 14 ++--- .../pages/guides/build-ai-agents/swml.mdx | 13 +++-- .../build-ai-agents/understanding-skills.mdx | 20 +++---- .../guides/build-ai-agents/voice-language.mdx | 18 ++++--- .../pages/guides/deploy/docker-kubernetes.mdx | 7 +-- .../pages/guides/deploy/overview.mdx | 22 +++++--- .../pages/guides/deploy/production.mdx | 11 ++-- .../pages/guides/deploy/serverless.mdx | 52 +++++++------------ .../make-and-receive-calls/overview.mdx | 10 ++-- .../guides/manage-resources/overview.mdx | 12 ++--- .../pages/guides/manage-resources/testing.mdx | 4 +- 38 files changed, 206 insertions(+), 230 deletions(-) diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/adding-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/adding-skills.mdx index 75f380101..66a255968 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/adding-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/adding-skills.mdx @@ -45,7 +45,7 @@ Pass parameters as a dictionary (or map/hash depending on language): | Language | Syntax | |----------|--------| | Python | `self.add_skill("web_search", {"api_key": "KEY", "num_results": 5})` | -| TypeScript | `await agent.addSkill(new WebSearchSkill({ apiKey: 'KEY', numResults: 5 }))` | +| TypeScript | `await agent.addSkill(new WebSearchSkill({ api_key: 'KEY', num_results: 5 }))` | {/* | Go | `a.AddSkill("web_search", map[string]any{"api_key": "KEY", "num_results": 5})` | | Ruby | `agent.add_skill('web_search', api_key: 'KEY', num_results: 5)` | @@ -166,7 +166,7 @@ Some skills support multiple instances. Give each instance a unique `tool_name`: | Language | Two instances of web_search | |----------|----------------------------| | Python | `self.add_skill("web_search", {"tool_name": "search_news", ...})` | -| TypeScript | `await agent.addSkill(new WebSearchSkill({ toolName: 'search_news', ... }))` | +| TypeScript | `await agent.addSkill(new WebSearchSkill({ tool_name: 'search_news', ... }))` | {/* | Go | `a.AddSkill("web_search", map[string]any{"tool_name": "search_news", ...})` | | Ruby | `agent.add_skill('web_search', tool_name: 'search_news', ...)` | @@ -296,10 +296,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, DateTimeSkill, MathSkill } from 'signalwire-agents'; +import { AgentBase, DateTimeSkill, MathSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'full-featured' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -314,10 +313,9 @@ agent.promptAddSection('Capabilities', { bullets: ['Current date and time', 'Math calculations'], }); -agent.run(); +await agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/agent-base.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/agent-base.mdx index 98bfecc19..2538f2c1c 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/agent-base.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/agent-base.mdx @@ -129,10 +129,9 @@ if __name__ == "__main__": agent.run(host="0.0.0.0", port=3000) ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: "customer-support", @@ -141,16 +140,15 @@ const agent = new AgentBase({ agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); agent.setParams({ end_of_speech_timeout: 500, attention_timeout: 15000, inactivity_timeout: 30000 }); -agent.promptAddSection('Role', 'You are Alex, a friendly customer support agent for Acme Inc.'); +agent.promptAddSection('Role', { body: 'You are Alex, a friendly customer support agent for Acme Inc.' }); agent.promptAddSection('Guidelines', { body: 'Follow these guidelines:', bullets: ['Be helpful and professional', 'Ask clarifying questions when needed', 'Keep responses concise for voice', 'Offer to transfer if you cannot help'] }); agent.addHints(['Acme', 'account number', 'order status', 'refund', 'billing', 'representative']); -agent.defineTool({ name: 'check_order', description: 'Look up an order by order number', parameters: { type: 'object', properties: { order_number: { type: 'string', description: 'The order number to look up' } }, required: ['order_number'] }, handler: async (args) => new FunctionResult(`Order ${args.order_number}: Shipped on Monday, arriving Thursday`) }); -agent.addSkill('datetime'); +agent.defineTool({ name: 'check_order', description: 'Look up an order by order number', parameters: { type: 'object', properties: { order_number: { type: 'string', description: 'The order number to look up' } }, required: ['order_number'] }, handler: async (args) => new FunctionResult(`Order ${args['order_number']}: Shipped on Monday, arriving Thursday`) }); +await agent.addSkillByName('datetime'); agent.setPostPrompt('Summarize: issue type, resolution, customer satisfaction'); agent.run({ host: '0.0.0.0', port: 3000 }); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/ai-parameters.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/ai-parameters.mdx index c76590922..80ab2ddff 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/ai-parameters.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/ai-parameters.mdx @@ -216,10 +216,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'configured-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); agent.setParams({ end_of_speech_timeout: 600, attention_timeout: 15000, inactivity_timeout: 45000 }); @@ -227,7 +226,6 @@ agent.promptAddSection('Role', { body: 'You are a helpful customer service agent agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/architecture.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/architecture.mdx index 84157246b..60a1ce257 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/architecture.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/architecture.mdx @@ -365,10 +365,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'customer-service' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -378,18 +377,23 @@ agent.promptAddSection('Role', { body: 'You are a helpful agent.' }); agent.defineTool({ name: 'lookup_order', description: 'Look up an order by ID', - parameters: { order_id: { type: 'string', description: 'Order ID' } }, + parameters: { + type: 'object', + properties: { + order_id: { type: 'string', description: 'Order ID' }, + }, + required: ['order_id'], + }, handler: (args) => { - const result = new FunctionResult(`Order ${args.order_id}: Shipped, arrives tomorrow`); + const result = new FunctionResult(`Order ${args['order_id']}: Shipped, arrives tomorrow`); return result; }, }); -agent.addSkill('datetime'); +await agent.addSkillByName('datetime'); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx index 1abe9e4a3..49ded1056 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx @@ -64,7 +64,7 @@ Get current date and time information with timezone support. This is one of the | Language | Adding datetime with config | |----------|----------------------------| | Python | `self.add_skill("datetime", {"default_timezone": "America/New_York"})` | -| TypeScript | `agent.addSkill('datetime', { defaultTimezone: 'America/New_York' })` | +| TypeScript | `await agent.addSkillByName('datetime', { default_timezone: 'America/New_York' })` | {/* | Go | `a.AddSkill("datetime", map[string]any{"default_timezone": "America/New_York"})` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/call-flow.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/call-flow.mdx index 3c27446c1..00fa68171 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/call-flow.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/call-flow.mdx @@ -86,10 +86,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'ringback', port: 3000 }); agent.addPreAnswerVerb('play', { urls: ['ring:us'], auto_answer: false }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -97,7 +96,6 @@ agent.promptAddSection('Role', { body: 'You are a helpful assistant.' }); agent.run(); ``` -*/} {/* @@ -269,10 +267,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'welcome', port: 3000 }); agent.addPostAnswerVerb('play', { url: 'say:Thank you for calling Acme Corporation. Your call may be recorded for quality assurance.', @@ -285,7 +282,6 @@ agent.promptAddSection('Role', { agent.run(); ``` -*/} {/* @@ -499,10 +495,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'call-flow', port: 3000 }); agent.addPreAnswerVerb('play', { urls: ['ring:us'], auto_answer: false }); agent.addPostAnswerVerb('play', { url: 'say:Welcome to Acme Corporation.' }); @@ -517,7 +512,6 @@ agent.addPostAiVerb('hangup', {}); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/call-recording.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/call-recording.mdx index b262fe251..ca08cdc32 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/call-recording.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/call-recording.mdx @@ -41,7 +41,7 @@ Recording methods across all languages: | Language | Start Recording | Stop Recording | |----------|----------------|----------------| | Python | `result.record_call(control_id="main", stereo=True, format="wav")` | `result.stop_record_call(control_id="main")` | -| TypeScript | `result.recordCall({ controlId: 'main', stereo: true, format: 'wav' })` | `result.stopRecordCall({ controlId: 'main' })` | +| TypeScript | `result.recordCall({ controlId: 'main', stereo: true, format: 'wav' })` | `result.stopRecordCall('main')` | {/* | Go | `result.RecordCall("main", true, "wav")` | `result.StopRecordCall("main")` | @@ -98,7 +98,7 @@ if __name__ == "__main__": |-----------|------|---------|-------------| | `control_id` | str | None | Identifier to stop specific recording | | `stereo` | bool | False | True for separate L/R channels | -| `format` | str | `"wav"` | Output format: "wav", "mp3", or "mp4" | +| `format` | str | `"wav"` | Output format: "wav", "mp3", or "mp4" (TypeScript: "wav" or "mp3" only) | | `direction` | str | `"both"` | "speak", "listen", or "both" | | `terminators` | str | None | DTMF digits that stop recording | | `beep` | bool | False | Play beep before recording | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/call-transfer.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/call-transfer.mdx index 41f79de0d..d0494c303 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/call-transfer.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/call-transfer.mdx @@ -24,7 +24,7 @@ Transfer methods across all languages: | Language | connect() | swml_transfer() | |----------|-----------|-----------------| | Python | `result.connect("+15551234567", final=True)` | `result.swml_transfer(dest="https://...", final=True)` | -| TypeScript | `result.connect('+15551234567', { final: true })` | `result.swmlTransfer({ dest: 'https://...', final: true })` | +| TypeScript | `result.connect('+15551234567', true)` | `result.swmlTransfer('https://...', 'Transferring now', true)` | {/* | Go | `result.Connect("+15551234567", true)` | `result.SwmlTransfer("https://...", true)` | @@ -318,10 +318,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const DEPARTMENTS: Record = { sales: '+15551111111', @@ -331,8 +330,8 @@ const DEPARTMENTS: Record = { }; const agent = new AgentBase({ name: 'receptionist-agent' }); -agent.addLanguage('English', 'en-US', 'rime.spore'); -agent.promptAddSection('Role', 'You are the company receptionist.'); +agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); +agent.promptAddSection('Role', { body: 'You are the company receptionist.' }); agent.defineTool({ name: 'transfer_to_department', @@ -345,19 +344,18 @@ agent.defineTool({ required: ['department'], }, handler: (args) => { - const dept = (args.department as string).toLowerCase(); + const dept = (args['department'] as string).toLowerCase(); if (!(dept in DEPARTMENTS)) { return new FunctionResult(`I don't recognize '${dept}'.`); } return new FunctionResult(`Transferring you to ${dept} now.`) - .connect(DEPARTMENTS[dept], { final: true }); + .connect(DEPARTMENTS[dept], true); }, }); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/concierge.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/concierge.mdx index 9ec6008b9..67f1b318d 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/concierge.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/concierge.mdx @@ -29,10 +29,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { ConciergeAgent } from 'signalwire-agents'; +import { ConciergeAgent } from '@signalwire/sdk'; const agent = new ConciergeAgent({ venueName: 'Grand Hotel', @@ -47,7 +46,6 @@ const agent = new ConciergeAgent({ agent.run(); ``` -*/} {/* @@ -199,7 +197,7 @@ amenities = { | Language | Import | |----------|--------| | Python | `from signalwire.prefabs import ConciergeAgent` | -| TypeScript | `import { ConciergeAgent } from 'signalwire-agents'` | +| TypeScript | `import { ConciergeAgent } from '@signalwire/sdk'` | {/* | Go | `"github.com/signalwire/signalwire-agents-go/pkg/prefabs"` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/contexts-workflows.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/contexts-workflows.mdx index 38ee0be75..2bb269f3d 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/contexts-workflows.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/contexts-workflows.mdx @@ -109,10 +109,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'order-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -136,7 +135,6 @@ order.addStep('confirm', { task: 'Confirm the order details and thank them.' }) agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/custom-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/custom-skills.mdx index aaebc18ff..7c473df18 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/custom-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/custom-skills.mdx @@ -98,10 +98,9 @@ class GreetingSkill(SkillBase): return FunctionResult(greeting) ``` -{/* ```typescript -import { SkillBase, FunctionResult, AgentBase } from 'signalwire-agents'; +import { SkillBase, FunctionResult } from '@signalwire/sdk'; class GreetingSkill extends SkillBase { static SKILL_NAME = 'greeting'; @@ -110,24 +109,25 @@ class GreetingSkill extends SkillBase { private greetingStyle: string = 'friendly'; - setup(agent: AgentBase): boolean { - this.greetingStyle = this.params.style || 'friendly'; - return true; - } - - registerTools(): void { + async setup(): Promise { + this.greetingStyle = (this.getConfig('style') as string) || 'friendly'; this.defineTool({ name: 'greet_user', description: 'Generate a personalized greeting', parameters: { - name: { type: 'string', description: 'Name of the person to greet' }, + type: 'object', + properties: { + name: { type: 'string', description: 'Name of the person to greet' }, + }, + required: ['name'], }, handler: this.greetHandler.bind(this), }); + return true; } - greetHandler(args: Record, rawData: any): FunctionResult { - const name = args.name || 'friend'; + greetHandler(args: Record): FunctionResult { + const name = (args['name'] as string) || 'friend'; const greeting = this.greetingStyle === 'formal' ? `Good day, ${name}. How may I assist you?` : `Hey ${name}! Great to hear from you!`; @@ -136,7 +136,6 @@ class GreetingSkill extends SkillBase { } ``` -*/} {/* @@ -382,7 +381,7 @@ class GreetingSkill : SkillBase { |-----------|------|-------------| | `REQUIRED_PACKAGES` | `List[str]` | Python packages needed | | `REQUIRED_ENV_VARS` | `List[str]` | Environment variables needed | -| `SUPPORTS_MULTIPLE` | `bool` | Allow multiple instances | +| `SUPPORTS_MULTIPLE_INSTANCES` | `bool` | Allow multiple instances | ### Required Methods @@ -545,7 +544,7 @@ Register the skill directory and use the custom skill in your agent: | Language | Register & use custom skill | |----------|----------------------------| | Python | `skill_registry.add_skill_directory("/path/to/skills")` then `agent.add_skill("product_search", {...})` | -| TypeScript | `skillRegistry.addSkillDirectory('/path/to/skills')` then `agent.addSkill('product_search', {...})` | +| TypeScript | `await SkillRegistry.getInstance().discoverFromDirectory('/path/to/skills')` then `await agent.addSkillByName('product_search', {...})` | {/* | Go | `skills.AddSkillDirectory("/path/to/skills")` then `a.AddSkill("product_search", map[string]any{...})` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/datamap.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/datamap.mdx index d9b74c258..224672361 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/datamap.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/datamap.mdx @@ -91,14 +91,12 @@ class WeatherAgent(AgentBase): self.register_swaig_function(weather_dm.to_swaig_function()) ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; -import { DataMap } from 'signalwire-agents/data-map'; +import { AgentBase, FunctionResult, DataMap } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'weather-agent' }); -agent.addLanguage('English', 'en-US', 'rime.spore'); +agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); const weatherDm = new DataMap('get_weather') .purpose('Get current weather for a city') @@ -112,7 +110,6 @@ const weatherDm = new DataMap('get_weather') agent.registerSwaigFunction(weatherDm.toSwaigFunction()); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/defining-functions.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/defining-functions.mdx index ca5e490f6..a4ffa519f 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/defining-functions.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/defining-functions.mdx @@ -81,14 +81,13 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'order-agent' }); -agent.addLanguage('English', 'en-US', 'rime.spore'); -agent.promptAddSection('Role', 'You are an order status assistant. Help customers check their orders.'); +agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); +agent.promptAddSection('Role', { body: 'You are an order status assistant. Help customers check their orders.' }); agent.defineTool({ name: 'check_order', @@ -105,15 +104,15 @@ agent.defineTool({ '12345': 'Shipped Monday, arriving Thursday', '67890': 'Processing, ships tomorrow' }; - const status = orders[args.order_number] || 'Order not found'; - return new FunctionResult(`Order ${args.order_number}: ${status}`); + const orderNumber = args['order_number'] as string; + const status = orders[orderNumber] || 'Order not found'; + return new FunctionResult(`Order ${orderNumber}: ${status}`); } }); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx index b8929e285..23c9eb922 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/faq-bot.mdx @@ -35,10 +35,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { FAQBotAgent } from 'signalwire-agents'; +import { FAQBotAgent } from '@signalwire/sdk'; const agent = new FAQBotAgent({ faqs: [ @@ -51,7 +50,6 @@ const agent = new FAQBotAgent({ agent.run(); ``` -*/} {/* @@ -185,7 +183,7 @@ agent.Run(); | Language | Import | |----------|--------| | Python | `from signalwire.prefabs import FAQBotAgent` | -| TypeScript | `import { FAQBotAgent } from 'signalwire-agents'` | +| TypeScript | `import { FAQBotAgent } from '@signalwire/sdk'` | {/* | Go | `"github.com/signalwire/signalwire-agents-go/pkg/prefabs"` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/hints.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/hints.mdx index 0282f28ba..821466c25 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/hints.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/hints.mdx @@ -367,23 +367,21 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: "hinted-agent" }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); agent.addHints(['Acme', 'Acme Pro', 'Acme Enterprise', 'AcmePay', 'AcmeCloud']); agent.addHints(['SKU', 'A100', 'A200', 'A300', 'PRO100', 'ENT500']); agent.addHints(['account', 'billing', 'invoice', 'refund', 'cancel', 'upgrade', 'downgrade', 'representative', 'supervisor']); agent.addHints(['API', 'webhook', 'integration', 'OAuth', 'SSO', 'MFA']); -agent.promptAddSection('Role', 'You are a customer service agent for Acme Corporation.'); +agent.promptAddSection('Role', { body: 'You are a customer service agent for Acme Corporation.' }); const products: Record = { 'A100': 'Acme Basic - $99/month', 'A200': 'Acme Standard - $199/month', 'A300': 'Acme Premium - $299/month', 'PRO100': 'Acme Pro - $499/month', 'ENT500': 'Acme Enterprise - Custom pricing' }; -agent.defineTool({ name: 'lookup_product', description: 'Look up product by SKU', parameters: { type: 'object', properties: { sku: { type: 'string', description: 'Product SKU like A100 or PRO100' } }, required: ['sku'] }, handler: async (args) => { const sku = (args.sku as string).toUpperCase(); return new FunctionResult(products[sku] ? `${sku}: ${products[sku]}` : `SKU ${sku} not found.`); } }); +agent.defineTool({ name: 'lookup_product', description: 'Look up product by SKU', parameters: { type: 'object', properties: { sku: { type: 'string', description: 'Product SKU like A100 or PRO100' } }, required: ['sku'] }, handler: async (args) => { const sku = (args['sku'] as string).toUpperCase(); return new FunctionResult(products[sku] ? `${sku}: ${products[sku]}` : `SKU ${sku} not found.`); } }); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/info-gatherer.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/info-gatherer.mdx index 0be1db252..783988e67 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/info-gatherer.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/info-gatherer.mdx @@ -26,23 +26,21 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { InfoGathererAgent } from 'signalwire-agents'; +import { InfoGathererAgent } from '@signalwire/sdk'; const agent = new InfoGathererAgent({ questions: [ - { keyName: 'full_name', questionText: 'What is your full name?' }, - { keyName: 'email', questionText: 'What is your email address?', confirm: true }, - { keyName: 'reason', questionText: 'How can I help you today?' }, + { key_name: 'full_name', question_text: 'What is your full name?' }, + { key_name: 'email', question_text: 'What is your email address?', confirm: true }, + { key_name: 'reason', question_text: 'How can I help you today?' }, ], }); agent.run(); ``` -*/} {/* @@ -187,7 +185,7 @@ InfoGathererAgent( | Language | Import | |----------|--------| | Python | `from signalwire.prefabs import InfoGathererAgent` | -| TypeScript | `import { InfoGathererAgent } from 'signalwire-agents'` | +| TypeScript | `import { InfoGathererAgent } from '@signalwire/sdk'` | {/* | Go | `"github.com/signalwire/signalwire-agents-go/pkg/prefabs"` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/lifecycle.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/lifecycle.mdx index 9201de3e5..eea2af428 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/lifecycle.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/lifecycle.mdx @@ -153,20 +153,28 @@ class MyAgent(AgentBase): self.log_call_summary(call_id, summary) ``` -{/* ```typescript -agent.setPostPrompt( - 'Summarize this call including: 1) The caller\'s main question ' - + '2) How it was resolved 3) Any follow-up actions needed' -); - -agent.onSummary((summary, rawData) => { - console.log('Call summary:', summary); -}); +import { AgentBase } from '@signalwire/sdk'; + +class SupportAgent extends AgentBase { + constructor() { + super({ name: 'support-agent' }); + this.setPostPrompt( + "Summarize this call including: 1) The caller's main question " + + '2) How it was resolved 3) Any follow-up actions needed' + ); + } + + async onSummary(summary: Record, rawData?: Record): Promise { + console.log('Call summary:', summary); + } +} + +const agent = new SupportAgent(); +agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/mcp-gateway.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/mcp-gateway.mdx index 27629e90a..a44469583 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/mcp-gateway.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/mcp-gateway.mdx @@ -128,7 +128,7 @@ The `mcp_gateway` skill connects agents to the gateway across all languages: | Language | Syntax | |----------|--------| | Python | `self.add_skill("mcp_gateway", {"gateway_url": "http://localhost:8080", "services": [...]})` | -| TypeScript | `agent.addSkill('mcp_gateway', { gatewayUrl: 'http://localhost:8080', services: [...] })` | +| TypeScript | `await agent.addSkillByName('mcp_gateway', { gateway_url: 'http://localhost:8080', services: [...] })` | {/* | Go | `a.AddSkill("mcp_gateway", agents.SkillOpt("gateway_url", "http://localhost:8080"))` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/multi-agent.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/multi-agent.mdx index 18733452b..41c18c206 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/multi-agent.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/multi-agent.mdx @@ -70,10 +70,9 @@ if __name__ == "__main__": server.run() ``` -{/* ```typescript -import { AgentBase, AgentServer } from 'signalwire-agents'; +import { AgentBase, AgentServer } from '@signalwire/sdk'; const sales = new AgentBase({ name: 'sales-agent' }); sales.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -89,7 +88,6 @@ server.register(support, '/support'); server.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/prompts-pom.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/prompts-pom.mdx index a341400ab..c461114fc 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/prompts-pom.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/prompts-pom.mdx @@ -56,15 +56,13 @@ class MyAgent(AgentBase): ) ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.promptAddSection('Role', { body: 'You are a helpful customer service representative for Acme Corp.' }); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/receptionist.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/receptionist.mdx index defdc9c8d..98ab68a43 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/receptionist.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/receptionist.mdx @@ -38,10 +38,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { ReceptionistAgent } from 'signalwire-agents'; +import { ReceptionistAgent } from '@signalwire/sdk'; const agent = new ReceptionistAgent({ departments: [ @@ -54,7 +53,6 @@ const agent = new ReceptionistAgent({ agent.run(); ``` -*/} {/* @@ -188,7 +186,7 @@ agent.Run(); | Language | Import | |----------|--------| | Python | `from signalwire.prefabs import ReceptionistAgent` | -| TypeScript | `import { ReceptionistAgent } from 'signalwire-agents'` | +| TypeScript | `import { ReceptionistAgent } from '@signalwire/sdk'` | {/* | Go | `"github.com/signalwire/signalwire-agents-go/pkg/prefabs"` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx index 0ea266e62..99aa96584 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx @@ -21,17 +21,15 @@ def check_order(self, args, raw_data): return FunctionResult(f"Order {order_number} shipped yesterday") ``` -{/* ```typescript -import { FunctionResult } from 'signalwire-agents'; +import { FunctionResult } from '@signalwire/sdk'; -function checkOrder(args: Record): FunctionResult { - return new FunctionResult(`Order ${args.order_number} shipped yesterday`); +function checkOrder(args: Record): FunctionResult { + return new FunctionResult(`Order ${args['order_number']} shipped yesterday`); } ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx index 9a35a372d..c7dd78715 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx @@ -135,7 +135,7 @@ Add the `native_vector_search` skill to enable search: | Language | Syntax | |----------|--------| | Python | `self.add_skill("native_vector_search", index_file="./knowledge.swsearch", count=5, tool_name="search_documents")` | -| TypeScript | `agent.addSkill('native_vector_search', { indexFile: './knowledge.swsearch', count: 5, toolName: 'search_documents' })` | +| TypeScript | `await agent.addSkillByName('native_vector_search', { index_file: './knowledge.swsearch', count: 5, tool_name: 'search_documents' })` | {/* | Go | `a.AddSkill("native_vector_search", agents.SkillOpt("index_file", "./knowledge.swsearch"), agents.SkillOpt("count", 5))` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/skill-config.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/skill-config.mdx index 244d8b6ed..d1d6260de 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/skill-config.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/skill-config.mdx @@ -21,7 +21,7 @@ Pass configuration when adding a skill: | Language | Passing config parameters | |----------|--------------------------| | Python | `self.add_skill("web_search", {"api_key": "...", "num_results": 5})` | -| TypeScript | `agent.addSkill('web_search', { apiKey: '...', numResults: 5 })` | +| TypeScript | `await agent.addSkillByName('web_search', { api_key: '...', num_results: 5 })` | {/* | Go | `a.AddSkill("web_search", map[string]any{"api_key": "...", "num_results": 5})` | @@ -108,7 +108,7 @@ Override SWAIG function metadata for skill tools: | Language | SWAIG fields override | |----------|----------------------| | Python | `self.add_skill("datetime", {"swaig_fields": {"fillers": {...}}})` | -| TypeScript | `agent.addSkill('datetime', { swaigFields: { fillers: {...} } })` | +| TypeScript | `await agent.addSkillByName('datetime', { swaig_fields: { fillers: {...} } })` | {/* | Go | `a.AddSkill("datetime", map[string]any{"swaig_fields": map[string]any{"fillers": ...}})` | @@ -197,7 +197,7 @@ Skills supporting multiple instances need unique tool names: | Language | Multi-instance with unique tool_name | |----------|--------------------------------------| | Python | `self.add_skill("web_search", {"tool_name": "search_news", "api_key": "KEY"})` | -| TypeScript | `agent.addSkill('web_search', { toolName: 'search_news', apiKey: 'KEY' })` | +| TypeScript | `await agent.addSkillByName('web_search', { tool_name: 'search_news', api_key: 'KEY' })` | {/* | Go | `a.AddSkill("web_search", map[string]any{"tool_name": "search_news", "api_key": "KEY"})` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/state-management.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/state-management.mdx index f67c71fe8..31f15cdc3 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/state-management.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/state-management.mdx @@ -411,13 +411,12 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'order-agent' }); -agent.addLanguage('English', 'en-US', 'rime.spore'); +agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); agent.setGlobalData({ store_name: 'Pizza Palace', @@ -425,10 +424,12 @@ agent.setGlobalData({ order_total: 0.0, }); -agent.promptAddSection('Role', - 'You are an order assistant for ${global_data.store_name}. Help customers place their order.'); -agent.promptAddSection('Current Order', - 'Items: ${global_data.order_items}\nTotal: $${global_data.order_total}'); +agent.promptAddSection('Role', { + body: 'You are an order assistant for ${global_data.store_name}. Help customers place their order.', +}); +agent.promptAddSection('Current Order', { + body: 'Items: ${global_data.order_items}\nTotal: $${global_data.order_total}', +}); agent.setPostPrompt('Extract the final order as JSON: { "items": [], "total": 0.00 }'); @@ -444,15 +445,16 @@ agent.defineTool({ required: ['item', 'price'], }, handler: (args) => { - return new FunctionResult(`Added ${args.item} ($${args.price}) to your order`) - .updateGlobalData({ last_item_added: args.item, last_item_price: args.price }); + const item = args['item'] as string; + const price = args['price'] as number; + return new FunctionResult(`Added ${item} ($${price}) to your order`) + .updateGlobalData({ last_item_added: item, last_item_price: price }); }, }); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/static-vs-dynamic.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/static-vs-dynamic.mdx index b10a79674..1cc3bcc98 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/static-vs-dynamic.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/static-vs-dynamic.mdx @@ -77,19 +77,19 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: "static-support" }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); -agent.promptAddSection('Role', 'You are a customer service agent for Acme Corp. ' + 'Help callers with general inquiries about our products.'); +agent.promptAddSection('Role', { + body: 'You are a customer service agent for Acme Corp. Help callers with general inquiries about our products.', +}); agent.promptAddSection('Guidelines', { bullets: ['Be helpful and professional', 'Answer questions about products', 'Transfer complex issues to support'] }); -agent.defineTool({ name: 'get_store_hours', description: 'Get store hours', parameters: {}, handler: async () => new FunctionResult("We're open Monday through Friday, 9 AM to 5 PM.") }); +agent.defineTool({ name: 'get_store_hours', description: 'Get store hours', parameters: { type: 'object', properties: {} }, handler: async () => new FunctionResult("We're open Monday through Friday, 9 AM to 5 PM.") }); agent.run(); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/survey.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/survey.mdx index 3852962e6..edaa3cd6c 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/survey.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/survey.mdx @@ -41,10 +41,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { SurveyAgent } from 'signalwire-agents'; +import { SurveyAgent } from '@signalwire/sdk'; const agent = new SurveyAgent({ surveyName: 'Customer Satisfaction Survey', @@ -58,7 +57,6 @@ const agent = new SurveyAgent({ agent.run(); ``` -*/} {/* @@ -207,7 +205,7 @@ agent.Run(); | Language | Import | |----------|--------| | Python | `from signalwire.prefabs import SurveyAgent` | -| TypeScript | `import { SurveyAgent } from 'signalwire-agents'` | +| TypeScript | `import { SurveyAgent } from '@signalwire/sdk'` | {/* | Go | `"github.com/signalwire/signalwire-agents-go/pkg/prefabs"` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/swaig.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/swaig.mdx index eedcaf62f..f6fd42f5c 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/swaig.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/swaig.mdx @@ -96,22 +96,24 @@ class MyAgent(AgentBase): return FunctionResult(f"Account {account_id} has a balance of $150.00") ``` -{/* ```typescript agent.defineTool({ name: 'get_balance', description: 'Get account balance for a customer', parameters: { - account_id: { type: 'string', description: 'The account ID to look up' }, + type: 'object', + properties: { + account_id: { type: 'string', description: 'The account ID to look up' }, + }, + required: ['account_id'], }, handler: (args) => { - return new FunctionResult(`Account ${args.account_id} has a balance of $150.00`); + return new FunctionResult(`Account ${args['account_id']} has a balance of $150.00`); }, }); ``` -*/} {/* @@ -386,7 +388,6 @@ def response_with_data(self, args, raw_data): return result ``` -{/* ```typescript // Simple response @@ -394,14 +395,13 @@ return new FunctionResult('Your order has been placed successfully.'); // With transfer return new FunctionResult('Transferring you now.') - .connect('+15551234567', { final: true }); + .connect('+15551234567', true); // With data return new FunctionResult("I've saved your preferences.") .updateGlobalData({ user_preference: 'email', confirmed: true }); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx index 508176368..62349aaf9 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/swml.mdx @@ -253,18 +253,23 @@ class MyAgent(AgentBase): self.define_tool(name="get_help", description="Get help", parameters={}, handler=self.get_help) # -> SWAIG ``` -{/* ```typescript +import { AgentBase, FunctionResult } from '@signalwire/sdk'; + const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); // -> languages agent.promptAddSection('Role', { body: 'You are helpful.' }); // -> prompt agent.addHints(['help', 'support']); // -> hints agent.setParams({ end_of_speech_timeout: 500 }); // -> params -agent.defineTool({ name: 'get_help', description: 'Get help', parameters: {}, handler: fn }); // -> SWAIG +agent.defineTool({ // -> SWAIG + name: 'get_help', + description: 'Get help', + parameters: { type: 'object', properties: {} }, + handler: async () => new FunctionResult('Here is some help.'), +}); ``` -*/} {/* @@ -350,7 +355,7 @@ agent.DefineTool(name: "get_help", description: "Get help", parameters: new Dict The above examples all produce identical SWML output. See the [Architecture][architecture] section for the full API comparison table. -When SignalWire requests SWML, the agent's `_render_swml()` method: +When SignalWire requests SWML, the agent's render method (`_render_swml()` in Python, `renderSwml()` in TypeScript): 1. Collects all configuration (prompts, languages, hints, params) 2. Builds the SWAIG functions array with webhook URLs diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx index b407ad290..63a77cac9 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx @@ -44,7 +44,7 @@ The `add_skill()` method is available across all SDK languages: | Language | Syntax | |----------|--------| | Python | `agent.add_skill("weather")` | -| TypeScript | `agent.addSkill('weather')` | +| TypeScript | `await agent.addSkillByName('weather_api')` | {/* | Go | `a.AddSkill("weather", nil)` | @@ -83,10 +83,9 @@ class MyAgent(AgentBase): ) ``` -{/* ```typescript -import { AgentBase, DateTimeSkill, MathSkill } from 'signalwire-agents'; +import { AgentBase, DateTimeSkill, MathSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -101,10 +100,9 @@ agent.promptAddSection('Role', { body: 'You are a helpful assistant that can tell time and do math.', }); -agent.run(); +await agent.run(); ``` -*/} {/* @@ -303,7 +301,7 @@ The `add_skill()` vs `define_tool()` distinction applies across all languages: | Language | add_skill | define_tool | |----------|-----------|-------------| | Python | `agent.add_skill("name")` | `agent.define_tool(...)` | -| TypeScript | `agent.addSkill('name')` | `agent.defineTool(...)` | +| TypeScript | `await agent.addSkillByName('name')` | `agent.defineTool(...)` | {/* | Go | `a.AddSkill("name", nil)` | `a.DefineTool(...)` | @@ -373,10 +371,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase, DateTimeSkill, MathSkill } from 'signalwire-agents'; +import { AgentBase, DateTimeSkill, MathSkill } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'assistant' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -394,10 +391,9 @@ agent.promptAddSection('Capabilities', { ], }); -agent.run(); +await agent.run(); ``` -*/} {/* @@ -643,7 +639,7 @@ All skills inherit from [`SkillBase`][ref-skillbase]. The pattern is similar acr | Language | Pattern | |----------|---------| | Python | `class MySkill(SkillBase): def setup(self, agent): ...` | -| TypeScript | `class MySkill extends SkillBase { setup(agent) { ... } }` | +| TypeScript | `class MySkill extends SkillBase { async setup() { ... return true; } }` | {/* | Go | `type MySkill struct { skills.SkillBase } func (s *MySkill) Setup(a *agent.AgentBase) { ... }` | @@ -806,7 +802,7 @@ Usage across languages: | Language | Adding multiple instances | |----------|--------------------------| | Python | `agent.add_skill("web_search", {"tool_name": "search_news", "api_key": "KEY"})` | -| TypeScript | `agent.addSkill('web_search', { toolName: 'search_news', apiKey: 'KEY' })` | +| TypeScript | `await agent.addSkillByName('web_search', { tool_name: 'search_news', api_key: 'KEY' })` | {/* | Go | `a.AddSkill("web_search", map[string]any{"tool_name": "search_news", "api_key": "KEY"})` | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/voice-language.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/voice-language.mdx index 55dbae7e0..a4f7e935f 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/voice-language.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/voice-language.mdx @@ -410,20 +410,25 @@ class FullyConfiguredVoiceAgent(AgentBase): self.prompt_add_section("Role", "You are a friendly customer service agent.") ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'voice-configured' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore', - fillers: ['Um', 'Well', 'Let me see', 'So'], - functionFillers: ['Let me look that up for you', 'One moment while I check', "I'm searching for that now", 'Just a second'], + fillers: { default: ['Um', 'Well', 'Let me see', 'So'] }, + functionFillers: { + lookup_product: { + 'en-US': ['Let me look that up for you', 'One moment while I check', "I'm searching for that now", 'Just a second'], + }, + }, }); agent.addLanguage({ name: 'Spanish', code: 'es-MX', voice: 'rime.luna', - fillers: ['Pues', 'Bueno'], - functionFillers: ['Un momento', 'Dejame ver'], + fillers: { default: ['Pues', 'Bueno'] }, + functionFillers: { + lookup_product: { 'es-MX': ['Un momento', 'Dejame ver'] }, + }, }); agent.setPronunciations([ { replace: 'ACME', with: 'Ack-me' }, @@ -434,7 +439,6 @@ agent.setPronunciations([ agent.promptAddSection('Role', { body: 'You are a friendly customer service agent.' }); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/deploy/docker-kubernetes.mdx b/fern/products/server-sdks/pages/guides/deploy/docker-kubernetes.mdx index 500394be1..aef1d88a5 100644 --- a/fern/products/server-sdks/pages/guides/deploy/docker-kubernetes.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/docker-kubernetes.mdx @@ -34,20 +34,22 @@ EXPOSE 3000 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "3000", "--workers", "4"] ``` -{/* ```dockerfile FROM node:20-slim WORKDIR /app -## Install dependencies +## Install dependencies (package.json must include "type": "module" — @signalwire/sdk is ESM-only) COPY package*.json ./ RUN npm ci --only=production ## Copy application COPY . . +## Build TypeScript to dist/ +RUN npm run build + ## Create non-root user RUN groupadd -r appuser && useradd -r -g appuser appuser && chown -R appuser:appuser /app USER appuser @@ -57,7 +59,6 @@ EXPOSE 3000 CMD ["node", "dist/app.js"] ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/deploy/overview.mdx b/fern/products/server-sdks/pages/guides/deploy/overview.mdx index e35aeb2ca..fe9ee7b4f 100644 --- a/fern/products/server-sdks/pages/guides/deploy/overview.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/overview.mdx @@ -76,10 +76,9 @@ if __name__ == "__main__": agent.run() ``` -{/* ```typescript -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -88,7 +87,6 @@ agent.promptAddSection('Role', { body: 'You are a helpful assistant.' }); agent.run(); ``` -*/} {/* @@ -190,9 +188,21 @@ agent.Run(); The `run()` method automatically: -- Detects serverless environments (Lambda, Cloud Functions, Azure) +- Detects serverless environments (Lambda, Cloud Functions, Azure) **(Python only)** - Starts a development server on localhost for local development -- Handles CGI mode when deployed to traditional web servers +- Handles CGI mode when deployed to traditional web servers **(Python only)** + + +In TypeScript, `run()` is an alias for `serve()` and only starts an HTTP server. +For serverless deployments (Lambda, Cloud Functions, Azure, CGI) call +`agent.runServerless(event, context, platform?)` from your platform handler, +or use the `ServerlessAdapter.createLambdaHandler` / `createGcfHandler` / +`createAzureHandler` helpers. See the [Serverless](/docs/server-sdks/guides/serverless) guide. + + +The SignalWire TypeScript SDK (`@signalwire/sdk`) is ESM-only. Your +`package.json` must set `"type": "module"`, or your entry file must be named +`.mjs`. Otherwise Node will try to load it as CommonJS and imports will fail. ## Starting the development server @@ -201,7 +211,7 @@ The simplest way to run your agent locally: | Language | Run Command | |----------|-------------| | Python | `python my_agent.py` | -| TypeScript | `npx ts-node my_agent.ts` or `node my_agent.js` | +| TypeScript | `npx tsx my_agent.ts` or `node my_agent.mjs` | {/* | Go | `go run my_agent.go` | diff --git a/fern/products/server-sdks/pages/guides/deploy/production.mdx b/fern/products/server-sdks/pages/guides/deploy/production.mdx index e3694feee..ee763c992 100644 --- a/fern/products/server-sdks/pages/guides/deploy/production.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/production.mdx @@ -84,13 +84,12 @@ if __name__ == "__main__": agent.run(host="0.0.0.0", port=3000) ``` -{/* Use Node.js with clustering or a process manager like PM2: ```typescript // app.ts -import { AgentBase } from 'signalwire-agents'; +import { AgentBase } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -99,13 +98,15 @@ agent.promptAddSection('Role', { body: 'You are a helpful assistant.' }); agent.run({ host: '0.0.0.0', port: 3000 }); ``` +Build to `app.mjs` (or set `"type": "module"` in `package.json`) — `@signalwire/sdk` +is ESM-only. For PM2 cluster mode, use PM2 5.2+ and point at the `.mjs` entry. + ```bash ## Run with PM2 for process management npm install -g pm2 -pm2 start app.js -i 4 --name signalwire-agent +pm2 start app.mjs -i 4 --name signalwire-agent ``` -*/} {/* @@ -277,7 +278,7 @@ Create `/etc/systemd/system/signalwire-agent.service`. Adjust `ExecStart` for yo | Language | ExecStart Example | |----------|-------------------| | Python | `/opt/agent/venv/bin/uvicorn app:app --host 127.0.0.1 --port 3000 --workers 4` | -| TypeScript | `/usr/bin/node /opt/agent/app.js` | +| TypeScript | `/usr/bin/node /opt/agent/app.mjs` | {/* | Go | `/opt/agent/signalwire-agent` | diff --git a/fern/products/server-sdks/pages/guides/deploy/serverless.mdx b/fern/products/server-sdks/pages/guides/deploy/serverless.mdx index 76dbcf6a8..92e7229b5 100644 --- a/fern/products/server-sdks/pages/guides/deploy/serverless.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/serverless.mdx @@ -90,16 +90,15 @@ def lambda_handler(event, context): return agent.handle_serverless_request(event, context) ``` -{/* -`handler.ts`: +`handler.ts` (deploy as `handler.mjs` or ensure `package.json` has `"type": "module"` — `@signalwire/sdk` is ESM-only): ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult } from '@signalwire/sdk'; const agent = new AgentBase({ name: "my-agent" }); -agent.addLanguage("English", "en-US", "rime.spore"); -agent.promptAddSection("Role", "You are a helpful assistant."); +agent.addLanguage({ name: "English", code: "en-US", voice: "rime.spore" }); +agent.promptAddSection("Role", { body: "You are a helpful assistant." }); agent.defineTool({ name: "say_hello", @@ -111,18 +110,17 @@ agent.defineTool({ }, required: ["name"] }, - handler: (args: any) => { - const name = args.name || "World"; + handler: (args: Record) => { + const name = (args['name'] as string) || "World"; return new FunctionResult(`Hello ${name}!`); } }); -export const handler = async (event: any, context: any) => { - return agent.handleRequest(event, context); +export const handler = async (event: unknown, context: unknown) => { + return agent.runServerless(event, context); }; ``` -*/} {/* @@ -302,13 +300,12 @@ def main(request): return agent.handle_serverless_request(request) ``` -{/* -`index.ts`: +`index.ts` (deploy as `.mjs` or ensure `package.json` has `"type": "module"` — `@signalwire/sdk` is ESM-only): ```typescript -import { AgentBase, FunctionResult } from 'signalwire-agents'; -import { HttpFunction } from '@google-cloud/functions-framework'; +import { AgentBase, FunctionResult, ServerlessAdapter } from '@signalwire/sdk'; +import type { HttpFunction } from '@google-cloud/functions-framework'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -324,17 +321,14 @@ agent.defineTool({ }, required: ['name'], }, - handler: (args: any) => { - return new FunctionResult(`Hello ${args.name || 'World'}!`); + handler: (args: Record) => { + return new FunctionResult(`Hello ${(args['name'] as string) || 'World'}!`); }, }); -export const main: HttpFunction = (req, res) => { - return agent.handleRequest(req, res); -}; +export const main: HttpFunction = ServerlessAdapter.createGcfHandler(agent.getApp()); ``` -*/} {/* @@ -468,13 +462,11 @@ def main(req: func.HttpRequest) -> func.HttpResponse: return agent.handle_serverless_request(req) ``` -{/* -`src/functions/agent.ts`: +`src/functions/agent.ts` (deploy as `.mjs` or set `"type": "module"` in `package.json` — `@signalwire/sdk` is ESM-only). This example uses the Azure Functions v3 programming model with `function.json` (shown below). The SDK's Azure helper follows that shape. ```typescript -import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions'; -import { AgentBase, FunctionResult } from 'signalwire-agents'; +import { AgentBase, FunctionResult, ServerlessAdapter } from '@signalwire/sdk'; const agent = new AgentBase({ name: 'my-agent' }); agent.addLanguage({ name: 'English', code: 'en-US', voice: 'rime.spore' }); @@ -490,19 +482,15 @@ agent.defineTool({ }, required: ['name'], }, - handler: (args: any) => { - return new FunctionResult(`Hello ${args.name || 'World'}!`); + handler: (args: Record) => { + return new FunctionResult(`Hello ${(args['name'] as string) || 'World'}!`); }, }); -export async function main(req: HttpRequest, context: InvocationContext): Promise { - return agent.handleRequest(req); -} - -app.http('agent', { methods: ['GET', 'POST'], authLevel: 'anonymous', handler: main }); +// Azure Functions v3 entry point — `context.res` is populated by the adapter. +export default ServerlessAdapter.createAzureHandler(agent.getApp()); ``` -*/} {/* diff --git a/fern/products/server-sdks/pages/guides/make-and-receive-calls/overview.mdx b/fern/products/server-sdks/pages/guides/make-and-receive-calls/overview.mdx index f77daee1b..6ac697fdc 100644 --- a/fern/products/server-sdks/pages/guides/make-and-receive-calls/overview.mdx +++ b/fern/products/server-sdks/pages/guides/make-and-receive-calls/overview.mdx @@ -66,14 +66,13 @@ async def handle_call(call): client.run() ``` -{/* ```typescript -import { RelayClient } from 'signalwire-agents'; +import { RelayClient } from '@signalwire/sdk'; const client = new RelayClient({ - projectId: 'your-project-id', - apiToken: 'your-api-token', + project: 'your-project-id', + token: 'your-api-token', host: 'your-space.signalwire.com', contexts: ['default'], }); @@ -88,7 +87,6 @@ client.onCall(async (call) => { client.run(); ``` -*/} {/* @@ -260,7 +258,7 @@ The RELAY client supports two authentication methods: | Language | Syntax | |----------|--------| | Python | `RelayClient(project="...", token="...", host="...")` | -| TypeScript | `new RelayClient({ projectId: '...', apiToken: '...', host: '...' })` | +| TypeScript | `new RelayClient({ project: '...', token: '...', host: '...' })` | {/* | Go | `relay.NewClient(relay.WithProjectID("..."), relay.WithAPIToken("..."), relay.WithHost("..."))` | diff --git a/fern/products/server-sdks/pages/guides/manage-resources/overview.mdx b/fern/products/server-sdks/pages/guides/manage-resources/overview.mdx index cd821de52..2c4f99647 100644 --- a/fern/products/server-sdks/pages/guides/manage-resources/overview.mdx +++ b/fern/products/server-sdks/pages/guides/manage-resources/overview.mdx @@ -47,15 +47,14 @@ available = client.phone_numbers.search(area_code="512") print(available) ``` -{/* ```typescript -import { RestClient } from 'signalwire-agents'; +import { RestClient } from '@signalwire/sdk'; const client = new RestClient({ - projectId: 'your-project-id', - apiToken: 'your-api-token', - spaceName: 'your-space.signalwire.com', + project: 'your-project-id', + token: 'your-api-token', + host: 'your-space.signalwire.com', }); // List AI agents @@ -67,7 +66,6 @@ const available = await client.phoneNumbers.search({ areaCode: '512' }); console.log(available); ``` -*/} {/* @@ -213,7 +211,7 @@ Console.WriteLine(available); | Language | Syntax | |----------|--------| | Python | `SignalWireClient(project="...", token="...", host="...")` | -| TypeScript | `new RestClient({ projectId: '...', apiToken: '...', spaceName: '...' })` | +| TypeScript | `new RestClient({ project: '...', token: '...', host: '...' })` | {/* | Go | `rest.NewClient(rest.WithProjectID("..."), rest.WithAPIToken("..."), rest.WithSpaceName("..."))` | diff --git a/fern/products/server-sdks/pages/guides/manage-resources/testing.mdx b/fern/products/server-sdks/pages/guides/manage-resources/testing.mdx index d8bc5be8d..284ef0dc0 100644 --- a/fern/products/server-sdks/pages/guides/manage-resources/testing.mdx +++ b/fern/products/server-sdks/pages/guides/manage-resources/testing.mdx @@ -50,7 +50,7 @@ Run your agent locally using the appropriate command for your language: | Language | Start Command | |----------|---------------| | Python | `python my_agent.py` | -| TypeScript | `npx ts-node my_agent.ts` | +| TypeScript | `npx tsx my_agent.ts` | {/* | Go | `go run my_agent.go` | @@ -156,7 +156,7 @@ Test call transfers carefully. The transfer API is the same across languages via | Language | Transfer Call | |----------|-------------| | Python | `FunctionResult("Transferring").connect(number, final=True)` | -| TypeScript | `new FunctionResult("Transferring").connect(number, { final: true })` | +| TypeScript | `new FunctionResult("Transferring").connect(number, true)` | {/* | Go | `agent.NewFunctionResult("Transferring").Connect(number, true)` | From 6cb7fb0646cab0fb0acbdb47e94ed45f09fd4c27 Mon Sep 17 00:00:00 2001 From: august l-r Date: Thu, 23 Apr 2026 21:21:15 +0000 Subject: [PATCH 14/21] docs(ts-sdk): list 5 missing builtin skills in guides Add api_ninjas_trivia, ask_claude, custom_skills, datasphere_serverless, and spider to the Available Skills and Skills Summary tables in builtin-skills.mdx and to the Available Built-in Skills table in understanding-skills.mdx. Multi-instance flags sourced from each skill's SUPPORTS_MULTIPLE_INSTANCES declaration in src/skills/builtin/. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../pages/guides/build-ai-agents/builtin-skills.mdx | 10 ++++++++++ .../guides/build-ai-agents/understanding-skills.mdx | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx index 49ded1056..9856ae7e1 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx @@ -23,6 +23,11 @@ max-toc-depth: 3 | `google_maps` | Address validation & routing | Google Maps API key | | `info_gatherer` | Structured question collection | (none) | | `claude_skills` | Load SKILL.md files as tools | PyYAML | +| `api_ninjas_trivia` | Trivia questions from API Ninjas | API key | +| `ask_claude` | Anthropic Claude reasoning / sub-queries | `ANTHROPIC_API_KEY` | +| `custom_skills` | Register one-off SWAIG tools from config | (none) | +| `datasphere_serverless` | DataSphere search via DataMap (no server callback) | API credentials | +| `spider` | Web scraping & crawling | `cheerio` (TS) / `lxml` (Python) | ### datetime @@ -611,5 +616,10 @@ class ClaudeSkillsAgent(AgentBase): | `google_maps` | 2 | Yes | No | | `info_gatherer` | 2 | No | Yes | | `claude_skills` | Dynamic | No | Yes | +| `api_ninjas_trivia` | 1 | Yes | Yes | +| `ask_claude` | 1 | Yes | No | +| `custom_skills` | Dynamic | No | No | +| `datasphere_serverless` | 1 | Yes | Yes | +| `spider` | 1 | No | Yes | \* Requires MCP Gateway service, not external API diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx index 63a77cac9..ea30c7900 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/understanding-skills.mdx @@ -275,6 +275,15 @@ agent.Run(); | `swml_transfer` | Transfer calls to SWML endpoints | | `datasphere` | Search DataSphere documents | | `native_vector_search` | Local vector search | +| `mcp_gateway` | Connect to MCP server tools | +| `google_maps` | Address validation and routing | +| `info_gatherer` | Structured question collection | +| `claude_skills` | Load SKILL.md files as tools | +| `api_ninjas_trivia` | Trivia questions from API Ninjas | +| `ask_claude` | Anthropic Claude reasoning / sub-queries | +| `custom_skills` | Register one-off SWAIG tools from config | +| `datasphere_serverless` | DataSphere search via serverless DataMap | +| `spider` | Web scraping and crawling | ## Chapter Contents From c20cd64c4a76acf63f317a69e9fbfa6e0d270b1b Mon Sep 17 00:00:00 2001 From: august l-r Date: Fri, 24 Apr 2026 16:27:47 +0000 Subject: [PATCH 15/21] docs(ts-sdk): fix orphan TypeScript rows in deploy tables deploy/serverless.mdx: collapse blank line at L23 between the Python and TypeScript rows of the "Language support for serverless" table so both rows render as one contiguous table. deploy/cgi-mode.mdx: move the TypeScript row into the `{/* */}` block that wraps the other non-TS language rows. --- fern/products/server-sdks/pages/guides/deploy/cgi-mode.mdx | 4 +--- fern/products/server-sdks/pages/guides/deploy/serverless.mdx | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/fern/products/server-sdks/pages/guides/deploy/cgi-mode.mdx b/fern/products/server-sdks/pages/guides/deploy/cgi-mode.mdx index 25dd2ec15..e951123bf 100644 --- a/fern/products/server-sdks/pages/guides/deploy/cgi-mode.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/cgi-mode.mdx @@ -16,10 +16,8 @@ CGI mode is primarily supported by the **Python** and **Perl** SDKs. Compiled la | Language | CGI Support | Notes | |----------|-------------|-------| | Python | Full | Automatic detection via `GATEWAY_INTERFACE` | - -| TypeScript | Possible | Via `node` as CGI; prefer server mode instead | {/* - +| TypeScript | Possible | Via `node` as CGI; prefer server mode instead | | Perl | Full | Natural CGI fit; works with `CGI.pm` and the SDK | | Ruby | Possible | Via `ruby` interpreter as CGI; prefer Rack instead | | Go | Not recommended | Compiled binary; use server mode | diff --git a/fern/products/server-sdks/pages/guides/deploy/serverless.mdx b/fern/products/server-sdks/pages/guides/deploy/serverless.mdx index 92e7229b5..64236fa06 100644 --- a/fern/products/server-sdks/pages/guides/deploy/serverless.mdx +++ b/fern/products/server-sdks/pages/guides/deploy/serverless.mdx @@ -20,7 +20,6 @@ max-toc-depth: 3 | Language | AWS Lambda | Google Cloud Functions | Azure Functions | |----------|------------|------------------------|-----------------| | Python | Yes | Yes | Yes | - | TypeScript | Yes (Node.js runtime) | Yes (Node.js runtime) | Yes (Node.js runtime) | {/* From 6a65508441aa05c0b018aa4e6bed37e14b96d189 Mon Sep 17 00:00:00 2001 From: august l-r Date: Fri, 24 Apr 2026 16:28:37 +0000 Subject: [PATCH 16/21] docs(ts-sdk): add TypeScript tabs to security guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit security.mdx: pair the two Python code blocks that port cleanly with matching TypeScript tabs, and scope the direct-SSL example to Python. - Credentials in Your Agent (L88): TS tab using AgentBase with basicAuth: [user, pass] reading from SWML_BASIC_AUTH_USER / SWML_BASIC_AUTH_PASSWORD env vars. - Function Token Security example (L166): TS tab showing a SecureAgent subclass calling defineTool({ ..., secure: true }). - SSL Configuration (L264): annotated with a Note explaining that TypeScript AgentBase.serve() does not accept SSL arguments — directs readers to the reverse-proxy pattern below (recommended) or the WebService reference for programmatic SSL. --- .../pages/guides/build-ai-agents/security.mdx | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/security.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/security.mdx index 15fe0730e..0921ff065 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/security.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/security.mdx @@ -85,6 +85,8 @@ INFO: Password: a7b3x9k2m5n1p8q4 # Use this in SignalWire webhook config #### Credentials in Your Agent + + ```python from signalwire import AgentBase import os @@ -98,6 +100,22 @@ class MyAgent(AgentBase): basic_auth_password=os.getenv("SWML_BASIC_AUTH_PASSWORD") ) ``` + + +```typescript +import { AgentBase } from '@signalwire/sdk'; + +const agent = new AgentBase({ + name: 'my-agent', + // Credentials from environment or defaults + basicAuth: [ + process.env['SWML_BASIC_AUTH_USER']!, + process.env['SWML_BASIC_AUTH_PASSWORD']!, + ], +}); +``` + + ### Function Token Security @@ -145,6 +163,8 @@ Enable per-function token validation with the `secure` flag: */} + + ```python from signalwire import AgentBase, FunctionResult @@ -176,6 +196,36 @@ class SecureAgent(AgentBase): # This only executes if token is valid return FunctionResult("Transfer complete") ``` + + +```typescript +import { AgentBase, FunctionResult } from '@signalwire/sdk'; + +class SecureAgent extends AgentBase { + constructor() { + super({ name: 'secure-agent' }); + + // Regular function - Basic Auth only + this.defineTool({ + name: 'get_balance', + description: 'Get account balance', + parameters: { type: 'object', properties: {} }, + handler: () => new FunctionResult('Balance is $150.00'), + }); + + // Secure function - Basic Auth + Token validation + this.defineTool({ + name: 'transfer_funds', + description: 'Transfer funds between accounts', + parameters: { type: 'object', properties: {} }, + handler: () => new FunctionResult('Transfer complete'), + secure: true, // Enable token security + }); + } +} +``` + + #### Token Generation @@ -224,6 +274,13 @@ class SecureAgent(AgentBase): ) ``` + +The TypeScript `AgentBase` does not expose SSL directly — `agent.serve()` +accepts only `{ host, port }`. For production TypeScript deployments, use +the reverse-proxy pattern below (recommended) or see the `WebService` +reference for programmatic SSL. + + #### Using a Reverse Proxy (Recommended) Most production deployments use a reverse proxy for SSL: From 9137e70277255d1b4c366462fa71a4c4b48eacd4 Mon Sep 17 00:00:00 2001 From: august l-r Date: Fri, 24 Apr 2026 16:29:41 +0000 Subject: [PATCH 17/21] docs(ts-sdk): document pgvector for TypeScript + fix threshold name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit search-knowledge.mdx: the TS NativeVectorSearchSkill source declares `backend: 'pgvector'`, `connection_string`, and `collection_name` at native_vector_search.ts:308-355 — pgvector is a supported TS config path, not Python-only as previously assumed. - pgvector Backend section: add a TypeScript tab alongside the existing Python example using addSkillByName('native_vector_search', { backend: 'pgvector', connection_string, collection_name, ... }). - Rename `distance_threshold` → `similarity_threshold` throughout. The TS source (native_vector_search.ts:797) and the Python source (skill.py:253) both use `similarity_threshold`; the doc was wrong for both SDKs. Also clarified that higher is better. --- .../build-ai-agents/search-knowledge.mdx | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx index c7dd78715..c69d52525 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/search-knowledge.mdx @@ -188,7 +188,7 @@ self.add_skill( # Search parameters count=5, # Results to return (1-20) - distance_threshold=0.0, # Min score (0.0-1.0) + similarity_threshold=0.0, # Min score (0.0-1.0) tags=["docs", "api"], # Filter by tags # Tool configuration @@ -201,6 +201,8 @@ self.add_skill( For production deployments, use PostgreSQL with pgvector: + + ```python self.add_skill( "native_vector_search", @@ -211,6 +213,19 @@ self.add_skill( tool_name="search_docs" ) ``` + + +```typescript +await agent.addSkillByName('native_vector_search', { + backend: 'pgvector', + connection_string: 'postgresql://user:pass@localhost/db', + collection_name: 'knowledge_base', + count: 5, + tool_name: 'search_docs', +}); +``` + + ### CLI Commands @@ -411,7 +426,7 @@ self.prompt_add_section( - `count=5`: Good balance (default) - `count=10`: More comprehensive, but may include less relevant results -**distance_threshold**: Minimum relevance score (0.0 to 1.0) +**similarity_threshold**: Minimum relevance score (0.0 to 1.0) — higher is better. - `0.0`: Return all results regardless of relevance - `0.3`: Filter out clearly irrelevant results - `0.5+`: Only high-confidence matches (may miss relevant content) @@ -432,7 +447,7 @@ self.add_skill( - Check that the index file exists and is readable - Verify the query is meaningful (not too short or generic) -- Lower distance_threshold if set too high +- Lower similarity_threshold if set too high - Ensure documents were actually indexed (check with `sw-search validate`) #### Poor result relevance @@ -462,7 +477,7 @@ self.add_skill( #### Agent Configuration - Set count=3-5 for most use cases -- Use distance_threshold to filter noise +- Use similarity_threshold to filter noise - Give descriptive tool_name and tool_description - Tell AI when/how to use search in the prompt - Handle "no results" gracefully in your prompt From 737c8c7413f2cf589816afd320d4b904ec23f79f Mon Sep 17 00:00:00 2001 From: august l-r Date: Fri, 24 Apr 2026 16:30:39 +0000 Subject: [PATCH 18/21] docs(ts-sdk): rebuild builtin-skills parameter tables from source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit builtin-skills.mdx: parameter tables for 11 skills had drifted from each skill's getParameterSchema(). Rebuilt every table against signalwire-typescript/src/skills/builtin/.ts, cross-checked against signalwire-python/.../skills//skill.py where relevant. - datetime and math: replaced Parameters tables with "no configuration parameters" note. Verified in both Python (datetime/skill.py:118, math/skill.py:136) and TypeScript — neither skill declares custom params. Removed the `default_timezone` config from the add-skill example at L72 (it never existed). - web_search: add `delay`, `max_content_length`, `oversample_factor`, `no_results_message`, `safe_search`; drop phantom `tool_description`. - wikipedia_search: replace `language`/`sentences`/`tool_name` (none exist) with `num_results` and `no_results_message`. - weather_api: add `units` enum; drop `tool_description`. - joke: drop phantom `category`. - play_background_file: full rewrite. Document catalog mode (`files`) and free-form mode (`default_file_url`/`allowed_domains`); remove non-existent `audio_url`/`volume`/`loop`/split tool_name_*. - swml_transfer: add Parameters table (didn't exist); list `transfers`, `patterns`, `allow_arbitrary`, `tool_name`, `description`, `parameter_name`, `parameter_description`, `default_message`, `default_post_process`, `required_fields`. - datasphere: add Parameters table; rename `api_token` → `token`; add `document_id`, `count`, `distance`, `tags`, `language`, `pos_to_expand`, `max_synonyms`, `no_results_message`. - native_vector_search: add Parameters table; rename `index_path` → `index_file`; add `backend` (sqlite/pgvector), `connection_string`, `collection_name`, `build_index`, `source_dir`, `remote_url`, `index_name`, `similarity_threshold`, `tags`, `global_tags`, `file_types`, `exclude_patterns`, `no_results_message`, `response_prefix`, `response_postfix`, `max_content_length`, `description`. - google_maps: add `geocode_tool_name`, `route_by_coords_tool_name`, `default_mode` enum. - info_gatherer: add `completion_message`; clarify `questions` shape. - claude_skills: add `include`, `exclude`, `prompt_title`, `prompt_intro`, `skill_descriptions`, `response_prefix`, `response_postfix`, `allow_shell_injection`, `allow_script_execution`, `ignore_invocation_control`, `shell_timeout`. --- .../guides/build-ai-agents/builtin-skills.mdx | 188 +++++++++++++----- 1 file changed, 135 insertions(+), 53 deletions(-) diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx index 9856ae7e1..b09439ab8 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx @@ -42,11 +42,7 @@ Get current date and time information with timezone support. This is one of the **Parameters:** -| Parameter | Type | Description | Default | -|-----------|------|-------------|---------| -| `default_timezone` | string | Default timezone if none specified | "UTC" | -| `tool_name_time` | string | Custom name for time function | "get_current_time" | -| `tool_name_date` | string | Custom name for date function | "get_current_date" | +This skill takes no configuration parameters. Timezone is specified per call via the `timezone` argument on `get_current_time`; UTC is the default when omitted. **Output format:** @@ -66,18 +62,18 @@ Get current date and time information with timezone support. This is one of the - Doesn't do time math or calculate durations - Doesn't handle historical dates -| Language | Adding datetime with config | -|----------|----------------------------| -| Python | `self.add_skill("datetime", {"default_timezone": "America/New_York"})` | -| TypeScript | `await agent.addSkillByName('datetime', { default_timezone: 'America/New_York' })` | +| Language | Adding datetime | +|----------|-----------------| +| Python | `self.add_skill("datetime")` | +| TypeScript | `await agent.addSkillByName('datetime')` | {/* -| Go | `a.AddSkill("datetime", map[string]any{"default_timezone": "America/New_York"})` | -| Ruby | `agent.add_skill('datetime', default_timezone: 'America/New_York')` | -| Java | `agent.addSkill("datetime", Map.of("default_timezone", "America/New_York"))` | -| Perl | `$agent->add_skill('datetime', { default_timezone => 'America/New_York' })` | -| C++ | `agent.add_skill("datetime", {{"default_timezone", "America/New_York"}})` | -| PHP | `$agent->addSkill('datetime', ['default_timezone' => 'America/New_York'])` | +| Go | `a.AddSkill("datetime", nil)` | +| Ruby | `agent.add_skill('datetime')` | +| Java | `agent.addSkill("datetime")` | +| Perl | `$agent->add_skill('datetime')` | +| C++ | `agent.add_skill("datetime")` | +| PHP | `$agent->addSkill('datetime')` | */} @@ -89,9 +85,7 @@ class TimeAgent(AgentBase): super().__init__(name="time-agent") self.add_language("English", "en-US", "rime.spore") - self.add_skill("datetime", { - "default_timezone": "America/New_York" - }) + self.add_skill("datetime") self.prompt_add_section( "Role", @@ -111,10 +105,7 @@ Perform mathematical calculations safely. The skill uses a secure expression eva **Parameters:** -| Parameter | Type | Description | Default | -|-----------|------|-------------|---------| -| `tool_name` | string | Custom function name | "calculate" | -| `tool_description` | string | Custom description | "Perform calculations" | +This skill takes no configuration parameters. The registered tool is always named `calculate`. **Supported operations:** @@ -177,14 +168,18 @@ Search the web using Google Custom Search API. Results are filtered for quality | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `api_key` | string | Google API key | Required | -| `search_engine_id` | string | Search engine ID | Required | +| `api_key` | string | Google API key (falls back to `GOOGLE_SEARCH_API_KEY`) | Required | +| `search_engine_id` | string | Search engine ID (falls back to `GOOGLE_SEARCH_ENGINE_ID`) | Required | +| `tool_name` | string | Custom function name (set per instance) | "web_search" | | `num_results` | integer | Results to return | 3 | +| `delay` | number | Seconds between requests | 0.5 | +| `max_content_length` | integer | Max characters of scraped page content | 32768 | +| `oversample_factor` | number | Fetch extra results then re-rank | 2.5 | | `min_quality_score` | number | Quality threshold (0-1) | 0.3 | -| `tool_name` | string | Custom function name | "web_search" | -| `tool_description` | string | Custom description | "Search the web" | +| `no_results_message` | string | Message returned when nothing matches | default | +| `safe_search` | string | `"off"`, `"medium"`, or `"high"` | "medium" | -**Multi-instance support:** Yes - add multiple instances for different search engines (news, docs, etc.) +**Multi-instance support:** Yes - add multiple instances with unique `tool_name` values (e.g. `search_news`, `search_docs`). ```python from signalwire import AgentBase @@ -220,9 +215,8 @@ Search Wikipedia for information. A free, no-API-key alternative to web search f | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `language` | string | Wikipedia language code | "en" | -| `sentences` | integer | Sentences to return per result | 3 | -| `tool_name` | string | Custom function name | "search_wikipedia" | +| `num_results` | integer | Max articles returned (1-5) | 1 | +| `no_results_message` | string | Message returned when nothing matches | default template | ```python from signalwire import AgentBase @@ -233,7 +227,7 @@ class WikiAgent(AgentBase): self.add_language("English", "en-US", "rime.spore") self.add_skill("wikipedia_search", { - "sentences": 5 # More detailed summaries + "num_results": 3 # Return up to three articles }) self.prompt_add_section( @@ -262,9 +256,9 @@ Get current weather information for locations worldwide. Commonly used for small | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `api_key` | string | WeatherAPI.com API key | Required | +| `api_key` | string | WeatherAPI.com API key (falls back to `WEATHER_API_KEY`) | Required | | `tool_name` | string | Custom function name | "get_weather" | -| `tool_description` | string | Custom description | "Get weather" | +| `units` | string | `"metric"`, `"imperial"`, `"standard"`, `"celsius"`, or `"fahrenheit"` | "fahrenheit" | ```python from signalwire import AgentBase @@ -298,7 +292,6 @@ Tell jokes to lighten the mood or entertain callers. Uses a curated joke databas | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `category` | string | Joke category filter | None (random) | | `tool_name` | string | Custom function name | "tell_joke" | ```python @@ -330,13 +323,21 @@ Play audio files in the background during calls. Audio plays while conversation **Parameters:** +This skill supports two configuration styles: + +- **Catalog mode** — preload named files via `files`, caller selects by `key`: + | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `audio_url` | string | URL of audio file to play | Required | -| `volume` | number | Playback volume (0.0-1.0) | 0.5 | -| `loop` | boolean | Loop the audio | false | -| `tool_name_play` | string | Custom play function name | "play_background_file" | -| `tool_name_stop` | string | Custom stop function name | "stop_background_file" | +| `tool_name` | string | Custom play function name | "play_background_file" | +| `files` | array | List of `{ key, description, url, wait? }` entries | Required | + +- **Free-form mode** — caller supplies a URL at call time (gated by `allowed_domains`): + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `default_file_url` | string | URL played when no argument is provided | Required | +| `allowed_domains` | array | Whitelisted domains for caller-supplied URLs | Required | **Supported formats:** MP3, WAV, OGG @@ -349,9 +350,13 @@ class MusicAgent(AgentBase): self.add_language("English", "en-US", "rime.spore") self.add_skill("play_background_file", { - "audio_url": "https://example.com/hold-music.mp3", - "volume": 0.3, # Lower volume for background - "loop": True + "files": [ + { + "key": "hold_music", + "description": "Looping hold music", + "url": "https://example.com/hold-music.mp3", + } + ] }) ``` @@ -361,10 +366,25 @@ Transfer calls to another SWML endpoint. **Functions:** -- `transfer_to_swml` - Transfer to SWML URL +- `transfer_call` (default name) - Transfer based on matched pattern **Requirements:** None +**Parameters:** + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `transfers` | object | Pattern → `{ url \| address, message?, return_message?, post_process?, final?, from_addr? }` | Required (or use `patterns`) | +| `patterns` | array | Alternative shape: list of pattern entries | Required (or use `transfers`) | +| `allow_arbitrary` | boolean | Accept caller-supplied URL instead of matching a pattern | false | +| `tool_name` | string | Custom function name | "transfer_call" | +| `description` | string | Tool description | default | +| `parameter_name` | string | Argument name the LLM supplies | "transfer_type" | +| `parameter_description` | string | Argument description | default | +| `default_message` | string | Message when no pattern matches | default | +| `default_post_process` | boolean | Default for transferred calls returning to the agent | false | +| `required_fields` | object | Extra per-pattern required fields | `{}` | + ```python from signalwire import AgentBase @@ -374,8 +394,12 @@ class TransferAgent(AgentBase): self.add_language("English", "en-US", "rime.spore") self.add_skill("swml_transfer", { - "swml_url": "https://your-server.com/other-agent", - "description": "Transfer to specialist" + "transfers": { + "specialist": { + "url": "https://your-server.com/other-agent", + "message": "Transferring you to a specialist." + } + } }) ``` @@ -385,10 +409,27 @@ Search SignalWire DataSphere documents. **Functions:** -- `search_datasphere` - Search uploaded documents +- `search_knowledge` (default name) - Search uploaded documents **Requirements:** DataSphere API credentials +**Parameters:** + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `space_name` | string | DataSphere space name | Required | +| `project_id` | string | Project ID (falls back to `SIGNALWIRE_PROJECT_ID`) | Required | +| `token` | string | API token (falls back to `SIGNALWIRE_TOKEN`) | Required | +| `document_id` | string | Document ID to search within | Required | +| `tool_name` | string | Custom function name | "search_knowledge" | +| `count` | integer | Results to return (1-10) | 1 | +| `distance` | number | Distance threshold (0-10) | 3.0 | +| `tags` | array | Filter by document tags | — | +| `language` | string | Language filter | — | +| `pos_to_expand` | array | POS tags to expand (`NOUN`, `VERB`, `ADJ`, `ADV`) | — | +| `max_synonyms` | integer | Synonym expansion limit (1-10) | — | +| `no_results_message` | string | Message when nothing matches | default | + ```python from signalwire import AgentBase @@ -400,7 +441,8 @@ class KnowledgeAgent(AgentBase): self.add_skill("datasphere", { "space_name": "your-space", "project_id": "YOUR_PROJECT_ID", - "api_token": "YOUR_API_TOKEN" + "token": "YOUR_API_TOKEN", + "document_id": "your-document-id" }) ``` @@ -410,10 +452,35 @@ Local vector search using .swsearch index files. **Functions:** -- `search_knowledge` - Search local vector index +- Dynamic name (default `search_knowledge`) - Search a local vector index **Requirements:** Search extras installed (`pip install "signalwire-sdk[search]"`) +**Parameters:** + +| Parameter | Type | Description | Default | +|-----------|------|-------------|---------| +| `tool_name` | string | Custom function name | "search_knowledge" | +| `index_file` | string | SQLite `.swsearch` path (SQLite backend) | — | +| `backend` | string | `"sqlite"` or `"pgvector"` | "sqlite" | +| `connection_string` | string | PostgreSQL URL (pgvector backend) | — | +| `collection_name` | string | Table/collection name (pgvector backend) | — | +| `build_index` | boolean | Rebuild index on startup | false | +| `source_dir` | string | Source directory when building | — | +| `remote_url` | string | Remote search-server URL (alternative to local index) | — | +| `index_name` | string | Named index on remote server | "default" | +| `count` | integer | Results to return (1-20) | 5 | +| `similarity_threshold` | number | Minimum score (0.0-1.0) | 0.0 | +| `tags` | array | Filter results by tag | `[]` | +| `global_tags` | array | Always-applied tag filter | `[]` | +| `file_types` | array | File extensions to index | `["md","txt","pdf","docx","html"]` | +| `exclude_patterns` | array | Glob patterns to skip | defaults | +| `no_results_message` | string | Message when nothing matches | default template | +| `response_prefix` | string | Prepended to result text | — | +| `response_postfix` | string | Appended to result text | — | +| `max_content_length` | integer | Max result chars | 32768 | +| `description` | string | Tool description override | — | + ```python from signalwire import AgentBase @@ -423,7 +490,7 @@ class LocalSearchAgent(AgentBase): self.add_language("English", "en-US", "rime.spore") self.add_skill("native_vector_search", { - "index_path": "/path/to/knowledge.swsearch", + "index_file": "/path/to/knowledge.swsearch", "tool_name": "search_docs" }) ``` @@ -500,9 +567,12 @@ Validate addresses and compute driving routes using Google Maps. Supports geocod | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `api_key` | string | Google Maps API key | Required | -| `lookup_tool_name` | string | Custom name for address lookup function | "lookup_address" | -| `route_tool_name` | string | Custom name for route computation function | "compute_route" | +| `api_key` | string | Google Maps API key (falls back to `GOOGLE_MAPS_API_KEY`) | Required | +| `lookup_tool_name` | string | Address lookup function name | "lookup_address" | +| `route_tool_name` | string | Route computation function name | "compute_route" | +| `geocode_tool_name` | string | Reverse-geocoding function name | "geocode_address" | +| `route_by_coords_tool_name` | string | Coord-based route function name | "compute_route_by_coords" | +| `default_mode` | string | `"driving"`, `"walking"`, `"bicycling"`, or `"transit"` | "driving" | ```python from signalwire import AgentBase @@ -537,8 +607,9 @@ Gather answers to a configurable list of questions. This is the skill version of | Parameter | Type | Description | Default | |-----------|------|-------------|---------| -| `questions` | list | List of question dictionaries (key_name, question_text, confirm) | Required | +| `questions` | list | List of question dictionaries (`key_name`, `question_text`, `confirm`, `prompt_add`) | Required | | `prefix` | string | Prefix for tool names and namespace (enables multi-instance) | None | +| `completion_message` | string | Message read after the last question | default template | **Multi-instance support:** Yes - use the `prefix` parameter to run multiple question sets on a single agent. With `prefix="intake"`, tools become `intake_start_questions` and `intake_submit_answer`, and state is stored under `skill:intake` in global_data. @@ -582,7 +653,18 @@ Load Claude Code-style SKILL.md files as agent tools. Each SKILL.md file in the | Parameter | Type | Description | Default | |-----------|------|-------------|---------| | `skills_path` | string | Path to directory containing SKILL.md files | Required | +| `include` | array | Glob patterns of SKILL.md files to load | `["*"]` | +| `exclude` | array | Glob patterns to skip | `[]` | | `tool_prefix` | string | Prefix for generated function names | "claude_" | +| `prompt_title` | string | Section title added to agent prompt | "Claude Skills" | +| `prompt_intro` | string | Prose introducing the loaded skills | default template | +| `skill_descriptions` | object | Override descriptions, keyed by skill name | `{}` | +| `response_prefix` | string | Prepended to each skill response | — | +| `response_postfix` | string | Appended to each skill response | — | +| `allow_shell_injection` | boolean | Permit shell metacharacters in arguments | false | +| `allow_script_execution` | boolean | Permit running scripts referenced by a skill | false | +| `ignore_invocation_control` | boolean | Bypass per-skill invocation gating | false | +| `shell_timeout` | integer | Shell command timeout (seconds) | 30 | ```python from signalwire import AgentBase From de0e8b0eb8d40c4eb950f7836baffdb031469943 Mon Sep 17 00:00:00 2001 From: august l-r Date: Fri, 24 Apr 2026 18:26:21 +0000 Subject: [PATCH 19/21] fix card link --- .../server-sdks/pages/guides/getting-started/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fern/products/server-sdks/pages/guides/getting-started/overview.mdx b/fern/products/server-sdks/pages/guides/getting-started/overview.mdx index b95d009cc..203a2f0c8 100644 --- a/fern/products/server-sdks/pages/guides/getting-started/overview.mdx +++ b/fern/products/server-sdks/pages/guides/getting-started/overview.mdx @@ -25,7 +25,7 @@ The SignalWire Server SDK is available in multiple languages. Select the variant Date: Mon, 27 Apr 2026 09:00:39 -0400 Subject: [PATCH 20/21] Updates, new methods --- fern/products/server-sdks/sdk-source-sync.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fern/products/server-sdks/sdk-source-sync.json b/fern/products/server-sdks/sdk-source-sync.json index d5085ec2b..1d57d90b5 100644 --- a/fern/products/server-sdks/sdk-source-sync.json +++ b/fern/products/server-sdks/sdk-source-sync.json @@ -12,8 +12,8 @@ "repository": "https://github.com/signalwire/signalwire-typescript.git", "local_path": "temp/signalwire-typescript", "status": "active", - "synced_commit": "ba6d5b1f1c68065bb378ab9c1a79c4a08da107e1", - "synced_at": "2026-04-23" + "synced_commit": "30391ceeb0d5e1e0b409826c99a4a1ac31b1be2b", + "synced_at": "2026-04-27" }, "go": { "repository": "https://github.com/signalwire/signalwire-go.git", From c344732301f852516283121da85ae1c225571156 Mon Sep 17 00:00:00 2001 From: Devon-White Date: Mon, 27 Apr 2026 09:00:44 -0400 Subject: [PATCH 21/21] Updates, new methods --- .../typescript/rest/phone-numbers/index.mdx | 79 ++++++++++++++++++- .../rest/phone-numbers/set-ai-agent.mdx | 46 +++++++++++ .../rest/phone-numbers/set-call-flow.mdx | 54 +++++++++++++ .../phone-numbers/set-cxml-application.mdx | 47 +++++++++++ .../rest/phone-numbers/set-cxml-webhook.mdx | 67 ++++++++++++++++ .../phone-numbers/set-relay-application.mdx | 47 +++++++++++ .../rest/phone-numbers/set-relay-topic.mdx | 54 +++++++++++++ .../rest/phone-numbers/set-swml-webhook.mdx | 50 ++++++++++++ 8 files changed, 442 insertions(+), 2 deletions(-) create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-ai-agent.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-call-flow.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-application.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-webhook.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-application.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-topic.mdx create mode 100644 fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-swml-webhook.mdx diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx index 8b6fb3597..10b33bf19 100644 --- a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/index.mdx @@ -1,7 +1,7 @@ --- title: "Phone Numbers" slug: /reference/typescript/rest/phone-numbers -description: "Search and manage phone numbers." +description: "Search and manage phone numbers, and bind inbound calls to handlers." max-toc-depth: 3 --- @@ -12,10 +12,19 @@ max-toc-depth: 3 [update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update [delete]: /docs/server-sdks/reference/typescript/rest/phone-numbers/delete [search]: /docs/server-sdks/reference/typescript/rest/phone-numbers/search +[setswml]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-swml-webhook +[setcxml]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-cxml-webhook +[setcxmlapp]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-cxml-application +[setai]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-ai-agent +[setflow]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-call-flow +[setrelayapp]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-relay-application +[setrelaytopic]: /docs/server-sdks/reference/typescript/rest/phone-numbers/set-relay-topic Search for available phone numbers, purchase them, and manage the numbers in your SignalWire project. This resource extends the standard CRUD pattern with a `search()` -method for discovering available numbers and uses PUT for updates. +method for discovering available numbers, uses PUT for updates, and provides typed +helpers for binding inbound calls to a handler (SWML webhook, cXML webhook, AI agent, +call flow, RELAY application/topic). Access via `client.phoneNumbers` on a [`RestClient`][restclient] instance. @@ -43,6 +52,8 @@ for (const number of available.data ?? []) { ## **Methods** +### Standard CRUD + List phone numbers owned by the project. @@ -63,3 +74,67 @@ for (const number of available.data ?? []) { Search for available phone numbers to purchase. + +### Typed Binding Helpers + +Each helper is a one-line wrapper over [`update`][update] that sets `call_handler` +to the right value and populates the handler-specific companion field for you. +Pass extra wire-level fields through the `extra` argument (or as additional keys +on the params object) for fields the helper doesn't name explicitly. Setting a +binding auto-materializes the matching Fabric resource on the server. + + + + Route inbound calls to an SWML webhook URL. + + + Route inbound calls to a cXML (LAML) webhook. + + + Route inbound calls to an existing cXML application by ID. + + + Route inbound calls to an AI Agent Fabric resource by ID. + + + Route inbound calls to a Call Flow by ID. + + + Route inbound calls to a named RELAY application. + + + Route inbound calls to a RELAY topic. + + + +## **PhoneCallHandler** + +For callers passing `call_handler` directly to [`update`][update], the +`PhoneCallHandler` const provides typed values. It is a `const`-as-enum +(`as const` object plus a same-named string-union type), so passing a member +serializes to its wire value with full type-checking on the call site. + +```typescript +import { PhoneCallHandler } from "@signalwire/sdk"; + +await client.phoneNumbers.update("phone-number-id", { + call_handler: PhoneCallHandler.AI_AGENT, + call_ai_agent_id: "ai-agent-id", +}); +``` + +| Member | Wire value | Companion field | Auto-creates | +|--------------------|----------------------|----------------------------|---------------------| +| `RELAY_SCRIPT` | `relay_script` | `call_relay_script_url` | `swml_webhook` | +| `LAML_WEBHOOKS` | `laml_webhooks` | `call_request_url` | `cxml_webhook` | +| `LAML_APPLICATION` | `laml_application` | `call_laml_application_id` | `cxml_application` | +| `AI_AGENT` | `ai_agent` | `call_ai_agent_id` | `ai_agent` | +| `CALL_FLOW` | `call_flow` | `call_flow_id` | `call_flow` | +| `RELAY_APPLICATION`| `relay_application` | `call_relay_application` | `relay_application` | +| `RELAY_TOPIC` | `relay_topic` | `call_relay_topic` | (routes via RELAY) | + + +`LAML_WEBHOOKS` (wire value `laml_webhooks`) produces a **cXML** handler, not a +generic webhook. For SWML, use `RELAY_SCRIPT` -- or, more conveniently, the +[`setSwmlWebhook`][setswml] helper. + diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-ai-agent.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-ai-agent.mdx new file mode 100644 index 000000000..04a05fbdb --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-ai-agent.mdx @@ -0,0 +1,46 @@ +--- +title: "setAiAgent" +slug: /reference/typescript/rest/phone-numbers/set-ai-agent +description: Route inbound calls to an AI Agent Fabric resource by ID. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to an existing AI Agent Fabric resource +by its ID. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`ai_agent` and populates `call_ai_agent_id` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + ID of the AI Agent Fabric resource to route calls to. + + + + Additional wire-level fields merged into the PUT body. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setAiAgent("phone-number-id", "ai-agent-id"); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-call-flow.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-call-flow.mdx new file mode 100644 index 000000000..39b5e7cdd --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-call-flow.mdx @@ -0,0 +1,54 @@ +--- +title: "setCallFlow" +slug: /reference/typescript/rest/phone-numbers/set-call-flow +description: Route inbound calls to a Call Flow by ID. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to an existing Call Flow by its ID. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`call_flow` and populates `call_flow_id` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + Flow ID and options. + + + + ID of the Call Flow to route calls to. Serialized as `call_flow_id`. + + + + Which Call Flow version to invoke. Accepts `"working_copy"` or + `"current_deployed"`. Defaults to the server's current deployed version when + omitted. Serialized as `call_flow_version`. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9-12} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setCallFlow("phone-number-id", { + flowId: "call-flow-id", + version: "working_copy", +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-application.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-application.mdx new file mode 100644 index 000000000..adb1203b7 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-application.mdx @@ -0,0 +1,47 @@ +--- +title: "setCxmlApplication" +slug: /reference/typescript/rest/phone-numbers/set-cxml-application +description: Route inbound calls to an existing cXML application by ID. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to an existing cXML (LAML) application +by its ID. The server auto-creates a `cxml_application` Fabric resource +referencing the application. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`laml_application` and populates `call_laml_application_id` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + ID of the cXML application to route calls to. + + + + Additional wire-level fields merged into the PUT body. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setCxmlApplication("phone-number-id", "cxml-application-id"); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-webhook.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-webhook.mdx new file mode 100644 index 000000000..2a7739d39 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-cxml-webhook.mdx @@ -0,0 +1,67 @@ +--- +title: "setCxmlWebhook" +slug: /reference/typescript/rest/phone-numbers/set-cxml-webhook +description: Route inbound calls to a cXML (LAML) webhook. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to a cXML (Twilio-compat / LAML) +webhook. Despite the wire value `laml_webhooks` being plural, this creates a +single `cxml_webhook` Fabric resource on the server. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`laml_webhooks` and populates the URL fields for you. + + +For SWML webhooks, use +[`setSwmlWebhook`](/docs/server-sdks/reference/typescript/rest/phone-numbers/set-swml-webhook) +instead. + + +## **Parameters** + + + ID of the phone number to bind. + + + + Webhook URL and options. + + + + Primary cXML document URL. Serialized as `call_request_url`. + + + + Fallback URL invoked when the primary URL fails. Serialized as + `call_fallback_url`. + + + + URL that receives call-status updates. Serialized as + `call_status_callback_url`. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9-12} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setCxmlWebhook("phone-number-id", { + url: "https://example.com/voice.xml", + fallbackUrl: "https://example.com/fallback.xml", + statusCallbackUrl: "https://example.com/status", +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-application.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-application.mdx new file mode 100644 index 000000000..4b852df0f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-application.mdx @@ -0,0 +1,47 @@ +--- +title: "setRelayApplication" +slug: /reference/typescript/rest/phone-numbers/set-relay-application +description: Route inbound calls to a named RELAY application. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to a named RELAY application. The +server auto-creates a `relay_application` Fabric resource referencing the +application name. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`relay_application` and populates `call_relay_application` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + Name of the RELAY application to route calls to. + + + + Additional wire-level fields merged into the PUT body. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setRelayApplication("phone-number-id", "my-relay-app"); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-topic.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-topic.mdx new file mode 100644 index 000000000..92e8a637c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-relay-topic.mdx @@ -0,0 +1,54 @@ +--- +title: "setRelayTopic" +slug: /reference/typescript/rest/phone-numbers/set-relay-topic +description: Route inbound calls to a RELAY topic. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to a RELAY topic. RELAY clients +subscribed to the topic will receive the inbound call event. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`relay_topic` and populates `call_relay_topic` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + Topic name and options. + + + + RELAY topic name. Serialized as `call_relay_topic`. + + + + URL that receives status updates for calls routed via this topic. Serialized + as `call_relay_topic_status_callback_url`. + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9-12} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setRelayTopic("phone-number-id", { + topic: "office", + statusCallbackUrl: "https://example.com/status", +}); +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-swml-webhook.mdx b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-swml-webhook.mdx new file mode 100644 index 000000000..48bc887f7 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/typescript/rest/phone-numbers/set-swml-webhook.mdx @@ -0,0 +1,50 @@ +--- +title: "setSwmlWebhook" +slug: /reference/typescript/rest/phone-numbers/set-swml-webhook +description: Route inbound calls to an SWML webhook URL. +max-toc-depth: 3 +--- + +[update]: /docs/server-sdks/reference/typescript/rest/phone-numbers/update + +Route inbound calls on this phone number to an SWML webhook URL. Your backend +returns an SWML document per call. The server auto-creates a `swml_webhook` +Fabric resource keyed off this URL — you do **not** need to call +`fabric.swmlWebhooks.create` or `fabric.resources.assignPhoneRoute`. + +This is a typed wrapper over [`update`][update] that sets `call_handler` to +`relay_script` and populates `call_relay_script_url` for you. + +## **Parameters** + + + ID of the phone number to bind. + + + + Webhook URL that returns SWML. The server keys the auto-created Fabric + resource off this value. + + + + Additional wire-level fields merged into the PUT body (e.g. `name`, + `call_fallback_url`). + + +## **Returns** + +`Promise` — The updated phone-number resource. + +## **Example** + +```typescript {9} +import { RestClient } from "@signalwire/sdk"; + +const client = new RestClient({ + project: "your-project-id", + token: "your-api-token", + host: "your-space.signalwire.com" +}); + +await client.phoneNumbers.setSwmlWebhook("phone-number-id", "https://example.com/swml"); +```