AgentExchange

Help & Support

Elevate Your Agents with AgentExchange Solutions
Easily enhance Agentforce with pre-built AI solutions from AgentExchange. Browse, install, and deploy agents, actions, and apps directly into your environment. Tell Me More

Have Questions?

Service Agentforce Human Escalation Configure

Beta

Overview

Use to configure and verify Agentforce agent-to-human escalation, including human handoff, a staffed fallback queue, and failure-threshold directives. Triggers: configure agent escalation, escalate to a human agent, agent handoff to a queue, configure a human escalation queue, set an Agentforce fallback handoff. Do not use to create an agent or configure inbound channel routing; use service-agentforce-channel-configure for inbound routing.

Configure Agentforce Agent → Human Escalation

Wire an Agentforce agent so it can hand a conversation off to a human agent through an Omni-Channel queue. This skill configures and verifies the escalation surfaces, then reports a single machine-readable JSON verdict. It is idempotent per developer name and refuses to write to production orgs. It runs standalone or as a stage in a larger setup flow (after the agent is created and active).

The agent, queue, outbound flow name, routed context object, service channel, and failure thresholds are all inputs, so the same skill serves any scenario (IT employee support, customer messaging, etc.) — the caller supplies the scenario-specific identifiers.

This skill is the authoritative owner of agent-to-human (outbound) escalation. service-agentforce-channel-configure may wire a basic outbound flow + connection block in the same pass as inbound channel setup, but it delegates full escalation configuration and verification here.

The honest boundary — what is deterministic vs. directive vs. runtime

Escalation in Agentforce is assembled from surfaces with different verifiability:

  • Deterministic (this skill writes and/or round-trip verifies via the Metadata/Data API): canEscalate=true on the escalation topic (GenAiPlugin); outboundRouteConfigs on the agent's Messaging planner surface (GenAiPlannerBundle), where the SAME block couples outboundRouteName to outboundRouteType=OmniChannelFlow on a Messaging-class surface; a QueueBased outbound RoutingFlow with a non-null ActiveVersionId; a human queue with a QueueSobject for the context object, its QueueRoutingConfig bound to the queue, and at least one active human member (a queue with zero members can never route an escalation to a human, so it never reaches CONFIGURED); and the agent Active after republish.
  • Directive / native policy (authored as Agent Script instructions, not a metadata counter): the default two consecutive failures threshold plus per-topic overrides (e.g. password reset = one failure). There is no metadata field that counts failed turns — the threshold is instruction text, verified by an ADK eval rubric, not a runtime read. See references/failure-policy.md.
  • Runtime / manual only: the actual conversational trigger, AgentWork creation, and same-session context preservation. These cannot be driven headlessly — they are a documented manual test + eval rubric. See references/runtime-verification.md.

Authoring models — classic vs next-gen (NGA)

Salesforce exposes two Agentforce authoring models, and Phase 1b auto-detects which the org supports from its metadata types. The routing infrastructure (queue, QueueSobject, members, QueueRoutingConfig, outbound RoutingFlow) is identical in both; only the agent-side escalation surface differs.

  • classic — org exposes GenAiPlugin + GenAiPlannerBundle. The agent surface is canEscalate (topic) + outboundRouteConfigs (planner Messaging surface). This surface is authored in Phase 4 (hand-edited, or via the optional AUTHOR_SURFACES=1 pass) and round-trip verified in Phase 7.
  • nga — org exposes AiAuthoringBundle (Agent Script) and no GenAiPlannerBundle. There is no outboundRouteConfigs metadata; the agent surface is a reachable @utils.escalate action (Service agents) or a create-record action (Employee agents, which cannot use @utils.escalate), and the queue routing is carried entirely by the deterministic routing half. This skill verifies that surface from the retrieved bundle and delegates its authoring to agentforce-generate.
  • none — neither surface is exposed → the skill fails closed before any write.

Detection can be pinned with AUTHORING_MODEL_OVERRIDE=classic|nga when both coexist. Full rules, the Service-vs-Employee split, and the NGA verdict set live in references/nga-escalation.md.

Scope

  • In scope: enabling the escalation topic (canEscalate); wiring outboundRouteConfigs on the GenAiPlannerBundle Messaging surface; deploying the bundled QueueBased outbound RoutingFlow; create-or-adopt of the human queue (QueueSobject for the context object) and its QueueRoutingConfig; authoring the failure-threshold directives; republish + reactivate; and a deterministic config round-trip verdict. Idempotent re-run.
  • Out of scope: creating/activating the agent; inbound channel transport (sessionHandlerAsa on the MessagingChannel) and the agent's outbound connection block (owned by service-agentforce-channel-configure); provisioning the messaging channel itself (service-digital-engagement-channel-configure); broader Omni-Channel routing infrastructure; standalone queue provisioning outside an escalation context; and any production-org write.

