Skip to content

Sync TypeScript Server SDK docs - #830

Merged
hey-august merged 38 commits into
mainfrom
august-20261022-sync-ts
Nov 11, 2026
Merged

hey-august merged 38 commits into
mainfrom
august-20261022-sync-ts

Conversation

@hey-august

@hey-august hey-august commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Description

  • Syncs the whole TypeScript Server SDK reference to @signalwire/sdk v3.7.1. It was synced to an unreleased commit between 2.0.5 and 3.5.0.
    • New pages: AgentBase.addPerCallConfig, onCallStart, onCallEnd, mount; FunctionResult.changeVoice, rpcAiGlobalData; ChatGateway; HandoffRouter; AIChatClient.rawPost; the capabilities helpers; the post-prompt helpers; validateWebhookSignatureSha256; the sw-tsdocs CLI; WebService; the SemanticGate helpers and limits (gateDefinitions, applyGateFields, MAX_*, RESERVED_FUNCTION_NAMES); AgentBase.runServerless, getTools; ServerlessAdapter.createCgiHandler; the skill module functions (registerSkill, listSkills, listSkillsWithParams, addSkillDirectory); standalone paginate/paginateAll.
    • Updated pages: dynamic config, tool handlers, onSummary, validateBasicAuth, enableMcpServer, defineContexts, addLanguage, hold, rpcAiMessage, tap, joinConference, pay, SemanticGate (visualInput), Bedrock, LiveWire, prefabs, skills, swaig-test, environment variables, serverless, AgentServer, Relay stream/userEvent/events, SwmlBuilder.ai.
    • REST reference (~90 pages): examples, ParamFields, and Returns now match 3.7.1's positional signatures and response types.
    • Removed APIs: SWMLService.run() (folded into serve), ConfigLoader getAll()/getFilePath(). Each old URL redirects to its replacement. AgentBase.run() is documented as dispatching to a serverless handler when it detects one, not as an alias of serve().
    • Prefabs: dropped the createXAgent() factories, which the package root doesn't export.
    • DataMap correction: body() sets the webhook's params, which is sent as a POST body. A webhook's output, expressions, and foreach read response fields from the root (${temp}) and arguments as ${input.args.x}. Applied to the TypeScript and Python reference and to every language tab of the DataMap guide. globalErrorKeys() no longer claims to apply to all webhooks.
    • Webhook signatures: cXML webhooks carry a SHA-256 header computed over the sorted form params, which validateWebhookSignatureSha256 can't verify; the example falls back to SHA-1 on a mismatch.
  • Fixes the 9 capability guides' TypeScript samples for 3.x, and unpins their install lines to npm install @signalwire/sdk, exactly as Install the latest Server SDK in guides instead of pinned versions #908 writes them:
    • REST: positional calling.dial, transfer, stream/streamStop, phoneNumbers.setRelayTopic, and fabric.tokens.createSubscriberToken; swmlScripts.create takes contents as a string; list data is optional.
    • Relay: nested ringback items; typed call.device and collect results; record()'s missing max_length.
    • Builder: enter_queue, stream, stop_stream, and connect's stream settings fail the SDK's schema validation, so those samples skip validation for that verb only, as the rule's builder-gap convention says.
  • Updates sdk-source-sync.json to the v3.7.1 tag commit.
  • Drops minimum-version wording for visual_input from the semantic gates guide and reference.

Notes for reviewers

Preview

Guides:

  • /docs/platform/voice/make-and-receive-calls
  • /docs/platform/voice/forward-calls
  • /docs/platform/voice/record-calls
  • /docs/platform/voice/call-queues
  • /docs/platform/voice/call-streaming
  • /docs/platform/voice/machine-detection
  • /docs/platform/voice/sip-refer
  • /docs/platform/voice/whatsapp/receive-calls
  • /docs/platform/fax/send-and-receive-faxes
  • /docs/platform/ai/semantic-gates
  • /docs/server-sdks/guides/data-map

