Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions .claude/rules/mdx-diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,28 @@ paths:
- "fern/**/*.mdx"
---

# Themed SVG diagrams
# Diagram authoring

## Themed SVG diagrams

Applies to hand-authored SVG diagrams under `fern/assets/images/img/`.
Exemplar: `ai-agent-flow-themed.svg`.

## One file, both modes
### One file, both modes

Author a single themed SVG and embed it as a plain `<img>`. Do not ship a
`.light-only` / `.dark-only` pair — that pattern is for diagrams whose brand
colors must not be inverted, not for new work.

## How theming works
### How theming works

The site sets `color-scheme` on `html`; it inherits to the `img`, and the
browser propagates it into the SVG's own document. So
`@media (prefers-color-scheme: dark)` *inside the SVG* tracks Fern's theme
toggle. Where a browser hasn't implemented that propagation it falls back to
the OS preference, which is what the toggle defaults to anyway.

## Colors
### Colors

- Custom properties do not cross document boundaries. Nothing from the page
reaches an img-embedded SVG — not Fern's `--accent`, not `--grayscale-*`.
Expand All @@ -37,18 +39,18 @@ the OS preference, which is what the toggle defaults to anyway.
chip `#40E0D0`, on-chip `#0e0e18`. Caller icon matches ink in light mode,
matches the chip color in dark mode.

## Filename
### Filename

Keep the word `diagram` **out** of the filename. `styles.css` inverts
`img.diagram` and `[src*="diagram"]` for dark mode, which wrecks a themed SVG.
Name it `<subject>-themed.svg`.

## Motion
### Motion

Guard every animation with
`@media (prefers-reduced-motion: reduce) { … { animation: none; } }`.

## Embedding
### Embedding

- Plain `<img>` with meaningful alt text. **No `<Frame>`** — its border artifact
shows in both themes and is worse in dark mode.
Expand All @@ -57,8 +59,21 @@ Guard every animation with
- Wrap the `<img>` in `<llms-ignore>` and pair it with an `<llms-only>` mermaid
block carrying the same information. An SVG reaches agents only as a link.

## When not to use SVG
### When not to use SVG

Mermaid is fine for anything whose source is already text and whose labels are
short. Reach for a themed SVG when Mermaid truncates long node text or when the
diagram carries brand weight.

## Information diagrams in LLM exports

Raster diagrams render as image links in the Markdown endpoint. Give human and agent readers equivalent information:

- Put the complete `<Frame>` that contains an information-bearing raster diagram inside `<llms-ignore>`.
- Follow it immediately with `<llms-only>` containing an equivalent in Mermaid or structured Markdown. Preserve the original entities, sequence, branches, labels, and direction; do not substitute a generic summary for relationships visible in the image.
- Choose the format that preserves the information most precisely. Use `sequenceDiagram` for messages between actors and `flowchart` for processes and decisions, but prefer an ordered list or table when it represents exact steps, ordering, or labels more faithfully.
- Do not infer relationships from visual placement alone. A grid or grouped layout may be organizing information rather than defining branches or connections.
- A standalone `<llms-ignore>` is allowed for a screenshot only when the adjacent prose already states every action or value needed to complete the task.
- Do not pair Mermaid source with these tags. Mermaid already exports as readable source.

Keep the visibility tags at column 0 with blank lines inside and around each block, as specified in `mdx-mechanics.md`.
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,30 @@ Before building agents, you should understand:

## Agent Architecture Overview

<llms-ignore>

<Frame caption="Agent Components">
<img class="diagram" src="/assets/images/sdks/diagrams/03_01_agent-base_diagram1.webp" alt="Agent components overview." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
flowchart TD
agentClass["Your agent class<br/>extends AgentBase"] --> config["Configuration"]
config --> prompts["Prompts<br/>role, guidelines, rules"]
config --> voice["Voice<br/>language, voice, TTS engine"]
config --> params["AI parameters<br/>timeouts, barge, attention"]
config --> hints["Hints<br/>keywords, names, terms"]
config --> functions["Functions<br/>tools, DataMap, handlers"]
config --> skills["Skills<br/>plugins, add-ons, integrations"]
prompts & voice & params & hints & functions & skills --> swml["Automatically generated SWML output"]
```

</llms-only>

## A Complete Agent Example

Here's what a production agent looks like across all supported languages:
Expand Down Expand Up @@ -381,10 +401,31 @@ swaig-test my_agent.py --exec check_order --order_number 12345

## Class Overview

<llms-ignore>

<Frame caption="AgentBase Inheritance">
<img class="diagram" src="/assets/images/sdks/diagrams/03_01_agent-base_diagram2.webp" alt="AgentBase inheritance diagram." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
classDiagram
AgentBase --|> AuthMixin
AgentBase --|> WebMixin
AgentBase --|> SWMLService
AgentBase --|> PromptMixin
AgentBase --|> ToolMixin
AgentBase --|> SkillMixin
AgentBase --|> AIConfigMixin
AgentBase --|> ServerlessMixin
AgentBase --|> StateMixin
```