Inputs

Input Positional Env Default
Org alias 1 (required)
Agent developer name 2 AGENT_DEVELOPER_NAME Support_Agent
Queue developer name 3 QUEUE_DEVELOPER_NAME Human_Support_Queue
Escalation topic API name 4 ESCALATION_TOPIC_API_NAME (unset — surface unverified)
Planner bundle API name 5 PLANNER_BUNDLE_API_NAME (unset — surface unverified)
Outbound flow developer name FLOW_DEVELOPER_NAME Human_Escalation_Outbound_Flow
Outbound flow label FLOW_LABEL flow name with _ → space
Context object (routed sObject) CONTEXT_OBJECT MessagingSession
Service channel dev name / label SERVICE_CHANNEL_DEV_NAME / SERVICE_CHANNEL_LABEL sfdc_livemessage / Messaging
Human members to add if empty QUEUE_MEMBER_USERNAMES (unset)
Failure threshold (consecutive failed attempts before hand-off) DEFAULT_FAILURE_THRESHOLD 2
Threshold directive authored (out-of-band flag) THRESHOLD_AUTHORED 0

For a non-MessagingSession context object (e.g. Case, VoiceCall), pass the matching SERVICE_CHANNEL_DEV_NAME / SERVICE_CHANNEL_LABEL.

Preconditions

  1. sf CLI installed and authenticated to the target org (sf org display -o <alias> shows Connected). All calls use --target-org <alias>.
  2. node ≥ 18 and jq on PATH (the deterministic classifiers and JSON assembly).
  3. The agent exists and its latest BotVersion is Active. This skill fails closed if not.
  4. For MessagingSession handoff, an active MessagingChannel exists. This skill fails closed if none is found. Other context objects use a different transport and are not gated on MessagingChannel.
  5. Sandbox / trial CDO / Developer Edition org. The skill refuses to configure escalation on a real production customer org.

If a precondition fails, sf surfaces the raw error — do not fabricate state; surface it and stop.


Workflow

Phase 0 — Production write-guard (mandatory, first write-gate)

Before any write, the orchestrator queries Organization (IsSandbox, TrialExpirationDate, OrganizationType) and computes safe_to_write. If the org is a real production customer org, the skill emits status: "BLOCKED" and stops. This is enforced in scripts/verify-and-configure.sh — never bypass it.

Phase 1 — Preconditions (read-only, fail closed)

  1. Agent Active — SOQL BotDefinition (+ latest BotVersion), classified deterministically by scripts/classify-agent-active.mjs. Not found or inactive → block with the activation click-path.
  2. Transport channel present — for MessagingSession, SOQL MessagingChannel WHERE IsActive=true; zero rows → block with a pointer to service-digital-engagement-channel-configure.

Phase 2 — Human queue (create-or-adopt) + members

Resolve the queue by DeveloperName. If missing, deploy a Queue (canonical Metadata API element order: doesSendEmailToMembers, name, queueSobject) with a QueueSobject for CONTEXT_OBJECT. For an adopted queue missing the binding, add the context object additively via the Data API. Create the QueueRoutingConfig if absent and bind it to the queue (Group.QueueRoutingConfigId), re-querying to confirm the bind persisted.

Members (human routability): the queue must have at least one active human member — otherwise the escalation routes to an empty queue. The skill counts GroupMember rows that resolve to an active User. If there are none and you pass QUEUE_MEMBER_USERNAMES (comma-separated usernames), it validates each against the username grammar up front, resolves the active User, and POSTs the GroupMember; it then re-counts. If the queue still has zero active human members the verdict is INCOMPLETE with queueHasActiveDirectUserMember in missing (an active direct user is necessary — not sufficient — for human routability; full Omni permission-set + presence-status eligibility is proven only at runtime). When there is no eligible member, the skill also skips QueueRoutingConfig binding and outbound-flow activation, so it never wires an empty queue. Use an approved Omni provisioning workflow when richer member reconciliation is required.

Phase 3 — Outbound QueueBased RoutingFlow

Deploy the bundled outbound flow template assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml, substituting the flow name/label, queue DeveloperName, and service-channel tokens. The flow looks the queue up by DeveloperName at runtime (portable, no hardcoded Id). After deploy, FlowDefinitionView.ActiveVersionId must be non-null.

Phase 4 — Escalation topic + planner outbound route (doc-driven edits)

