Skip to content

feat: add "Passing data between assistants" page to squads#1033

Merged
dhruva-reddy merged 4 commits intomainfrom
dr/squads-passing-data-between-assistants
Apr 29, 2026
Merged

feat: add "Passing data between assistants" page to squads#1033
dhruva-reddy merged 4 commits intomainfrom
dr/squads-passing-data-between-assistants

Conversation

@dhruva-reddy
Copy link
Copy Markdown
Contributor

Description

  • New page: fern/squads/passing-data-between-assistants.mdx — a focused decision guide for the three mechanisms Vapi supports for forwarding context across squad handoffs.
  • fern/docs.yml updated: new entry under the Build → Squads section, sitting between the existing Handoff tool page and the Examples subsection.

The existing /squads/handoff page covers configuration mechanics for the handoff tool itself but doesn't compare the three approaches (function.parameters, variableExtractionPlan.schema, Liquid in the destination prompt) as alternatives. Customers default to schema extraction even when handoff arguments or direct Liquid would be faster, cheaper, and more reliable.

The page covers:

  • At-a-glance comparison table (latency, hallucination risk, where the value comes from)
  • Per-approach example + when-to-use / when-to-avoid
  • Decision flowchart for choosing the right mechanism
  • Common patterns: forwarding extracted IDs, classifying intent, structured booking requests, mix-and-match
  • Failure-mode notes (empty plan, LLM rejection, non-object result) reflecting the platform-hardening guarantees in vapi#11302 (PRISM-467)

Resolves the docs follow-up tracked alongside PRISM-467.

Testing Steps

  • Run fern check — passes with 0 errors (5 pre-existing warnings, unrelated)
  • Verify JSON examples are valid — 2 JSON blocks, both parse cleanly
  • Verify internal links resolve — 5 links: /squads/handoff, /squads/handoff#variable-extraction, /squads/handoff (again), /tools/static-variables-and-aliases, /assistants/dynamic-variables — all OK
  • New page added to fern/docs.yml between Handoff tool and Examples in the Squads section
  • Confirm the page renders at /squads/passing-data-between-assistants in the preview deployment
  • Confirm sidebar position appears between Handoff tool and Examples
  • Style guide compliance — active voice, present tense, second person, no marketing language, key terms bolded on first use
  • Code examples use realistic placeholders (Specialist, Scheduler) and reference actual JSON schemas matching the API
  • No commit trailer added

Adds a focused decision guide for the three mechanisms Vapi supports for
forwarding context across squad handoffs:

1. Handoff arguments (function.parameters on the handoff tool) — LLM fills
   inline, zero added latency
2. variableExtractionPlan.schema — separate dedicated LLM call against the
   transcript, structured output with JSON-schema validation
3. Liquid templating in the destination's prompt — sub-millisecond, deterministic,
   reads anything already in the variable bag

The existing /squads/handoff page covers configuration mechanics for the
handoff tool itself but doesn't compare these three approaches as alternatives.
Customers consistently pick the wrong path (usually defaulting to schema
extraction when handoff arguments or direct Liquid would be faster and more
reliable). New page sits next to /squads/handoff in the nav.

Includes:
- At-a-glance comparison table
- Per-approach example + when-to-use / when-to-avoid
- Decision flowchart for choosing
- Common patterns (forwarding extracted IDs, classifying intent, mixed)
- Failure-mode notes (empty plan, LLM rejection, non-object result) reflecting
  the platform-hardening guarantees from PRISM-467

Validated: fern check passes, 2 JSON blocks valid, 5 internal links resolve.
…andoff tool

- Flags that function.parameters is API-only today (dashboard UX for the
  Tools page shipping in VapiAI/vapi#10727, squad-builder backend gap tracked
  in PRISM-471)
- Directs customers to put the handoff tool on the assistant's model.tools[]
  via the API instead of the squad-member Handoff Tools path until the
  backend gap (callAssistantsGet synthesizing without `function`) is closed
@github-actions
Copy link
Copy Markdown
Contributor

@github-actions
Copy link
Copy Markdown
Contributor

…exist yet

The Tip block claimed the Vapi dashboard exposes function.parameters on
the handoff tool as a 'Handoff Arguments' section in the squad builder.
That section does not currently render. Verified two ways:

