@salesforce/afv-skills 1.6.9 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/package.json +1 -1
  2. package/skills/developing-agentforce/README.md +112 -0
  3. package/skills/{agentforce-development → developing-agentforce}/SKILL.md +109 -16
  4. package/skills/{agentforce-development → developing-agentforce}/assets/agents/README.md +2 -2
  5. package/skills/developing-agentforce/assets/agents/order-service.agent +272 -0
  6. package/skills/developing-agentforce/assets/agents/verification-gate.agent +280 -0
  7. package/skills/{agentforce-development → developing-agentforce}/assets/bundle-meta.xml +1 -1
  8. package/skills/{agentforce-development → developing-agentforce}/references/actions-reference.md +20 -0
  9. package/skills/{agentforce-development → developing-agentforce}/references/agent-design-and-spec-creation.md +1 -1
  10. package/skills/{agentforce-development → developing-agentforce}/references/agent-metadata-and-lifecycle.md +3 -3
  11. package/skills/{agentforce-development → developing-agentforce}/references/agent-script-core-language.md +40 -3
  12. package/skills/{agentforce-development → developing-agentforce}/references/agent-user-setup.md +60 -57
  13. package/skills/{agentforce-development → developing-agentforce}/references/agent-validation-and-debugging.md +22 -20
  14. package/skills/developing-agentforce/references/architecture-patterns.md +158 -0
  15. package/skills/developing-agentforce/references/complex-data-types.md +57 -0
  16. package/skills/developing-agentforce/references/deploy-reference.md +134 -0
  17. package/skills/developing-agentforce/references/discover-reference.md +102 -0
  18. package/skills/developing-agentforce/references/examples.md +350 -0
  19. package/skills/developing-agentforce/references/feature-validity.md +43 -0
  20. package/skills/developing-agentforce/references/instruction-resolution.md +545 -0
  21. package/skills/{agentforce-development → developing-agentforce}/references/known-issues.md +18 -18
  22. package/skills/{agentforce-development → developing-agentforce}/references/production-gotchas.md +24 -3
  23. package/skills/developing-agentforce/references/safety-review-reference.md +145 -0
  24. package/skills/{agentforce-development → developing-agentforce}/references/salesforce-cli-for-agents.md +9 -7
  25. package/skills/developing-agentforce/references/scaffold-reference.md +153 -0
  26. package/skills/developing-agentforce/references/scoring-rubric.md +24 -0
  27. package/skills/{agentforce-development → developing-agentforce}/references/version-history.md +2 -2
  28. package/skills/observing-agentforce/SKILL.md +368 -0
  29. package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls +1262 -0
  30. package/skills/observing-agentforce/apex/AgentforceOptimizeService.cls-meta.xml +5 -0
  31. package/skills/observing-agentforce/references/improve-reference.md +359 -0
  32. package/skills/observing-agentforce/references/issue-classification.md +220 -0
  33. package/skills/observing-agentforce/references/reproduce-reference.md +131 -0
  34. package/skills/observing-agentforce/references/stdm-queries.md +381 -0
  35. package/skills/observing-agentforce/references/stdm-schema.md +189 -0
  36. package/skills/testing-agentforce/SKILL.md +335 -0
  37. package/skills/testing-agentforce/assets/basic-test-spec.yaml +59 -0
  38. package/skills/testing-agentforce/assets/guardrail-test-spec.yaml +101 -0
  39. package/skills/testing-agentforce/assets/standard-test-spec.yaml +123 -0
  40. package/skills/testing-agentforce/references/action-execution.md +241 -0
  41. package/skills/testing-agentforce/references/batch-testing.md +274 -0
  42. package/skills/testing-agentforce/references/preview-testing.md +353 -0
  43. package/skills/testing-agentforce/references/test-report-format.md +160 -0
  44. package/skills/testing-agentforce/references/troubleshooting.md +73 -0
  45. /package/skills/{agentforce-development → developing-agentforce}/assets/README-legacy.md +0 -0
  46. /package/skills/{agentforce-development → developing-agentforce}/assets/agent-spec-template.md +0 -0
  47. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/hello-world.agent +0 -0
  48. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/multi-topic.agent +0 -0
  49. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.agent +0 -0
  50. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/production-faq.bundle-meta.xml +0 -0
  51. /package/skills/{agentforce-development → developing-agentforce}/assets/agents/simple-qa.agent +0 -0
  52. /package/skills/{agentforce-development → developing-agentforce}/assets/apex/models-api-queueable.cls +0 -0
  53. /package/skills/{agentforce-development → developing-agentforce}/assets/components/apex-action.agent +0 -0
  54. /package/skills/{agentforce-development → developing-agentforce}/assets/components/error-handling.agent +0 -0
  55. /package/skills/{agentforce-development → developing-agentforce}/assets/components/escalation-setup.agent +0 -0
  56. /package/skills/{agentforce-development → developing-agentforce}/assets/components/flow-action.agent +0 -0
  57. /package/skills/{agentforce-development → developing-agentforce}/assets/components/n-ary-conditions.agent +0 -0
  58. /package/skills/{agentforce-development → developing-agentforce}/assets/components/topic-with-actions.agent +0 -0
  59. /package/skills/{agentforce-development → developing-agentforce}/assets/deterministic-routing.agent +0 -0
  60. /package/skills/{agentforce-development → developing-agentforce}/assets/escalation-pattern.agent +0 -0
  61. /package/skills/{agentforce-development → developing-agentforce}/assets/flow-action-lookup.agent +0 -0
  62. /package/skills/{agentforce-development → developing-agentforce}/assets/hub-and-spoke.agent +0 -0
  63. /package/skills/{agentforce-development → developing-agentforce}/assets/invocable-apex-template.cls +0 -0
  64. /package/skills/{agentforce-development → developing-agentforce}/assets/local-info-agent-annotated.agent +0 -0
  65. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/basic-prompt-template.promptTemplate-meta.xml +0 -0
  66. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-apex.xml +0 -0
  67. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-function-flow.xml +0 -0
  68. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/genai-plugin.xml +0 -0
  69. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/http-callout-flow.flow-meta.xml +0 -0
  70. /package/skills/{agentforce-development → developing-agentforce}/assets/metadata/record-grounded-prompt.promptTemplate-meta.xml +0 -0
  71. /package/skills/{agentforce-development → developing-agentforce}/assets/minimal-starter.agent +0 -0
  72. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/README.md +0 -0
  73. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/action-callbacks.agent +0 -0
  74. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/advanced-input-bindings.agent +0 -0
  75. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/bidirectional-routing.agent +0 -0
  76. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/critical-input-collection.agent +0 -0
  77. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/delegation-routing.agent +0 -0
  78. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/lifecycle-events.agent +0 -0
  79. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/llm-controlled-actions.agent +0 -0
  80. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/multi-step-workflow.agent +0 -0
  81. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/open-gate-routing.agent +0 -0
  82. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/procedural-instructions.agent +0 -0
  83. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/prompt-template-action.agent +0 -0
  84. /package/skills/{agentforce-development → developing-agentforce}/assets/patterns/system-instruction-overrides.agent +0 -0
  85. /package/skills/{agentforce-development → developing-agentforce}/assets/prompt-rag-search.agent +0 -0
  86. /package/skills/{agentforce-development → developing-agentforce}/assets/template-multi-topic.agent +0 -0
  87. /package/skills/{agentforce-development → developing-agentforce}/assets/template-single-topic.agent +0 -0
  88. /package/skills/{agentforce-development → developing-agentforce}/assets/verification-gate.agent +0 -0
  89. /package/skills/{agentforce-development → developing-agentforce}/references/action-prompt-templates.md +0 -0
  90. /package/skills/{agentforce-development → developing-agentforce}/references/agent-access-guide.md +0 -0
  91. /package/skills/{agentforce-development → developing-agentforce}/references/agent-topic-map-diagrams.md +0 -0
  92. /package/skills/{agentforce-development → developing-agentforce}/references/minimal-examples.md +0 -0
