Skip to content

Sync TypeScript Server SDK docs - #830

Open
hey-august wants to merge 21 commits into
mainfrom
august-20261022-sync-ts
Open

hey-august wants to merge 21 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 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.
    • 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.
    • 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}, so 20 examples change.
  • Bumps the TypeScript pin in the 9 capability guides from @signalwire/sdk@2.0.5 to 3.7.1 and fixes the samples 3.x breaks:
    • 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.
  • mdx-capability-guides.md: the TypeScript pin is now 3.7.1, and a new rule requires each pinned Server SDK version to match the release recorded in sdk-source-sync.json, bumped together in one PR.
  • Semantic gates guide: the TypeScript SDK accepts visual_input from 3.7.1.

Notes for reviewers

  • Open PRs still pin @signalwire/sdk@2.0.5: Add Transcribe Calls guide #829, Add send and receive messages guide #819, Add Speak text on a call guide #789, Add AI sidecar guide to the platform guides #783. Each needs the 3.7.1 pin and the same sample fixes before or after merge.
  • SDK inconsistencies worked around. Each is verified against the platform and the API spec, and each is worth an upstream issue:
    • The SDK's SWML schema requires transfer_after_bridge on enter_queue, which the platform doesn't. This repo's generated specs/swml/tsp-output still lists that field too, though the .tsp source was updated.
    • The SDK's SWML schema rejects the stream and stop_stream verbs and connect's codec, realtime, and name.
    • Relay record()'s type omits max_length, which the platform honors.
    • SwmlBuilder.build() returns a type that calling.dial's swml option rejects under --strict, and that option's type isn't exported. Samples pass JSON.parse(builder.render()).
    • The SDK's JSDoc says Relay dial maxDuration is in minutes. The platform reads seconds, and the reference keeps seconds.
  • Bedrock voices: joanna was replaced with tiffany in the examples, since the valid Bedrock voices are tiffany, matthew, amy, lupe, and carlos.
  • Not covered: WebService and ServerlessAdapter.createCgiHandler have no TypeScript reference pages; that gap predates this sync. The Python reference may have the same DataMap template issue; out of scope here.

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

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/cli/sw-tsdocs
  • /docs/server-sdks/reference/typescript/core/capabilities
  • /docs/server-sdks/reference/typescript/core/post-prompt
  • /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 bumps the pin and syncs the TypeScript reference.

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. Compared rendered SWML between 2.0.5 and 3.7.1 as well; the only differences are AgentBase rendering the prompt as POM and adding per-function token URLs.
  • New and changed reference-page examples type-check against 3.7.1. Internal links resolve to existing slugs.
  • 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

🤖 Generated with Claude Code

@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.

