Relay API reference: TypeSpec→AsyncAPI 3.0 tooling + full Relay surface + Fern docs#423
Draft
Devon-White wants to merge 95 commits into
Draft
Relay API reference: TypeSpec→AsyncAPI 3.0 tooling + full Relay surface + Fern docs#423Devon-White wants to merge 95 commits into
Devon-White wants to merge 95 commits into
Conversation
Also fixes test harness: import the library and use the full SignalWire.AsyncAPI namespace path so decorators resolve.
…uth security Avoids depending on @typespec/http (whose lib tsp won't load in the hoisted standalone tester); custom @bearerAuth keeps the emitter self-contained.
…dModel, inline-param docs Addresses adversarial review: numeric enum/discriminator type inference (latent invalid-schema bug), Array.isArray guard, isNamedModel helper, inline-parameter description extraction, and a multi-method/multi-event collision-coverage test. String-discriminator output is unchanged (golden snapshot + Relay artifact in sync).
@minValue/@maxValue/exclusive, @minLength/@maxlength, @minItems/@Maxitems, @pattern, @Format, @secret→format:password, property defaults, and @example now map to the corresponding JSON-Schema keywords (valid per AsyncAPI 3.0's Draft-07 superset). Relay timeout now models its non-negative/default-30 semantics.
…odedname Completes the standard property-decorator surface: @encode decays to its wire type with a JSON-Schema format (e.g. utcDateTime+rfc3339 → string/date-time), @Encodedname remaps the emitted JSON property key. No standard property decorator is silently dropped now.
…r assertions, dup-method diagnostic Addresses the remaining adversarial-review quality findings: - Replace SchemaObject=Record<string,unknown> with a structured AsyncAPISchema interface (correct AsyncAPI/Draft-07 dialect: numeric exclusiveMin/Max, string discriminator, no nullable) — removes the as-Record casts. Not reusing @typespec/openapi3's OpenAPI3Schema, which models a different dialect. - RefFn returns SchemaOrRef (= AsyncAPISchema | AsyncAPIRef); unionInline typed to Union (removes the as-any casts). - emitRpcMethods/emitEvents take a typed EmitTarget context instead of drilling doc!.components! — removes non-null assertions. - Add duplicate-@rpcMethod diagnostic + test.
…lwire + calling core
…s across 6 services
…p invented /api/relay/wss path)
Verified against the TS + Python SDK clients: both connect to `wss://${host}` with
DEFAULT_RELAY_HOST = relay.signalwire.com and reject a host containing a path. The
service is selected by the JSON-RPC method in the payload, not a URL path.
With address null, Fern composes the channel URL as wss://<host>/<channelId>, showing a misleading per-service path (e.g. wss://relay.signalwire.com/messaging). Relay multiplexes every service over one root connection and routes by the JSON-RPC method, so emit the root address "/" — Fern then renders wss://relay.signalwire.com/. Verified live for the messaging and calling channels.
…pecs The emitter's dist/ is gitignored and nothing built it in CI, so build:relay failed with import-not-found on ../dist/src/index.js. build:relay now runs the emitter's tsc build first (verified against a clean dist/).
The Relay API was rendering in the same flat sidebar as REST. Convert the apis product nav to tabs (matching the compatibility-api pattern): a REST tab and a Relay tab. URLs are preserved — Core stays at /docs/apis/<page>, REST at /docs/apis/rest/..., Relay at /docs/apis/relay/... (tab carries the slug, the API uses skip-slug). Verified live: both tabs render and all existing URLs 200.
…mples Correctness fixes from the one-to-one spec audit (6 services / 71 methods / 26 events): - pay: input enum speech->voice; add PayPrompt.attempt + require_matching_inputs; actions optional; numeric/bool params retyped to wire strings per pay_schema.md - calling: join_conference recording_status_callback_event enum->string; hold/unhold result state literals; broaden TapCodec + detector-event enums - signalwire: ConnectResult.ice_servers optional; strip internal jargon (BLADE/etc.) - tasking: drop carrier fields (timestamp/space_id/project_id) the emitter synthesizes - add missing customer-facing @doc across event/refer models Examples: @opExample on every method + @example on every event; discriminator-union variant models carry schema-level @example where an op frame can't narrow the base. All 6 specs validate 0 errors via the official AsyncAPI CLI; fern check clean.
…_transcribe/translate Verified the SWML models against the mod_openai/mod_infrastructure C engine (96/96 AIParams fields parsed by the engine; SWAIG schema shared via one process_swaig_function; live_transcribe/translate hit the same parse_transcribe_json). Replicated the engine-confirmed shapes into the Relay specs (cross-import blocked by @jsonSchema/SWMLVar), stripping ~72 markup arms: - calling.ai/amazon_bedrock: params Record<unknown> -> typed AiBehaviorParams (91 fields) - SWAIG: native_functions enum, web_hook_auth_* + meta_data on function/defaults/includes, mcp_servers; kept parameters/data_map/internal_fillers loose (@OneOf, validate-first) - live_transcribe/translate: start/summarize/inject Record<unknown> -> typed action models - added @opExample to all 7 AI ops calling validates 0 errors (AsyncAPI CLI); fern check clean.
Replace the hand-replicated AiBehaviorParams (91 fields) with a direct spread of
the engine-verified SWML AIParams model, stripping its markup-only `| SWMLVar`
template-variable arms at emit time so they never reach the live JSON-RPC wire.
- typespec-emit-filter: standalone, generic @excludeFromEmit(...types) decorator
package (TypeSpec's shared-decorator-library pattern).
- asyncapi emitter: honor @excludeFromEmit on models/unions/properties — drop the
named arms and collapse the union (0 -> {}, 1 -> bare, all-string -> enum, else
oneOf). Applied on both the component and inline-model paths (open models with a
`...Record<unknown>` index signature always inline).
- asyncapi emitter: namespace-qualified component names via getTypeName so reused
cross-namespace SWML types stay collision-free (service-local types stay bare);
add a duplicate-type-name diagnostic backstop.
- relay calling: AiBehaviorParams now spreads SWML.Calling.AIParams, keeping the 2
deprecated eleven_labs_* fields.
Verified: 32 emitter tests pass; AsyncAPI CLI 0 errors; fern check clean (only the
known FDR 403); parity diff vs 158d9c1 shows only additive/authoritative deltas
(added defaults/examples, SWML constraints, reused SWML.Calling.ConversationMessage,
+2 deprecated fields, int32->integer format drops); the other 5 relay specs are
byte-identical; SWML's own json-schema emit still includes SWMLVar.
…zon_bedrock Extend the SWML reuse from `params` (AIParams) to the entire AI agent config object, which mod_openai's create_app_from_json parses identically for the SWML `ai` verb and Relay calling.ai (verified in C source). The Relay-local Ai* sub-models were incomplete projections of one shared backend object; replace them with direct references to the engine-verified SWML models. - AiParams/AmazonBedrockParams: prompt -> AIPrompt, post_prompt -> AIPostPrompt, pronounce -> Pronounce, hints -> (string|Hint)[], languages -> Languages, SWAIG -> SWAIG (incl. the full function/parameters/data_map tree and the SWMLAction that returns a full SWML document), global_data -> GlobalData. Delete the 11 hand-rolled Ai* sub-models (-288 lines net). - Exclude ONLY the markup-only `SWMLVar` template-variable arms via @excludeFromEmit on the entry models (resolved at SWML execution, never on the live JSON-RPC wire). Every other surface SWML accepts is emitted as-is, including the recursive SWML document a SWAIG data_map action can return (handled natively via $ref). - Reused SWML as-is; SWML's current gaps vs Relay (missing web_hook_auth_* on SWAIG, Hint requiring pattern/replace, AIPrompt missing barge_confidence/model) are logged in SWML-REUSE-GAPS.md for a later SWML-truing pass. Verified: 0 SWMLVar leak; valid AsyncAPI (fern check clean); fern docs dev renders the calling AI reference incl. the recursive SWML `$ref`; other 5 relay specs byte-identical; SWML's own emit unaffected.
Remove the 'Relay (Single Channel)' tab and the 'Playground' page (which rendered relay-single) from the Relay tab. Also fix the Webrtc section's stale referenced-packages (webrtc/message/conferenceList -> webrtcVerto/webrtcMessage) left over from the webrtc.verto rename + conference.list removal.
The relay-single (single-channel) spec is no longer used in the docs (tab + Playground page removed). Drop its generation entirely: remove the build:relay-single-spec step from build:relay, delete specs/relay/tspconfig.single.yaml and the generated fern/apis/relay-single/ output. Only the one multi-channel Relay AsyncAPI spec (relay.yaml) remains. The emitter's channel-mode:single capability and its unit test are unchanged (still a supported feature, just unused by the build).
…nhance event models - Introduced JsonRpcRequest and JsonRpcResponse models for standardized request/response handling across Relay services. - Updated transfer and user-event operations to utilize new request/response models. - Refactored messaging events (receive, state) to align with new event model structure. - Enhanced connect and disconnect operations with new request/response models. - Added new documentation pages for Relay authentication and error handling. - Improved overall structure and clarity of Relay API specifications.
…tooling # Conflicts: # yarn.lock
… Address terminology + field order)
- emitter: a parameterless @channel op now emits a receive-only channel (channel + receive ops, no request frame, no send op); add the reply-without-request diagnostic; correct the stale channel-mode doc - tasking: model queuing.relay.tasks as a receive-only channel and move TasksEvent off signalwire.receive (de-dup) with a pointer note on receive - reorg every operation to models/{send,reply,events}.tsp (REST-aligned, AsyncAPI-named); split state.tsp into per-op events plus calling/events/shared.tsp; co-locate every per-op event with its op - apis.yml: fix relay nav refs (messagingSend, provisioningConfigure, queuingRelayTasks; drop invalid tasking/webrtcMessage) - rebuild all specs The reorg is output-neutral (relay.yaml byte-identical).
- Removed redundant comments and documentation sections across various models in the Relay Calling API specifications to enhance clarity and reduce clutter. - Streamlined model definitions by eliminating unnecessary comments related to shared structures and enums. - Updated event and operation models to focus on essential documentation, improving readability and maintainability. - Ensured consistency in documentation style across all models, enhancing the overall coherence of the API specifications.
…d new event models - Added example values for Acknowledgement model in core.tsp. - Introduced GroupSignalwireConnect and GroupSignalwireDisconnect constants for better organization in connect and disconnect operations. - Enhanced ConnectRequest and ConnectResult models with additional example values for clarity. - Updated Version model to reflect the current Relay protocol version and added examples. - Improved DisconnectParams model with an example for the restart parameter. - Refined receive and unreceive operations with new group constants and updated documentation. - Added new event models for AI operations, including CallAiEvent, AiCompletionEvent, and others to support AI functionalities. - Created new event models for room membership changes and user-defined events in the calling operations.
- Updated CallReceiveParams to make direction and context mandatory. - Introduced RelayResultBase for base result handling, separating it from RelayResult. - Updated various operation results (e.g., AiHoldResult, AiMessageResult) to use RelayResultWithCall for consistency. - Added new events for live transcription and translation, including TranscribeUtteranceEvent and TranslateTranscriptDeltaEvent. - Enhanced documentation across models and events for better understanding. - Removed unused fields and clarified existing ones in various models (e.g., CallQueueStatus, DisconnectEvent). - Adjusted response structures for connect and disconnect operations to reflect changes in event handling.
- Changed channel names from camelCase (e.g., `callingDial`) to dot notation (e.g., `calling.dial`) for consistency and clarity. - Updated references in tests and serialization to reflect new channel naming convention. - Modified serialization logic to inline repeated values instead of using YAML anchors/aliases, improving compatibility with OpenAPI/AsyncAPI tooling. - Introduced new models for request parameters in channel operations, enhancing type safety and clarity in the API specification. - Adjusted tests to validate the new structure and naming conventions across various scenarios, ensuring comprehensive coverage.
…rvices - Added summaries for JoinRoomResult, LeaveRoomResult, SendDigitsResult, StreamResult, StreamStopResult, TranscribeResult, and others to improve clarity. - Updated documentation for SendDigitsRequest and SendDigitsParams to specify DTMF tones more clearly. - Clarified descriptions in Tap and UserEvent models, including detailed explanations for parameters and results. - Improved the overall readability of JSON-RPC request and response models, including better descriptions for error handling and event frames. - Enhanced the provisioning and WebRTC sections with more precise language regarding configuration and signaling.
…maries and conversation logs
…e relay calling, messaging, provisioning, signalwire, tasking, and webrtc specifications. This cleanup enhances code clarity and reduces unnecessary dependencies.
… messaging receive events
…nd update related operations
- Added new call event operations for receiving inbound calls and call state changes. - Updated the API navigation to include new call-related packages. - Modified existing operations to remove unnecessary event types and streamline responses. - Removed redundant imports and improved documentation for clarity on event subscriptions.
- Updated documentation for `calling.pass` to enhance clarity. - Revised summaries and documentation for `calling.pay` operations to provide better context. - Improved descriptions in `calling.play` operations for better understanding of control IDs. - Clarified event documentation in `calling.queue` operations to specify event types. - Enhanced descriptions in `calling.record` and `calling.refer` operations for better user guidance. - Updated `calling.transcribe` documentation to clarify the flow of transcription results. - Improved messaging operations documentation for better clarity on message IDs and outcomes. - Refined `signalwire` operations documentation to enhance understanding of connection and disconnection processes. - General improvements to documentation across various models to ensure consistency and clarity.
…lifecycle, members, settings, and volume control - Implemented `call.raisehand` and `call.lowerhand` operations with corresponding parameters. - Added layout management operations: `call.layout.list` and `call.layout.set`, including request and reply models. - Introduced lifecycle operations: `call.end` and `call.hangup` with necessary parameters. - Created member management operations: `call.member.list`, `call.member.remove`, and `call.member.position.set`. - Developed settings operations for managing video-muted visibility, room locking, low-bitrate mode, denoise settings, and audio flags. - Added volume control operations for microphone and speaker adjustments. - Established subscriber online/offline operations for managing subscriber states. - Implemented ping operations for connection keepalive and reauthentication processes. - Updated configuration files for client and server to support new operations.
- Updated `MuteParams`, `UnmuteParams`, `DeafParams`, and `UndeafParams` to require `target` field for clarity. - Enhanced documentation across various models to specify required fields and their usage. - Added new events in `events/main.tsp` for audio playback, connection progress, recording states, and conversation messaging. - Improved `send.tsp` models in messaging operations to clarify error handling and validation. - Introduced separate client and server connection handling in `connect/client.tsp` and `connect/server.tsp`. - Updated connection parameters to differentiate between client and server authentication methods. - Enhanced documentation for `reauthenticate` models to clarify usage of project ID and JWT tokens.
- Removed `voice_id` from `RelayBedrockPromptText` and `RelayBedrockPromptPom` models due to backend constraints. - Changed `result` in `CallCollectParams` from optional to required. - Updated `digit_timeout` example in `CollectDigits` model to reflect default value. - Made several fields in `ConferenceParams` required, including `name`, `region`, and `size`. - Added new fields for call quality metrics in `ConferenceParams`. - Added minimum value constraints for `max_duration` and `max_price_per_minute` in `ConnectParams`. - Improved documentation for `DetectMachineParams` and related models. - Updated `DialParams` to include `dest_swml` and clarified `tag` usage. - Added `reason` field to `DisconnectParams` for opaque disconnect reasons. - Enhanced `LiveTranscribeStart` and `LiveTranslateStart` models with additional parameters and constraints. - Made `translate_data` in `TranslateConversationLogEventData` required. - Clarified payment error documentation in `CallPayParams`. - Updated `PayResult` to extend `RelayResult` instead of `RelayResultWithCall`. - Added WhatsApp message types and parameters to `SendParams` for enhanced messaging capabilities. - Removed unused `reply.tsp` in `disconnect` operation and cleaned up imports. - Improved documentation across various models for clarity and completeness.
…operations in the Relay Fabric and WebRTC specifications - Updated timestamps documentation to specify Unix timestamp format in milliseconds/seconds. - Clarified descriptions for call leg operations, emphasizing the context of the call leg being operated from. - Enhanced clarity in error handling and event descriptions, particularly for legacy methods and their compatibility with newer versions. - Improved consistency in terminology, replacing "epoch" with "Unix timestamp" for better understanding. - Adjusted examples to provide clearer context and usage scenarios for parameters in various models. - Refined the descriptions of events and parameters in messaging and provisioning operations for better comprehension.
- Removed the overview page for Relay. - Added new documentation for client-side authentication, connection lifecycle, errors, events, and an overview. - Introduced server-side documentation for authentication, connection lifecycle, errors, events, and an overview. - Updated content to clarify the differences between client and server implementations, including authentication methods and event handling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Type of Change
Related Issues
Testing
Checklist
Additional Notes