@@ -0,0 +1,131 @@
1
+ # Phase 2: Reproduce -- Live Preview (Full Reference)
2
+
3
+ Use `sf agent preview` to simulate conversations in an isolated session (no production data affected).
4
+
5
+ ---
6
+
7
+ ## Build Test Scenarios from Phase 1 Findings
8
+
9
+ Before opening a preview session, define one test scenario per confirmed issue:
10
+
11
+ | Issue type (Phase 1) | Test message to send | Expected behavior | Failure indicator |
12
+ |---|---|---|---|
13
+ | Dead topic -- never entered | Utterance that *should* route to that topic | `topic` in response = `<dead_topic>` | Topic stays `entry` |
14
+ | Action not called | Ask directly for the action's task | Action fires in the response | Conversational reply with no action invoked |
15
+ | Handoff topic -- no post-collection routing | Enter the handoff topic, then send a follow-up | Session continues in specialized topic | Falls back to `entry` after 1 turn |
16
+ | LOW adherence | Exact utterance from the flagged `TRUST_GUARDRAILS_STEP` | Response follows topic instruction | Generic/off-instruction answer |
17
+ | Knowledge miss | Question requiring a specific knowledge article | Agent cites correct information | Hallucinated or generic answer |
18
+ | Topic misroute | Utterance that belongs to topic A | `topic` = A in response | `topic` = B or `entry` |
19
+
20
+ ---
21
+
22
+ ## Run a Preview Session
23
+
24
+ Use `--authoring-bundle` to compile from the local `.agent` file and generate local trace files:
25
+
26
+ | Flag | Compiles from | Local traces? | Use when |
27
+ |------|---------------|---------------|----------|
28
+ | `--authoring-bundle <BundleName>` | Local `.agent` file | YES | Development iteration (recommended) |
29
+ | `--api-name <name>` | Last published version | NO | Testing activated agent |
30
+
31
+ > **Note:** `--authoring-bundle` must appear on all three subcommands (`start`, `send`, `end`).
32
+
33
+ ```bash
34
+ # Start a preview session (--authoring-bundle enables local traces)
35
+ sf agent preview start --json \
36
+ --authoring-bundle <AgentApiName> \
37
+ -o <org> | tee /tmp/preview_start.json
38
+
39
+ # Extract the session ID
40
+ SESSION_ID=$(python3 -c "import json,sys; print(json.load(open('/tmp/preview_start.json'))['result']['sessionId'])")
41
+ echo "Session ID: $SESSION_ID"
42
+
43
+ # Send the test utterance (flag is --utterance, not --message)
44
+ sf agent preview send --json \
45
+ --session-id "$SESSION_ID" \
46
+ --utterance "your test utterance here" \
47
+ --authoring-bundle <AgentApiName> \
48
+ -o <org> | tee /tmp/preview_response.json
49
+
50
+ # Extract the agent's response text
51
+ # The message type is "Inform" in current API versions -- print all messages regardless of type
52
+ python3 -c "
53
+ import json
54
+ data = json.load(open('/tmp/preview_response.json'))
55
+ result = data.get('result', data)
56
+ # Response field varies by API version -- try common shapes
57
+ for key in ['messages', 'message', 'response']:
58
+ if key in result:
59
+ msgs = result[key] if isinstance(result[key], list) else [result[key]]
60
+ for m in msgs:
61
+ if isinstance(m, dict):
62
+ msg_type = m.get('type', '?')
63
+ msg_text = m.get('message', m.get('text', m))
64
+ print(f'Agent [{msg_type}]: {msg_text}')
65
+ break
66
+ else:
67
+ print(json.dumps(result, indent=2)) # fallback: print full result
68
+ "
69
+
70
+ # End the session when done (--authoring-bundle required on end too)
71
+ sf agent preview end --json \
72
+ --session-id "$SESSION_ID" \
73
+ --authoring-bundle <AgentApiName> \
74
+ -o <org>
75
+ ```
76
+
77
+ **Trace file location:**
78
+ ```
79
+ .sfdx/agents/{AgentApiName}/sessions/{sessionId}/traces/{planId}.json
80
+ ```
81
+
82
+ For multi-turn scenarios (e.g. handoff routing), repeat the `send` step for each follow-up utterance before ending the session.
83
+
84
+ ---
85
+
86
+ ## Local Trace Diagnosis
87
+
88
+ For each Phase 1 issue type, diagnose from the local trace:
89
+
90
+ | Phase 1 Issue | Local Trace Command |
91
+ |---|---|
92
+ | Topic misroute | `jq -r '.topic' "$TRACE"` + `jq -r '.plan[] \| select(.type=="NodeEntryStateStep") \| .data.agent_name' "$TRACE"` |
93
+ | Action not called | `jq -r '.plan[] \| select(.type=="EnabledToolsStep") \| .data.enabled_tools[]' "$TRACE"` |
94
+ | LOW adherence | `jq -r '.plan[] \| select(.type=="ReasoningStep") \| {category, reason}' "$TRACE"` |
95
+ | Variable capture fail | `jq -r '.plan[] \| select(.type=="VariableUpdateStep") \| .data.variable_updates[] \| "\(.variable_name): \(.variable_past_value) -> \(.variable_new_value) (\(.variable_change_reason))"' "$TRACE"` |
96
+ | Vague/wrong instructions | `jq -r '.plan[] \| select(.type=="LLMStep") \| .data.messages_sent[0].content' "$TRACE"` |
97
+
98
+ **UNGROUNDED retry detection:** When grounding returns UNGROUNDED, you'll see the retry pattern: UNGROUNDED -> error injection -> second LLMStep -> second ReasoningStep. Count `ReasoningStep` entries (>1 = retry happened):
99
+ ```bash
100
+ jq '[.plan[] | select(.type == "ReasoningStep")] | length' "$TRACE"
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Classify Each Scenario
106
+
107
+ Run each test scenario **3 times** (start a new session each run) and classify:
108
+
109
+ | Verdict | Criteria |
110
+ |---|---|
111
+ | `[CONFIRMED]` | Same failure in 3/3 runs |
112
+ | `[INTERMITTENT]` | Failure in 1-2 of 3 runs |
113
+ | `[NOT REPRODUCED]` | Passes in 3/3 runs -- re-examine Phase 1 evidence |
114
+
115
+ ---
116
+
117
+ ## Record Results
118
+
119
+ For each scenario, record before proceeding to Phase 3:
120
+
121
+ ```
122
+ Scenario: <issue type from Phase 1>
123
+ Test message: "<exact utterance sent>"
124
+ Expected: <topic name / action name / response behavior>
125
+ Actual: <observed topic / action / verbatim response>
126
+ Verdict: [CONFIRMED] / [INTERMITTENT] / [NOT REPRODUCED]
127
+ ```
128
+
129
+ Only `[CONFIRMED]` and `[INTERMITTENT]` issues proceed to Phase 3.
130
+
131
+ For `[NOT REPRODUCED]` issues: re-examine the Phase 1 STDM evidence. The session data may be stale (issue was already fixed), the utterance may not match the original user input closely enough, or the issue may be environment-dependent. Report these to the user as "not reproducible" and move on -- do not attempt fixes for issues that cannot be confirmed.
@@ -0,0 +1,381 @@
1
+ # STDM Query Reference
2
+
3
+ Detailed procedures for querying Session Trace Data Model (STDM) via the `AgentforceOptimizeService` Apex helper class.
4
+
5
+ ---
6
+
7
+ ## Deploy Helper Class (Once Per Org)
8
+
9
+ `AgentforceOptimizeService` is a bundled Apex class that queries STDM DMOs and returns clean JSON. Deploy it once; subsequent runs reuse the deployed class.
10
+
11
+ Methods:
12
+ - `findSessions(dataSpaceName, startIso, endIso, maxRows, agentName)` -> `List<SessionSummary>`
13
+ - `getConversationDetails(dataSpaceName, sessionId)` -> `ConversationData`
14
+ - `getMultipleConversationDetails(dataSpaceName, sessionIds)` -> `List<ConversationData>`
15
+ - `getLlmStepDetails(dataSpaceName, stepIds)` -> `List<LlmStepDetail>`
16
+ - `getMomentInsights(dataSpaceName, sessionIds)` -> `List<SessionInsights>` (moments, turn counts, retriever metrics)
17
+ - `getAggregatedMetrics(dataSpaceName, startIso, endIso, maxRows, agentName)` -> `AggregatedMetrics` (session rates, top intents, RAG quality)
18
+ - `runObservabilityQuery(List<ObservabilityInput>)` -> `List<ObservabilityOutput>` (@InvocableMethod -- RAG observability queries for Flow/Agentforce actions)
19
+
20
+ **Step 1 -- copy the class into the project:**
21
+
22
+ ```bash
23
+ # Ensure the classes directory exists
24
+ mkdir -p <project-root>/force-app/main/default/classes
25
+
26
+ # Copy from the installed skill location
27
+ cp skills/observing-agentforce/apex/AgentforceOptimizeService.cls \
28
+ <project-root>/force-app/main/default/classes/
29
+ cp skills/observing-agentforce/apex/AgentforceOptimizeService.cls-meta.xml \
30
+ <project-root>/force-app/main/default/classes/
31
+ ```
32
+
33
+ If the skill is installed globally via the installer, use the installed path:
34
+ ```bash
35
+ cp ~/.claude/skills/observing-agentforce/apex/AgentforceOptimizeService.cls \
36
+ <project-root>/force-app/main/default/classes/
37
+ cp ~/.claude/skills/observing-agentforce/apex/AgentforceOptimizeService.cls-meta.xml \
38
+ <project-root>/force-app/main/default/classes/
39
+ ```
40
+
41
+ **Step 2 -- ensure `sfdx-project.json` exists** (if absent, create a minimal one):
42
+
43
+ ```json
44
+ {
45
+ "packageDirectories": [{ "path": "force-app", "default": true }],
46
+ "sourceApiVersion": "63.0"
47
+ }
48
+ ```
49
+
50
+ **Step 3 -- deploy to the org:**
51
+
52
+ ```bash
53
+ sf project deploy start --json \
54
+ --metadata ApexClass:AgentforceOptimizeService \
55
+ -o <org>
56
+ ```
57
+
58
+ Confirm the deploy succeeds before proceeding. If it fails with a compile error, check that the org has Data Cloud enabled (the `ConnectApi.CdpQuery` namespace requires Data Cloud).
59
+
60
+ **Skip this step if `AgentforceOptimizeService` is already deployed** -- check with:
61
+ ```bash
62
+ sf data query --json \
63
+ --query "SELECT Id, Name FROM ApexClass WHERE Name = 'AgentforceOptimizeService'" \
64
+ -o <org>
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Find Sessions
70
+
71
+ If the user provided session IDs, skip to conversation details. Otherwise, write `/tmp/stdm_find.apex` and run it (substitute actual ISO 8601 UTC timestamps, DATA_SPACE, and AGENT_API_NAME):
72
+
73
+ ```apex
74
+ String result = AgentforceOptimizeService.findSessions(
75
+ 'DATA_SPACE',
76
+ 'START_ISO',
77
+ 'END_ISO',
78
+ 20,
79
+ 'AGENT_MASTER_LABEL'
80
+ );
81
+ System.debug('STDM_RESULT:' + result);
82
+ ```
83
+
84
+ ```bash
85
+ sf apex run --json --file /tmp/stdm_find.apex -o <org>
86
+ ```
87
+
88
+ Parse: search for `DEBUG|STDM_RESULT:` (not `STDM_RESULT:` -- the first occurrence of that string is in the source echo, not the debug output) and extract the JSON that follows on that line:
89
+
90
+ ```bash
91
+ python3 -c "
92
+ import json, sys
93
+ logs = json.load(sys.stdin)['result']['logs']
94
+ idx = logs.find('DEBUG|STDM_RESULT:')
95
+ print(logs[idx + len('DEBUG|STDM_RESULT:'):].split('\n')[0].strip())
96
+ " < /tmp/apex_result.json
97
+ ```
98
+
99
+ The result is a JSON array of `SessionSummary` objects:
100
+ ```json
101
+ [
102
+ {
103
+ "session_id": "...", "start_time": "...", "end_time": "...",
104
+ "channel": "...", "duration_ms": 12345,
105
+ "end_type": "USER_ENDED"
106
+ }
107
+ ]
108
+ ```
109
+
110
+ - `end_time` and `duration_ms` may be `null` when the session has no recorded end event -- this is a normal STDM data quality gap, not an error.
111
+ - `end_type` values: `USER_ENDED`, `AGENT_ENDED`, or `null` (in-progress or not recorded). A `null` `end_type` may indicate an abandoned session.
112
+
113
+ **Session quality filter:** `findSessions` automatically filters to sessions with actual conversation turns by querying `AiAgentInteraction` first. Sessions from `sf agent preview`, `sf agent test`, and Agent Builder that created `AiAgentSession` records but no `AiAgentInteraction` (TURN) records are excluded. If `findSessions` returns an empty list, there are no sessions with actionable data — go directly to Phase 1-ALT (local traces).
114
+
115
+ **How agent filtering works** -- `findSessions` tries two strategies in order:
116
+
117
+ 1. **Direct** (preferred): `ssot__AiAgentApiName__c = agentApiName` on `ssot__AiAgentSessionParticipant__dlm` -- no SOQL needed, uses a dedicated DMO field. Resolves in a single Data Cloud query.
118
+ 2. **Planner fallback**: If strategy 1 returns no rows, SOQL: `SELECT Id FROM GenAiPlannerDefinition WHERE MasterLabel = :agentApiName` -> `ssot__ParticipantId__c IN (...)`. Both 15-char and 18-char ID formats are included (the DMO stores them inconsistently). If both strategies return empty, the query falls back to all sessions in the date range.
119
+
120
+ **If the debug log shows `Agent not found: <name>`**, no `GenAiPlannerDefinition` matched -- verify the agent name with:
121
+ ```bash
122
+ sf data query --json --query "SELECT Id, MasterLabel, DeveloperName FROM GenAiPlannerDefinition" -o <org>
123
+ ```
124
+ Use the exact `MasterLabel` value (not `DeveloperName`). `MasterLabel` matches the agent's display name; `DeveloperName` has a version suffix (e.g. `TeslaSupportAgent_v1`).
125
+
126
+ **If the debug log shows a warning about no sessions for the agent**, both strategies returned empty -- the agent may have no sessions in this date range, or Data Cloud ingestion may be delayed. The query falls back to all sessions in the date range.
127
+
128
+ ---
129
+
130
+ ## Get Conversation Details
131
+
132
+ For up to 5 sessions (most recent first), write `/tmp/stdm_details.apex` and run it (substitute session IDs and DATA_SPACE):
133
+
134
+ ```apex
135
+ String result = AgentforceOptimizeService.getMultipleConversationDetails(
136
+ 'DATA_SPACE',
137
+ new List<String>{ 'SESSION_ID_1', 'SESSION_ID_2' }
138
+ );
139
+ System.debug('STDM_RESULT:' + result);
140
+ ```
141
+
142
+ ```bash
143
+ sf apex run --json --file /tmp/stdm_details.apex -o <org>
144
+ ```
145
+
146
+ Parse using the same `DEBUG|STDM_RESULT:` pattern. Each element is a `ConversationData` object:
147
+
148
+ ```json
149
+ {
150
+ "session_id": "...",
151
+ "start_time": "...", "end_time": "...", "channel": "...",
152
+ "duration_ms": 45000,
153
+ "end_type": "USER_ENDED",
154
+ "session_variables": "{...}",
155
+ "turn_count": 3,
156
+ "action_error_count": 1,
157
+ "turns": [
158
+ {
159
+ "interaction_id": "...",
160
+ "topic": "CheckOrderStatus",
161
+ "start_time": "...", "end_time": "...", "duration_ms": 8000,
162
+ "telemetry_trace_id": "...",
163
+ "messages": [
164
+ { "message_type": "Input", "text": "Where is my order?", "sent_at": "..." },
165
+ { "message_type": "Output", "text": "I found your order...", "sent_at": "..." }
166
+ ],
167
+ "steps": [
168
+ { "step_type": "TOPIC_STEP", "name": "CheckOrderStatus" },
169
+ { "step_type": "LLM_STEP", "name": "...", "duration_ms": 3200,
170
+ "generation_id": "abc123", "gateway_request_id": "def456" },
171
+ { "step_type": "ACTION_STEP", "name": "GetOrderDetails",
172
+ "input": "{...}", "output": "{...}", "error": null,
173
+ "pre_vars": "{...}", "post_vars": "{...}", "duration_ms": 1500 }
174
+ ]
175
+ }
176
+ ]
177
+ }
178
+ ```
179
+
180
+ Key fields:
181
+ - `end_type` -- how the session ended (`USER_ENDED`, `AGENT_ENDED`, or null)
182
+ - `session_variables` -- final variable snapshot for the session (null when absent)
183
+ - `telemetry_trace_id` -- distributed tracing ID for this turn (null when absent)
184
+ - `generation_id` / `gateway_request_id` on `LLM_STEP` -- pass these step IDs to `getLlmStepDetails()` to retrieve the actual LLM prompt and response (useful for diagnosing LOW instruction adherence)
185
+
186
+ Treat any `null` field as absent/unknown. The `"NOT_SET"` sentinel is stripped by the service class before returning.
187
+
188
+ ---
189
+
190
+ ## Get LLM Prompt/Response (Optional, for LOW Adherence)
191
+
192
+ When a session shows `TRUST_GUARDRAILS_STEP` with `'value': 'LOW'`, use `getLlmStepDetails()` to retrieve the actual LLM prompt and response for the associated `LLM_STEP` records. Pass the `step_id` values from steps where `step_type == "LLM_STEP"` and `generation_id != null`.
193
+
194
+ ```apex
195
+ String result = AgentforceOptimizeService.getLlmStepDetails(
196
+ 'DATA_SPACE',
197
+ new List<String>{ 'STEP_ID_1', 'STEP_ID_2' }
198
+ );
199
+ System.debug('STDM_RESULT:' + result);
200
+ ```
201
+
202
+ ```bash
203
+ sf apex run --json --file /tmp/stdm_llm.apex -o <org>
204
+ ```
205
+
206
+ Returns a JSON array of `LlmStepDetail` objects:
207
+ ```json
208
+ [
209
+ {
210
+ "step_id": "...",
211
+ "interaction_id": "...",
212
+ "step_name": "...",
213
+ "prompt": "System: You are a Tesla support agent...\nUser: I want to schedule a test drive",
214
+ "llm_response": "I'd be happy to help you schedule a test drive...",
215
+ "generation_id": "...",
216
+ "gateway_request_id": "..."
217
+ }
218
+ ]
219
+ ```
220
+
221
+ - `prompt` -- full prompt from `GenAIGatewayRequest__dlm.prompt__c` (null if Einstein Audit DMO not enabled)
222
+ - `llm_response` -- model response from `GenAIGeneration__dlm.responseText__c` (null if not available)
223
+
224
+ Use these to confirm whether the agent's instructions were included in the prompt and whether the response deviated from them.
225
+
226
+ ---
227
+
228
+ ## Get Aggregated Metrics (Recommended First Step)
229
+
230
+ Before drilling into individual sessions, get a high-level health dashboard with `getAggregatedMetrics()`. This gives session rates, top intents, and RAG quality averages across the date range.
231
+
232
+ ```apex
233
+ String result = AgentforceOptimizeService.getAggregatedMetrics(
234
+ 'DATA_SPACE',
235
+ 'START_ISO',
236
+ 'END_ISO',
237
+ 50,
238
+ 'AGENT_MASTER_LABEL'
239
+ );
240
+ System.debug('STDM_RESULT:' + result);
241
+ ```
242
+
243
+ Returns an `AggregatedMetrics` object:
244
+ ```json
245
+ {
246
+ "total_sessions": 36,
247
+ "total_moments": 32,
248
+ "total_turns": 101,
249
+ "avg_quality_score": 4.34,
250
+ "avg_session_duration_sec": 45.2,
251
+ "end_type_counts": { "USER_ENDED": 5, "AGENT_ENDED": 10, "UNKNOWN": 21 },
252
+ "quality_distribution": { "5": 20, "4": 6, "3": 4, "2": 1, "1": 1 },
253
+ "abandonment_rate": 0.14,
254
+ "deflection_rate": 0.28,
255
+ "escalation_rate": 0.0,
256
+ "top_intents": { "I want help finding homes in San Jose.": 3, "Check order status": 2 },
257
+ "avg_faithfulness": 0.85,
258
+ "avg_answer_relevance": 0.72,
259
+ "avg_context_precision": 0.91,
260
+ "unavailable_dmos": []
261
+ }
262
+ ```
263
+
264
+ Key signals:
265
+ - `avg_quality_score` < 4.0 -> agent has Medium/Low quality responses, investigate low-scoring moments. Score labels: 5=High, 3-4=Medium, 2=Low, 1=Very Low
266
+ - `quality_distribution` skewed toward 1-3 -> systemic agent quality issue; focus on moments with score <= 3
267
+ - High `abandonment_rate` (> 0.3) -> users giving up, check for dead-ends or missing actions
268
+ - Low `avg_faithfulness` / `avg_answer_relevance` -> RAG retrieval issues, check knowledge base content
269
+ - `top_intents` shows what users ask about most -- verify the agent has topics/actions for each
270
+ - `unavailable_dmos` lists any DMOs that couldn't be queried (graceful degradation)
271
+
272
+ ---
273
+
274
+ ## Get Moment Insights (Per-Session Detail)
275
+
276
+ For deeper analysis of specific sessions, use `getMomentInsights()` to get intent summaries, moment durations, and retriever quality metrics per session.
277
+
278
+ ```apex
279
+ String result = AgentforceOptimizeService.getMomentInsights(
280
+ 'DATA_SPACE',
281
+ new List<String>{ 'SESSION_ID_1', 'SESSION_ID_2' }
282
+ );
283
+ System.debug('STDM_RESULT:' + result);
284
+ ```
285
+
286
+ Returns a JSON array of `SessionInsights` objects:
287
+ ```json
288
+ [
289
+ {
290
+ "session_id": "...",
291
+ "start_time": "...", "end_time": "...", "end_type": null,
292
+ "duration_ms": null, "turn_count": 3, "moment_count": 2,
293
+ "avg_quality_score": 4.5,
294
+ "action_error_count": 0,
295
+ "moments": [
296
+ {
297
+ "moment_id": "...",
298
+ "session_id": "...",
299
+ "start_time": "...", "end_time": "...", "duration_ms": 10000,
300
+ "request_summary": "I want help finding homes in San Jose.",
301
+ "response_summary": "The agent provided details on three homes...",
302
+ "agent_api_name": "MyServiceAgent",
303
+ "agent_version": null,
304
+ "quality_score": 5,
305
+ "quality_reasoning": "The agent provided a detailed and helpful response..."
306
+ }
307
+ ],
308
+ "retriever_metrics": [],
309
+ "debug_message": null
310
+ }
311
+ ]
312
+ ```
313
+
314
+ Key fields:
315
+ - `quality_score` (1-5) -- per-moment quality score from `AiAgentTagAssociation -> AiAgentTag.Value`. Maps to UI labels: 5=High, 3-4=Medium, 2=Low, 1=Very Low
316
+ - `quality_reasoning` -- LLM-generated explanation for the score (from `AssociationReasonText`)
317
+ - `avg_quality_score` -- session-level average across all scored moments
318
+ - `request_summary` / `response_summary` -- LLM-generated intent and response summaries per moment
319
+ - `moment_count` vs `turn_count` -- if `turn_count` >> `moment_count`, the agent needed many turns per intent (inefficient)
320
+ - `retriever_metrics` -- RAG quality scores per retrieval (empty if agent doesn't use knowledge retrieval)
321
+ - `debug_message` -- non-null if a DMO was unavailable (e.g. "AiAgentMoment DMO not available in this org")
322
+
323
+ ---
324
+
325
+ ## Run Observability Queries (RAG Deep-Dive)
326
+
327
+ For targeted RAG/retriever quality analysis, use the `@InvocableMethod` entry point `runObservabilityQuery()`. This can be called from anonymous Apex, Flows, or Agentforce actions. It queries Data Lake objects (`*__dll`) directly without a Data Space parameter.
328
+
329
+ **Query types:**
330
+
331
+ | `queryType` | What it returns |
332
+ |---|---|
333
+ | `KnowledgeGap` | Avg context precision + answer relevancy by topic/agent (lowest first) |
334
+ | `Hallucination` | Topics with avg faithfulness < 0.8 |
335
+ | `RetrievalQuality` | Avg context precision by retriever/topic/agent |
336
+ | `AnswerRelevancy` | Topics with avg answer relevancy < 0.7 |
337
+ | `Leaderboard` | Combined precision, relevancy, and faithfulness by topic/agent |
338
+
339
+ **From anonymous Apex:**
340
+
341
+ ```apex
342
+ AgentforceOptimizeService.ObservabilityInput inp = new AgentforceOptimizeService.ObservabilityInput();
343
+ inp.queryType = 'KnowledgeGap';
344
+ inp.agentApiName = 'AGENT_API_NAME'; // optional
345
+ inp.topicApiName = 'TOPIC_API_NAME'; // optional
346
+ inp.lookbackDays = 90; // optional, default 90
347
+
348
+ List<AgentforceOptimizeService.ObservabilityOutput> results =
349
+ AgentforceOptimizeService.runObservabilityQuery(
350
+ new List<AgentforceOptimizeService.ObservabilityInput>{ inp }
351
+ );
352
+ System.debug('STDM_RESULT:' + results[0].summaryText);
353
+ System.debug('STDM_RESULT:' + results[0].resultJson);
354
+ ```
355
+
356
+ ```bash
357
+ sf apex run --json --file /tmp/observability_query.apex -o <org>
358
+ ```
359
+
360
+ **When to use observability queries vs `getAggregatedMetrics()`:**
361
+
362
+ - Use `getAggregatedMetrics()` for a broad health dashboard (session rates, top intents, overall RAG averages)
363
+ - Use `runObservabilityQuery()` for targeted RAG deep-dives when knowledge gaps or hallucination issues are detected -- it provides per-topic and per-retriever breakdowns
364
+
365
+ ---
366
+
367
+ ## Reconstruct Conversations
368
+
369
+ For each session, render the turn-by-turn timeline from the `ConversationData` JSON:
370
+
371
+ ```
372
+ Session <session_id> [<channel>] <duration_ms>ms total <turn_count> turns
373
+ ------------------------------------------------------------
374
+ Turn 1 [Topic: <topic>] <duration_ms>ms
375
+ User: <messages[type=Input].text>
376
+ Agent: <messages[type=Output].text>
377
+ Steps:
378
+ TOPIC_STEP: <name>
379
+ LLM_STEP: <name> (<duration_ms>ms)
380
+ ACTION_STEP: <name> in: <input> out: <output> [ERROR: <error>]
381
+ ```