--- name: service-itsm-agentic-setup-fulfiller-agent-configure description: "Create and activate the IT Service Fulfiller agent as a Next-Gen Authoring (NGA) native agent from the shipped ITSM Fulfiller template's Agent Script, using the Salesforce CLI (sf): read the template, check idempotency, create the NGA bundle then publish and activate it, then verify it is live. Idempotent per developer name. The Fulfiller agent is the IT-technician-facing assistant for incident triage, case summarization, field updates, and related-record automations. Use when asked to create the Fulfiller agent, set up the IT Service Fulfiller agent, provision the fulfiller assistant, or activate the Fulfiller agent. Triggers: create fulfiller agent, set up fulfiller agent, provision fulfiller agent, activate fulfiller agent. DO NOT TRIGGER: checking org prerequisites (service-itsm-agentic-setup-agentforce-studio-validate), or CMDB CRUD." metadata: version: "3.7" domains: ["Service", "Agentforce"] minApiVersion: "67.0" relatedSkills: - "service-itsm-agentic-setup-agent-runtime-access-assign" - "service-itsm-agentic-setup-agentforce-studio-configure" - "service-itsm-agentic-setup-agentforce-studio-validate" - "service-itsm-agentic-setup-employee-agent-configure" - "service-itsm-agentic-setup-itsm-agentforce-permset-assign" cliTools: - tool: ["node"] semver: ">=18.0.0" - tool: ["sf"] semver: ">=2.0.0" accessCheck: - type: "license" value: "Agentforce" allowed-tools: | Bash Read Write AskUserQuestion --- # Create the IT Service Fulfiller Agent Create and activate the **IT Service Fulfiller Agent** as a **Next-Gen Authoring (NGA) native agent** — Agent-Script-based (`AiAuthoringBundleDefVer`/bundle), appearing natively in Agentforce Studio's Agents list with no external-link icon — entirely through the **Salesforce CLI (`sf`)**. **This skill does not call the legacy `/connect/service-itsm/createAgent`**; instead it reuses the shipped ITSM Fulfiller template's `agentScript` and feeds it into the NGA bundle pipeline: 1. `POST /nextgen-authoring/bundles` (`createBundleWithVersion`) — creates the bundle + first version from the template's Agent Script. 2. `POST /nextgen-authoring/bundle-versions/{id}/publish` — publishes the version (creates the underlying `BotDefinition`/`BotVersion`). 3. `POST /nextgen-authoring/bundle-versions/{id}/activate` — activates it. Commands: `sf api request rest` for Connect API GET/POST; `sf data query` for the SOQL idempotency + verify reads. Helper scripts (invoked via `Bash`) hold every JSON-parsing / decision rule so the model never eyeballs a response body (A9): `classify-preflight.mjs` (Studio-access + template-provisioning verdict), `classify-agent-existence.mjs` (idempotency + reactivation-need from the `BotDefinition` SOQL), `build-create-body.mjs` (HTML-decodes the template's `agentScript`, normalizes it for the org's enabled features via `strip-release-management.mjs`, substitutes `config.developer_name`/`config.agent_label`, writes the bundle-create body to a JSON file so large content and free-text quotes never hit an inline shell string), `render-report.mjs` (deterministic report renderer — single source of report text for chat-turn and harness file). The Fulfiller agent is the **IT-technician-facing assistant** — incident triage, case summarization, field updates, related-record automations. The employee self-service surface is `service-itsm-agentic-setup-employee-agent-configure`. ## Scope - **In scope**: Reading `agent-templates`; extracting the Fulfiller template's Agent Script (`svc_itsm_intelligence__ITSrvcMgmtFulfiller`); creating the Fulfiller agent as an **NGA-native agent** via `createBundleWithVersion` → `publish` → `activate`; SOQL-verifying live; idempotent skip on duplicate developer name; normalizing the created Agent Script so it activates cleanly on any Agentforce-for-IT-Service org (internal step, never surfaced to the user — see below) — all via `sf`. - **Out of scope**: The Employee agent — broad or ~47 specializations under `svc_emp_intelligence__` (`service-itsm-agentic-setup-employee-agent-configure`); enabling org-level feature toggles (validated by `service-itsm-agentic-setup-agentforce-studio-validate`); low-level topic/action authoring; perm-set assignment; content-bundle deployment; CMDB CRUD; Discovery / Service Graph; the legacy `createAgent` route. --- ## Preconditions If any of these are unmet, `sf` surfaces an auth error or a `401`/`403`/`404`; **surface the raw error verbatim and stop — do not fabricate state**. 1. **`sf` CLI authenticated** to the target org (`sf org display -o ` shows Connected). All calls use `--target-org `; never extract the access token by hand. 2. **API v67.0+** — pinned in the URL path; do not hand-edit below the minimum. 3. **ITSM features + Fulfiller template provisioned** (`svc_itsm_intelligence__ITSrvcMgmtFulfiller`). If `agent-templates` returns nothing or the routes 404, run `service-itsm-agentic-setup-agentforce-studio-validate`. 4. **`node` ≥ 18** on PATH. --- ## Operations at a glance | Concern | Command | Notes | |---------|---------|-------| | Studio access (precondition read) | `sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" --method GET -o ` | `hasAccess=false` ⇒ prerequisite hand-off | | List agent templates + Agent Script (read) | `sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" --method GET -o ` | `agentType=AgentforceEmployeeAgent` required; confirms Fulfiller template + non-empty `agentScript` | | Enumerate the existing agent + latest version status (read) | `sf data query -q "SELECT Id,DeveloperName,MasterLabel,AgentTemplate,(SELECT Id,Status FROM BotVersions ORDER BY VersionNumber DESC LIMIT 1) FROM BotDefinition WHERE Id='' OR AgentTemplate='' OR DeveloperName=''" -o --json` | Keyed PRIMARILY on the template's `botDefinitionId` (Phase-1 row); `OR AgentTemplate=` is a defensive fallback that would catch a live agent instantiated from the OOTB source template (`svc_itsm_intelligence__ITSrvcMgmtFulfiller` = Phase-1 `template.id`) regardless of its DeveloperName; `OR DeveloperName=` is the real guard here — the normal Fulfiller case (never pre-provisioned; null `AgentTemplate`) and the guard for a dangling Id link (deleted target). Classified by `scripts/classify-agent-existence.mjs`; Active latest ⇒ ALREADY-CREATED; Inactive latest ⇒ offer reactivation | | **Create the NGA bundle** (write) | `sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" --method POST --body @ -o ` | Body built by `scripts/build-create-body.mjs`; response `id` = the bundle **version** Id | | **Publish the bundle version** (write) | `sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions//publish" --method POST --body '{}' -o ` | Returns `publishedBotId`/`publishedBotVersionId` — creates the underlying `BotDefinition`/`BotVersion` | | **Activate the bundle version** (write) | `sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions//activate" --method POST --body '{}' -o ` | Empty response on success; agent is now live and NGA-native | | **Activate an existing inactive version** (write) | `sf api request rest "/services/data/v67.0/connect/bot-versions//activation" --method POST --body '{"status":"Active"}' -o ` | Reactivation path only (Phase 2b) — skips create/publish | | Verify agent is live (read) | `sf data query -q "SELECT ... FROM BotDefinition WHERE Id=''" -o --json` | `` = create path's `publishedBotId` (Phase-5) or the Phase-2 classifier's returned live matched Id (its `botDefinitionId`/`agentId`) on ALREADY-CREATED / reactivation — not the null Phase-1 template `botDefinitionId`, never the collected developerName; confirm `BotDefinition` present + latest version Active | Full command shapes and the ITSM Connect API reference live in `references/cli-invocation.md`; the reactivation-path call + idempotency verdict table live in `references/reactivation.md`; the response-body error codes and recurring gotchas live in `references/error-taxonomy.md`. > **Never extract the access token.** Use `sf api request rest` / `sf data query` directly — they use the CLI's stored session for the target org. Do **not** pull the `accessToken` out of `sf org display` and hand-build an HTTP request with it; that bypasses the CLI session and leaks a bearer token into shell context. > **`--json` rule.** `sf data query` **takes** `--json` (results come back in a `.result.records[]` envelope — that's what the classifier expects). `sf api request rest` does **not** — omit `--json` there; its raw stdout body is already JSON. --- ## Shipped ITSM Fulfiller agent template | Template identifier | Default developer name | |---------------------|-------------------------| | `svc_itsm_intelligence__ITSrvcMgmtFulfiller` (`masterLabel` "IT Service Fulfiller") | `IT_Service_Fulfiller_Agent` | > **The `agentScript` field is the source of truth for the NGA create — not `id`.** `scripts/build-create-body.mjs` matches on `masterLabel`, HTML-decodes `agentScript`, and substitutes the collected ``/`