Reference (main entry points):

  • /docs/server-sdks/reference/typescript/agents/agent-base
  • /docs/server-sdks/reference/typescript/agents/chat-gateway
  • /docs/server-sdks/reference/typescript/agents/handoff-router
  • /docs/server-sdks/reference/typescript/agents/function-result
  • /docs/server-sdks/reference/typescript/agents/data-map
  • /docs/server-sdks/reference/typescript/agents/semantic-gate
  • /docs/server-sdks/reference/typescript/agents/semantic-gate/constants
  • /docs/server-sdks/reference/typescript/agents/web-service
  • /docs/server-sdks/reference/typescript/agents/cli/sw-tsdocs
  • /docs/server-sdks/reference/typescript/core/capabilities
  • /docs/server-sdks/reference/typescript/core/post-prompt
  • /docs/server-sdks/reference/typescript/core/security
  • /docs/server-sdks/reference/typescript/rest/overview
  • /docs/server-sdks/reference/typescript/relay/events
  • /docs/server-sdks/reference/typescript/agents/configuration/environment-variables

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Code cleanup / refactor

Related Issues

Follow-up to #829, which pins @signalwire/sdk@2.0.5 and notes that this PR syncs the TypeScript reference. Aligns with #908.

Testing

Behavior verified against the platform and the API spec.

  • Every TypeScript block in the 9 guides, complete samples and fragments, passes tsc --strict against an installed @signalwire/sdk@3.7.1. One existing JavaScript sample (call streaming, Hono server) has a checkJs-only type mismatch under both 2.0.5 and 3.7.1; it runs as-is.
  • Ran every TypeScript SWML builder chain against 3.7.1 and diffed the output against the JSON sample beside it: all match.
  • Every TypeScript reference example that imports the SDK type-checks against 3.7.1, except intentional fragments, signature-only blocks, and the e164 cases above.
  • yarn fern-md-check: all MDX files valid.

Tests

  • Added/updated unit tests
  • Tested manually
  • Tested with live SignalWire credentials (if applicable)

Checklist

  • I have read the CONTRIBUTING guidelines
  • My code follows the project's style guidelines
  • I have added tests for my changes (if applicable)
  • I have updated documentation (if applicable)
  • All existing tests pass

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

@Devon-White Devon-White left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked every changed reference page against the v3.7.1 tag (875e6e2, the commit sdk-source-sync.json now records) and the published @signalwire/sdk@3.7.1. I type-checked every TypeScript block in the PR under tsc --strict and checked platform behavior in mod_openai, mod_infrastructure and prime-rails. Most of it holds up. Six things should change before this merges. The first two are coordination; the rest are wrong content.

Must change before merge

1. The pin bump and the new "Pins match the reference" rule conflict with #908. #908 unpins Server SDK installs in every guide and replaces the "Pinned versions" rule. This PR pins @3.7.1 and adds a rule that ties pins to sdk-source-sync.json, so the two can't both land. This PR also conflicts with main in .claude/rules/mdx-capability-guides.md, where main moved the Browser pin to rc.5. Even on its own terms, merging main leaves 14 guides that this PR doesn't touch on @signalwire/sdk@2.0.5: sidecar, SIP/byoc, eight TTS/* pages, both SMS pages, api-credentials and SWML deployment. That breaks "identical across every guide".

My suggestion: drop the install-line bumps and the rule change, rebase on #908 after it lands, and keep the sample fixes. The builder-gap fixes are right, and #908 doesn't have them. I ran addVerb on 3.7.1, and enter_queue without transfer_after_bridge, stream, stop_stream, and connect with codec/realtime/name all throw schema errors. #908 still chains .enter_queue({...}) in the Call queues TypeScript sample, which throws on 3.7.1.

2. The sync record says 3.7.1, but parts of the TypeScript reference still document 2.x. None of these files is in the PR, but moving synced_commit to the 3.7.1 tag says they're current. Either fix them here, or leave synced_commit where it was and list them as remaining work.

  • REST pages still pass the 2.x options object. 3.7.1 takes positional arguments here, so these fail tsc and send malformed requests. fabric/tokens/create-subscriber-token.mdx:27 calls createSubscriberToken({ reference }), but the 3.7.1 signature is createSubscriberToken(reference: string, options?) (dist/rest/namespaces/fabric.resources.generated.d.ts:167). phone-numbers/set-relay-topic.mdx:50 calls setRelayTopic(id, { topic, statusCallbackUrl }), but the signature is setRelayTopic(resourceId, topic: string, status_callback_url?, …) (relay-rest.resources.generated.d.ts:81). The guides in this PR fix exactly these two calls, so guide and reference now disagree on the same methods. The same pattern appears in:
    • fabric/tokens/{index,create-embed-token,create-guest-token,create-invite-token,refresh-subscriber-token}
    • phone-numbers/{set-cxml-webhook,set-call-flow}
    • mfa/{index,sms,call,verify}
    • video/room-tokens/{index,create}, video/rooms/create-stream, video/conferences/create-stream, video/streams/update
    • verified-callers/submit-verification, number-groups/add-membership, fabric/resources/assign-domain-application
  • Wrong argument counts (TS2554): addresses/create, chat/{index,create-token}, pubsub/{index,create-token}, project/{index,create}, imported-numbers/{index,create}, short-codes/update, fabric/resources/assign-phone-route and fabric/subscribers/create-sip-endpoint.
  • Missing required field: fabric/swml-scripts/create.mdx:27 omits the required contents.
  • SWMLService.run() no longer exists. 3.7.1 has only serve() and stop() (src/SWMLService.ts:1319). swml-service/run.mdx still documents it, and swml-service/index.mdx:247, set-on-request-callback.mdx:51, as-router.mdx:19 and stop.mdx:4 still refer to it.
  • data-map/global-error-keys.mdx:10-12 says the keys "apply to all webhooks". The 3.7.1 JSDoc on DataMap.globalErrorKeys (src/DataMap.ts:467-476) says the platform reads error_keys only on a webhook, "so these keys fail no request". The PR edits this page's example but not the claim, so the page still promises behavior the method doesn't have.

