Reframe prompt guardrails, document the SWAIG wire protocol, and replace AI diagrams with themed SVGs - #512
Merged
Conversation
Contributor
Contributor
Author
|
Requested by: Devon White |
…za example The request field list came from the SWML reference snippet unchanged, and promoting it onto the tool calling guide as "complete" put it next to the OpenAPI webhook describing the same payload with different contents. Verified the list against the post_data construction in mod_openai actions.c: - purpose is not a request field. The engine reads functions.purpose (or its replacement, functions.description) from the config and sends it as description. Documented description; dropped purpose. - Added the eight fields that were missing: conversation_id, meta_data_token, SWMLCall, call_log, raw_call_log, fatal_error, error_reason, description. - argument.parsed is an array, not an object; argument_desc is always an object when the function declares parameters, and absent for the legacy string form. - Split the list into always-present and conditional, and said what each condition is, since more than half the payload is conditional. Retitled the accordions off the completeness claim so the OpenAPI webhook stays the contract of record. Also fixed three things the guardrails rewrite left inconsistent: - The pizza prompt told the agent to quote sizes and toppings only from get_menu while its own knowledge base listed them. Only prices were ever absent from that knowledge base, so the guardrails now cover prices, totals, discounts, and substitutions, and the response guideline that promised "clear pricing information" defers to place_order. - The diagram's discount turn claimed a priced order before one existed. - meta_data is declared in the SWML document or written by set_meta_data and scoped by meta_data_token; it is not call-global and not set through the APIs at call creation. Framed the prompt impact diagram to match the other two.
The SWAIG snippets on the amazon_bedrock reference pages described the `ai` agent's payload. Bedrock builds its request on a separate code path (bedrock.c:4333 -> bedrock_get_post_data(bs, FALSE, "agent.function")), so most of what those pages claimed was wrong. Omit<> can't express the difference: it is not a subset. Against the ai payload Bedrock drops 10 fields, adds 10, and changes 6 more, including two whose documented constant values differ and a nested object that loses a member. The sidecar webhook already sets the precedent of a separate model for a divergent SWAIG payload, so Bedrock gets one too. Spec: - Added BedrockSwaigToolWebhookPayload and registered it on the Calls namespace. content_type is text/json, content_disposition agent.function, plus conversation_type, action, caller_id, the call/agent timestamps (microseconds) and times; argument has no substituted; no version, description, or argument_desc. Docs: - New _bedrock-swaig-request-fields, _bedrock-swaig-actions, and _bedrock-web-hook-url snippets, and pointed the three Bedrock pages at them. - Bedrock accepts only 6 actions (SWML, transfer, set/unset_global_data, set/unset_meta_data) against the ai path's 17, and its transfer is a boolean modifier on SWML rather than a standalone action with a destination. Verified DataMap output actions run through the same restricted handler, so that page was relisting ai-only actions too. - Unrecognized action keys are silently ignored, which is worth stating: an ai-shaped reply fails quietly on Bedrock. Two corrections to the previous commit, both found while checking Bedrock: - meta_data_token and meta_data are not conditional on either path. The engine falls back to a derived token when you don't set one, so both are always sent to a webhook-backed function. Moved them and described the fallback. - The ai request example still showed purpose; the wire field is description.
Webhooks only render if they are listed in apis.yml; without the entry the page 404s even though the operation is in the OpenAPI document.
- Updated AI SWAIG function documentation to clarify request and response formats, including examples for webhook payloads. - Revised Bedrock SWAIG function documentation to streamline function definitions and clarify webhook interactions. - Enhanced TypeSpec models for SWAIG webhook payloads, adding detailed descriptions and examples for better clarity. - Removed deprecated fields from SWAIG models and documentation, ensuring alignment with current API specifications. - Introduced new conventions for TypeSpec documentation and editing practices to maintain consistency and accuracy across specs.
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.
Requested by: Fern Support
Targets
Devon/ai-tool-guide(#490), notmain.Summary
Three related pieces of feedback on the AI platform section, all fixed on this branch.
1. Prompt guardrails (original scope)
The Boundaries section taught prompt-level don'ts as the default way to constrain an agent ("Don't ask for passwords", "Don't offer discounts"). That runs against both the rest of #490 and current model guidance: Anthropic (tell the model what to do, not what not to do), OpenAI's GPT-4.1 guidance (literal instruction following, so a pile of rules mostly produces conflicts), and Google's prompt-design guidance (prefer goals and success criteria; constrain only where exactness or safety demands it).
### Boundaries→### Guardrails, rewritten as an ordered ladder: state success criteria → enforce hard rules in code behind a tool call → remove the possibility with context steps and step-scoped functions → put global non-negotiables inparams.conscience(which is reinforced through the call, including after function calls) → then, sparingly, a short list of don'ts phrased as the behavior you want. The pizza example's five-don't block becomes a## Guardrailsblock pointing atget_menu/place_order;prompt-areas.mdxno longer models the anti-pattern and names the conscience as the home for cross-cutting rules;best-practices.mdxrenames "Defining boundaries" to "Define success, not a list of don'ts".2. SWAIG is now described as a protocol
Feedback was that SWAIG is described many ways but never plainly as JSON over HTTP. The field-level spec did exist, but only inside two SWML reference pages and never framed as a wire format.
## The protocol: JSON over HTTPsection on the tool calling guide: SignalWire POSTs one JSON document toweb_hook_url(HTTP basic auth when the URL carriesusername:password@host), you return one JSON document withresponseand optionalaction. Complete request and reply field tables live there in accordions._web-hook-url.mdxwas split so nothing is duplicated: the field lists moved into_swaig-request-fields.mdxand_swaig-response-fields.mdx, and both the SWML reference pages and the tool calling guide render the same snippets.aiSwaigToolWebhook/AiSwaigToolWebhookPayloadon the Calls namespace), so the guide links that reference page instead of publishing a second copy of the same contract.Deliberately left out, pending confirmation from engineering: status-code handling, timeout and retry behavior, payload size limits, and what
version: "2.0"tracks.3. Diagrams
The clipped diagrams were mermaid rendering at natural width in a narrow column. Two of them are now themed SVGs following
ai-agent-flow-themed.svg— the pair in "AI in the media path" on/ai/capabilities, plus the prompt-impact chart on the prompt engineering page: one file per diagram tracking the site theme throughcolor-schemeplus aprefers-color-schemequery,role="img"with a descriptivearia-label, wrapped in a<Frame caption>inside<llms-ignore>, with the original mermaid kept in<llms-only>so LLM consumers lose nothing. The sequence diagrams stay in mermaid, andstyles.csslets.mermaid-containerscroll horizontally so they no longer clip.4.
meta_dataunder content redactionAdded a limitations bullet: redaction masks what gets recorded, it does not decide where a value lives. Data that must outlive the call belongs on your server; data that only matters during the call can go in the call's
meta_data, set through the APIs at call creation or by a SWAIG function while the call runs, which is not stored afterward.Validation
fern docs md checkpasses (all 2811 MDX files valid), andspecs/is unchanged by this branch.fern checkcan't run its link rule in this environment (needs auth plus a rolldown native binding), so link validation is left to CI.