$npx -y skills add forcedotcom/sf-skills --skill agentforce-d360-analyzeData Cloud 360° view of a single Agentforce session. TRIGGER when user asks to trace, inspect, summarize, or describe a specific Agentforce session by session id (Agent Session UUID 019d… or MessagingSession id 0Mw…). Also triggers on session discovery — find/list/search sess
| 1 | # agentforce-d360-analyze — Data Cloud 360° session view |
| 2 | |
| 3 | Hierarchical session reconstruction from Data Cloud STDM + GenAI DMOs for one Agentforce session. Three stages — fetch → assemble → render. Typical wall-clock: ~10–30s for a ~15-turn session. |
| 4 | |
| 5 | The pipeline is **DC-only**: it reads runtime audit rows that Data Cloud has materialized. It is **not** a runtime-availability tool — see "DC-only blind spot" below for what this skill cannot answer. |
| 6 | |
| 7 | ## If the user hasn't given enough to proceed |
| 8 | |
| 9 | When invoked with no session id AND no discovery criteria, print this block **verbatim** — do not paraphrase, do not pre-run any script. Trigger condition: the input is empty OR contains no session-id shape (neither a UUID nor a `0Mw…` messaging id) AND no discovery expression (no time phrase / `--agent` / `--channel` / `--outcome` / `--grep` / verbs like "find" / "list"). |
| 10 | |
| 11 | > Which session should I pull from Data Cloud, and in which org? |
| 12 | > |
| 13 | > I need: |
| 14 | > - **Session id** — either an Agent Session UUID (`019db7f6-…`) or a MessagingSession id (`0Mw…`, 15/18 chars). |
| 15 | > - **No session id?** — Tell me what you remember and I'll find it: how recent (e.g. "last 2 hours", "today", a date), which agent, which channel (Messaging / Builder / Voice), how it ended (escalated, user ended, transferred, timed out), or a phrase from the conversation. I'll show matching sessions as a numbered list — you pick one, I pull it. |
| 16 | > - **Org alias** — for `sf` CLI auth (the alias you configured with `sf org login`). |
| 17 | > |
| 18 | > Artifacts land in `~/.vibe/data/agentforce-d360-analyze/<org_id15>/<agent>__<ver>/<session_id>/` (override per-script with `--data-dir <path>`). |
| 19 | |
| 20 | ## Session id forms — UUID or MessagingSession id |
| 21 | |
| 22 | Both forms are accepted on `--session`: |
| 23 | |
| 24 | | Form | Example | Resolution | |
| 25 | |---|---|---| |
| 26 | | Agent Session UUID | `019dface-0000-7000-8000-000000000002` | Pass-through | |
| 27 | | MessagingSession id (`0Mw` prefix) | `0MwTESTMSG12345AAA` | Resolved via `resolve_session.py` — live DC lookup on first fetch, disk-first thereafter | |
| 28 | |
| 29 | **Multi-match is real.** One MessagingSession id can map to multiple Agent Session UUIDs. On multi-match the resolver prints every candidate and exits non-zero; the user re-invokes with a specific UUID. |
| 30 | |
| 31 | Artifacts always land under `~/.vibe/data/agentforce-d360-analyze/<org_id15>/<agent>__<ver>/<session_id>/` (default; overridable per-script with `--data-dir <path>`) — the messaging id is a lookup key only, never a directory name. The dominant agent (first in `sorted(agents_observed)`) names the `<agent>__<ver>/` segment. |
| 32 | |
| 33 | ## Resolving the script prefix |
| 34 | |
| 35 | The default install puts the skill under the runtime's plugin root. If the |
| 36 | skill was cloned somewhere else (e.g. directly from the `forcedotcom/sf-skills` |
| 37 | repo into a custom path), set `PLUGIN_ROOT` to point at the runtime's skills |
| 38 | directory. |
| 39 | |
| 40 | ```bash |
| 41 | prefix="${SKILL_ROOT:-${PLUGIN_ROOT:-$HOME/.vibe/skills}/agentforce-d360-analyze}/scripts" |
| 42 | ``` |
| 43 | |
| 44 | Every subsequent invocation in this doc uses `"$prefix/..."`. |
| 45 | |
| 46 | ## Session discovery (no id yet) |
| 47 | |
| 48 | When the user doesn't have a session id, run `discover_sessions.py` against the STDM session DMO. Prints a numbered picker; user picks one; proceed with the chosen UUID. |
| 49 | |
| 50 | ```bash |
| 51 | python3 "$prefix/discover_sessions.py" --org <alias> [filters...] |
| 52 | ``` |
| 53 | |
| 54 | **Filters** (all optional except `--org`): `--since <expr>` (default last 24h; accepts "last 2 hours", "today", ISO dates), `--agent <api-name>`, `--channel <Messaging|Builder|Voice>`, `--outcome <USER_ENDED|ESCALATED|TRANSFERRED|TIMEOUT|NOT_SET>`, `--grep <substring>` (conversation text), `--tz <IANA>`, `--limit <N>` (default 20). |
| 55 | |
| 56 | **Output**: markdown table with `#`, `UUID`, `Start (UTC)`, `Agent`, `Channel`, `Duration`, `Outcome`. User replies with a number; proceed with that UUID. |
| 57 | |
| 58 | ## Pipeline — three stages |
| 59 | |
| 60 | ``` |
| 61 | fetch_dc.py → 24 dc.<name>.json + dc._session_manifest.json (DC Query REST waterfall, 5 waves) |
| 62 | assemble_dc.py → dc._session_tree.json (pure in-memory hierarchical join) |
| 63 | render_dc.py → dc._session_summary.md (human summary, multi-section) |
| 64 | ``` |
| 65 | |
| 66 | Each stage is independently runnable. `fetch_dc.py --session <sid> --org <alias>` chains all three by default. |
| 67 | |
| 68 | ### Invocation |
| 69 | |
| 70 | ```bash |
| 71 | python3 "$prefix/fetch_dc.py" --session <session-id-or-messaging-id> --org <alias> |
| 72 | ``` |
| 73 | |
| 74 | Flags: |