3. validateWebhookSignatureSha256 is wrong about cXML, and its example rejects genuine cXML webhooks. See the inline comments. The page copies the SDK JSDoc, which needs an upstream fix too.

4. The prefab factory imports don't resolve. prefabs/receptionist-agent.mdx:105 imports createReceptionistAgent and prefabs/survey-agent.mdx:150 imports createSurveyAgent, both from @signalwire/sdk. The package root exports only the classes (src/index.ts:272-276), the factories exist only in src/prefabs/index.ts, and package.json exports has no deep path to them. tsc fails with TS2724/TS2305. The PR edits both pages. The same import is on concierge-agent.mdx:88, faq-bot-agent.mdx:110 and info-gatherer-agent.mdx:116, and prefabs/index.mdx:34 lists the factories. Show new ReceptionistAgent({...}) etc. instead, or drop the sections.

5. The DataMap template fix stops partway. The correction itself is right. In mod_openai actions.c (around 1333-1346), a webhook's output, expressions and foreach expand against the response root plus input, global_data and prompt_vars, with no response key. That matches the SWML data_map reference. Four places still teach the old form:

  • data-map/foreach.mdx:51 uses input_key: 'response.items', which resolves to nothing. It should be input_key: 'items'. Also, the ParamFields are ordered input_key, output_key, max, append, but source order is …, append, max (DataMap.ts:407).
  • data-map/index.mdx:125: the params card still says "Set query or form parameters for a webhook", which contradicts the rewritten params.mdx. Suggested: "Set the JSON request body for a webhook."
  • guides/build-ai-agents/datamap.mdx uses ${response.*} and ${args.city} inside webhook output in every language tab, TypeScript included (lines 106-107, the table at 260-265, and 45 ${response. uses in all). After this merges, the guide contradicts the TypeScript reference.
  • The Python DataMap reference has 17 ${response. uses. mdx-reference-pages says to sync an edit across every language variant, so this belongs here or in a follow-up opened before merge. Separately, Python's body() writes body (signalwire/core/data_map.py:273 at the synced Python commit), and the platform ignores that key (actions.c:740 reads only params). That's an upstream SDK bug worth filing next to your TypeScript ones.

6. Version wording in pages. The semantic gates guide Note and semantic-gate/index.mdx:97 add "from version 3.7.1" and "Requires SDK 3.7.1 or later". Guides and reference shouldn't state minimum Server SDK versions, and guide prose shouldn't name per-language options. See the inline suggestions.

Should fix

Inline: relay/call/user-event.mdx (the platform rejects what the page now says is sent), the ChatGateway constructor's other throw conditions, serve.mdx's run() alias claim, the security overview's fallback wording, and a highlight range in Record calls.

Nits

  • configuration/index.mdx:78-83 (not in the PR) still passes index_file to native_vector_search. The updated skills/native-vector-search.mdx correctly says no index file is read (native_vector_search.ts:252-256).
  • ai-chat-client/raw-post.mdx:23: "check the status first" works against the source. The _request JSDoc says success is decided by the body because the keepalive commits a 200 early. Reading the body's error member is the check.
  • agent-base/add-per-call-config.mdx:30: ## Rejecting a call sits before ## Parameters. Fold it into the intro or move it after Returns.
  • agent-base/add-language.mdx: functionFillers comes after speechModel. LanguageConfig order (types.ts:108) puts it right after speechFillers.
  • function-result/index.mdx:218: the hold card still says only "with an optional timeout". It now also takes the announcement and the resume step.
  • cli/sw-tsdocs.mdx:193-195 hard-codes 3.7.1 as the --version output. That goes stale, so use a placeholder.
  • Highlights already off in blocks this PR touches: agent-base/register-swaig-function.mdx:32 {15} should be {16}, and swml-service/register-swaig-function.mdx:30 {12} should be {13}.
  • record-calls.mdx: Object(event.params.result).params?.digits reads oddly as a teaching sample. A typed cast with the comment you already have would be clearer.
  • 19 touched pages lack max-toc-depth: 3 (both prefab pages, skill-manager/*, skill-registry/*, skills/*). This predates the PR.

Public API still without a page

Besides WebService and createCgiHandler, which you noted:

  • AgentBase.runServerless() and getTools()
  • The SemanticGate helpers: gateDefinitions, applyGateFields, MAX_GATES, MAX_QUESTION_BYTES, MAX_CRITERIA_BYTES, MAX_ON_FAIL_BYTES and RESERVED_FUNCTION_NAMES
  • The top-level registerSkill() and listSkillsWithParams()
  • paginateAll
  • Relay CollectAction.pause()/resume()
  • SkillManager.size and SkillRegistry.size

Not blocking, but worth a tracking issue.

What I verified as correct

  • Guide samples: every complete TypeScript sample in the 10 guides type-checks against 3.7.1. The only failure is the Hono checkJs mismatch you called out.
  • AgentBase: addPerCallConfig, setDynamicConfigCallback, onCallStart/onCallEnd, mount, defineContexts overloads, validateBasicAuth (now actually called, constant-time), credential precedence, swaigSecret and /mcp auth.
  • FunctionResult: hold, changeVoice, rpcAiMessage/rpcAiGlobalData, joinConference (no 250 default), pay coercion, and tap (speak|listen|both).
  • ChatGateway and HandoffRouter: options and defaults; I ran register/redeem/say/escalate and the outputs match.
  • Other areas: the capabilities and post-prompt helpers (run, and the output matches the comments), Bedrock voices (match the schema enum), the swaig-test and sw-tsdocs flags, Relay stream track, and SemanticGate.visualInput.
  • Environment variables: every public variable the source reads is documented, and nothing documented is missing from the source.

I couldn't verify the startup_hook 120-second wait and retry in mod_openai, swaig-test loading .ts agents on Node below 22, or "SignalWire address widget" as a customer-facing name (it isn't in the glossary). My mod_openai and mod_infrastructure checkouts are from April 2026, so the DataMap and user_event points should be rechecked against the deployed build if anything looks off.

Comment thread .claude/rules/mdx-capability-guides.md Resolved
@Devon-White

Copy link
Copy Markdown
Collaborator

A correction to item 5 of my review: Python's body() isn't an SDK bug in current releases. On v3.7.5 (facbeee, current main), signalwire/signalwire/core/data_map.py:329 writes params, and so does v3.7.1. Only the older commit the Python reference is synced to (f7fec89) writes body, so there's nothing to file upstream. The Python body.mdx and params.mdx pages are just behind the SDK, which makes the Python sync I asked for more pressing.

I re-checked the other backend-based points against current code, and they hold:

  • DataMap templates: mod_openai main (21281c1), actions.c. Response fields are at the root with the call data under input (around lines 1486-1512), there's no response key, the webhook body comes only from params (around line 880), and error_keys is read only per webhook (line 1290). Current code also adds ${input.*} to the URL and params stage (lines 2843-2847). That's an addition: ${args.x} still works there.
  • user_event: mod_infrastructure master (c80bf95). The relay_apis.c:2431 allowlist is unchanged. relay_calling_call_user_event (relay.c:11438) now returns "event is required" when event is missing.

@Devon-White Devon-White left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review of everything since 5508bc59, checked against the v3.7.1 tag (875e6e2) and the published @signalwire/sdk@3.7.1, which is still npm latest.

Earlier review: all resolved

  • Must-change 1–6: the pin-sync rule is gone and mdx-capability-guides.md is no longer in the diff. The REST reference matches 3.7.1's positional signatures. SWMLService.run() and ConfigLoader getAll()/getFilePath() are removed, with redirects and no stale links left. globalErrorKeys now carries a Warning. The webhook signature pages and example are fixed. The prefab factories are dropped. The DataMap template fix now reaches foreach, the params card, every tab of the DataMap guide, and the Python reference (no ${response. left). The version wording is gone.
  • Inline threads: userEvent, the ChatGateway throws, serve/run, the security overview, and the Record calls highlight are all fixed. I'll resolve those threads.
  • Nits: all addressed, including max-toc-depth on every touched page.
  • Missing API pages: WebService, the SemanticGate helpers and constants, runServerless, getTools, createCgiHandler, the skill module functions, and paginateAll are now documented. CollectAction.pause()/resume() are left out on purpose, as #241 tracks.

What I verified in the delta

  • I extracted all 272 TypeScript blocks that import the SDK from the files changed since 5508bc59 and ran tsc --strict against 3.7.1. The only failures are intentional fragments ({ /* ConciergeConfig */ }, the LiveWire before/after import, undeclared db/app/MySkill) and the e164 cases already noted in the PR body.
  • I read the new pages against source: WebService (options, defaults, the dotfile/.well-known rule, start() throwing without credentials, stop()), runServerless/run (env detection, CGI with an empty event), createCgiHandler, getTools (defineTools() first, SwaigFunction only), the skill module functions (including addSkillDirectory → addSearchPath, no validation), paginate/paginateAll, and HandoffRouter.redeem() returning null on a mint failure after spending the nonce. All match.
  • I ran the SemanticGate constants and helpers. The values, RESERVED_FUNCTION_NAMES, and the error messages match the pages, except for the two examples flagged inline.
  • CI is green.

Before merge

  1. Should fix: the applyGateFields example throws at runtime, and the gateDefinitions plain-object example would too once its threshold is fixed. Both pass a string on_fail, and a plain-object gate needs an object. See inline.
  2. Nit: the as never note and comments name "3.7.1". See inline.
  3. Coordination, already in your notes: nine guides still install @signalwire/sdk@3.7.1, so take #908's unpinned lines when you rebase. The branch is also 96 commits behind main.

@hey-august

hey-august commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator Author

@Devon-White Thanks for the review. Inline threads are answered in place; here are the review-body items.

  1. 908 conflict: pins and rule now follow Install the latest Server SDK in guides instead of pinned versions #908 (see the thread on the rule file). Coordination notes are there also.
  2. Reference still on 2.x: I type-checked every TypeScript reference block against 3.7.1 and fixed what failed. That covered your list and more: about 90 REST pages (signatures, response fields, swmlScripts.create's contents), Relay events, detect options, LiveWire, and extract-sip-username (9b3a2ae, 0ebdb6f). SWMLService.run() and ConfigLoader getAll()/getFilePath() are removed, with redirects (3107973). globalErrorKeys is corrected in a7bf454.
  3. cXML signatures: answered inline.
  4. Prefab factories: dropped (77d4c5b).
  5. DataMap: foreach input_key and ParamField order, the params card, the DataMap guide in every language tab, and the Python ${response.*} uses are fixed in a7bf454. Python body()/params() is filed as Sync the Python Server SDK reference: DataMap body() and params() describe an old release #939.
  6. Version wording: answered inline.

Nits: all applied. That includes max-toc-depth on every TypeScript reference page that lacked it (63 pages), and the sw-tsdocs --version example no longer hard-codes a version.

Public API without a page: added WebService, the SemanticGate helpers and constants, runServerless, getTools, createCgiHandler, the skill module functions, and paginate/paginateAll (c2758b6, 830d97b, 8c56e30). SkillManager.size and SkillRegistry.size were already documented as properties. CollectAction.pause()/resume() send play_and_collect.pause/.resume, which mod_infrastructure doesn't handle, so they're left undocumented and filed as signalwire/signalwire-typescript#241.

Couldn't verify, now checked:

  • startup_hook: the SWAIG POST uses a 120-second default timeout and retries up to 3 times on a timeout or 5xx (mod_openai webhook.c).
  • swaig-test on Node below 22: the page no longer makes that claim.
  • "SignalWire address widget": still unverified; the Python pages use the same name.

e164: I took your spec fix from main. 3.7.1's types still say number, so those 5 examples fail tsc until signalwire/signalwire-typescript#235 is fixed.

SDK issues: I filed #233, #235, #238, #241 in signalwire-typescript, consolidated from the gaps above.

@hey-august
hey-august merged commit d4bc6bd into main Nov 11, 2026
2 checks passed
@hey-august
hey-august deleted the august-20261022-sync-ts branch November 11, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants