Help & Support
Elevate Your Agents with AgentExchange Solutions
Have Questions?
Service Itsm Agentic Setup Agentforce Studio Configure
- references/
- scripts/
- SKILL.md
Enable Agentforce for IT Service Prerequisites
Enable the Agentforce for IT Service Salesforce Go feature toggles — Einstein Generative AI, Agentforce Studio, the parent umbrella, and the path-specific agent template (Fulfiller or Employee) — entirely through the Salesforce CLI (sf). These toggles are the prerequisites for creating the Fulfiller/Employee agent; this write-capable step turns them on via the Setup Discovery POST /connect/setup/discovery/feature/{apiName}/enable Connect API route. Each toggle is enabled idempotently (skipped if already ENABLED), dependencies are enabled first, and explicit confirmation is required before any write.
| Step | Skill | What it does |
|---|---|---|
| 1. Validate | service-itsm-agentic-setup-agentforce-studio-validate |
Read the toggles → READY / NOT-READY (no writes) |
| 2. Configure (this skill) | service-itsm-agentic-setup-agentforce-studio-configure |
Turn the disabled toggles ON |
| 3. Create agent | service-itsm-agentic-setup-fulfiller-agent-configure |
Create + activate the Fulfiller agent |
This skill is typically reached via hand-off from the validate skill's NOT-READY report, but can also be run directly.
A helper script — scripts/classify-enable-plan.mjs — reads the batched /features/status response and deterministically computes the dependency-ordered enable plan (before writing) and the final per-feature verdict (after writing). This mirrors the validate skill's classify-readiness.mjs contract (authoring standard A9): the decision logic lives in a script, not in prose.
Scope
- In scope: Enabling Einstein Generative AI (
sales-cloud-einstein-generative-ai), Agentforce Studio (sales-cloud-agent-studio), the parent umbrella (service-cloud-agentforce-for-itsm), and the path-specific template (service-cloud-it-fulfiller-agentfor fulfiller;service-cloud-requestor-agent+service-cloud-it-service-employee-agentfor employee) viaPOST .../feature/{apiName}/enable; reading live per-org state from/features/statusbefore and after each write; enabling dependencies first; confirming enablement stuck via re-query; surfacing an ENABLED / ALREADY-ENABLED / FAILED verdict per feature. Writes are idempotent — skip if alreadyENABLED. - Out of scope: Provisioning Agentforce licenses (Setup > Company Information > Permission Set Licenses); assigning permission sets to users; creating, configuring, or activating an agent (
service-itsm-agentic-setup-fulfiller-agent-configure); read-only prerequisite validation without writes (service-itsm-agentic-setup-agentforce-studio-validate); the org-wide multi-agent orchestration toggle (a Headless360-only pref, not a Connect feature).
Which path?
Determine whether the user is enabling prerequisites for the fulfiller agent or an employee agent. If unclear, ask (AskUserQuestion) — same path selection the validate skill uses:
- fulfiller →
sales-cloud-einstein-generative-ai→sales-cloud-agent-studio→service-cloud-agentforce-for-itsm→service-cloud-it-fulfiller-agent - employee →
sales-cloud-einstein-generative-ai→sales-cloud-agent-studio→service-cloud-agentforce-for-itsm→service-cloud-requestor-agent→service-cloud-it-service-employee-agent
Einstein Generative AI is a dependency of Agentforce Studio and is not one of the toggles the validate skill reports on directly, but it must be enabled first if it is off — the classifier includes it in the enable plan for both paths.
Preconditions
Same as the validate skill (they share the target org and API surface). If unmet, sf surfaces an auth error or a 401/403/404; do not fabricate state — surface the raw error and stop.
sfCLI installed and authenticated to the target org (sf org display -o <alias>shows Connected). All calls use--target-org <alias>; never extract or pass the access token by hand.- API v67.0+: the
connect/setup/discoveryfeature APIs are available at v67.0. The version is pinned in the URL path; do not hand-edit it below the minimum. node≥ 18 on PATH (runs the classifier script).- Agentforce license on the org (
accessCheck) — a missing license surfaces as403or asenableBlockedReasonson the read.
Operations at a glance
| Operation | Command | Returns |
|---|---|---|
| Read feature toggles | sf api request rest ".../connect/setup/discovery/features/status" --method POST --body '{"featureApiNames":[...]}' --target-org <alias> |
{items:[{apiName,status,enableBlockedReasons[],dependencyStatuses[]}]} |
| Enable one toggle | sf api request rest ".../connect/setup/discovery/feature/{apiName}/enable" --method POST --body '{}' --target-org <alias> |
{success:boolean} — endpoint takes no meaningful body, but --body '{}' must be passed explicitly (see gotchas) |
Both are Connect API routes reachable via sf api request rest — no Headless360 dispatcher required. Full command shapes, the response envelope, and the error taxonomy live in references/cli-invocation.md.
Never extract the access token. Use
sf api request restdirectly — it uses the CLI's stored session for the target org. Do not pull theaccessTokenout ofsf org displayand hand-build an HTTP request with it.
CRITICAL: DO NOT use IPCManagement
updateOrgPrefto flip agent prefs. That controller's write allow-list rejects the agent prefNames (Invalid prefName, 500). The Setup DiscoveryPOST /feature/{apiName}/enableendpoint is the only correct write path for these toggles.
Architecture — How enablement works
| Step | What happens | Tool used |
|---|---|---|
| Pick path | Determine fulfiller vs employee (ask if unclear) | AskUserQuestion |
| Read current state | POST the feature-status batch for the path's toggles, capture to a file | Bash (sf api request rest) |
| Plan | Run scripts/classify-enable-plan.mjs <file> <agentType> [exitStatus] → dependency-ordered pending list |
Bash (node) |
| Confirm-to-write | Present the exact pending list and require explicit "yes" |
AskUserQuestion |
| Enable | Re-read + reclassify before each apiName in order, POST .../feature/{apiName}/enable when unblocked, record the result |
Bash (sf api request rest + node scripts/record-enable-result.mjs) |
| Verify | Re-read /features/status, re-run the classifier |
Bash (sf + node) |
| Report | Run scripts/classify-final-report.mjs over the before/results/after files → final verdict |
Bash (node) |
Workflow
Substitute <alias> with the target org alias. <agentType> is fulfiller or employee.
Phase 1 — Read Current State
POST the feature-status batch for every toggle the chosen path needs, capturing stdout to a file. Do not add
--json. Write the request body once to a temp file and reuse it verbatim in Phases 1, 4, and 5 via--body "$(cat ...)"— never retype it, substitute a placeholder like[...], or rely on a shell variable, since each Bash invocation may run in a fresh shell where a plain variable would be unset:cat > /tmp/feature-status-body.json <<'EOF' {"featureApiNames":["sales-cloud-einstein-generative-ai","sales-cloud-agent-studio","service-cloud-agentforce-for-itsm","service-cloud-it-fulfiller-agent","service-cloud-requestor-agent","service-cloud-it-service-employee-agent"]} EOF sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \ --method POST \ --body "$(cat /tmp/feature-status-body.json)" \ --target-org <alias> > /tmp/enable-status-before.json 2>/tmp/enable-status-before.err echo $? > /tmp/enable-status-before.exitCapture the exit status — do not swallow it with
|| true.
Phase 2 — Plan (helper script)
Run the classifier over the captured file to compute the dependency-ordered enable plan, saving its output — Phase 6 consumes this file, not the raw
/features/statusresponse:node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-before.json <agentType> "$(cat /tmp/enable-status-before.exit)" > /tmp/enable-plan-before.jsonIt prints
{ agentType, readState, features, order, alreadyEnabled, pending, blocked, unconfirmed, verdict, reasons, rawError }.verdict: "ALL-ENABLED"means nothing to do — skip to Phase 6.verdict: "NEEDS-ENABLE"meanspending(inorder) lists what to enable.blockedlists anypendingtoggle whoseenableBlockedReasonsis non-empty as of this read — a toggle blocked only on an earlier dependency inorderbecomes enable-able once that dependency is on, so Phase 4 re-checks each toggle immediately before attempting it rather than trusting this snapshot for the whole loop.unconfirmedlists any required toggle missing from the response or carrying a status this classifier doesn't recognize —verdict: "CANNOT-CONFIRM"(not"ALL-ENABLED") whenunconfirmedis non-empty andpendingis empty.readState: "error"⇒ surfacerawErrorand stop;readState: "not-wired"⇒ report CANNOT-CONFIRM and stop.
Phase 3 — Confirm-to-Write Checkpoint (REQUIRED)
- Present the exact
pendinglist (excluding anything inblocked) and require an explicit "yes" from the user viaAskUserQuestionbefore proceeding. Enabling org prefs mutates org state. Proceed to Phase 4 ONLY on an explicit "yes". On "no", stop and report the current state without any writes.
Phase 4 — Enable (Dependencies First, Re-Checked Before Each Toggle)
Iterate
orderin sequence (Einstein GenAI → Studio → parent → child template(s)). Before attempting to enable each<apiName>, re-read and reclassify — this is what lets a child that wasblockedin Phase 2 (only because Studio/parent was still off) become enable-able once that dependency's own enable has landed, instead of being permanently written off from the Phase-2 snapshot:sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \ --method POST \ --body "$(cat /tmp/feature-status-body.json)" \ --target-org <alias> > /tmp/enable-status-loop.json 2>/tmp/enable-status-loop.err echo $? > /tmp/enable-status-loop.exit node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-loop.json <agentType> "$(cat /tmp/enable-status-loop.exit)"Inspect
features["<apiName>"].signalfrom that output:PASS→ alreadyENABLED; nothing to do, move to the nextapiNameinorder.FAILwith an emptyenableBlockedReasons→ enable it now:sf api request rest "/services/data/v67.0/connect/setup/discovery/feature/<apiName>/enable" \ --method POST \ --body '{}' \ --target-org <alias> > /tmp/enable-<apiName>.json 2>/tmp/enable-<apiName>.err node "<skill_dir>/scripts/record-enable-result.mjs" /tmp/enable-<apiName>.json <apiName> /tmp/enable-results.jsonThe
/enableendpoint itself takes no meaningful body, butsf api request rest --method POSTwith no--bodyflag at all fails withError (SfError): No 'mode' found in 'body' entry— always pass--body '{}'explicitly.record-enable-result.mjsreads the response, classifies it ENABLED/FAILED, and accumulates it into/tmp/enable-results.jsonkeyed byapiName— the deterministic per-toggle bookkeeping Phase 6 consumes.FAILwith a non-emptyenableBlockedReasons→ still blocked even after this iteration's re-check (a real, not merely-sequential, blocker — e.g. unlicensed) — do not POST; move to the nextapiNameinorderand let Phase 6 report the blocker verbatim.CANNOT-CONFIRM/ERRORon this specificapiName's read → stop the loop and surface the read failure; do not guess at remaining toggles.
One failed toggle does not block the rest of the plan — continue the loop.
Phase 5 — Verify Enablement
Re-run the Phase 1 read (same
/tmp/feature-status-body.json) into a fresh file, and re-run the classifier over it, saving its output for Phase 6:sf api request rest "/services/data/v67.0/connect/setup/discovery/features/status" \ --method POST \ --body "$(cat /tmp/feature-status-body.json)" \ --target-org <alias> > /tmp/enable-status-after.json 2>/tmp/enable-status-after.err echo $? > /tmp/enable-status-after.exit node "<skill_dir>/scripts/classify-enable-plan.mjs" /tmp/enable-status-after.json <agentType> "$(cat /tmp/enable-status-after.exit)" > /tmp/enable-plan-after.jsonverdict: "ALL-ENABLED"⇒ every toggle inorderis confirmedENABLED— success. Anything still inpending/blocked/unconfirmedneeds Phase 6 to classify it precisely (FAILED vs CANNOT-CONFIRM).
Phase 6 — Aggregate Verdict (helper script)
Run the final aggregator over the Phase-2 classifier output (
/tmp/enable-plan-before.json, not the raw/features/statusresponse), the Phase-4 accumulated results (or-if Phase 2 was alreadyALL-ENABLED/CANNOT-CONFIRM/ERRORand Phase 4 never ran), and the Phase-5 classifier output (/tmp/enable-plan-after.json):node "<skill_dir>/scripts/classify-final-report.mjs" /tmp/enable-plan-before.json /tmp/enable-results.json /tmp/enable-plan-after.jsonIt prints
{ features: { <apiName>: { finalStatus, reason } }, order, overall, reasons }wherefinalStatusisALREADY-ENABLED | ENABLED | FAILED | CANNOT-CONFIRM | ERRORandoverallisSUCCESS | PARTIAL | FAILED | CANNOT-CONFIRM | ERROR. Render this directly into the Output Format — do not re-derive the per-feature verdict or the overall summary in prose (authoring standard A9). Onoverall: "SUCCESS", point the user atservice-itsm-agentic-setup-fulfiller-agent-configure(fulfiller) orservice-itsm-agentic-setup-employee-agent-configure(employee) to proceed.
Rules / Constraints
| Constraint | Rationale |
|---|---|
Enable via POST /connect/setup/discovery/feature/{apiName}/enable only |
The IPCManagement updateOrgPref write allow-list rejects the agent prefNames (Invalid prefName) — this is the only correct write path |
Read live per-feature state from POST /features/status, never a flat catalog list |
Only /status carries per-org ENABLED/NOT_ENABLED + enableBlockedReasons[] + dependencyStatuses[] |
Enable dependencies before children, in the classifier's order |
Enabling a child before Einstein GenAI / Studio surfaces unmet-dependency blockers |
| Re-read and reclassify immediately before each toggle in the Phase-4 loop, not once at the top of the loop | A child blocked only because an earlier dependency was still off becomes enable-able the instant that dependency's own /enable lands — a single Phase-2 snapshot would report it FAILED even though it was never really blocked |
Idempotent: skip /enable for anything already ENABLED |
The classifier's alreadyEnabled list is authoritative; enabling an already-enabled feature returns {success:true} but is redundant |
REQUIRED confirm-to-write checkpoint before any /enable POST |
Enabling org prefs mutates org state; the user must explicitly approve the exact pending list |
Never attempt to enable a toggle whose current (re-checked) enableBlockedReasons is non-empty |
Non-empty enableBlockedReasons means the write would fail — report the blocker instead of a doomed POST |
verdict: "CANNOT-CONFIRM" when unconfirmed is non-empty, even if pending is empty |
A required toggle missing from the response, or with an unrecognized status, must not be reported as ALL-ENABLED just because nothing is left in pending |
Classification and per-toggle result recording live in scripts/classify-enable-plan.mjs, scripts/record-enable-result.mjs, and scripts/classify-final-report.mjs, invoked via Bash — not in prose |
Deterministic decision tables and aggregation over fixed feature statuses (authoring standard A9) |
The read/write goes through sf api request rest; never extract the access token |
sf api request rest uses the CLI's stored session for --target-org |
Do not pass --json to sf api request rest |
Unsupported on some Connect endpoints; the raw stdout body is already JSON |
| These are Connect API features — use SF CLI, not Headless360 | A Connect/Tooling equivalent exists, so SF CLI is preferred (avoids the Headless360HostedMcpServer org-perm gate) |
Gotchas
| Issue | Resolution |
|---|---|
sf api request rest --method POST with no --body flag errors No 'mode' found in 'body' entry |
The /enable endpoint itself takes no meaningful body, but the CLI still requires the flag — always pass --body '{}' explicitly (verified on CLI 2.140.6 and 2.145.6) |
| Feature API name unavailable / unlicensed on the org | No catalog endpoint enumerates valid names — the Phase-1 /features/status read surfaces an unavailable/unlicensed feature via enableBlockedReasons[] before any enable attempt |
/features/status shows NOT_ENABLED with dependencyStatuses[] unmet |
Enable the listed dependency first (Einstein GenAI before Studio, Studio before the parent/child toggles) |
updateOrgPref → 500 Invalid prefName for an agent pref |
Wrong write path — use the Setup Discovery feature/{apiName}/enable endpoint instead |
Auth error from sf api request rest |
The target org's session needs re-authentication (sf org login web) |
| Treating an auth/permission/empty-body read failure as "not wired" | Pass the captured $? as the classifier's 3rd arg — only a confirmed 404 is CANNOT-CONFIRM; anything else is ERROR (surface rawError, stop) |
Reporting ALL-ENABLED because pending is empty |
Also check unconfirmed — a required toggle missing from the response or with an unrecognized status is neither confirmed ENABLED nor NOT_ENABLED |
| Re-deriving the per-feature / overall verdict in prose from the before/after JSON | Run scripts/classify-final-report.mjs — the aggregation is fixed comparison logic (authoring standard A9), not a judgment call |
| Setting the feature-status request body in a shell variable in Phase 1 and expecting it in Phase 4/5 | Each Bash invocation may run in a fresh shell where the variable is unset, silently sending an empty body — persist it to /tmp/feature-status-body.json once and read it back with --body "$(cat /tmp/feature-status-body.json)" in every phase |
Verification Checklist
- The agent path (fulfiller / employee) was determined (asked if unclear).
- Phase 1 read
/features/statusviasf api request rest, captured to a file, with its exit status captured. -
scripts/classify-enable-plan.mjscomputed thepending(dependency-ordered),blocked, andunconfirmedlists before any write. - The user explicitly confirmed the exact
pendinglist at the Phase-3 checkpoint before any/enablePOST. - Phase 4 re-read and reclassified before each toggle, not once for the whole loop — so a child unblocked by an earlier dependency's enable was still attempted.
- Each attempted
/enablePOST's response was recorded viascripts/record-enable-result.mjs, accumulated across the loop. -
/features/statuswas re-read after enablement and the classifier re-run to confirm the final per-feature verdict. -
scripts/classify-final-report.mjs(not prose) computed the final per-feature status and overall summary from the before/results/after files; the access token was never extracted.
Output Format
Emit the report as live Markdown — never inside a code fence (a fenced table shows raw
| pipes, not a table). This is Stage 1 (Foundation) that Stage 2 (install & activate the
agent) builds on; each Status is ENABLED / ALREADY-ENABLED / FAILED / CANNOT-CONFIRM. Lay it
out exactly like this:
Agentforce for IT Service — Stage 1: Enable Platform Features (via service-itsm-agentic-setup-agentforce-studio-configure)
- Org:
<org-alias>(API v67.0) - Agent path: fulfiller | employee
| # | Platform feature | Status |
|---|---|---|
| 1 | Einstein Generative AI | <status> |
| 2 | Agentforce Studio | <status> |
| 3 | Agentforce for IT Service | <status> |
| 4 | <path-specific toggle(s)> |
<status> |
Verdict: SUCCESS | PARTIAL | FAILED | CANNOT-CONFIRM | ERROR
Next steps:
- If SUCCESS: "Stage 1 (foundation) complete — proceed to Stage 2: install + activate the
<path>agent viaservice-itsm-agentic-setup-fulfiller-agent-configure(fulfiller) / the employee-agent skill." - If PARTIAL/FAILED/CANNOT-CONFIRM/ERROR: list the affected toggle(s) + reason (
enableBlockedReasons, unconfirmed status, or read error) + remediation steps
Substitute overall and each feature's finalStatus from scripts/classify-final-report.mjs into the <status> cells verbatim — do not recompute. No files are produced beyond the classifiers' temporary response captures.
Label rows exactly as the classifier emits them — never add Requestor, Specialized, or parent.
Reference File Index
| File | When to read |
|---|---|
references/cli-invocation.md |
Every phase — exact sf api request rest read/write call shapes, response envelope, feature API names, the classifier contract, and the error taxonomy |
Related Skills
Salesforce
Validate the Agentforce for IT Service prerequisites for a Fulfiller or Employee agent, using the Salesforce CLI (sf). The READ-ONLY prerequisite check: it reads the Salesforce Go feature toggles behind the Agentforce for IT Service setup page (Agentforce
Categories
Agentforce Content
Salesforce
Create and activate an IT Service Employee agent as a Next-Gen Authoring (NGA) native agent from an ITSM Employee agent template's Agent Script, via the Salesforce CLI (sf): read the template, check idempotency, create the NGA bundle then publish and acti
Categories
Agentforce Content
Salesforce
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