1. The string 'Handoff Arguments' appears nowhere in apps/dashboard
   (case-sensitive and case-insensitive grep, both with and without
   TS/TSX type filters).
2. apps/dashboard/src/features/squads/components/panels/sections/
   DestinationEditor.tsx (the component that renders the squad-builder
   handoff destination panel) only labels three sections: 'Context
   Engineering Plan', 'Variable Extraction Plan', and 'Description'.
   No 'Handoff Arguments' / 'Function Parameters' / JSON-schema editor.

The page also contradicted itself — the Warning earlier on the same
page (line 28) correctly states the squad builder does NOT carry
function.parameters through. The Warning is correct; the Tip was
aspirational, likely written assuming the squad-builder UX PR would
land before this docs PR, and is the outlier.

Removing the Tip rather than rewriting it because the existing Warning
already covers what readers need to know about dashboard support, so a
second callout restating it is redundant. When the squad-builder UX
ships, add a fresh callout pointing readers at the actual section name
(verified against the dashboard codebase at that time).
Comment thread fern/docs.yml
@github-actions
Copy link
Copy Markdown
Contributor

…ntry

The original commit 7c1bb11 inadvertently bundled three reverts of
unrelated upstream changes alongside the squads-page nav entry.
Investigation showed the entire fern/docs.yml file in that commit
predated three independent main commits — pattern-consistent with
a stale local copy of the file having been committed wholesale,
rather than a targeted nav addition.

This commit restores fern/docs.yml to origin/main verbatim and then
adds ONLY the new 'Passing data between assistants' nav entry under
the Squads section, immediately after 'Handoff tool'.

Specifically restored from main:

- Changelog tab display-name 'What's New?' / slug 'whats-new' (set
  by #1021 'Rename Changelog to What's New?')
