@salesforce/afv-skills 1.40.0 → 1.41.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 (136) hide show
  1. package/package.json +1 -1
  2. package/skills/automation-flow-generate/SKILL.md +32 -43
  3. package/skills/experience-portal-create/SKILL.md +497 -0
  4. package/skills/experience-portal-create/assets/report-template.md +30 -0
  5. package/skills/experience-portal-create/references/mcp-invocation.md +288 -0
  6. package/skills/experience-portal-create/references/post-creation-activate-publish.md +165 -0
  7. package/skills/experience-portal-create/references/templates.md +253 -0
  8. package/skills/experience-ui-bundle-features-generate/SKILL.md +5 -1
  9. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -0
  10. package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -0
  11. package/skills/platform-datamask-run/SKILL.md +345 -0
  12. package/skills/platform-datamask-run/references/api-surface.md +130 -0
  13. package/skills/platform-datamask-run/references/policy-authoring.md +185 -0
  14. package/skills/platform-datamask-run/references/run-and-abort.md +116 -0
  15. package/skills/platform-datamask-run/scripts/poll-job.sh +115 -0
  16. package/skills/platform-dataspace-access-configure/SKILL.md +51 -3
  17. package/skills/platform-dataspace-access-configure/scripts/inspect-dataspace-scopes.sh +56 -0
  18. package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +1 -0
  19. package/skills/platform-sandbox-configure/SKILL.md +17 -2
  20. package/skills/platform-trial-org-create/SKILL.md +175 -0
  21. package/skills/platform-trial-org-create/examples/create_request.json +9 -0
  22. package/skills/platform-trial-org-create/examples/error_response.json +41 -0
  23. package/skills/platform-trial-org-create/examples/success_response.json +27 -0
  24. package/skills/platform-trial-org-create/references/error_codes.md +42 -0
  25. package/skills/platform-trial-org-create/references/signup_request_fields.md +69 -0
  26. package/skills/platform-trial-org-create/scripts/create_signup_request.sh +175 -0
  27. package/skills/platform-trial-org-create/scripts/get_signup_request.sh +155 -0
  28. package/skills/platform-widget-generate/SKILL.md +47 -6
  29. package/skills/platform-widget-generate/examples/conditional.json +3 -3
  30. package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
  31. package/skills/platform-widget-generate/examples/single-object.json +2 -2
  32. package/skills/platform-widget-generate/references/widget-bundle-layout.md +1 -1
  33. package/skills/service-agentforce-channel-configure/SKILL.md +271 -0
  34. package/skills/service-agentforce-channel-configure/references/agent-wiring.md +97 -0
  35. package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +145 -0
  36. package/skills/service-agentforce-channel-configure/references/channel-branch-voice.md +69 -0
  37. package/skills/service-agentforce-channel-configure/references/channel-types.md +61 -0
  38. package/skills/service-agentforce-channel-configure/references/live-traffic-gate.md +86 -0
  39. package/skills/service-agentforce-channel-configure/references/queue-resolution.md +135 -0
  40. package/skills/service-agentforce-channel-configure/references/routing-flow.md +384 -0
  41. package/skills/service-catalog-template-deploy/SKILL.md +310 -0
  42. package/skills/service-catalog-template-deploy/references/cli-invocation.md +258 -0
  43. package/skills/service-catalog-template-deploy/scripts/activate-verify.mjs +164 -0
  44. package/skills/service-catalog-template-deploy/scripts/build-deploy-payload.mjs +94 -0
  45. package/skills/service-catalog-template-deploy/scripts/resolve-template.mjs +331 -0
  46. package/skills/service-catalog-template-search/SKILL.md +212 -0
  47. package/skills/service-catalog-template-search/references/cli-invocation.md +128 -0
  48. package/skills/service-catalog-template-search/scripts/classify-catalog.mjs +205 -0
  49. package/skills/service-concierge-portal-generate/SKILL.md +126 -0
  50. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1428 -0
  51. package/skills/service-digital-engagement-channel-configure/SKILL.md +46 -6
  52. package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +2 -1
  53. package/skills/service-digital-engagement-channel-configure/examples/asa_agent_channel.xml +4 -1
  54. package/skills/service-helpagent-coordinate/README.md +8 -2
  55. package/skills/service-helpagent-coordinate/SKILL.md +126 -130
  56. package/skills/service-helpagent-coordinate/assets/help-agent-spec.md +70 -53
  57. package/skills/service-helpagent-coordinate/references/agent-script.md +571 -457
  58. package/skills/service-helpagent-coordinate/references/channel-voice.md +38 -9
  59. package/skills/service-helpagent-coordinate/references/channel-web-chat.md +173 -49
  60. package/skills/service-helpagent-coordinate/references/output-report-format.md +126 -0
  61. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +153 -0
  62. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +79 -0
  63. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +35 -0
  64. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +271 -0
  65. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +265 -0
  66. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +220 -0
  67. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-final-report.mjs +102 -0
  68. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/record-enable-result.mjs +73 -0
  69. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +206 -0
  70. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +194 -0
  71. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +223 -0
  72. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +45 -7
  73. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +45 -5
  74. package/skills/service-itsm-agentic-setup-configure/SKILL.md +116 -0
  75. package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +64 -0
  76. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +158 -0
  77. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md +361 -0
  78. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/error-taxonomy.md +44 -0
  79. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/reactivation.md +66 -0
  80. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +66 -0
  81. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/specialized-templates.md +148 -0
  82. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +169 -0
  83. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/build-create-body.mjs +116 -0
  84. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-agent-existence.mjs +185 -0
  85. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-preflight.mjs +168 -0
  86. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  87. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +197 -0
  88. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +186 -0
  89. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +51 -0
  90. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/cli-invocation.md +345 -0
  91. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/error-taxonomy.md +44 -0
  92. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/reactivation.md +63 -0
  93. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +44 -0
  94. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +149 -0
  95. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +110 -0
  96. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +201 -0
  97. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-activate-result.mjs +135 -0
  98. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-agent-existence.mjs +194 -0
  99. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-preflight.mjs +158 -0
  100. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  101. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +191 -0
  102. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +133 -0
  103. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +71 -0
  104. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +308 -0
  105. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +23 -0
  106. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +193 -0
  107. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +57 -0
  108. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +394 -0
  109. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +266 -0
  110. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +106 -0
  111. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +142 -0
  112. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +82 -0
  113. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-action-surface.mjs +137 -0
  114. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-assignment-state.mjs +99 -0
  115. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +120 -0
  116. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/resolve-target-user.mjs +86 -0
  117. package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +284 -0
  118. package/skills/service-itsm-agentic-setup-uel-user-create/references/mcp-invocation.md +302 -0
  119. package/skills/service-itsm-channels-coordinate/SKILL.md +472 -0
  120. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +212 -0
  121. package/skills/service-itsm-incident-mgmt-configure/references/mcp-invocation.md +225 -0
  122. package/skills/service-itsm-incident-priority-configure/SKILL.md +53 -12
  123. package/skills/service-itsm-swarming-configure/SKILL.md +212 -0
  124. package/skills/service-itsm-teams-configure/SKILL.md +395 -0
  125. package/skills/service-itsm-teams-configure/references/azure-credential-population.md +213 -0
  126. package/skills/service-itsm-teams-configure/references/gotchas.md +23 -0
  127. package/skills/service-itsm-teams-coordinate/SKILL.md +175 -0
  128. package/skills/service-itsm-teams-coordinate/examples/output-templates.md +85 -0
  129. package/skills/service-itsm-teams-debug/SKILL.md +144 -0
  130. package/skills/service-itsm-teams-debug/references/configuration-checklists.md +277 -0
  131. package/skills/service-itsm-teams-debug/references/report-generation.md +95 -0
  132. package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +139 -0
  133. package/skills/service-itsm-teams-employee-agent-configure/assets/Teams_AgentForce.EmbeddedServiceConfig-meta.xml +43 -0
  134. package/skills/service-itsm-teams-employee-agent-configure/references/teams-embedded-employee-agent.md +480 -0
  135. package/skills/service-itsm-teams-itdesk-configure/SKILL.md +232 -0
  136. package/skills/service-itsm-teams-itservice-configure/SKILL.md +391 -0
