Create the IT Service Fulfiller Agent

SkillProductivity

Sets up an IT service request fulfillment agent by creating and activating its configuration via Salesforce CLI.

Use Create the IT Service Fulfiller Agent in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Create the IT Service Fulfiller Agent and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the Create the IT Service Fulfiller Agent skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Create the IT Service Fulfiller AgentStart free
About this skill

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. Idem

What this skill tells your AI

The instructions your AI receives, as published by forcedotcom/sf-skills in skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md and read by ahel’s review.

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 <alias> shows Connected). All calls use --target-org <alias>; 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

ConcernCommandNotes
Studio access (precondition read)sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" --method GET -o <alias>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 <alias>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='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'" -o <alias> --jsonKeyed 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 @<body-file> -o <alias>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/<bundleVersionId>/publish" --method POST --body '{}' -o <alias>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/<bundleVersionId>/activate" --method POST --body '{}' -o <alias>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/<latestVersionId>/activation" --method POST --body '{"status":"Active"}' -o <alias>Reactivation path only (Phase 2b) — skips create/publish
Verify agent is live (read)sf data query -q "SELECT ... FROM BotDefinition WHERE Id='<verifyId>'" -o <alias> --json<verifyId> = 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 identifierDefault 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 <developerName>/<label> into config.developer_name/config.agent_label before it becomes the bundle's resourceContent. The Employee-facing agent is handled by service-itsm-agentic-setup-employee-agent-configure.

Internal template normalization — never surfaced to the user. Before the decoded script becomes resourceContent, scripts/strip-release-management.mjs removes the topic ReleaseManagement: block — plus its go_to_ReleaseManagement: selector transition and routing bullet. That topic's only action, svc_itsm_intelligence__SummarizeRelease, is gated behind an org preference (ReleaseManagementPref) and is not surfaced by /actions/custom/generatePromptResponse on an org that has not enabled it; shipping it would make activate return HTTP 200 with a {success:false, "... does not exist"} silent-failure body. classify-action-availability.mjs applies the identical transform so Phase 2c scans the same normalized script — the two callers must stay in lock-step. The transform is a no-op if the block is absent (safe against future template revisions). This normalization is an implementation detail: do NOT mention it, the removed subagent, or Release Management in chat narration, the confirm-to-write step, or the report — the admin only ever sees that the agent was created and activated.


Architecture — Creation stages

StageWhat happensTool used
PreflightConfirm Studio access (agentforce-studio/access/Agents) and that the template's agentScript is presentBash (sf api request rest)
EnumerateRead the Fulfiller template (agent-templates) and existing agents + latest version status (SOQL on BotDefinition/BotVersions); classify idempotency and reactivation-need via scriptBash (sf, node)
Confirm-to-writePresent the exact developerName + label (the NGA create target), OR — if the existing agent is inactive — present the reactivation option instead, and require explicit "yes" either wayAskUserQuestion
Create (create path only)POST createBundleWithVersion (builds the NGA bundle + first version from the decoded, substituted template Agent Script)Bash (sf api request rest, node)
Publish (create path only)POST .../bundle-versions/<id>/publish (creates the underlying BotDefinition/BotVersion)Bash (sf api request rest)
ActivatePOST .../bundle-versions/<id>/activate (create path) OR POST .../connect/bot-versions/<latestVersionId>/activation with {"status":"Active"} (reactivation path — skips create/publish)Bash (sf api request rest)
VerifySOQL-read BotDefinition/BotVersions and confirm the agent exists with an Active latest versionBash (sf data query)

Idempotency: keyed PRIMARILY on the template's botDefinitionId (Phase-1 agent-templates row — the platform's authoritative template→BotDefinition link), FALLING BACK first to the BotDefinition's AgentTemplate (the OOTB namespaced source template = Phase-1 template.id) and then to the collected <developerName>. The Phase-2 read is BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>' (the OR AgentTemplate= half is a defensive key that would catch a live agent instantiated from the source template regardless of its DeveloperName; the OR DeveloperName= half is both the null-botDefinitionId fallback — the normal Fulfiller case — AND the guard for a dangling Id link whose target BotDefinition was deleted), + latest BotVersion.Status (classified by the helper script). Outcomes: no match on any key ⇒ exists:false ⇒ create; latestVersionStatus:"Active" ⇒ ALREADY-CREATED (skip the write, fall through to Phase 7 verification); needsActivation:true (latest version Inactive) ⇒ offer to activate the existing version instead of creating a new agent (Phase 2b) rather than silently skipping or duplicating. Why the fallbacks matter: the Fulfiller is never pre-provisioned and this skill's create path never stamps templateName, so BOTH the template's botDefinitionId AND the agent's AgentTemplate are always null — the <developerName>-keyed fallback is the guard that actually catches a repeat run; short-circuiting straight to create on a null botDefinitionId would re-create and collide with DUPLICATE_VALUE. The server does reject a duplicate DeveloperName at publish (unique-constraint → bundle cleanup), but only this Phase-2 read turns a repeat into a graceful skip instead of that hard error.


Clarifying Questions

Collect from the user (ask only what is not already in conversation context):

FieldDescriptionDefault
Target orgThe sf org alias to create the agent inDefault org (sf config get target-org)
Developer nameUnique DeveloperName for the agentIT_Service_Fulfiller_Agent
LabelUser-facing label for the agentIT Service Fulfiller Agent
Confirm the writeExplicit confirmation before the create/publish/activate sequenceREQUIRED — present the developerName + label and require "yes" via AskUserQuestion

The idempotency read keys PRIMARILY on the template's botDefinitionId (Phase-1 row) and FALLS BACK to the BotDefinition's AgentTemplate (defensive — null on the never-pre-provisioned Fulfiller) and then to the collected <developerName>, the guard that actually catches a repeat here, when that is null; the verify read keys on the publish response's publishedBotId (create path) or the template's botDefinitionId (ALREADY-CREATED / reactivation). The collected <developerName> and <label> (defaults IT_Service_Fulfiller_Agent / IT Service Fulfiller Agent) also thread through the createBundleWithVersion body — both the outer apiName/label AND the substituted config.developer_name/config.agent_label inside the Agent Script. Never hardcode the name in one call and collect it in another — a mismatch between the bundle's outer apiName and the script's internal developer_name causes the platform to diverge the two. Creating an agent provisions a live, activated agent on the org; the user must explicitly approve the write.


Workflow

Substitute <alias> with the collected target org and <developerName> / <label> with the collected values. Full command shapes + per-phase verdict-branch handling live in references/workflow-detail.md — the phase summary below names each step and its load-bearing rule; the reference file holds the exact sf / node invocations to copy.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
1k
Forks
351
Last commit
Sep 2026

ahel review

  • K2info
    exfiltration (in references/cli-invocation.md)

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Item type
skill
Key
service-itsm-agentic-setup-fulfiller-agent-configure
Source
github.com/forcedotcom/sf-skills