These two edits require per-org topic/bundle discovery, so they are authored explicitly (retrieve → edit → deploy), then verified by the orchestrator when you pass the topic/bundle API names. Follow references/escalation-mechanism.md:

  1. Retrieve the escalation topic (GenAiPlugin), set <canEscalate>true</canEscalate>, deploy.
  2. Retrieve the agent's GenAiPlannerBundle, add outboundRouteConfigs (escalationMessage, outboundRouteName=<FLOW_DEVELOPER_NAME>, outboundRouteType=OmniChannelFlow) on the Messaging planner surface, deploy. The verifier couples name + type inside the SAME block on a Messaging-class surface (via scripts/extract-outbound-route.mjs) — a bundle with the right name and an OmniChannelFlow type in unrelated blocks will not pass.

Phase 5 — Failure-threshold directives (native policy)

The failure threshold and any per-topic overrides are directives, not enforced counters — there is no metadata field that counts failed turns (see references/failure-policy.md). The orchestrator does not write these into the agent; it only renders DEFAULT_FAILURE_THRESHOLD (default 2) into the local directive template assets/escalation-thresholds.instructions.md — pass e.g. DEFAULT_FAILURE_THRESHOLD=3 for a three-attempt scenario — and reports that value under threshold.default_failures (with threshold.directive_rendered) as verdict evidence. Authoring the rendered directive into the agent's Agent Script is a manual/out-of-band step; set THRESHOLD_AUTHORED=1 on the verifier run to record threshold.authored=true. The directive is eval-verified, never a headless runtime read, so it never blocks the deterministic verdict.

Phase 6 — Republish + reactivate

After the Phase 4/5 edits, republish and reactivate the agent so they take effect. These are manual operator commands for the hand-edited path; the orchestrator itself only publishes/deactivates/reactivates the agent inside the optional AUTHOR_SURFACES=1 pass (see "Running it"):

sf agent validate authoring-bundle --api-name "$AGENT_DN" --target-org "$ORG" --json
sf agent publish  authoring-bundle --api-name "$AGENT_DN" --target-org "$ORG" --json
sf agent activate --api-name "$AGENT_DN" --target-org "$ORG"

Phase 7 — Deterministic verification (single JSON verdict)

The orchestrator round-trips every deterministic surface, assembles an evidence object, and classifies it with scripts/verify-escalation-config.mjs into one of three states so a missing escalation policy can never masquerade as fully configured:

  • CONFIGURED — all deterministic surfaces satisfied and the failure-threshold directive is authored.
  • ROUTING_CONFIGURED_POLICY_PENDING — routing and the agent escalation surface are verified, but the failure-threshold directive (thresholdAuthored) is not yet confirmed. Author it (AUTHOR_SURFACES=1 / THRESHOLD_AUTHORED=1) and re-run to reach CONFIGURED.
  • INCOMPLETE — one or more deterministic surfaces are missing (see missing[]).

Note the NGA escalation-surface detection (scripts/classify-nga-escalation.mjs) is an advisory preflight — it matches for a reachable @utils.escalate / create-record action in the authoring bundle but does not prove runtime reachability from the topic. Treat a passing NGA surface check as a strong signal, not end-to-end runtime proof; confirm the live handoff with the Phase 8 runtime step.

Phase 8 — Runtime / manual proof (out of headless scope)

Confirm the conversational trigger, AgentWork creation, and same-session context preservation with a live conversation — see references/runtime-verification.md.


Running it

bash scripts/verify-and-configure.sh <org-alias> \
  [<agent-developer-name>] [<queue-developer-name>] \
  [<escalation-topic-api-name>] [<planner-bundle-api-name>]
  • Positionals 2–5 also read from env (see the Inputs table). Further scenario inputs are env-only: FLOW_DEVELOPER_NAME, FLOW_LABEL, CONTEXT_OBJECT, SERVICE_CHANNEL_DEV_NAME, SERVICE_CHANNEL_LABEL, QUEUE_MEMBER_USERNAMES.
  • PLAN_ONLY=1 previews (read-only) and stops before any write.
  • THRESHOLD_AUTHORED=1 marks the directive policy as authored for the verdict.
  • AUTHOR_SURFACES=1 (optional, run mode) — deterministically author the two doc-driven surfaces instead of hand-editing XML, following the Agentforce lifecycle in agentforce-generate/references/known-issues.md (Issue 18): publish (regenerate the compiled bundle) → retrieve the GenAiPlugin topic + GenAiPlannerBundle in metadata format (--target-metadata-dir … --unzip) → deactivate the agent (deploys fail while it is active) → apply a schema-aware, XSD-ordered, loss-less, idempotent patch (scripts/patch-escalation-surfaces.mjs) that sets canEscalate=true (after aiPluginUtterances, before description) and inserts outboundRouteConfigs (outboundRouteType=OmniChannelFlow, before <surface> on a Messaging-class planner surface, targeting the outbound flow) → deploy with --metadata-diractivate (fail-closed; the agent is never left inactive silently) → re-read the latest BotVersion so the verdict reflects the freshly-authored version. It requires the topic and/or bundle API names, runs only after the membership gate (never wires an empty queue), and refuses (blocks) rather than guess if it cannot find a safe, XSD-ordered patch point. Omit it to keep the skill verify-only.
  • The canEscalate and outboundRouteConfigs surfaces are verified only when you pass <escalation-topic-api-name> / <planner-bundle-api-name> (they are authored via the doc-driven edits in Phase 4).