@@ -0,0 +1,480 @@
1
+ # Embedded Agentforce Employee Agent in Microsoft Teams (verified recipe — build from scratch, 100% API)
2
+
3
+ Making the embedded Agentforce agent ("IT Service Employee Agent") actually reply inside the
4
+ Microsoft Teams custom client ("Salesforce Employee Assist" / "Ask AI Agent") is the hardest,
5
+ most under-documented part of Teams ITSM. Everything below is **verified end-to-end against a
6
+ real org** — the agent returns contextual replies inside Teams — and **every step has a working
7
+ API path, so the whole build runs headlessly with zero Setup-UI clicks.** The Teams custom client
8
+ loads the deployment named **exactly** `Teams_AgentForce` (hard-wired in committed Core config —
9
+ you cannot rename it per-org).
10
+
11
+ ## The blessed architecture: Web channel + User Verification ON + a JWKS_URL Key Set
12
+
13
+ This is the product-provided manual, verified working. The agent replies when **all** of these are true:
14
+
15
+ 1. A **Web** Enhanced-messaging channel routing (Omni-Flow) to a real, Active IT Service Employee Agent.
16
+ 2. **User Verification ON** on that channel (`<embeddedConfig><authMode>Auth</authMode>`).
17
+ 3. An **Enhanced Chat User Verification Key Set** (`PublicKeyCertificateSet`, type **`JWKS_URL`**)
18
+ whose endpoint is `<Org_Url>/id/keys` and whose issuer is the **Employee Site URL**, **linked
19
+ into the channel** via `<embeddedConfig><messagingAuthorizations>`.
20
+ 4. The **`Teams_AgentForce`** custom-client Embedded Service Deployment (Enhanced Chat), linked to
21
+ the channel and **published**.
22
+ 5. The **portal user has an "Agent Access" permission set** enabling the IT Service Employee Agent.
23
+
24
+ Miss #2+#3 together, or #5, and you get the classic "agent joins the conversation, then leaves,
25
+ no reply" symptom.
26
+
27
+ > **This corrects an earlier version of this recipe** that insisted User Verification must be
28
+ > **OFF** and that a Key Set must **not** be attached. That was wrong — it was diagnosed on a
29
+ > build that turned **auth ON but never attached a Key Set**, so the Teams client fell back to the
30
+ > scrt2 *unauthenticated* token endpoint, which rejects an auth-ON channel with `BAD_REQUEST`
31
+ > "Set the auth mode to false." **The fix is not to turn auth off — it is to attach the Key Set.**
32
+ > With a Key Set present, the Teams client uses the *authenticated* token flow that the auth-ON
33
+ > channel expects, and the agent replies. The verified, product-blessed build is **auth ON +
34
+ > JWKS_URL Key Set** (screenshot-confirmed live).
35
+
36
+ ## Concept map (what the Teams custom client actually needs)
37
+
38
+ | Layer | Object | Role |
39
+ |-------|--------|------|
40
+ | Deployment | `EmbeddedServiceConfig` (ESD), **named `Teams_AgentForce`**, Enhanced-chat **custom client** | The deployment the Teams app loads by its `DeveloperName` (`esDeveloperName`). Stored with `deploymentType: API` / `site: null` in Metadata even though the wizard flow is "Web / custom client" — that is expected. |
41
+ | Channel | `MessagingChannel` (MessageType=`EmbeddedMessaging`), **Web** deployment, **User Verification ON** | The Enhanced messaging channel. Domain = the Employee Site URL. Routes via `sessionHandlerFlow`/`SessionHandlerId`. `<embeddedConfig><authMode>Auth</authMode>` + a linked Key Set. |
42
+ | **Key Set** | **`PublicKeyCertificateSet`, type `JWKS_URL`** | Enhanced Chat User Verification Key Set. `jwksEndPoint` = `<Org_Url>/id/keys`; `jwtIssuer` = Employee Site URL. Linked into the channel's `<embeddedConfig><messagingAuthorizations>`. |
43
+ | Routing | `Flow` (ProcessType=`RoutingFlow`) → `FlowDefinitionView` | An Omni **RoutingFlow** whose `routeWork` action hardcodes the target agent id in `agentforceEmployeeAgentId`. |
44
+ | Agent | `BotDefinition` (Type=`InternalCopilot`, AgentType=`AgentforceEmployeeAgent`) + Active `BotVersion` | The Agentforce agent that generates replies. |
45
+ | **Agent access** | **Permission set with "Agent Access" → the IT Service Employee Agent**, assigned to the **portal user** | Without this, routing delivers the work but the running user cannot access the agent, so it joins then immediately leaves with no reply. |
46
+
47
+ ## The full headless build (maps 1:1 to the product manual — zero manual steps)
48
+
49
+ The product manual and its API equivalent, step for step. All deploys use an isolated
50
+ `sfdx-project.json` (packageDir `force-app`) at `--api-version 67.0`. Run one step at a time.
51
+
52
+ | Manual step | API step |
53
+ |-------------|----------|
54
+ | 1–4. Setup → Messaging Settings → New channel; name; deployment type **Web**; domain = Employee Site URL | **§A** — Metadata-deploy the `MessagingChannel` |
55
+ | 5–6. Routing type = **Omni-Flow** → Flow = "Route to AEA"; Fallback Queue = chat_queue; Save | Channel `sessionHandlerFlow`/`sessionHandlerQueue` (§A) — the flow + queue must pre-exist (§E/§F) |
56
+ | 7. Enable **Add User Verification** + Save | Channel `<embeddedConfig><authMode>Auth</authMode>` (§A) |
57
+ | 8. Setup → Enhanced Chat User Verification → **New Key Set** (issuer = Site URL, endpoint = `<Org>/id/keys`) | **§B** — Metadata-deploy the `PublicKeyCertificateSet` (type `JWKS_URL`) |
58
+ | 9. Attach the Key Set to the channel (User Verification Configuration) | Channel `<embeddedConfig><messagingAuthorizations>` (§A) — deploy the Key Set **first**, then the channel |
59
+ | 10. New ESD → Enhanced Chat → Custom Client → name `Teams_AgentForce` → select the channel | **§C** — Metadata-deploy the `API`-type ESD |
60
+ | 11. Save & Publish | **§D** — Connect publish |
61
+ | (access) Permission set → Agent Access → the agent, assigned to the portal user | **§G** |
62
+
63
+ Deploy order matters: **Key Set (§B) → Channel (§A, which references the Key Set) → activate the
64
+ channel → ESD (§C) → publish (§D).** (The routing flow §E and fallback queue §F are prerequisites
65
+ of the channel — build/verify them first if they don't already exist.)
66
+
67
+ ### §A. The `MessagingChannel` (Web, auth ON, Key Set linked)
68
+
69
+ `force-app/main/default/messagingChannels/<DevName>.messagingChannel-meta.xml`. The
70
+ `publicKeyCertificateSetName` must match the Key Set's dev name from §B, so **deploy the Key Set
71
+ first.** `sessionHandlerFlow` = the routing flow's dev name (e.g. `Route_To_MIAW_AEA`);
72
+ `sessionHandlerQueue` = the fallback queue's dev name (e.g. `chatqueue`).
73
+
74
+ ```xml
75
+ <?xml version="1.0" encoding="UTF-8"?>
76
+ <MessagingChannel xmlns="http://soap.sforce.com/2006/04/metadata">
77
+ <masterLabel>Teams AgentForce</masterLabel>
78
+ <messagingChannelType>EmbeddedMessaging</messagingChannelType>
79
+ <sessionHandlerFlow>Route_To_MIAW_AEA</sessionHandlerFlow>
80
+ <sessionHandlerQueue>chatqueue</sessionHandlerQueue>
81
+ <sessionHandlerType>Flow</sessionHandlerType>
82
+ <embeddedConfig>
83
+ <authMode>Auth</authMode>
84
+ <messagingAuthorizations>
85
+ <authorizationType>PublicKeyCertificateSet</authorizationType>
86
+ <publicKeyCertificateSetName>Teams_AgentForce_KeySet</publicKeyCertificateSetName>
87
+ <enabled>true</enabled>
88
+ <authIdentifier>Teams_AgentForce_KeySet</authIdentifier>
89
+ </messagingAuthorizations>
90
+ </embeddedConfig>
91
+ </MessagingChannel>
92
+ ```
93
+
94
+ ```bash
95
+ sf project deploy start --metadata "MessagingChannel:<DevName>" \
96
+ --target-org <org-alias> --api-version 67.0 --dry-run # validate
97
+ sf project deploy start --metadata "MessagingChannel:<DevName>" \
98
+ --target-org <org-alias> --api-version 67.0 # deploy
99
+ ```
100
+
101
+ A freshly-deployed channel may be **`IsActive=false`** — activate it before publishing the ESD:
102
+
103
+ ```text
104
+ # data-API record update (MessagingChannel is a data-API object, not Tooling)
105
+ sf data update record --sobject MessagingChannel --record-id <channelId> --values "IsActive=true"
106
+ ```
107
+
108
+ Verify:
109
+
110
+ ```text
111
+ SELECT Id, DeveloperName, IsActive, SessionHandlerId, ChannelAddressIdentifier, MessageType
112
+ FROM MessagingChannel WHERE DeveloperName='<DevName>'
113
+ # IsActive=true, MessageType=EmbeddedMessaging, SessionHandlerId resolves to the routing flow.
114
+ ```
115
+
116
+ ### §B. The Enhanced Chat User Verification Key Set (`PublicKeyCertificateSet`, `JWKS_URL`)
117
+
118
+ `force-app/main/default/PublicKeyCertificateSet/<DevName>.PublicKeyCertificateSet-meta.xml`.
119
+
120
+ > **Casing is load-bearing.** The directory must be `PublicKeyCertificateSet/` (capital P), and the
121
+ > file suffix must be `.PublicKeyCertificateSet-meta.xml`. Lowercase (`publicKeyCertificateSets/` /
122
+ > `.publicKeyCertificateSet-meta.xml`) fails with a `TypeInferenceError`.
123
+
124
+ > **The enum is `JWKS_URL`.** `PublicKeyCertificateSetType` has two values: **`JWKS_URL`** (retrieve
125
+ > keys from the remote `jwksEndPoint` — this is the mode the manual uses) and **`Jwks`** (an
126
+ > uploaded/local key via child `PublicKeyCertificateSetKey`). `Jwks` **rejects** a `jwksEndPoint`
127
+ > with "You can't configure JWKS_URL when the key type selected is JWKS_KEY." Use `JWKS_URL`. The
128
+ > sObject has **no REST describe** (both data-API and Tooling `/sobjects/PublicKeyCertificateSet/describe`
129
+ > return `NOT_FOUND`), so this enum can only be confirmed from the Metadata API docs — do not
130
+ > blind-guess camelCase variants (`JwksUrl`, `JwksEndpoint`, `RemoteJwks`, `SelfSignedCert`, … all
131
+ > fail enum validation).
132
+
133
+ ```xml
134
+ <?xml version="1.0" encoding="UTF-8"?>
135
+ <PublicKeyCertificateSet xmlns="http://soap.sforce.com/2006/04/metadata">
136
+ <masterLabel>Teams AgentForce KeySet</masterLabel>
137
+ <type>JWKS_URL</type>
138
+ <jwksEndPoint>https://<org>.my.salesforce.com/id/keys</jwksEndPoint>
139
+ <jwtIssuer>https://<org>.my.site.com/<sitePath></jwtIssuer>
140
+ </PublicKeyCertificateSet>
141
+ ```
142
+
143
+ - `jwksEndPoint` = the org's **My Domain URL** + `/id/keys` (the `<Org_Url>/id/keys` from the manual).
144
+ - `jwtIssuer` = the **Employee Site URL** (Setup → All Sites → the employee portal).
145
+
146
+ ```bash
147
+ sf project deploy start --metadata "PublicKeyCertificateSet:<DevName>" \
148
+ --target-org <org-alias> --api-version 67.0 --dry-run # validate
149
+ sf project deploy start --metadata "PublicKeyCertificateSet:<DevName>" \
150
+ --target-org <org-alias> --api-version 67.0 # deploy
151
+ ```
152
+
153
+ ### §C. The `Teams_AgentForce` ESD (Enhanced Chat custom client, `API`-type)
154
+
155
+ `force-app/main/default/embeddedServiceConfigs/Teams_AgentForce.EmbeddedServiceConfig-meta.xml`.
156
+ The file/dir name **and** `<messagingChannel>` must be the channel's **metadata developer name**
157
+ (not its Id). `deploymentType` is **`API`** and `site` is left **null** — Teams stores the
158
+ Enhanced-chat custom-client deployment this way, so **no ESW Picasso site is required** (the Tooling
159
+ create of a *Web* ESD does need a platform-managed ESW site and fails `UNKNOWN_EXCEPTION` without
160
+ one — the Metadata `API`-type deploy sidesteps that entirely).
161
+
162
+ ```xml
163
+ <?xml version="1.0" encoding="UTF-8"?>
164
+ <EmbeddedServiceConfig xmlns="http://soap.sforce.com/2006/04/metadata">
165
+ <areGuestUsersAllowed>false</areGuestUsersAllowed>
166
+ <deploymentFeature>EmbeddedMessaging</deploymentFeature>
167
+ <deploymentType>API</deploymentType>
168
+ <embeddedServiceMessagingChannel>
169
+ <isChatInvitationCustomizable>false</isChatInvitationCustomizable>
170
+ <isEnabled>true</isEnabled>
171
+ <isInvitationEnabled>false</isInvitationEnabled>
172
+ <isSendInvtAllowedAfterAccept>false</isSendInvtAllowedAfterAccept>
173
+ <isSendInvtAllowedAfterReject>false</isSendInvtAllowedAfterReject>
174
+ <messagingChannel>Teams_AgentForce_Channel</messagingChannel>
175
+ <shouldShowAgentforceTagline>false</shouldShowAgentforceTagline>
176
+ <shouldShowDeliveryReceipts>false</shouldShowDeliveryReceipts>
177
+ <shouldShowEmojiSelection>false</shouldShowEmojiSelection>
178
+ <shouldShowReadReceipts>false</shouldShowReadReceipts>
179
+ <shouldShowTypingIndicators>false</shouldShowTypingIndicators>
180
+ <shouldStartNewLineOnEnter>false</shouldStartNewLineOnEnter>
181
+ </embeddedServiceMessagingChannel>
182
+ <isEnabled>true</isEnabled>
183
+ <isTermsAndConditionsEnabled>false</isTermsAndConditionsEnabled>
184
+ <isTermsAndConditionsRequired>false</isTermsAndConditionsRequired>
185
+ <masterLabel>Teams AgentForce</masterLabel>
186
+ <shouldHideAuthDialog>false</shouldHideAuthDialog>
187
+ </EmbeddedServiceConfig>
188
+ ```
189
+
190
+ > Replace `Teams_AgentForce_Channel` with **your channel's** dev name from §A. The ESD's own
191
+ > dev/file name must remain exactly **`Teams_AgentForce`** (Teams hard-codes `esDeveloperName`).
192
+
193
+ ```bash
194
+ sf project deploy start --metadata "EmbeddedServiceConfig:Teams_AgentForce" \
195
+ --target-org <org-alias> --api-version 67.0 --dry-run # validate
196
+ sf project deploy start --metadata "EmbeddedServiceConfig:Teams_AgentForce" \
197
+ --target-org <org-alias> --api-version 67.0 # deploy
198
+ ```
199
+
200
+ Get the ESD Id (Tooling):
201
+
202
+ ```text
203
+ SELECT Id, DeveloperName FROM EmbeddedServiceConfig WHERE DeveloperName='Teams_AgentForce'
204
+ ```
205
+
206
+ ### §D. Publish the ESD (Connect API — makes it live)
207
+
208
+ ```text
209
+ POST /services/data/v67.0/connect/embeddedservice/embeddedserviceconfig/publish/<esdId>
210
+ body: {}
211
+ # → 201 {"isSuccess": true}
212
+ ```
213
+
214
+ The publish endpoint is **v67.0** (it 404s at v62/v64). Check `isSuccess:true`; publish can take up
215
+ to ~10 minutes to propagate. Then **retest from a brand-NEW Teams chat** — existing sessions bind
216
+ to the prior config.
217
+
218
+ ### §E. The routing flow (`Route_To_MIAW_AEA`)
219
+
220
+ The channel's Omni-Flow target. When the agent is created via the **template-install path**, the org
221
+ already has a `Route_To_MIAW_AEA` `RoutingFlow` — but its `routeWork` action ships with **placeholder
222
+ ids** (e.g. `agentforceEmployeeAgentId=0Xxxx0000000001CAA`, `serviceChannelId=0N9xx…`, `queueId=00Gxx…`,
223
+ label "Agentforce HR Service Agent"). Left as-is it silently misroutes (agent joins then leaves).
224
+ **Repoint it to the real records before using the channel:**
225
+
226
+ 1. Retrieve: `sf project retrieve start --metadata "Flow:Route_To_MIAW_AEA"` (create `force-app/main/default`
227
+ + a minimal `sfdx-project.json` first).
228
+ 2. In `routeWork`, set:
229
+ - `agentforceEmployeeAgentId` → the **real** Active `BotDefinition` Id (`0Xx…`) — the same agent
230
+ the Agent Access permset (§G) enables; **these two MUST match**.
231
+ - `serviceChannelId` → real `sfdc_livemessage` `ServiceChannel` Id
232
+ (`SELECT Id FROM ServiceChannel WHERE DeveloperName='sfdc_livemessage'` — standard, pre-existing).
233
+ - `queueId` → the fallback queue's `Group` Id (§F).
234
+ - `agentforceEmployeeAgentLabel` → the real agent label (cosmetic).
235
+ 3. Deploy: `sf project deploy start --metadata "Flow:Route_To_MIAW_AEA"`. Deploying an Active flow
236
+ makes a **new active version** (`FlowDefinitionView.DurableId` — the channel's `SessionHandlerId`
237
+ — is unchanged; only `ActiveVersionId` bumps). Confirm:
238
+ `SELECT DurableId, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='Route_To_MIAW_AEA'`.
239
+
240
+ If **no** routing flow exists at all, author one from scratch — the load-bearing `routeWork`
241
+ input parameters (verified from a live working flow) are:
242
+
243
+ - `routingType` = `AgentforceEmployeeAgent`
244
+ - `agentforceEmployeeAgentId` = the real, Active `BotDefinition` Id (must match the Agent Access permset)
245
+ - `serviceChannelDevName` = `sfdc_livemessage`, `serviceChannelLabel` = `Messaging`
246
+ - `serviceChannelId` = the Messaging `ServiceChannel` Id; `queueId` = the fallback queue's `Group` Id
247
+ - `recordId` = `{!recordId}` (input variable, elementReference)
248
+
249
+ ```xml
250
+ <?xml version="1.0" encoding="UTF-8"?>
251
+ <Flow xmlns="http://soap.sforce.com/2006/04/metadata">
252
+ <apiVersion>65.0</apiVersion>
253
+ <actionCalls>
254
+ <name>routeWork</name>
255
+ <actionName>routeWork</actionName>
256
+ <actionType>routeWork</actionType>
257
+ <label>Route To MIAW AEA</label>
258
+ <flowTransactionModel>CurrentTransaction</flowTransactionModel>
259
+ <inputParameters>
260
+ <name>recordId</name>
261
+ <value><elementReference>recordId</elementReference></value>
262
+ </inputParameters>
263
+ <inputParameters>
264
+ <name>routingType</name>
265
+ <value><stringValue>AgentforceEmployeeAgent</stringValue></value>
266
+ </inputParameters>
267
+ <inputParameters>
268
+ <name>agentforceEmployeeAgentId</name>
269
+ <value><stringValue><REAL_ACTIVE_BOTDEFINITION_ID></stringValue></value>
270
+ </inputParameters>
271
+ <inputParameters>
272
+ <name>serviceChannelDevName</name>
273
+ <value><stringValue>sfdc_livemessage</stringValue></value>
274
+ </inputParameters>
275
+ <inputParameters>
276
+ <name>serviceChannelLabel</name>
277
+ <value><stringValue>Messaging</stringValue></value>
278
+ </inputParameters>
279
+ <inputParameters>
280
+ <name>serviceChannelId</name>
281
+ <value><stringValue><SERVICE_CHANNEL_ID></stringValue></value>
282
+ </inputParameters>
283
+ <inputParameters>
284
+ <name>queueId</name>
285
+ <value><stringValue><FALLBACK_QUEUE_GROUP_ID></stringValue></value>
286
+ </inputParameters>
287
+ <inputParameters>
288
+ <name>queueLabel</name>
289
+ <value><stringValue>chatqueue</stringValue></value>
290
+ </inputParameters>
291
+ </actionCalls>
292
+ <label>Route To MIAW AEA</label>
293
+ <processType>RoutingFlow</processType>
294
+ <start>
295
+ <connector><targetReference>routeWork</targetReference></connector>
296
+ </start>
297
+ <status>Active</status>
298
+ <variables>
299
+ <name>recordId</name>
300
+ <dataType>String</dataType>
301
+ <isInput>true</isInput>
302
+ <isCollection>false</isCollection>
303
+ <isOutput>false</isOutput>
304
+ </variables>
305
+ </Flow>
306
+ ```
307
+
308
+ A subtly-wrong `routeWork` param set silently misroutes — most commonly a **ghost/mismatched
309
+ `agentforceEmployeeAgentId`** (points at a deleted agent, or one the portal user's Agent Access
310
+ permset doesn't enable → "joins then leaves, no reply").
311
+
312
+ ### §F. The fallback queue (prerequisite of the routing flow)
313
+
314
+ The `routeWork` references a **queue** (`queueId`) as fallback. A "queue" is a `Group` of
315
+ `Type='Queue'` plus one `QueueSobject` per Messaging object it routes. Reuse an existing one if
316
+ present (`chatqueue`) — do not create a duplicate (`DeveloperName` must be unique;
317
+ `DUPLICATE_DEVELOPER_NAME` on a second `chatqueue`).
318
+
319
+ ```text
320
+ # reuse if it exists
321
+ SELECT Id, Name, DeveloperName, Type FROM Group WHERE Type='Queue' AND DeveloperName='chatqueue'
322
+
323
+ # else create the Group…
324
+ POST /services/data/v67.0/sobjects/Group body: {"Name":"chatqueue","DeveloperName":"chatqueue","Type":"Queue"}
325
+ # …then a QueueSobject per object (verified set: MessagingSession, MessagingEndUser, LiveChatTranscript)
326
+ POST /services/data/v67.0/sobjects/QueueSobject body: {"QueueId":"<00G…>","SobjectType":"MessagingSession"}
327
+ # repeat for MessagingEndUser and LiveChatTranscript
328
+
329
+ # verify (expect 3 rows)
330
+ SELECT Id, QueueId, SobjectType FROM QueueSobject WHERE QueueId='<00G…>'
331
+ ```
332
+
333
+ The Omni service channel `sfdc_livemessage` the flow references is **standard/pre-existing** — query,
334
+ don't create: `SELECT Id, DeveloperName, RelatedEntity FROM ServiceChannel WHERE DeveloperName='sfdc_livemessage'`.
335
+
336
+ ### §G. Agent Access permission set (required — the piece most often missing)
337
+
338
+ Routing delivers the work, but the **running portal user must be able to access the agent** or it
339
+ joins then immediately leaves with zero `ConversationEntry`.
340
+
341
+ - Create a dedicated permission set (label e.g. "Agent Access").
342
+ - Enable the **IT Service Employee Agent** under its **Agent Access** section. By API, this is a
343
+ `SetupEntityAccess` row keyed on the agent's `BotDefinition` Id (no `SetupEntityType` needed — it
344
+ auto-resolves). See the project memory note on granting embedded-agent access.
345
+ - **Assign the permission set to the portal user** (the user who signs in through Teams).
346
+
347
+ > **RBAC note.** Creating/assigning a permission set is a permission grant — get explicit user
348
+ > approval before assigning it, per standing policy.
349
+
350
+ ## Prerequisite: the IT Service Employee Agent must exist and be Active (two provisioning paths)
351
+
352
+ The whole recipe needs a **real, Active** `BotDefinition` with `AgentType='AgentforceEmployeeAgent'`
353
+ (query: `SELECT Id FROM BotDefinition WHERE AgentType='AgentforceEmployeeAgent'`, with an `Active`
354
+ `BotVersion`). Two ways it gets created — **verify live, don't assume**:
355
+
356
+ 1. **Feature-enable auto-provision (some orgs).** Enabling `service-cloud-it-service-employee-agent`
357
+ via `POST /connect/setup/discovery/feature/service-cloud-it-service-employee-agent/enable` kicks
358
+ off an async job that *may* create the agent, its ESD, an ESW Picasso `Site`, and its channel —
359
+ **not guaranteed** (verified: in one org the feature flipped `ENABLED` but provisioned nothing).
360
+ 2. **Explicit create + activate (reliable).** Use **`service-itsm-agentic-setup-employee-agent-configure`**
361
+ (reads the shipped Employee template's Agent Script and creates + publishes + activates the agent
362
+ as an NGA-native bundle). The equivalent underlying path is the ITSM Connect **agent-templates
363
+ install + activate** against `EmployeeCopilot__AgentforceEmployeeAgent`:
364
+ - `GET /connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent` — find
365
+ `EmployeeCopilot__AgentforceEmployeeAgent`; its `agentScript` is HTML-entity-encoded (unescape it).
366
+ - `POST /connect/service-itsm/agent-templates` with `agentConfigs:[{agentName, agentScript, companyDescription, templateId}]`
367
+ → creates + publishes (BotVersion starts **Inactive**).
368
+ - `POST /connect/service-itsm/activate-agents` with `{"agentTemplateIds":["EmployeeCopilot__AgentforceEmployeeAgent"]}`
369
+ → flips `BotVersion` to **Active**.
370
+ - Capture the new `BotDefinition` Id (`0Xx…`) — it is the `agentforceEmployeeAgentId` for the
371
+ routing flow **and** the agent the Agent Access permset (§G) enables; the two MUST match.
372
+
373
+ Deploy the agent first, then run this recipe to embed it in Teams.
374
+
375
+ ## Verify the chain via API (after publish + assignment)
376
+
377
+ ```text
378
+ # Channel active + routes
379
+ SELECT Id, DeveloperName, IsActive, SessionHandlerId, ChannelAddressIdentifier, MessageType
380
+ FROM MessagingChannel WHERE DeveloperName='<DevName>'
381
+ # IsActive=true; ChannelAddressIdentifier must match the channelAddId claim in the scrt2 token JWT.
382
+
383
+ # Routing flow targets a REAL, Active agent
384
+ SELECT DurableId, ApiName, ActiveVersionId FROM FlowDefinitionView WHERE DurableId='<SessionHandlerId>'
385
+ SELECT Id, FullName, Metadata FROM Flow WHERE Id='<ActiveVersionId>' (Tooling)
386
+ # → inputParameters[name=agentforceEmployeeAgentId].value.stringValue ← must be a real agent
387
+ SELECT Id FROM BotDefinition WHERE Id='<that id>' # ghost id → 0 rows
388
+ SELECT Id, DeveloperName, Status FROM BotVersion WHERE BotDefinitionId='<that id>' # need Status=Active
389
+
390
+ # ESD published + linked
391
+ GET /services/data/v67.0/tooling/sobjects/EmbeddedServiceConfig/<esdId>
392
+
393
+ # Key Set exists
394
+ SELECT Id FROM EmbeddedServiceConfig WHERE DeveloperName='Teams_AgentForce' (Tooling)
395
+
396
+ # Portal user actually has the agent enabled (Agent Access)
397
+ SELECT Id, PermissionSetId, AssigneeId FROM PermissionSetAssignment WHERE AssigneeId='<portalUserId>'
398
+ # One assigned set must be the "Agent Access" set that enables the IT Service Employee Agent.
399
+ ```
400
+
401
+ ## "Agent joins then leaves" (no reply) — diagnose, don't hand-wave
402
+
403
+ Work through these before escalating to the Agentforce team:
404
+
405
+ 1. **User Verification / Key Set mismatch.** If the scrt2 token call returns `BAD_REQUEST`
406
+ "Set the auth mode to false" and there is **no Key Set attached**, the client is on the
407
+ *unauthenticated* endpoint while the channel demands auth. **Attach a JWKS_URL Key Set (§B) and
408
+ link it into the channel (§A)** — do **not** turn auth off. Conversely, if a Key Set is attached
409
+ but its `jwksEndPoint`/`jwtIssuer` are wrong, the authenticated mint fails → 401 on
410
+ `/eventrouter/v1/sse`. Fix the endpoint (`<Org>/id/keys`) / issuer (Employee Site URL).
411
+ 2. **Portal user lacks Agent Access.** Tokens mint, SSE connects, but the agent joins then leaves
412
+ with no `ConversationEntry` → the running user cannot access the agent. Create + assign the
413
+ Agent Access permset (§G).
414
+ 3. **The `Teams_AgentForce` ESD does not exist** (`SELECT Id FROM EmbeddedServiceConfig WHERE
415
+ DeveloperName='Teams_AgentForce'` → 0 rows) — the Teams client can't load a missing deployment.
416
+ Create + publish it (§C/§D).
417
+ 4. **Routing flow points at a placeholder/ghost agent id** — repoint `Route_To_MIAW_AEA` (§E).
418
+
419
+ Diagnostic queries:
420
+
421
+ ```text
422
+ # Sessions on the channel
423
+ SELECT Id, Status, StartTime, EndTime, OwnerId, Origin, CreatedDate
424
+ FROM MessagingSession WHERE MessagingChannelId='<channelId>' ORDER BY CreatedDate DESC
425
+ # Broken: Status 'Waiting'/'Ended' quickly, OwnerId = the QUEUE (00G… Group), never the agent.
426
+ # Working: session goes Active and an agent-authored entry appears.
427
+
428
+ # Conversation entries — who actually spoke
429
+ SELECT Id, ConversationId, EntryType, ActorType, ActorName, CreatedDate
430
+ FROM ConversationEntry WHERE ConversationId='<messagingSessionId>' ORDER BY CreatedDate ASC
431
+ # Broken: zero entries (or only user entries). Working: an entry with ActorType=Agent/Bot
432
+ # ("IT Service Employee Agent") carrying the reply text.
433
+ ```
434
+
435
+ If the agent *still* won't reply after all of the above are confirmed (auth ON + Key Set linked,
436
+ Agent Access assigned, ESD created + published, flow points at the real Active agent), **delegate to
437
+ `service-itsm-teams-debug`** — its `AGENTFORCE` pass/fail checklist walks the whole
438
+ token/routing/ESD/agent chain — before handing off to the Agentforce Employee Agent team (agent Omni
439
+ presence / capacity / GenAI planner) as the last resort.
440
+
441
+ ## Gotchas index
442
+
443
+ Top runtime traps (build-time / API-mechanics issues are in the troubleshooting reference below).
444
+
445
+ | Issue | Fix |
446
+ |-------|-----|
447
+ | `/unauthenticated/access-token` → `BAD_REQUEST` "Set the auth mode to false." **and no Key Set attached** | The channel is auth-ON but the client fell back to the *unauthenticated* endpoint because no Key Set is linked. **Attach a `JWKS_URL` Key Set (§B) and link it into `<embeddedConfig><messagingAuthorizations>` (§A)** — do NOT turn auth off. |
448
+ | `GET /eventrouter/v1/sse` → **401** with a Key Set attached | The *authenticated* token mint failed — usually a wrong `jwksEndPoint` (must be `<Org>/id/keys`) or `jwtIssuer` (must be the Employee Site URL) on the Key Set. Fix §B and redeploy. |
449
+ | Key Set deploy: `'…' is not a valid value for the enum 'PublicKeyCertificateSetType'` | Use **`JWKS_URL`** (endpoint-URL mode). `Jwks` = uploaded-key mode (rejects `jwksEndPoint`). All camelCase guesses (`JwksUrl`, `JwksEndpoint`, `RemoteJwks`, `SelfSignedCert`, …) are invalid. |
450
+ | Key Set deploy: `TypeInferenceError` | Directory must be `PublicKeyCertificateSet/` and file suffix `.PublicKeyCertificateSet-meta.xml` (capital, singular). |
451
+ | `…/sobjects/PublicKeyCertificateSet/describe` → `NOT_FOUND` (data AND tooling) | This type has no REST describe surface. Confirm the enum from the Metadata API docs, not a describe call. |
452
+ | Channel deployed but `IsActive=false` | Activate before publishing the ESD: `sf data update record --sobject MessagingChannel --record-id <id> --values "IsActive=true"`. |
453
+ | Agent joins then leaves, no reply, empty `ConversationEntry`, session stays queue-owned | Portal user lacks **Agent Access** (§G), or the routing flow points at a placeholder/wrong agent id (§E). (First rule out the auth/Key-Set chain above.) |
454
+ | No agent exists even after enabling `service-cloud-it-service-employee-agent` | Feature auto-provisioning is **not guaranteed**. Fall back to `service-itsm-agentic-setup-employee-agent-configure` (or `agent-templates` install + `activate-agents`). Verify the agent + Active BotVersion by query. |
455
+ | `Route_To_MIAW_AEA` (template-installed) has **placeholder** `routeWork` ids | Retrieve → repoint `agentforceEmployeeAgentId`/`serviceChannelId`/`queueId`/label to real records → deploy (new active version; `DurableId`/`SessionHandlerId` unchanged). See §E. |
456
+ For build-time deployment and API-mechanics gotchas (ESD create/publish, naming, query surfaces),
457
+ see the next section.
458
+
459
+ ## Deployment & API-mechanics troubleshooting reference
460
+
461
+ Lower-frequency, build-time issues (distinct from the runtime failures in the Gotchas index above) —
462
+ kept here as a troubleshooting reference so the Gotchas index stays focused on the top runtime traps:
463
+
464
+ | Issue | Fix |
465
+ |-------|-----|
466
+ | ESD create via **Tooling** API fails `UNKNOWN_EXCEPTION` | Only the Tooling create of a Web/custom-client ESD needs a platform-managed ESW Picasso `Site`, and no Connect *create* route exists (only *publish*). Deploy an **`API`-type** ESD via **Metadata API** (`site: null`) and publish it — verified working. §C/§D. |
467
+ | ESD publish → `NOT_FOUND` | The publish endpoint is **v67.0**: `POST /services/data/v67.0/connect/embeddedservice/embeddedserviceconfig/publish/<esdId>` body `{}`. It 404s at v62/v64. |
468
+ | Deployment name must be exactly `Teams_AgentForce` | Teams hard-codes `esDeveloperName=Teams_AgentForce`. Cannot rename per-org; reuse the same DeveloperName if recreating. |
469
+ | ESD Metadata shows `deploymentType: API` even for the Web/custom-client wizard | Expected — the Enhanced-chat custom-client deployment is stored as `API` internally (`site: null`). Not a misconfiguration. |
470
+ | Publish shows "processing… up to 10 minutes" | Wait for propagation before retesting. |
471
+ | Old Teams chat still errors after the fix | Existing sessions bind to the old deployment/config. Always retest from a **brand-new** chat. |
472
+ | `MessagingChannel` not queryable via Tooling | It's a data-API object — query via `/services/data/vXX.0/query/`, not `/tooling/query/`. |
473
+ | `EmbeddedServiceConfig` not queryable via the data API | Query it via the **Tooling** API (`--use-tooling-api` / `/tooling/query`). |
474
+
475
+ ## Related SSO note
476
+
477
+ For the Teams app to resolve the Microsoft user to a Salesforce user, the MS `email` claim must
478
+ exactly equal a Salesforce `User.Username` (custom Apex handler `MsTeamsItsmSSOHandler`), and the
479
+ Azure redirect URI must be registered under the **"Web"** platform, not "Single-page application."
480
+ See `service-itsm-teams-configure` and the project memory note on SSO user mapping.