</llms-only>

## Constructor Parameters

The constructor accepts the agent name plus optional configuration:
Expand Down Expand Up @@ -588,10 +629,26 @@ agent.data_map # DataMap builder

## Agent Lifecycle

<llms-ignore>

<Frame caption="Agent Lifecycle">
<img class="diagram" src="/assets/images/sdks/diagrams/03_01_agent-base_diagram3.webp" alt="Agent lifecycle." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
flowchart TD
init["1. Instantiate<br/>initialize mixins, load config, register routes"] --> configure["2. Configure<br/>add languages, prompt sections, tools, and skills"]
configure --> run["3. Start server with run()<br/>create FastAPI app, mount routes, start Uvicorn"]
run --> get["GET / or POST /<br/>return SWML document"]
run --> swaig["POST /swaig<br/>execute SWAIG function"]
```

</llms-only>

## Configuration File

Load configuration from a YAML/JSON file:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,30 @@ Before diving into these concepts, you should have:

## The Big Picture

<llms-ignore>

<Frame caption="SignalWire Server SDK Architecture">
<img class="diagram" src="/assets/images/sdks/diagrams/02_01_architecture_diagram1.webp" alt="SignalWire Server SDK Architecture." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
sequenceDiagram
participant Caller
participant Cloud as SignalWire Cloud
participant Agent as Your Agent<br/>AgentBase and SWMLService
Caller->>Cloud: Incoming call
Cloud->>Agent: POST / or POST /swaig
Note over Cloud: Receive call, request SWML,<br/>execute AI, call SWAIG tools
Note over Agent: AuthMixin, WebMixin, PromptMixin,<br/>ToolMixin, SkillMixin, AIConfigMixin,<br/>ServerlessMixin, StateMixin
Agent-->>Cloud: SWML JSON or function result
```

</llms-only>

## Key Terminology

| Term | Definition |
Expand Down Expand Up @@ -71,12 +91,34 @@ Understanding these core concepts helps you:

## The Mixin Composition Pattern

AgentBase doesn't inherit from a single monolithic class. Instead, it combines nine specialized mixins plus the SWMLService base class:
AgentBase doesn't inherit from a single monolithic class. Instead, it combines eight specialized mixins plus the SWMLService base class:

<llms-ignore>

<Frame caption="AgentBase mixin composition">
<img class="diagram" src="/assets/images/sdks/diagrams/02_01_architecture_diagram2.webp" alt="AgentBase mixin composition." />
</Frame>

</llms-ignore>

<llms-only>

`AgentBase` inherits from the following classes in method resolution order (MRO):

| Order | Class | Responsibilities |
|---:|---|---|
| 1 | `AuthMixin` | Basic authentication, credentials, and validation |
| 2 | `WebMixin` | FastAPI, routes, and the server |
| 3 | `SWMLService` | Base class for schema, rendering, and verbs |
| 4 | `PromptMixin` | POM, sections, and templates |
| 5 | `ToolMixin` | SWAIG functions, decorators, and DataMap |
| 6 | `SkillMixin` | Skill management, registry, and loading |
| 7 | `AIConfigMixin` | Languages, hints, and parameters |
| 8 | `ServerlessMixin` | Lambda, CGI, and Azure |
| 9 | `StateMixin` | Session, call state, and persistence |

</llms-only>

## Each Mixin's Role

### AuthMixin - Authentication & Security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,26 @@ answer -> ai

The SDK provides three insertion points to customize this flow:

<llms-ignore>