- 'Email address reading' nav entry under Assistants (set by #1024)
- 'Monitoring' section + Quickstart entry under Observability (set
  by #991)

Net effect on PR #1033's docs.yml diff: only the 2-line addition of
the new Squads nav entry remains. Verified via:

  git diff origin/main -- fern/docs.yml

shows exactly the +2 lines for the new page entry, nothing else.
@dhruva-reddy dhruva-reddy merged commit 3887bf0 into main Apr 29, 2026
6 checks passed
dhruva-reddy added a commit that referenced this pull request Apr 29, 2026
…iers (#1035)

## Description

Stacked on top of #1033 (`dr/squads-passing-data-between-assistants`). Targets the static-variables-and-aliases page; the squads page in #1033 stays scoped to its own concern.

Surfaced by an FDE conversation with **Mudflap** asking how to do progressive authentication on inbound calls without giving the LLM a path to forward a fake caller-ID. The current page documents the mechanics of static `parameters` correctly but doesn't frame it as a security boundary, and doesn't address the failure modes that break that boundary in practice. This PR adds that framing.

### What changes in `fern/tools/static-variables-and-aliases.mdx`

- **Naming distinction** added at the top: `function.parameters` (LLM-facing JSON schema, model fills it) vs. top-level `parameters` (server-merged, LLM never sees it). The dashboard surfaces both as similarly-named sections (just **Parameters** vs **Static Body Fields**), which is the most common cause of customers accidentally exposing trusted fields to the model.
- **Trust tiers for the Liquid variable bag.** Tier 1 (server-trusted: `customer.*`, `phoneNumber.*`, `transport.*`, `call.*`, `assistant.*`, time variables, `assistantOverrides.variableValues` set at call start). Tier 2 (conversation-derived, not safe as a security boundary: `messages`, `transcript`, `prompt`). Tier 3 (LLM-derived, never trustworthy: `variableExtractionPlan` aliases from non-trusted sources, handoff arguments, handoff schema extraction).
- **Five common failure modes** with bad/good code pairs: defining the trusted field in `function.parameters`; body-default leak; system-prompt forwarding; unsafe alias chains; mid-call bag mutation.
- **Worked example** for caller-ID-based progressive authentication (the Mudflap pattern).
- **Tool-type support matrix** plus an explicit warning that legacy `assistant.model.functions[]` does **not** support static parameters (the converter zeroes them out at request time, so customers on the deprecated shape have no orchestration-layer injection at all).
- **Handoff section** cross-linking to `/squads/passing-data-between-assistants` (#1033). Documents that `tool.parameters` doesn't exist on handoff and explains why it doesn't need to: call-level Liquid variables persist across handoffs; aliases from server-trusted sources persist via `allMessagesContext.variablesAdd`; `destination.assistantOverrides.variableValues` is merged at handoff time bypassing the LLM. Flags that #1033's *Approach 1* (handoff arguments via `function.parameters`) is correct for **LLM-derived** values like sentiment/intent but is **not** a security boundary for signaling-derived values like caller-ID.
- **Known limitation** flagged: Liquid templates inside `destination.assistantOverrides.variableValues` are not currently resolved at handoff time (values spread verbatim into the bag).
- **Dashboard mental model** section: how the API request and function tool forms surface the two `parameters` fields, with a step-by-step for the caller-ID pattern.

### Skipped

- **Workflows extraction failure mode** -- workflows are deprecated, intentionally not addressed.
- **test-writer / code-reviewer** -- docs-only PR.

## Testing Steps

- [x] `fern check` -- 0 errors
- [x] All JSON code blocks validate (15/15 OK)
- [x] All internal links resolve (5/5: `/squads/passing-data-between-assistants` resolves via the parent branch in this stack; `/tools/code-tool`, `/tools/custom-tools`, `/tools/tool-rejection-plan`, `/api-reference/tools/create` all resolve)
- [ ] Verify the page renders correctly in the preview deployment, especially the trust-tier tables and the bad/good code-pair sections
- [ ] Confirm the new section anchors render (`#the-variable-bag`, `#forwarding-trusted-data-across-handoffs`) so the cross-references inside the page resolve
- [ ] Sanity-check the dashboard section against the live ToolsV2 form -- verify section labels still read "Parameters" and "Static Body Fields"
- [x] Style guide compliance (active voice, present tense, no marketing language)
- [x] Code examples use realistic placeholders (`YOUR_API_KEY`, etc.)

## Related

- Stacked on #1033 ("Passing data between assistants" page) -- merge order: #1033 first, then this PR rebases onto main; or merge this into #1033's branch first to land as a single combined PR.
- Source: FDE conversation with Mudflap (Steffen) about progressive caller-ID authentication.
- Follow-up worth filing: `destination.assistantOverrides.variableValues` should support Liquid template resolution at handoff time -- usability gap, not a security gap.
@github-actions
Copy link
Copy Markdown
Contributor

dhruva-reddy added a commit that referenced this pull request Apr 29, 2026
…stic ≠ invisible (#1038)

Two combined goals -- the previous PR #1035 was orphaned by an inverted
merge order (parent #1033 squash-merged to main 25 seconds before child
#1035 squash-merged into the parent's branch, so #1035's content was
applied to a branch that was already obsolete and never propagated to
main). This restores that hardening AND fixes wording the user flagged
in review of the original page.

Recovers from orphaned commit 3bbefdb the full PR #1035 hardening
work: trust tiers (Tier 1 server-trusted, Tier 2 conversation-derived,
Tier 3 LLM-derived), five common failure modes, prompt-injection
threat-model framing, dashboard mental model, handoff-data-forwarding
section, legacy assistant.model.functions[] footgun warning, the
'Static parameters as a security boundary' section, and the worked
caller-ID example.

Wording fixes applied on top of that recovery, eliminating language
that conflated two different guarantees -- (1) static parameters are
truly LLM-invisible (server-merged into the request body, never in
the schema sent to the model) vs. (2) variableExtractionPlan aliases
chain values across tools deterministically but the source response
IS in the LLM's context (it was added to conversation history as a
role: tool message). Specific changes:

- Subtitle (line 3): split the two guarantees, no longer claims both
  are 'without LLM involvement'
- Intro bullet (line 19): 'deterministically -- the next tool gets
  the correct value regardless of how the LLM behaves between calls'
- Deterministic tool chaining intro (line 457): rewritten + new
  Warning callout explicitly stating 'Deterministic does not mean
  invisible' with the specific code-level claim that Tool A's
  response is added to the LLM's role:tool message history
- Tips section: new bullet 'Aliases are a determinism primitive,
  not an invisibility primitive', flagging that hiding values from
  the model requires the tool server to omit them from the response
  body in the first place

Skipped: test-writer / code-reviewer (docs-only PR).
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.

3 participants