@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.
- package/package.json +1 -1
- package/skills/automation-flow-generate/SKILL.md +32 -43
- package/skills/experience-portal-create/SKILL.md +497 -0
- package/skills/experience-portal-create/assets/report-template.md +30 -0
- package/skills/experience-portal-create/references/mcp-invocation.md +288 -0
- package/skills/experience-portal-create/references/post-creation-activate-publish.md +165 -0
- package/skills/experience-portal-create/references/templates.md +253 -0
- package/skills/experience-ui-bundle-features-generate/SKILL.md +5 -1
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -0
- package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -0
- package/skills/platform-datamask-run/SKILL.md +345 -0
- package/skills/platform-datamask-run/references/api-surface.md +130 -0
- package/skills/platform-datamask-run/references/policy-authoring.md +185 -0
- package/skills/platform-datamask-run/references/run-and-abort.md +116 -0
- package/skills/platform-datamask-run/scripts/poll-job.sh +115 -0
- package/skills/platform-dataspace-access-configure/SKILL.md +51 -3
- package/skills/platform-dataspace-access-configure/scripts/inspect-dataspace-scopes.sh +56 -0
- package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +1 -0
- package/skills/platform-sandbox-configure/SKILL.md +17 -2
- package/skills/platform-trial-org-create/SKILL.md +175 -0
- package/skills/platform-trial-org-create/examples/create_request.json +9 -0
- package/skills/platform-trial-org-create/examples/error_response.json +41 -0
- package/skills/platform-trial-org-create/examples/success_response.json +27 -0
- package/skills/platform-trial-org-create/references/error_codes.md +42 -0
- package/skills/platform-trial-org-create/references/signup_request_fields.md +69 -0
- package/skills/platform-trial-org-create/scripts/create_signup_request.sh +175 -0
- package/skills/platform-trial-org-create/scripts/get_signup_request.sh +155 -0
- package/skills/platform-widget-generate/SKILL.md +47 -6
- package/skills/platform-widget-generate/examples/conditional.json +3 -3
- package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
- package/skills/platform-widget-generate/examples/single-object.json +2 -2
- package/skills/platform-widget-generate/references/widget-bundle-layout.md +1 -1
- package/skills/service-agentforce-channel-configure/SKILL.md +271 -0
- package/skills/service-agentforce-channel-configure/references/agent-wiring.md +97 -0
- package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +145 -0
- package/skills/service-agentforce-channel-configure/references/channel-branch-voice.md +69 -0
- package/skills/service-agentforce-channel-configure/references/channel-types.md +61 -0
- package/skills/service-agentforce-channel-configure/references/live-traffic-gate.md +86 -0
- package/skills/service-agentforce-channel-configure/references/queue-resolution.md +135 -0
- package/skills/service-agentforce-channel-configure/references/routing-flow.md +384 -0
- package/skills/service-catalog-template-deploy/SKILL.md +310 -0
- package/skills/service-catalog-template-deploy/references/cli-invocation.md +258 -0
- package/skills/service-catalog-template-deploy/scripts/activate-verify.mjs +164 -0
- package/skills/service-catalog-template-deploy/scripts/build-deploy-payload.mjs +94 -0
- package/skills/service-catalog-template-deploy/scripts/resolve-template.mjs +331 -0
- package/skills/service-catalog-template-search/SKILL.md +212 -0
- package/skills/service-catalog-template-search/references/cli-invocation.md +128 -0
- package/skills/service-catalog-template-search/scripts/classify-catalog.mjs +205 -0
- package/skills/service-concierge-portal-generate/SKILL.md +126 -0
- package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1428 -0
- package/skills/service-digital-engagement-channel-configure/SKILL.md +46 -6
- package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +2 -1
- package/skills/service-digital-engagement-channel-configure/examples/asa_agent_channel.xml +4 -1
- package/skills/service-helpagent-coordinate/README.md +8 -2
- package/skills/service-helpagent-coordinate/SKILL.md +126 -130
- package/skills/service-helpagent-coordinate/assets/help-agent-spec.md +70 -53
- package/skills/service-helpagent-coordinate/references/agent-script.md +571 -457
- package/skills/service-helpagent-coordinate/references/channel-voice.md +38 -9
- package/skills/service-helpagent-coordinate/references/channel-web-chat.md +173 -49
- package/skills/service-helpagent-coordinate/references/output-report-format.md +126 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +153 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +79 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +35 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +271 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +265 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +220 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-final-report.mjs +102 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/record-enable-result.mjs +73 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +206 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +194 -0
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +223 -0
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +45 -7
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +45 -5
- package/skills/service-itsm-agentic-setup-configure/SKILL.md +116 -0
- package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +64 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +158 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md +361 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/error-taxonomy.md +44 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/reactivation.md +66 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +66 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/specialized-templates.md +148 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +169 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/build-create-body.mjs +116 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-agent-existence.mjs +185 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-preflight.mjs +168 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/create-scratch-dir.mjs +58 -0
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +197 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +186 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +51 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/cli-invocation.md +345 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/error-taxonomy.md +44 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/reactivation.md +63 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +44 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +149 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +110 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +201 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-activate-result.mjs +135 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-agent-existence.mjs +194 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-preflight.mjs +158 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/create-scratch-dir.mjs +58 -0
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +191 -0
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +133 -0
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +71 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +308 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +23 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +193 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +57 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +394 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +266 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +106 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +142 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +82 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-action-surface.mjs +137 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-assignment-state.mjs +99 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +120 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/resolve-target-user.mjs +86 -0
- package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +284 -0
- package/skills/service-itsm-agentic-setup-uel-user-create/references/mcp-invocation.md +302 -0
- package/skills/service-itsm-channels-coordinate/SKILL.md +472 -0
- package/skills/service-itsm-incident-mgmt-configure/SKILL.md +212 -0
- package/skills/service-itsm-incident-mgmt-configure/references/mcp-invocation.md +225 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +53 -12
- package/skills/service-itsm-swarming-configure/SKILL.md +212 -0
- package/skills/service-itsm-teams-configure/SKILL.md +395 -0
- package/skills/service-itsm-teams-configure/references/azure-credential-population.md +213 -0
- package/skills/service-itsm-teams-configure/references/gotchas.md +23 -0
- package/skills/service-itsm-teams-coordinate/SKILL.md +175 -0
- package/skills/service-itsm-teams-coordinate/examples/output-templates.md +85 -0
- package/skills/service-itsm-teams-debug/SKILL.md +144 -0
- package/skills/service-itsm-teams-debug/references/configuration-checklists.md +277 -0
- package/skills/service-itsm-teams-debug/references/report-generation.md +95 -0
- package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +139 -0
- package/skills/service-itsm-teams-employee-agent-configure/assets/Teams_AgentForce.EmbeddedServiceConfig-meta.xml +43 -0
- package/skills/service-itsm-teams-employee-agent-configure/references/teams-embedded-employee-agent.md +480 -0
- package/skills/service-itsm-teams-itdesk-configure/SKILL.md +232 -0
- package/skills/service-itsm-teams-itservice-configure/SKILL.md +391 -0
package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md
ADDED
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# CLI invocation reference — Create an IT Service Employee Agent (broad or specialized)
|
|
2
|
+
|
|
3
|
+
This skill uses the **Salesforce CLI (`sf`)** as its only transport:
|
|
4
|
+
`sf api request rest` for the NGA Connect API reads/writes, `sf data query` for the
|
|
5
|
+
`BotDefinition` idempotency + verify SOQL, and two Node helper scripts for the
|
|
6
|
+
deterministic decisions. It extracts no access tokens.
|
|
7
|
+
|
|
8
|
+
The agent is created as a **Next-Gen Authoring (NGA) native agent** via the
|
|
9
|
+
`/nextgen-authoring/*` Connect API — **not** via the legacy
|
|
10
|
+
`/connect/service-itsm/createAgent` route. That legacy route creates a
|
|
11
|
+
Setup-page bot that shows an external-link icon in Agentforce Studio and is
|
|
12
|
+
also listed on the old Setup > Agentforce Agents page; the NGA bundle pipeline
|
|
13
|
+
below produces an agent that is native to Agentforce Studio's Agents list with
|
|
14
|
+
no external-link icon, matching the platform's own Employee agents.
|
|
15
|
+
|
|
16
|
+
**Broad vs specialized:** the `agent-templates?agentType=AgentforceEmployeeAgent`
|
|
17
|
+
endpoint returns the broad `IT Service Employee` template plus ~78 specialized
|
|
18
|
+
Employee templates as siblings in `data[]`. This flow is byte-identical between
|
|
19
|
+
the two — the only difference is which `masterLabel` is passed to the
|
|
20
|
+
classifier and the body-builder (Phase 1 and Phase 4). See
|
|
21
|
+
`../references/specialized-templates.md` for the picker menu and the exclusion
|
|
22
|
+
list (non-Employee entries the endpoint leaks in).
|
|
23
|
+
|
|
24
|
+
## Why `sf api request rest` / `sf data query`, never curl + token
|
|
25
|
+
|
|
26
|
+
Both commands authenticate using the CLI's stored session for the
|
|
27
|
+
`--target-org` alias — the CLI mints/refreshes the token internally and never
|
|
28
|
+
exposes it. **Do not** do:
|
|
29
|
+
|
|
30
|
+
<!-- skill-validate: ignore -->
|
|
31
|
+
```bash
|
|
32
|
+
# FORBIDDEN — leaks a bearer token into shell context, bypasses the CLI session
|
|
33
|
+
TOKEN=$(sf org display --json -o <alias> | jq -r '.result.accessToken')
|
|
34
|
+
curl -X POST -H "Authorization: Bearer $TOKEN" .../nextgen-authoring/bundles
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Every call this skill makes is a plain `/services/data/v67.0/...` Connect API or
|
|
38
|
+
`/query` path — exactly what `sf api request rest` and `sf data query` proxy.
|
|
39
|
+
There is no reason to fall back to curl.
|
|
40
|
+
|
|
41
|
+
## Target org, API version, and the `--json` split
|
|
42
|
+
|
|
43
|
+
- **Target org**: always `--target-org <alias>` (or `-o <alias>`). Resolve the
|
|
44
|
+
alias from the user or the default org (`sf config get target-org`).
|
|
45
|
+
- **API version**: pinned in the URL path (`/services/data/v67.0/...`). Do not
|
|
46
|
+
hand-edit it below `metadata.minApiVersion` (`67.0`).
|
|
47
|
+
- **`--json` rule** — the two commands differ:
|
|
48
|
+
- `sf api request rest` prints the **raw** Connect response body to stdout;
|
|
49
|
+
do **not** add `--json` (it is unsupported on some Connect endpoints and
|
|
50
|
+
errors). The stdout body is already JSON.
|
|
51
|
+
- `sf data query --json` **does** wrap results in a `{status, result:{records[]}}`
|
|
52
|
+
envelope — that envelope is exactly what `scripts/classify-agent-existence.mjs`
|
|
53
|
+
expects. Always pass `--json` to `sf data query`.
|
|
54
|
+
|
|
55
|
+
## Thread the collected developerName / label through EVERY call
|
|
56
|
+
|
|
57
|
+
The `<developerName>` and `<label>` are collected from the user (defaults
|
|
58
|
+
`IT_Service_Employee_Agent` / `IT Service Employee Agent`). The **same**
|
|
59
|
+
`<developerName>` must appear in the idempotency SOQL, the `createBundleWithVersion`
|
|
60
|
+
body's outer `apiName` AND its `resourceContent`'s internal `config.developer_name`,
|
|
61
|
+
and the verify SOQL — otherwise a custom name creates one agent while the
|
|
62
|
+
idempotency/verify reads check a different one, or the bundle's outer identity
|
|
63
|
+
diverges from the script's internal identity.
|
|
64
|
+
|
|
65
|
+
## The source content — the legacy template's `agentScript` field
|
|
66
|
+
|
|
67
|
+
The legacy `agent-templates` read (still used, read-only) returns each
|
|
68
|
+
template's full **Agent Script** (AFScript) in an `agentScript` field,
|
|
69
|
+
HTML-entity-encoded (sometimes double-encoded). This is the SAME content
|
|
70
|
+
format an NGA bundle version's `resourceContent` expects — there is no
|
|
71
|
+
separate "NGA template catalog" endpoint; the fix simply routes this existing
|
|
72
|
+
read's content into the NGA bundle pipeline instead of the legacy
|
|
73
|
+
`createAgent` call.
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
GET /services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Response: `{data:[{id, masterLabel, agentScript, isInstalled, isActivated, botDefinitionId, ...}]}` — 79 entries on a fully-provisioned org (the broad `IT Service Employee` template + ~78 specialized Employee templates as siblings).
|
|
80
|
+
The classifier (`scripts/classify-preflight.mjs`) finds the item whose
|
|
81
|
+
`masterLabel` matches the resolved target (`"IT Service Employee"` for the
|
|
82
|
+
default broad path, or the picked specialized `masterLabel` for a specialized
|
|
83
|
+
path) and confirms `agentScript` is a non-empty string. `scripts/build-create-body.mjs`
|
|
84
|
+
re-reads the same captured file, re-locates the match, and does the actual
|
|
85
|
+
decode + substitution (see below) — the classifier only confirms presence, it
|
|
86
|
+
does not re-emit the ~70KB script content on stdout.
|
|
87
|
+
|
|
88
|
+
## The NGA Connect API
|
|
89
|
+
|
|
90
|
+
All three calls live under `/nextgen-authoring/`, owning team **Agentforce
|
|
91
|
+
Platform**. Org access check: `NextGenAuthoring.orgHasNextGenAgentAuthoringEnabled
|
|
92
|
+
&& NextGenAuthoring.userCanAccessNextGenAgentAuthoring`. User access check:
|
|
93
|
+
`NextGenAuthoring.userCanAccessAuthoringBundle` (create) /
|
|
94
|
+
`NextGenAuthoring.userCanEditAuthoringBundle` (publish/activate).
|
|
95
|
+
|
|
96
|
+
| Route | Method | Purpose |
|
|
97
|
+
|-------|--------|---------|
|
|
98
|
+
| `/services/data/v67.0/nextgen-authoring/bundles` | POST | `createBundleWithVersion` — create the bundle + its first DRAFT version from an Agent Script |
|
|
99
|
+
| `/services/data/v67.0/nextgen-authoring/bundle-versions/{bundleVersionId}/publish` | POST | `publishBundleVersion` — publish the version, creating the underlying `BotDefinition`/`BotVersion` |
|
|
100
|
+
| `/services/data/v67.0/nextgen-authoring/bundle-versions/{bundleVersionId}/activate` | POST | `activateBundleVersion` — activate the published version |
|
|
101
|
+
| `/services/data/v67.0/nextgen-authoring/bundles` | GET | List bundles (optional post-hoc check for `isLegacy:false`) |
|
|
102
|
+
|
|
103
|
+
> **The legacy `createAgent` / `create-agents` / `activate-agents` routes under
|
|
104
|
+
> `/connect/service-itsm/` are NOT part of this flow.** They create a
|
|
105
|
+
> Setup-page bot with an external-link icon in Agentforce Studio — the wrong
|
|
106
|
+
> kind of agent. Do not fall back to them even on an NGA-route error; surface
|
|
107
|
+
> the error and stop instead.
|
|
108
|
+
|
|
109
|
+
## Preflight — Studio access + template's Agent Script presence (one classifier)
|
|
110
|
+
|
|
111
|
+
Capture both reads, then let `scripts/classify-preflight.mjs` make the
|
|
112
|
+
deterministic decisions (do not read `hasAccess` or search `data[]` in prose — A9):
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" \
|
|
116
|
+
--method GET --target-org <alias> > ${SCRATCH_DIR}/studio-access.json 2>${SCRATCH_DIR}/studio-access.err || true
|
|
117
|
+
sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" \
|
|
118
|
+
--method GET --target-org <alias> > ${SCRATCH_DIR}/agent-templates.json 2>${SCRATCH_DIR}/agent-templates.err || true
|
|
119
|
+
node "<skill_dir>/scripts/classify-preflight.mjs" ${SCRATCH_DIR}/studio-access.json ${SCRATCH_DIR}/agent-templates.json "<masterLabel>"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Pass the resolved `<masterLabel>` — `"IT Service Employee"` for the default
|
|
123
|
+
broad path, or the picked specialized `masterLabel` (e.g. `"Password Manager Assistance"`)
|
|
124
|
+
for a specialized path. The classifier matches `data[]` on `masterLabel`
|
|
125
|
+
case-insensitively.
|
|
126
|
+
|
|
127
|
+
**Studio access** body: `{ "hasAccess": true, "productName": "Agents" }`. The
|
|
128
|
+
classifier maps `hasAccess=true`→PASS, `false`→FAIL (offer the hand-off to
|
|
129
|
+
`service-itsm-agentic-setup-agentforce-studio-validate`), a **confirmed** `404`
|
|
130
|
+
(gate not wired, expected on scratch orgs)→CANNOT-CONFIRM (does not block — a
|
|
131
|
+
successful create/publish/activate is authoritative), and any other parseable
|
|
132
|
+
error body (`401`/`403`/unexpected)→**ERROR** (surface the raw response and
|
|
133
|
+
stop — do not treat an auth/permission failure as an unwired gate). The
|
|
134
|
+
product in the path must be `Agents` (any other value ⇒ `400 Invalid product name`).
|
|
135
|
+
|
|
136
|
+
**agent-templates**: the `agentType` query param is **required** — omitting it
|
|
137
|
+
returns `400 MISSING_ARGUMENT: agentType`; the value is `AgentforceEmployeeAgent`
|
|
138
|
+
for every Employee template (broad OR specialized — a wrong value returns an
|
|
139
|
+
empty `data[]`, since specialized Employee templates are siblings in the same
|
|
140
|
+
response, not behind different `agentType`s). The classifier finds the item
|
|
141
|
+
whose `masterLabel` matches the label arg — either the default broad
|
|
142
|
+
`"IT Service Employee"` or a user-picked specialized `masterLabel` from
|
|
143
|
+
`../references/specialized-templates.md` — and confirms its `agentScript`
|
|
144
|
+
field is a non-empty string; that field, not `id`, is what Phase 4 consumes.
|
|
145
|
+
Empty/no-match `data[]` ⇒ `template.signal=FAIL`; a `404` ⇒ CANNOT-CONFIRM —
|
|
146
|
+
hand off to the readiness check; a match with no/empty `agentScript` ⇒
|
|
147
|
+
CANNOT-CONFIRM (nothing to build the NGA bundle from).
|
|
148
|
+
|
|
149
|
+
Classifier output:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"studio": { "hasAccess": true, "signal": "PASS|FAIL|CANNOT-CONFIRM|ERROR", "reason": "..." },
|
|
154
|
+
"template": { "present": true, "id": "svc_emp_intelligence__ItEmployeeAssistance", "hasAgentScript": true, "botDefinitionId": "0Xx...", "signal": "PASS|FAIL|CANNOT-CONFIRM", "reason": "..." },
|
|
155
|
+
"verdict": "READY | NOT-READY | CANNOT-CONFIRM | ERROR",
|
|
156
|
+
"reasons": ["..."]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`template.botDefinitionId` is copied from the matched `agent-templates` row. **`botDefinitionId` is the PRIMARY Phase-2 idempotency key** — a populated value means the template has already been instantiated into a live `BotDefinition` (the broad Employee agent ships pre-provisioned this way); `null` means either it has not been created yet OR it was created by this skill (a self-created agent never back-fills the template row — see Phase 2). Capture `botDefinitionId` for the Phase-2 read below and always carry the collected `<developerName>` as the fallback key. (`isInstalled`/`isActivated` are no longer emitted: they ride the same AgentTemplate join as `botDefinitionId`, so they read false for self-created agents and nothing consumes them.)
|
|
161
|
+
|
|
162
|
+
`verdict=ERROR` (`studio.signal="ERROR"` — a parseable non-404 Studio-access
|
|
163
|
+
error, e.g. `401`/`403`) ⇒ surface the raw error and stop; takes priority over
|
|
164
|
+
template state so a present template cannot outrun a failed prerequisite read.
|
|
165
|
+
`verdict=NOT-READY` (studio FAIL or template FAIL) ⇒ hand off / stop.
|
|
166
|
+
`verdict=READY` ⇒ proceed to Phase 2. It exits `0` on usable args.
|
|
167
|
+
|
|
168
|
+
## Enumerate the existing agent — SOQL on `BotDefinition` BY Id (falling back to DeveloperName)
|
|
169
|
+
|
|
170
|
+
Idempotency is keyed **PRIMARILY** on the template's `botDefinitionId` (from the
|
|
171
|
+
Phase-1 row) and **FALLS BACK** to the collected `<developerName>`. The broad
|
|
172
|
+
"IT Service Employee" agent ships pre-provisioned+active under DeveloperName
|
|
173
|
+
`IT_Service_Employee`, which never matches this skill's default guess
|
|
174
|
+
`IT_Service_Employee_Agent`; a name-only read false-negatives on THAT agent
|
|
175
|
+
(`exists:false`) and the create then collides on `apiName` with
|
|
176
|
+
`DUPLICATE_VALUE` — so `botDefinitionId` (the platform's authoritative link from
|
|
177
|
+
the template to the `BotDefinition` it was instantiated into) is the primary key.
|
|
178
|
+
But that link is back-filled onto the template row **only** for pre-provisioned
|
|
179
|
+
agents: an agent THIS skill creates never stamps `templateName`, so its template
|
|
180
|
+
`botDefinitionId` stays `null` on every later read. For that self-created case a
|
|
181
|
+
`DeveloperName`-keyed read is the reliable guard — so use it as the fallback,
|
|
182
|
+
never short-circuit straight to create when `botDefinitionId` is absent.
|
|
183
|
+
|
|
184
|
+
- **`botDefinitionId` empty/null** (template row never joined — either not
|
|
185
|
+
created yet, or created by this skill) ⇒ fall back to a DeveloperName-keyed
|
|
186
|
+
read and let the classifier match on it:
|
|
187
|
+
```bash
|
|
188
|
+
sf data query -q "SELECT Id,DeveloperName,MasterLabel,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE DeveloperName='<developerName>'" \
|
|
189
|
+
--target-org <alias> --json > ${SCRATCH_DIR}/bot-existing.json 2>${SCRATCH_DIR}/bot-existing.err || true
|
|
190
|
+
node "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-existing.json "" "<developerName>"
|
|
191
|
+
```
|
|
192
|
+
- **`botDefinitionId` present** ⇒ read the `BotDefinition` by Id **`OR` by the
|
|
193
|
+
collected `<developerName>`** in one query, then classify. The `OR DeveloperName=`
|
|
194
|
+
clause catches a **dangling** link — a `botDefinitionId` whose target row was
|
|
195
|
+
since deleted: the by-Id half returns nothing, the live same-name agent still
|
|
196
|
+
surfaces, and the classifier falls back to it (`matchedBy:"developerName"`)
|
|
197
|
+
rather than concluding `exists:false` and colliding with `DUPLICATE_VALUE`:
|
|
198
|
+
```bash
|
|
199
|
+
sf data query -q "SELECT Id,DeveloperName,MasterLabel,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE Id='<botDefinitionId>' OR DeveloperName='<developerName>'" \
|
|
200
|
+
--target-org <alias> --json > ${SCRATCH_DIR}/bot-existing.json 2>${SCRATCH_DIR}/bot-existing.err || true
|
|
201
|
+
node "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-existing.json "<botDefinitionId>" "<developerName>"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Only when **both** `botDefinitionId` and `<developerName>` are absent does the
|
|
205
|
+
classifier return `exists:false` without reading a query file — in practice the
|
|
206
|
+
collected `<developerName>` is always present, so the fallback read always runs.
|
|
207
|
+
|
|
208
|
+
The `BotVersions` subquery (child relationship on `BotDefinition`) is what lets
|
|
209
|
+
the classifier see the latest version's `Status` — omit it and
|
|
210
|
+
`latestVersionStatus`/`needsActivation` come back `null`/`false` even when the
|
|
211
|
+
existing agent is actually inactive. The classifier prints
|
|
212
|
+
`{ exists, count, matchedBy, agentId, botDefinitionId, developerName, latestVersionId, latestVersionStatus, needsActivation }`
|
|
213
|
+
(`matchedBy` is `"botDefinitionId"` | `"developerName"` | `null`; `developerName`
|
|
214
|
+
is the ACTUAL live agent's DeveloperName read from the record — surface it in the
|
|
215
|
+
report instead of the collected guess):
|
|
216
|
+
- `exists:false` ⇒ proceed to create.
|
|
217
|
+
- `exists:true` and `needsActivation:false` (latest version `Active`) ⇒
|
|
218
|
+
**ALREADY-CREATED** (skip the entire create/publish/activate sequence).
|
|
219
|
+
- `exists:true` and `needsActivation:true` (latest version `Inactive`) ⇒ do
|
|
220
|
+
**not** create a duplicate — take the reactivation path documented in
|
|
221
|
+
`references/reactivation.md` (direct `BotVersion` activation, skips
|
|
222
|
+
create + publish).
|
|
223
|
+
- **Exit 3** ⇒ the query itself failed (auth error, malformed SOQL) — surface
|
|
224
|
+
the raw CLI error and stop; do **not** assume the agent is absent.
|
|
225
|
+
|
|
226
|
+
On any `exists:true` hit reached via the `matchedBy:"developerName"` fallback
|
|
227
|
+
(the template `botDefinitionId` was `null`, or present-but-dangling), Phase 7
|
|
228
|
+
verifies the agent using the classifier's returned live `agentId` /
|
|
229
|
+
`botDefinitionId` — the actual matched `BotDefinition.Id` — **never** the Phase-1
|
|
230
|
+
template `botDefinitionId`, so the verify read never degrades to `WHERE Id=''`
|
|
231
|
+
and never false-fails after a successful skip or reactivation.
|
|
232
|
+
|
|
233
|
+
Use the skill's **absolute** `<skill_dir>` in the `node` invocation — a bare
|
|
234
|
+
`./scripts/...` resolves against the shell CWD, not the skill dir.
|
|
235
|
+
|
|
236
|
+
## Create the NGA bundle — `createBundleWithVersion`
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
node "<skill_dir>/scripts/build-create-body.mjs" ${SCRATCH_DIR}/agent-templates.json "<masterLabel>" "<developerName>" "<label>" ${SCRATCH_DIR}/create-bundle-body.json
|
|
240
|
+
sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" \
|
|
241
|
+
--method POST \
|
|
242
|
+
--body @${SCRATCH_DIR}/create-bundle-body.json \
|
|
243
|
+
--target-org <alias> > ${SCRATCH_DIR}/create-bundle.json 2>${SCRATCH_DIR}/create-bundle.err || true
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Pass the same resolved `<masterLabel>` used in Phase 1 (broad or specialized).
|
|
247
|
+
`build-create-body.mjs` re-reads `${SCRATCH_DIR}/agent-templates.json` (the SAME file
|
|
248
|
+
captured in Phase 1), re-locates the item whose `masterLabel` matches the arg
|
|
249
|
+
(case-insensitive), and:
|
|
250
|
+
1. Fully HTML-decodes its `agentScript` — named entities (`&`, `"`,
|
|
251
|
+
`'`, `<`, `>`) AND numeric entities (`&#(\d+);` →
|
|
252
|
+
`String.fromCharCode`), applied in a loop (up to 4 passes) to fully unwind
|
|
253
|
+
double-encoding. A naive single-pass decode leaves artifacts (e.g.
|
|
254
|
+
`&quot;`, an undecoded `\` for a literal backslash) that break
|
|
255
|
+
AFScript parsing.
|
|
256
|
+
2. Substitutes the script's `config.developer_name` / `config.agent_label`
|
|
257
|
+
with the collected `<developerName>` / `<label>` via a regex replace on the
|
|
258
|
+
`developer_name: "..."` / `agent_label: "..."` lines. If either
|
|
259
|
+
substitution doesn't land (pattern not found), the script exits 3 rather
|
|
260
|
+
than silently building a body with the wrong internal identity.
|
|
261
|
+
3. Writes `{ apiName: <developerName>, label: <label>, assets: [{ resourceName:
|
|
262
|
+
"agentDefinition", resourceType: "agentDefinition", sections: [],
|
|
263
|
+
resourceContent: <decoded+substituted script> }] }` to the output path.
|
|
264
|
+
|
|
265
|
+
Response on success — a bundle-version detail:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"apiName": "IT_Service_Employee_Agent",
|
|
270
|
+
"label": "IT Service Employee Agent",
|
|
271
|
+
"bundleId": "1bY...",
|
|
272
|
+
"id": "1bZ...",
|
|
273
|
+
"versionStatus": "DRAFT",
|
|
274
|
+
"assets": [ { "resourceName": "agentDefinition", "resourceType": "agentDefinition", "resourceContent": "...", "sections": [] } ],
|
|
275
|
+
"publishedBotId": null,
|
|
276
|
+
"publishedBotVersionId": null
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Capture `id` — that is the `bundleVersionId`** used in the publish/activate
|
|
281
|
+
calls below. `bundleId` is the bundle's own Id, not the version's; passing it
|
|
282
|
+
to `/bundle-versions/{...}` returns a 404.
|
|
283
|
+
|
|
284
|
+
Common errors:
|
|
285
|
+
|
|
286
|
+
| HTTP | Error code | Meaning | Action |
|
|
287
|
+
|------|-----------|---------|--------|
|
|
288
|
+
| 403 / 404 | `FUNCTIONALITY_NOT_ENABLED` / not found | NGA authoring namespace not provisioned on the org | Trigger the Phase-1 hand-off — `AskUserQuestion` → on Yes delegate to `service-itsm-agentic-setup-agentforce-studio-validate` |
|
|
289
|
+
| (script exit 3) | — | `build-create-body.mjs` couldn't find the template / its `agentScript` / couldn't substitute developer_name or agent_label in `${SCRATCH_DIR}/agent-templates.json` | Surface the script's stderr verbatim; re-verify Phase 1's `template.hasAgentScript:true` rather than hand-typing a body |
|
|
290
|
+
|
|
291
|
+
## Publish the bundle version — `publishBundleVersion`
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/publish" \
|
|
295
|
+
--method POST --body '{}' \
|
|
296
|
+
--target-org <alias> > ${SCRATCH_DIR}/publish-bundle.json 2>${SCRATCH_DIR}/publish-bundle.err || true
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Path param only — the body is ignored by the endpoint but `--body '{}'` is
|
|
300
|
+
still required (see Gotchas). Response on success:
|
|
301
|
+
|
|
302
|
+
```json
|
|
303
|
+
{ "lastPublishedOn": "2026-08-05T01:22:54.278Z", "publishedBotId": "0Xx...", "publishedBotVersionId": "0X9..." }
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
This is the call that creates the underlying `BotDefinition`/`BotVersion`. An
|
|
307
|
+
error here means the DRAFT version failed platform-side validation.
|
|
308
|
+
|
|
309
|
+
## Activate the bundle version — `activateBundleVersion`
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/activate" \
|
|
313
|
+
--method POST --body '{}' \
|
|
314
|
+
--target-org <alias> > ${SCRATCH_DIR}/activate-bundle.json 2>${SCRATCH_DIR}/activate-bundle.err || true
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Success returns an **empty response body** (`EmptyRepresentation`) — do not
|
|
318
|
+
treat empty stdout as a failure signal. Check the CLI exit code, then confirm
|
|
319
|
+
success via the Phase-7 `BotDefinition`/`BotVersion` verify read, not by
|
|
320
|
+
parsing this call's output.
|
|
321
|
+
|
|
322
|
+
## Verify the agent is live — SOQL on `BotDefinition` BY Id
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
sf data query -q "SELECT Id,DeveloperName,MasterLabel,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE Id='<verifyId>'" \
|
|
326
|
+
--target-org <alias> --json > ${SCRATCH_DIR}/bot-verify.json 2>${SCRATCH_DIR}/bot-verify.err || true
|
|
327
|
+
node "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-verify.json "<verifyId>"
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
The verify `<verifyId>` is the create path's **`publishedBotId`** (captured from
|
|
331
|
+
the Phase-5 publish response) or, on the ALREADY-CREATED / reactivation path, the
|
|
332
|
+
**live matched Id the Phase-2 classifier returned** (its `botDefinitionId` /
|
|
333
|
+
`agentId` output — the actual `BotDefinition.Id` of the matched record) — **not**
|
|
334
|
+
the Phase-1 template `botDefinitionId`, which is `null` on a
|
|
335
|
+
`matchedBy:"developerName"` fallback hit (using it would run the verify as
|
|
336
|
+
`WHERE Id=''` and falsely report failure after a successful skip/activation).
|
|
337
|
+
Never the collected `<developerName>`.
|
|
338
|
+
Confirm `exists:true` with `count:1`, and — whether the create or the
|
|
339
|
+
reactivation path was taken — `latestVersionStatus:"Active"`. `exists:false`
|
|
340
|
+
after a successful activate ⇒
|
|
341
|
+
report the discrepancy verbatim, do not fabricate success. Optionally
|
|
342
|
+
cross-check
|
|
343
|
+
`GET /services/data/v67.0/nextgen-authoring/bundles` for an entry with
|
|
344
|
+
`apiName=<developerName>` and `isLegacy:false` — this is the same shape as the
|
|
345
|
+
platform's own "IT Service Employee Agent" entry and confirms the created
|
|
346
|
+
agent is NGA-native (no external-link icon in Agentforce Studio).
|
|
347
|
+
|
|
348
|
+
## Idempotency semantics
|
|
349
|
+
|
|
350
|
+
The full `ALREADY-CREATED` / `ACTIVATED` / `CREATED` verdict table (Phase-2
|
|
351
|
+
classifier signal → verdict) — plus the note on how the Phase-2 SOQL read turns
|
|
352
|
+
the server's `DeveloperName`-keyed duplicate rejection into a graceful skip —
|
|
353
|
+
lives in `references/reactivation.md`.
|
|
354
|
+
|
|
355
|
+
## Errors and gotchas
|
|
356
|
+
|
|
357
|
+
The response-body error codes each phase can return (auth, `FUNCTIONALITY_NOT_ENABLED`,
|
|
358
|
+
missing `agentType`, build-script exit codes, empty-response semantics) and the
|
|
359
|
+
recurring foot-guns (legacy-`createAgent`, `--body '{}'`, `bundleId` vs
|
|
360
|
+
`bundleVersionId`, multi-pass HTML decode, threading the collected
|
|
361
|
+
`<developerName>`, token+curl, …) live in `references/error-taxonomy.md`.
|
package/skills/service-itsm-agentic-setup-employee-agent-configure/references/error-taxonomy.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Error taxonomy and gotchas — Create the IT Service Employee Agent
|
|
2
|
+
|
|
3
|
+
Split from `references/cli-invocation.md` — that file documents the per-phase
|
|
4
|
+
CLI call shapes and the classifier contracts; this file collects the errors
|
|
5
|
+
those calls can return and the recurring foot-guns.
|
|
6
|
+
|
|
7
|
+
## Error taxonomy
|
|
8
|
+
|
|
9
|
+
- **Auth error / `401 Unauthorized`** — the org session is expired or the alias
|
|
10
|
+
is wrong. Re-run `sf org login web` for the target org; there is no token to
|
|
11
|
+
refresh by hand.
|
|
12
|
+
- **`401`/`403`/unexpected error body on the Phase-1 Studio-access read** — the
|
|
13
|
+
preflight classifier maps this to `studio.signal="ERROR"` / `verdict="ERROR"`
|
|
14
|
+
(distinct from a confirmed 404 gate). Surface the raw response and stop —
|
|
15
|
+
do not proceed to Phase 2 even if the template read succeeded.
|
|
16
|
+
- **`403`/`404` on `createBundleWithVersion` / `publish` / `activate`** — the
|
|
17
|
+
NGA authoring namespace isn't provisioned or enabled on the org. Trigger the
|
|
18
|
+
Phase-1 hand-off offer.
|
|
19
|
+
- **`400 MISSING_ARGUMENT: agentType`** on `agent-templates` — the required
|
|
20
|
+
`agentType` query param was omitted; pass `AgentforceEmployeeAgent`.
|
|
21
|
+
- **Build-script exit 3** — the template, its `agentScript`, or a successful
|
|
22
|
+
`developer_name`/`agent_label` substitution wasn't found in the captured
|
|
23
|
+
`agent-templates.json`; surface stderr, don't hand-author a body.
|
|
24
|
+
- **Classifier exit 3** on a `sf data query` read — the SOQL query failed
|
|
25
|
+
(auth/malformed); surface the raw CLI error, do not treat as NOT-EXISTS.
|
|
26
|
+
- **Empty stdout from `activate`** — this is the SUCCESS response
|
|
27
|
+
(`EmptyRepresentation`), not a failure; confirm via the Phase-7 verify SOQL.
|
|
28
|
+
|
|
29
|
+
## Gotchas
|
|
30
|
+
|
|
31
|
+
| Issue | Resolution |
|
|
32
|
+
|-------|------------|
|
|
33
|
+
| Legacy `createAgent` produces the wrong kind of agent | Never call `/connect/service-itsm/createAgent` — it creates a Setup-page bot with an external-link icon in Agentforce Studio. Use the three `/nextgen-authoring/*` calls in `references/cli-invocation.md` |
|
|
34
|
+
| `sf api request rest --method POST` with no `--body` flag | Fails with `No 'mode' found in 'body' entry`, even for `publish`/`activate` which ignore the body — always pass `--body '{}'` explicitly |
|
|
35
|
+
| `sf api request rest --json` errors | Don't pass `--json` there — the raw stdout body is already JSON. `--json` is for `sf data query` (which needs the `.result.records[]` envelope) |
|
|
36
|
+
| Confusing `bundleId` with `bundleVersionId` | The `createBundleWithVersion` response's `id` field is the bundle **version** Id used in publish/activate; `bundleId` is the parent bundle's Id and 404s if passed to `/bundle-versions/{...}` |
|
|
37
|
+
| Naive single-pass HTML-entity decode leaves compile errors | `&quot;` (double-encoded) and `\` (numeric, backslash) require a multi-pass decode covering both named and numeric entities — see `build-create-body.mjs` |
|
|
38
|
+
| Bundle's outer `apiName` diverging from the script's internal `config.developer_name` | Always substitute both via `build-create-body.mjs` before the create call — a divergence is exactly the kind of mismatch that produces confusing platform behavior |
|
|
39
|
+
| Hardcoding `IT_Service_Employee_Agent` in one call but collecting it in another | Thread the collected `<developerName>` through the idempotency SOQL, the bundle body (outer + internal), AND the verify SOQL — a mismatch creates the wrong agent |
|
|
40
|
+
| Bare `./scripts/classify-agent-existence.mjs` "not found" | Use the skill's absolute `<skill_dir>` in the `node` invocation |
|
|
41
|
+
| `agent-templates` → `400 MISSING_ARGUMENT: agentType` | The `agentType` query param is required — pass `AgentforceEmployeeAgent` |
|
|
42
|
+
| `agent-templates` returns empty `data[]` | Wrong `agentType` value — use `AgentforceEmployeeAgent`; empty results are not the same as "not provisioned" |
|
|
43
|
+
| Treating `activate`'s empty response as a failure | It's the documented success response (`EmptyRepresentation`) — verify via the Phase-7 SOQL instead of parsing this call's stdout |
|
|
44
|
+
| Tempted to token+curl for any of the three writes | Never — `sf api request rest --method POST --body @<file>` (or `--body '{}'`) handles auth for `/services/data/...` writes; token extraction is forbidden |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Reactivation path — activating an existing inactive IT Service Employee Agent
|
|
2
|
+
|
|
3
|
+
Split from `references/cli-invocation.md` — this file documents the direct
|
|
4
|
+
`BotVersion` activation call used when the Phase-2 classifier reports the agent
|
|
5
|
+
already exists but its latest version is `Inactive`. `cli-invocation.md` covers
|
|
6
|
+
the create/publish/activate happy path; this file covers "skip create/publish,
|
|
7
|
+
just reactivate what's already there".
|
|
8
|
+
|
|
9
|
+
## When this path fires
|
|
10
|
+
|
|
11
|
+
`scripts/classify-agent-existence.mjs` (called with the template's
|
|
12
|
+
`botDefinitionId` as the PRIMARY idempotency key and the collected
|
|
13
|
+
`DeveloperName` as the FALLBACK — see `cli-invocation.md` → "Enumerate the
|
|
14
|
+
existing agent") returns
|
|
15
|
+
`{ exists:true, needsActivation:true, latestVersionId, latestVersionStatus:"Inactive" }`.
|
|
16
|
+
That means a `BotDefinition` matching the template (by `botDefinitionId`) or the
|
|
17
|
+
collected `DeveloperName` already exists (created on a prior run, or — for the
|
|
18
|
+
broad Employee agent — by the platform) but its most-recent `BotVersion` is
|
|
19
|
+
inactive; creating a new bundle would produce a duplicate. Instead, flip the
|
|
20
|
+
existing version to `Active`.
|
|
21
|
+
|
|
22
|
+
## Activate an existing inactive version — `POST /connect/bot-versions/{id}/activation`
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
sf api request rest "/services/data/v67.0/connect/bot-versions/<latestVersionId>/activation" \
|
|
26
|
+
--method POST --body '{"status":"Active"}' \
|
|
27
|
+
--target-org <alias> > ${SCRATCH_DIR}/activate-existing.json 2>${SCRATCH_DIR}/activate-existing.err || true
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`<latestVersionId>` is the captured `latestVersionId` from the Phase-2
|
|
31
|
+
classifier output — **not** a bundle version id. This is a direct
|
|
32
|
+
`BotVersion` activation toggle that bypasses the NGA bundle pipeline entirely,
|
|
33
|
+
because the `BotDefinition`/`BotVersion` records already exist. Skips create
|
|
34
|
+
(Phase 4) and publish (Phase 5) — go straight to activate, then verify.
|
|
35
|
+
|
|
36
|
+
## Verify — same SOQL as the happy path
|
|
37
|
+
|
|
38
|
+
Run the Phase-7 verify read (see `cli-invocation.md` → "Verify the agent is
|
|
39
|
+
live"). Confirm `exists:true` with `count:1` **and**
|
|
40
|
+
`latestVersionStatus:"Active"`. If `latestVersionStatus` is still `Inactive`
|
|
41
|
+
after a successful activation call, report the discrepancy verbatim — do not
|
|
42
|
+
fabricate success.
|
|
43
|
+
|
|
44
|
+
## Idempotency semantics
|
|
45
|
+
|
|
46
|
+
| Signal | Verdict |
|
|
47
|
+
|--------|---------|
|
|
48
|
+
| Neither the template's `botDefinitionId` nor the collected `DeveloperName` matches a live `BotDefinition` — classifier returns `exists:false` | proceed to CREATE |
|
|
49
|
+
| Phase-2 classifier returns `exists:true` and `needsActivation:false` (latest version `Active`), matched by `botDefinitionId` or the `DeveloperName` fallback | ALREADY-CREATED (skip create/publish/activate entirely) |
|
|
50
|
+
| Phase-2 classifier returns `exists:true` and `needsActivation:true` (latest version `Inactive`), user confirms reactivation, and the bot-version activation call succeeds | ACTIVATED (skip create/publish entirely — direct `BotVersion` activation only) |
|
|
51
|
+
| `createBundleWithVersion` → `publish` → `activate` all succeed and Phase-7 classifier (keyed on the publish `publishedBotId`) confirms `exists:true` with `latestVersionStatus:"Active"` | CREATED |
|
|
52
|
+
|
|
53
|
+
The server-side create path **does** reject a duplicate, but keyed on
|
|
54
|
+
`DeveloperName`, not `apiName`: a pre-validation lookup
|
|
55
|
+
(`lookupBotDefinitionIdByDeveloperName`) plus a publish-time `BotDefinition`
|
|
56
|
+
DeveloperName unique-constraint catch that cleans up the orphaned bundle version.
|
|
57
|
+
That guard fires only when the `DeveloperName` being created already exists — so
|
|
58
|
+
it catches a repeat run of THIS skill (same collected `developerName`), but it
|
|
59
|
+
does **not** catch the pre-provisioned broad Employee agent, whose live
|
|
60
|
+
`DeveloperName` (`IT_Service_Employee`) differs from this skill's guess
|
|
61
|
+
(`IT_Service_Employee_Agent`). The Phase-2 read closes that gap and upgrades the
|
|
62
|
+
outcome from a hard error to a graceful skip: it keys on the template's
|
|
63
|
+
`botDefinitionId` (primary — catches the pre-provisioned agent regardless of
|
|
64
|
+
name) and falls back to the collected `DeveloperName` (catches a self-created
|
|
65
|
+
repeat), so both surface as ALREADY-CREATED / reactivation instead of a
|
|
66
|
+
`DUPLICATE_VALUE` from the create call.
|
package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Report Format — Employee Agent Create & Activate
|
|
2
|
+
|
|
3
|
+
The report layout is generated deterministically by `scripts/render-report.mjs` — the single source of report text for both the chat-turn response and the harness's `${outputDir}/report.md` file, so the two never diverge. Never hand-compose the layout, field placement, stage rows, or next-step wording in prose (authoring standard A9); always shell out to the helper.
|
|
4
|
+
|
|
5
|
+
## Rendered shape
|
|
6
|
+
|
|
7
|
+
The helper reads a phase-state JSON and emits a report in this exact shape:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
# Employee Agent — Create & Activate
|
|
11
|
+
|
|
12
|
+
IT Service Employee Agent Creation (via service-itsm-agentic-setup-employee-agent-configure)
|
|
13
|
+
|
|
14
|
+
Org: <org-alias> (API v67.0)
|
|
15
|
+
Template: <resolvedMasterLabel> (id=<resolvedId>) — <broad umbrella|specialized>
|
|
16
|
+
Source: <resolvedId> Agent Script
|
|
17
|
+
Agent: <developerName> ("<label>") — NGA-native bundle
|
|
18
|
+
|
|
19
|
+
Preflight ......................... Studio hasAccess=<true|false|cannot-confirm>; template agentScript present=<yes|no>
|
|
20
|
+
Enumerate ......................... target agent exists before write=<yes|no>; latest version status=<Active|Inactive|n/a>
|
|
21
|
+
Confirm-to-write ................... user-confirmed=<true|false|pending>
|
|
22
|
+
Create bundle ...................... <bundleVersionId=... | ALREADY-CREATED | skipped (reactivation path) | pending confirmation | FAILED>
|
|
23
|
+
Publish ............................ <publishedBotId=... | skipped | pending confirmation | FAILED>
|
|
24
|
+
Activate ........................... <succeeded (created) | succeeded (reactivated existing) | skipped | pending confirmation | FAILED>
|
|
25
|
+
Verify ............................. <BotDefinition present: yes|no; latest version Active: yes|no | skipped>
|
|
26
|
+
|
|
27
|
+
Verdict: CREATED | ALREADY-CREATED | ACTIVATED | PENDING CONFIRMATION | DECLINED | FAILED
|
|
28
|
+
Reason: <plain-language explanation naming the atomicity constraint, the idempotency decision, and any decline/skip reasoning — the caller populates this before invoking the helper, so it can be as rubric-facing as the situation warrants without repeating raw API calls>
|
|
29
|
+
|
|
30
|
+
Next steps:
|
|
31
|
+
- <helper-emitted next-step line for the emitted verdict>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Report-state JSON schema (input to `render-report.mjs`)
|
|
35
|
+
|
|
36
|
+
The caller writes `${SCRATCH_DIR}/report-state.json` and passes it as the first arg:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"org": "<alias>",
|
|
41
|
+
"template": {"masterLabel": "...", "id": "...", "kind": "broad umbrella"|"specialized"},
|
|
42
|
+
"developerName": "...",
|
|
43
|
+
"label": "...",
|
|
44
|
+
"preflight": {"studioHasAccess": true|false|"cannot-confirm", "templateAgentScriptPresent": true|false},
|
|
45
|
+
"enumerate": {"existsBeforeWrite": true|false, "latestVersionStatus": "Active"|"Inactive"|"n/a"},
|
|
46
|
+
"confirmToWrite": "true"|"false"|"pending",
|
|
47
|
+
"verdict": "CREATED"|"ALREADY-CREATED"|"ACTIVATED"|"PENDING CONFIRMATION"|"DECLINED"|"FAILED",
|
|
48
|
+
"reason": "..."
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The helper enforces a validated verdict set and picks the `Next steps` line from the verdict, so the file never drifts from that shape.
|
|
53
|
+
|
|
54
|
+
## Checkpoint writes (harness / non-interactive runs)
|
|
55
|
+
|
|
56
|
+
When `${outputDir}` is provided (via the harness's generated-file location directive), write the helper output to `${outputDir}/report.md` at three checkpoints so it always exists even when a run parks at a confirmation gate:
|
|
57
|
+
|
|
58
|
+
1. **After Phase 2** — render with `verdict:"PENDING CONFIRMATION"` (create path) or the applicable ALREADY-CREATED / needsActivation state.
|
|
59
|
+
2. **After Phase 6 (or Phase 2b activation)** — re-render with the create-succeeded (or reactivation-succeeded) state; leave `verify` as `pending`.
|
|
60
|
+
3. **After Phase 8** — re-render with the final verdict (CREATED / ALREADY-CREATED / ACTIVATED / DECLINED / FAILED).
|
|
61
|
+
|
|
62
|
+
Each write overwrites the same file, so the last state on disk is always the most complete. The helper produces a ~30-line report — do NOT append extra sections (raw HTTP commands, full JSON bodies, per-phase narratives, remediation walkthroughs, session notes) to the report file; those belong in the assistant's turn-side response only.
|
|
63
|
+
|
|
64
|
+
## Interactive runs
|
|
65
|
+
|
|
66
|
+
Skip these writes when running interactively for a user in a chat surface — write only when `${outputDir}` was passed as an explicit destination. In chat, the assistant may add turn-side narrative context above or below the helper output (raw command traces, error diagnostics, remediation walkthroughs) — the *report* is what the helper emits, the *turn* can be as rich as the situation warrants.
|