Render a SIP trace as a Mermaid call-flow ladder
render_sip_ladder[cost: free (pure CPU, no network) | read-only]
Parse a raw SIP trace (PCAP-decoded text, sngrep export, syslog, or pasted INVITE/200 dialog) and emit a Mermaid sequenceDiagram block visualizing the call flow. Most chat hosts (Claude, ChatGPT, Cursor, GitHub) render Mermaid inline.
Lane keying: by default participants are keyed by IP, not ip:port, so an endpoint that sends from an ephemeral source port and listens on 5060 collapses into one column. Multi-port IPs list their ports in the participant label (e.g. 10.0.0.1 :5060,:53412) and arrows touching them get a (:srcPort→:dstPort) suffix. Pass groupByIp: false to restore the legacy one-column-per-ip:port layout.
Lane labeling: aliases are matched against (in order) ${ip}:${port} from message source/dest, then bare ${ip}, then top-Via host, then Contact host. The most-specific match wins. When no alias matches the renderer falls back to the peer's address rather than emitting unknown:5060.
Pair with: minimize_sip_trace first to compact a noisy trace; diff_sip_messages when two adjacent INVITEs in the ladder differ unexpectedly; lint_sip_request to validate a single message you pulled from the ladder.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Raw SIP trace text. Multiple messages may be concatenated. | |
| callId | No | Render only this Call-ID. Required when the trace contains multiple calls; otherwise the only call is used. | |
| aliases | No | Friendly lane labels. Match order: exact "ip:port" → bare "ip" → top-Via host (with or without port) → Contact host (with or without port). Most-specific match wins; otherwise the lane is labeled with its raw "ip:port" (never "unknown"). Example: `{"192.0.2.10:5060":"Alice","203.0.113.50":"Carrier"}`. | |
| compact | No | Drop OPTIONS keepalives and retransmissions. Hidden counts are summarized in a `Note over` line. | |
| groupByIp | No | Collapse multiple ports on the same IP into one participant lane (default). Set to `false` to fall back to the legacy one-column-per-`ip:port` layout when you specifically need port-level granularity in the rendered Mermaid. | |
| maxMessages | No | Hard cap on rendered arrows. Extra messages produce a truncation note. Hard ceiling is 200. | |
| includeTiming | No | Append `+Nms` (delta from previous arrow) to each arrow label. | |
| groupRetransmits | No | Collapse adjacent identical retransmissions on the same direction into a single arrow + `Note over: xN over Tms`. Independent of `compact` (which drops them entirely). | |
| splitOnNewBranch | No | Emit a `--- failover to <ip[:port]> ---` separator before any request sent to a previously-unseen destination. Useful when the trace fails over between gateway IPs. | |
| highlightFailures | No | Bold the first non-1xx final response per request leg (CSeq) so the failure jumps out in the ladder. | |
| correlationHeaders | No | Header names to use for cross-leg call correlation (value-equality). When provided, calls sharing the same value for any listed header are merged into one ladder. Example: `["X-ACME-Session-ID","X-ACME-Call-ID"]`. |