<Frame caption="Call flow insertion points">
<img class="diagram" src="/assets/images/sdks/diagrams/03_07_call-flow_diagram1.webp" alt="Call flow insertion points for pre-answer, post-answer, and post-AI verbs." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
flowchart TD
pre["Pre-answer verbs while call rings<br/>ringback, screening, conditional routing"] --> answer["answer verb<br/>automatic when auto_answer=True"]
answer --> postAnswer["Post-answer verbs before AI<br/>welcome messages, disclaimers, hold music"]
postAnswer --> ai["AI verb<br/>conversation"]
ai --> postAI["Post-AI verbs<br/>cleanup, transfers, surveys, logging"]
```

</llms-only>

### Verb Insertion Methods

| Method | Purpose | Common Uses |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,23 @@ if __name__ == "__main__":

### Transfer Flow

<llms-ignore>

<Frame caption="Call transfer flow showing permanent and temporary transfer paths.">
<img class="diagram" src="/assets/images/sdks/diagrams/06_04_call-transfer_diagram1.webp" alt="Diagram showing the flow of permanent and temporary call transfers between agents and destinations." />
</Frame>

</llms-ignore>

<llms-only>

| Transfer type | Call flow | Result |
| --- | --- | --- |
| Permanent (`final=True`) | Caller → Agent → “Transferring...” → Destination | The agent exits when it hands the call to the destination. |
| Temporary (`final=False`) | Caller → Agent → “Connecting...” → Destination | When the destination hangs up, the call returns to the agent and the conversation continues. |

</llms-only>

### Department Transfer Example

<Tabs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,27 @@ ConciergeAgent provides these SWAIG functions automatically:

### Concierge Flow

<llms-ignore>

<Frame caption="Concierge agent conversation flow.">
<img class="diagram" src="/assets/images/sdks/diagrams/09_05_concierge_diagram1.webp" alt="Diagram showing the concierge flow from greeting through information lookup, service requests, and booking assistance." />
</Frame>

</llms-ignore>

<llms-only>

The concierge uses a different tool according to the guest's request:

```mermaid
flowchart LR
amenity["Amenity question"] --> lookup["Look up the amenity"] --> info["Return hours and location"]
booking["Booking request"] --> availability["Call check_availability()"] --> offer["Report availability and offer to book"]
directions["Directions request"] --> route["Call get_directions()"] --> instructions["Return directions"]
```

</llms-only>

### Complete Example

```python
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,31 @@ Understanding how contexts, steps, and navigation work together is essential for

The AI automatically tracks which context and step the conversation is in. When step criteria are met, it advances to the next allowed step. When context navigation is permitted and appropriate, it switches contexts entirely.

<llms-ignore>

<Frame caption="Context structure showing contexts, steps, and navigation paths.">
<img class="diagram" src="/assets/images/sdks/diagrams/06_01_contexts-workflows_diagram1.webp" alt="Diagram showing the hierarchical structure of ContextBuilder, Contexts, and Steps with navigation flow." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
flowchart LR
subgraph builder[ContextBuilder]
subgraph sales["Context: sales"]
info["Step 1: get_info"] --> confirm["Step 2: confirm"] --> process["Step 3: process"]
end
subgraph support["Context: support"]
help["Step 1: help"]
end
sales <--> support
end
```

</llms-only>

**How state flows through contexts:**

1. Caller starts in the first step of the default (or specified) context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,30 @@ This chapter covers everything about SWAIG functions:

## How SWAIG Functions Work

<llms-ignore>

<Frame caption="SWAIG Function Flow">
<img class="diagram" src="/assets/images/sdks/diagrams/04_01_defining-functions_diagram1.webp" alt="SWAIG function flow diagram." />
</Frame>

</llms-ignore>

<llms-only>

```mermaid
sequenceDiagram
participant Caller
participant AI
participant Agent as Your SWAIG endpoint
Caller->>AI: Ask for order 12345 status
Note over AI: Select check_order with<br/>order_number 12345
AI->>Agent: POST /swaig with function and arguments
Agent-->>AI: SwaigFunctionResult with shipment status
AI-->>Caller: Speak the result
```

</llms-only>

## Quick Start Example

Here's a complete agent with a SWAIG function:
Expand Down
10 changes: 10 additions & 0 deletions fern/products/server-sdks/pages/guides/build-ai-agents/hints.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,20 @@ max-toc-depth: 3

### Why Use Hints?

<llms-ignore>

<Frame caption="Speech Hints">
<img class="diagram" src="/assets/images/sdks/diagrams/03_06_hints_diagram1.webp" alt="Speech hints improving recognition accuracy." />
</Frame>

</llms-ignore>

<llms-only>

Without a hint, the STT engine may transcribe “My Acme account” as “My acne account.” Adding “Acme” as a hint tells the engine to listen for that term and preserves the intended transcription.

</llms-only>

### Adding Simple Hints

The hint methods accept a single string or a list of strings:
Expand Down
Loading
Loading