- **Pinned versions** are literal and identical across every guide: `signalwire-sdk==3.4.1`, `@signalwire/sdk@2.0.5`, `@signalwire/js@4.0.0-rc.2 rxjs@7.8.2`. Bump them in every guide in one PR, never one page at a time.
- **Header comments** on every complete sample. Python: `# Install: python -m pip install signalwire-sdk==3.4.1` then `# Save as <name>.py and run: python <name>.py`. TypeScript with no type annotations: `// Install: npm install @signalwire/sdk@3.7.1` then `// This sample also runs as JavaScript: save as <name>.mjs,` / `// then run: node <name>.mjs`. TypeScript that uses types: `// Save as <name>.mts and run: npx tsx <name>.mts`. Browser: `// Install: npm install @signalwire/js@4.0.0-rc.2 rxjs@7.8.2` plus the HTML elements the script expects, as comments.
- **Pinned versions** are literal and identical across every guide: `signalwire-sdk==3.4.1`, `@signalwire/sdk@3.7.1`, `@signalwire/js@4.0.0-rc.2 rxjs@7.8.2`. Bump them in every guide in one PR, never one page at a time.
- **Pins match the reference.** Each pinned Server SDK version must be the release whose source the reference pages are synced to, as recorded for that SDK in `fern/products/server-sdks/sdk-source-sync.json` (`synced_commit` is that release's tag commit). Bumping a pin means syncing that SDK's reference to the same release, and syncing the reference to a new release means bumping the pin: do both in the same PR, or guide samples and reference pages disagree.

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.

This rule and the @3.7.1 pin go the opposite way from #908. #908 replaces "Pinned versions" with unpinned Server SDK installs and a no-minimum-version rule. Under this rule, every reference sync would also have to bump every guide. I'd drop this line and the pin changes on 105-106. The file also conflicts with main, which moved the Browser pin to @signalwire/js@4.0.0-rc.5.

Comment on lines +16 to +17
Only RELAY, SWML, and JSON webhooks are signed this way. Form-encoded cXML webhooks stay on the SHA-1
signature, which [`validateWebhookSignature()`][validate-webhook-signature] checks.

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.

cXML webhooks do carry a SHA-256 header, just in a different scheme. prime-rails app/services/laml/send_callback.rb (build_headers) sets X-SignalWire-SHA256-Signature on cXML callbacks. The value is Hmac::GenerateTwilioCompatibleSignature with SHA-256: base64 of the HMAC over the URL plus sorted params. mod_infrastructure.c does the same for laml-format requests. This function only checks hex HMAC-SHA256 over URL + raw body (src/WebhookValidator.ts, validateWebhookSignatureSha256), so it returns false for a genuine cXML webhook. The SDK JSDoc this copies says the same thing and is worth an upstream issue.

Suggested change
Only RELAY, SWML, and JSON webhooks are signed this way. Form-encoded cXML webhooks stay on the SHA-1
signature, which [`validateWebhookSignature()`][validate-webhook-signature] checks.
cXML webhooks also carry this header, but it's computed over the sorted form parameters in a
different encoding, and this function doesn't verify it. Validate cXML webhooks with
[`validateWebhookSignature()`][validate-webhook-signature].

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.

A qualifier on my suggested wording. I re-checked this against current mod_infrastructure master (c80bf95) and prime-rails master (00cf02f), and the finding holds: cXML requests carry a SHA-256 header that this function can't verify.

"In a different encoding" isn't accurate for every cXML request, though:

  • Callbacks sent from prime-rails (app/services/laml/send_callback.rb:95-96, 138-140) are base64.
  • Requests signed in mod_infrastructure.c (build_hmac_base_string and hmac_hex, around line 2015) are hex.

What differs in both cases is the signed string: the URL plus the sorted parameters, not the URL plus the raw body. The wording should be:

Suggested change
Only RELAY, SWML, and JSON webhooks are signed this way. Form-encoded cXML webhooks stay on the SHA-1
signature, which [`validateWebhookSignature()`][validate-webhook-signature] checks.
cXML webhooks also carry this header, but it's computed over the URL and the sorted form
parameters rather than the raw body, and this function doesn't verify it. Validate cXML webhooks
with [`validateWebhookSignature()`][validate-webhook-signature].

Comment on lines +70 to +72
const ok = sha256
? validateWebhookSignatureSha256(signingKey, sha256, url, rawBody)
: validateWebhookSignature(signingKey, sha1, url, rawBody);

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.

This rejects genuine cXML webhooks. On a cXML callback the SHA-256 header is present but doesn't match under this scheme (see above), so the ternary never reaches the SHA-1 check and returns 403. validate() falls back on a mismatch, not just on a missing header (src/WebhookMiddleware.ts:116-124). The sample should do the same:

Suggested change
const ok = sha256
? validateWebhookSignatureSha256(signingKey, sha256, url, rawBody)
: validateWebhookSignature(signingKey, sha1, url, rawBody);
const ok =
(sha256 !== undefined && validateWebhookSignatureSha256(signingKey, sha256, url, rawBody)) ||
validateWebhookSignature(signingKey, sha1, url, rawBody);

Line 55 then becomes "Check the SHA-256 header when it is present, and fall back to the SHA-1 header when it is missing or doesn't match:".

Comment on lines +19 to +22
SignalWire sends two signature headers on signed webhooks: `X-SignalWire-Sha256-Signature` (HMAC-SHA256)
and `X-SignalWire-Signature` (SHA-1). [`validate()`][validate] and
[`webhookValidationMiddleware()`][webhook-validation-middleware] check the SHA-256 header first and fall
back to the SHA-1 header, so deployments that only receive the SHA-1 header keep validating.

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.

The fallback also runs on a mismatch, and that's the case that matters for cXML. validate() and the middleware try the SHA-1 header whenever the SHA-256 check fails (src/WebhookMiddleware.ts:116-124), and cXML webhooks carry a SHA-256 header this scheme doesn't match.

Suggested change
SignalWire sends two signature headers on signed webhooks: `X-SignalWire-Sha256-Signature` (HMAC-SHA256)
and `X-SignalWire-Signature` (SHA-1). [`validate()`][validate] and
[`webhookValidationMiddleware()`][webhook-validation-middleware] check the SHA-256 header first and fall
back to the SHA-1 header, so deployments that only receive the SHA-1 header keep validating.
SignalWire sends two signature headers on signed webhooks: `X-SignalWire-Sha256-Signature` (HMAC-SHA256)
and `X-SignalWire-Signature` (SHA-1). [`validate()`][validate] and
[`webhookValidationMiddleware()`][webhook-validation-middleware] check the SHA-256 header first and fall
back to the SHA-1 header when the SHA-256 header is missing or doesn't match, so cXML webhooks and
deployments that only receive the SHA-1 header keep validating.

Comment on lines +18 to +19
The `options` type also accepts additional keys (`& Record<string, unknown>`), and
every field is sent in the RPC call. `event` is left out when it isn't set.

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.

This matches the SDK (src/relay/Call.ts:1741-1751), but the platform rejects both cases it describes. The call_user_event whitelist is method,call_id,project_id,protocol,event,swml,async (mod_infrastructure relay_apis.c:1836), so any other key fails CHECK_call_user_event. relay_calling_call_user_event (relay.c:9186) returns Bad Request when event is missing. In practice event is required, and the ParamField on line 14 should get required={true}. The return type is CallingUserEventResult (protocol.types.generated.ts:1253), not Record<string, unknown>.

Suggested change
The `options` type also accepts additional keys (`& Record<string, unknown>`), and
every field is sent in the RPC call. `event` is left out when it isn't set.
The `options` type also accepts additional keys (`& Record<string, unknown>`), and the SDK sends
every field. SignalWire accepts only `event`: a request without it, or with any other key, fails
with a bad request error.

Comment on lines +62 to +63
The constructor takes one options object, `ChatGatewayOptions`. It throws an `Error` when
`configUrl` is empty.

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.

It also throws when client is omitted and the environment can't build one. ChatGateway.ts:381 calls new AIChatClient(), which throws "project is required" without SIGNALWIRE_PROJECT_ID, and "No service URL" without SIGNALWIRE_SPACE or a url (AIChatClient.ts:299-314). Every sample that builds a bare new ChatGateway({ configUrl }) throws unless those are set. That covers close.mdx, mint-handle.mdx, read-handle.mdx, and the HandoffRouter index/escalate/redeem/register/say pages. A line about the environment in those samples, or on the client field, would help too.

Suggested change
The constructor takes one options object, `ChatGatewayOptions`. It throws an `Error` when
`configUrl` is empty.
The constructor takes one options object, `ChatGatewayOptions`. It throws an `Error` when
`configUrl` is empty, and, when `client` is omitted, when `SIGNALWIRE_PROJECT_ID` isn't set or no
service URL resolves from `SIGNALWIRE_SPACE`.

Comment on lines 28 to 29
[`run()`][run] is an alias for `serve()`. Both methods are equivalent in the
TypeScript SDK.

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.

run() isn't an alias anymore. In 3.7.1, AgentBase.run() (src/AgentBase.ts:3976) hands off to runServerless() when it gets an event, or when AWS_LAMBDA_FUNCTION_NAME, _HANDLER, FUNCTION_TARGET, FUNCTIONS_WORKER_RUNTIME or GATEWAY_INTERFACE is set, and only otherwise calls serve(). It was already true at the previous sync commit. run.mdx needs the same correction: its opts include event, context and platform, and it returns Promise<void | ServerlessResponse>.

Suggested change
[`run()`][run] is an alias for `serve()`. Both methods are equivalent in the
TypeScript SDK.
[`run()`][run] starts the server like `serve()`, except that when it's given a serverless `event`,
or detects a serverless platform from the environment, it handles that one invocation instead.
Call `serve()` when you always want a server.

as the gate that asks for the most. If the call has no video frame to show, the
gate fails without being asked. The gate's provider must accept images: one that
doesn't makes the check an error, and the function isn't called. Omitted by
default. Requires SDK 3.7.1 or later.

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.

Drop the minimum version. Reference and guides don't state "requires X.Y or later" for the Server SDKs. Version lines like this go stale.

Suggested change
default. Requires SDK 3.7.1 or later.
default.

Comment on lines 463 to 467
<Note>
The Python Server SDK accepts `visual_input` on a gate from version 3.7.1. The TypeScript Server SDK
doesn't accept it yet, so define video gates in SWML.
The Server SDKs accept `visual_input` on a gate from version 3.7.1: `visual_input` in Python and the
`visualInput` option in TypeScript.
</Note>

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'd delete this Note. It states a minimum SDK version and names per-language options in guide prose, and the guides avoid both: say "the Server SDKs" and let the code tabs carry language names. Now that both SDKs accept visual_input, nothing is left to warn about. If you want SDK coverage here, a <CodeBlocks> with Python and TypeScript tabs ahead of the YAML would follow the SDK-first rule.

Suggested change
<Note>
The Python Server SDK accepts `visual_input` on a gate from version 3.7.1. The TypeScript Server SDK
doesn't accept it yet, so define video gates in SWML.
The Server SDKs accept `visual_input` on a gate from version 3.7.1: `visual_input` in Python and the
`visualInput` option in TypeScript.
</Note>

```

```typescript title="TypeScript — Relay client" {12-14}
```typescript title="TypeScript — Relay client" {11-16}

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.

The highlight now covers the extraction lines and a trailing blank line. The Python block highlights only the if and record lines ({14-15}). Here those are lines 13-14.

Suggested change
```typescript title="TypeScript — Relay client" {11-16}
```typescript title="TypeScript — Relay client" {13-14}

@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.

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