Typical two-pass flow: run once to stand up the queue + outbound flow and preconditions; perform the Phase 4/5/6 doc-driven edits; then re-run with the topic + bundle API names and THRESHOLD_AUTHORED=1 to reach CONFIGURED.

Output contract

A single JSON object to stdout:

{
  "skill": "service-agentforce-human-escalation-configure",
  "status": "CONFIGURED",
  "agent": { "developer_name": "Support_Agent", "active": true },
  "queue": { "developer_name": "Human_Support_Queue", "id": "00G...", "active_direct_user_member_count": 1 },
  "outbound_flow": { "api_name": "Human_Escalation_Outbound_Flow", "active_version_id": "301..." },
  "escalation_topic": "Escalate_To_Human",
  "planner_bundle": "Support_Agent",
  "config_verification": {
    "verdict": "CONFIGURED",
    "deterministicPass": true,
    "directivePass": true,
    "checks": [],
    "missing": []
  },
  "next_steps": [],
  "manual_actions": [],
  "blocking_issue": null
}
  • status: CONFIGURED (all deterministic surfaces satisfied), INCOMPLETE (some config_verification.missing), or BLOCKED (bad input / auth / production / precondition; exit 1).
  • Re-running an already-configured org is a no-op that returns CONFIGURED (idempotent).

Idempotency

Existing queue, QueueSobject, QueueRoutingConfig, queue members, and an already-active outbound flow are reused, not recreated (members are only added when the queue has zero active members and QUEUE_MEMBER_USERNAMES is supplied; already-present members are left untouched). The doc-driven edits (canEscalate, outboundRouteConfigs) are set-if-absent. A second run against a fully configured org performs no writes and returns CONFIGURED.

Classifier contracts

Before investigating or changing any of the deterministic Node classifiers referenced above (scripts/classify-agent-active.mjs, scripts/verify-escalation-config.mjs, scripts/extract-outbound-route.mjs, scripts/classify-nga-escalation.mjs), read references/classifier-contracts.md for each one's exact input/output contract.

Verification

Run the bundled escalation contract tests after changing this skill or its scripts:

python3 scripts/tests/test_escalation_contracts.py

Categories

Domains
Service Cloud
Agentforce

Related Skills

  • SkillSkill
    Salesforce
    Agentforce Generate

    Salesforce, Inc.

    Build, modify, audit, repair, optimize, debug, and deploy agents with Agentforce Agent Script. TRIGGER when: user creates, reviews, or changes .agent files or aiAuthoringBundle metadata; asks to fix AgentScript, audit an existing agent, run an AgentScript

  • SkillSkill
    Salesforce
    Service Agentforce Channel Configure

    Salesforce, Inc.

    Wires an existing, active Agentforce agent to a channel by resolving a fallback queue, setting up inbound routing (either PATCH SessionHandlerId on the MessagingChannel, or an inbound RoutingFlow for Voice/Email), and optionally configuring outbound escal

  • SkillSkill
    Salesforce
    Service Digital Engagement Channel Configure

    Salesforce, Inc.

    Configures and deploys enhanced chat Messaging Channels for Messaging for In-App and Web (MIAW). Use when the user needs to create, deploy, and activate a messaging channel configured with Omni-Channel Flow, Omni-Channel Queue, User, or Agentforce Service

  • SkillSkill
    Salesforce
    Service Itsm Agentic Setup Agentforce Coordinate

    Salesforce, Inc.

    Orchestrator for setting up Agentforce in Salesforce Service Cloud ITSM — Agentforce Studio enablement, the IT Service Fulfiller agent, the IT Service Employee agent, specialized employee agents, and human escalation. Use when the user asks to set up Agen