Install
$ agentstack add skill-rammc-salesforce-agent-script-salesforce-agent-script ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Salesforce Agent Script
Build, review, and refactor Agentforce agents written in Agent Script. Agent Script is Salesforce's declarative DSL for hybrid reasoning agents on the Agentforce 360 Platform. It compiles to portable JSON metadata consumed by the Atlas Reasoning Engine.
This skill covers the language itself and the surrounding pro-code tooling (Agentforce Builder Script view, Agentforce DX CLI, VS Code extension, Agentforce Vibes). It does not cover Atlas Reasoning Engine internals, Data Cloud grounding configuration, multi-org deployment strategy, or Apex / Flow / Prompt Template authoring — those are adjacent disciplines.
Contents
- [When to use this skill](#when-to-use-this-skill)
- [Mental Model](#mental-model)
- [Terminology: Topics vs. Subagents](#terminology-topics-vs-subagents)
- [Anatomy of an Agent](#anatomy-of-an-agent)
- [The Hybrid Reasoning Decision](#the-hybrid-reasoning-decision)
- [Quick Reference](#quick-reference)
- [Authoring Workflow](#authoring-workflow)
- [Review Checklist](#review-checklist)
- [Reference Files](#reference-files)
- [Verification Pointers](#verification-pointers)
When to use this skill
Trigger this skill when the task involves:
- Writing, reading, or refactoring Agent Script source (
.agentfiles or
scripts shown in the Builder).
- Designing the structure of a new agent:
start_agentrouting, topic
decomposition, action surfaces, variable design.
- Debugging unexpected agent behavior that comes from prompt vs. logic
mis-balance, transitions, or variable scope.
- Choosing between deterministic logic (
->) and prompt instructions (|). - Translating natural-language requirements ("if total > 100, free shipping")
into Agent Script.
- Migrating from a chat/Canvas-built agent to Script view, or from natural
language–only agents to hybrid reasoning.
- Integrating with the surrounding tooling (Agentforce DX, Vibes, VS Code).
Skip this skill for: Apex action implementation, Flow design, Data Cloud configuration, model selection / Atlas tuning, multi-org metadata deployment.
Mental Model
Agent Script combines two execution modes in one file:
- Logic instructions prefixed with
->run deterministically every time
the subagent is parsed. Use them for business rules, action calls, variable mutation, transitions, conditional branches.
- Prompt instructions prefixed with
|are concatenated into a string
that is sent to the LLM as a prompt. The LLM then decides what to say or which exposed tool to call.
The execution flow per customer turn:
- Enter at
start_agent(or current subagent after a transition). - Parse phase. Resolve all reasoning instructions top-to-bottom: run
logic, mutate variables, execute deterministic actions, concatenate prompt strings (conditionally where if gates apply).
- Reasoning phase. Send the resolved prompt + the list of
reasoning.actions
tools to the LLM. The LLM may answer directly, or may call one or more tools.
- Reasoning loop. After each tool execution, the system **loops back to
step 2** to re-resolve and re-send. The cycle repeats until the LLM responds without calling a tool.
after_reasoningruns (if defined) once the loop exits.- The agent waits for the next customer utterance, then re-enters at
start_agent.
The central insight: reasoning is a loop, not a single pass. A subagent may resolve its prompt many times in a single customer turn as the LLM calls tools. Variables mutated between iterations are visible to the next iteration. Design accordingly — and when debugging, inspect the trace, not just the final prompt.
Terminology: Topics vs. Subagents
Beginning April 2026, agent topics are renamed subagents. This is more than a UI change — topic is deprecated in the official Reference index, and subagent is the keyword to prefer for new code.
In practice, both terms appear in the field:
subagent :— preferred block keyword for new code.topic :— legacy keyword, still parses, still appears in older
recipes, blog posts, and existing customer agents.
@subagent.— preferred reference syntax.@topic.— legacy reference syntax, still works.
Functionally identical. When writing new agents, prefer subagent / @subagent. throughout. When reviewing or editing an existing agent, match the form already in use; do not silently flip terminology mid-file unless the user asks for migration.
Anatomy of an Agent
Every agent is a single Agent Script file containing these block types (roughly in this order):
| Block | Required | Purpose | |---|---|---| | config | yes | Agent identity: developer_name, agent_label, description, agent_type, default_agent_user. | | system | yes | Global instructions and message templates. Must define welcome and error. | | variables | optional | Global state shared across subagents: regular, linked, and (predefined) system variables. | | language | optional | Supported languages. | | connection | optional | External integrations, e.g. Enhanced Chat for @utils.escalate. | | start_agent | yes | The entry router. Runs at the start of every customer turn. Handles classification and routing. | | subagent | 1+ | A specialized capability. Contains description, reasoning.instructions, reasoning.actions, actions. (Legacy keyword: topic .) |
For full block reference, see references/syntax-reference.md.
File layout
In a Salesforce DX project, an Agent Script lives at:
force-app/main/aiAuthoringBundles//.agent
The directory is called the authoring bundle — the source-of-truth during development, alongside any supporting metadata. Agentforce DX commands (sf agent ...) operate on authoring bundles.
The Hybrid Reasoning Decision
The single most important design decision in Agent Script is what runs deterministically vs. what the LLM decides. Use this rubric:
| Situation | Use | |---|---| | Business rule with a clear true/false outcome (eligibility, threshold, status check) | Logic (-> with if/else) | | Sequence of actions that must run in a fixed order | Logic (run @actions.x chained) | | Setting state from an action's output | Logic (set @variables.x = @outputs.y) | | Generating a friendly, contextual customer message | Prompt (|) | | Choosing which of N optional capabilities to invoke based on intent | Tool surface (reasoning.actions) — LLM decides | | Filling an action input from free-form user input | ... token in the action input (LLM-extracted) | | Capturing free-form input directly into a variable | @utils.setVariables tool with variable's description | | Hard handoff to another subagent the moment a condition is met | transition to @subagent.x from logic | | Soft handoff offered to the LLM as one option among several | @utils.transition to @subagent.x exposed in reasoning.actions |
Bias toward determinism for business rules; bias toward LLM for phrasing, classification, and slot filling. Overloaded prompts with embedded business rules are the most common antipattern (see references/antipatterns.md).
Quick Reference
Resource references — always use the @ prefix:
@actions. # action defined in the current subagent
@variables. # global variable
@outputs. # action output (within run/set context)
@subagent. # another subagent (preferred)
@topic. # legacy alias for @subagent
@utils. # built-in utility (transition, setVariables, escalate)
@system_variables.user_input # latest customer utterance (read-only)
Variable interpolation in prompt text — use the bang-brace form:
| Hi {!@variables.user_name}, your order {!@variables.order_id} is on the way.
Operators (full list in syntax-reference.md):
== != >= # comparison
is None is not None # null check
and or not # logical
+ - # arithmetic (numbers only)
if / else only — there is no else if. Nest if you need it.
Indentation is whitespace-sensitive. Use spaces only — Salesforce recommends 3 spaces per level. Comments start with #.
For deeper coverage see:
references/syntax-reference.mdfor the complete language reference.references/patterns.mdfor idiomatic patterns.references/antipatterns.mdfor common pitfalls.
Authoring Workflow
When writing or refactoring an agent, follow this sequence:
Step 1 — Map the conversation surface
Before touching script, list:
- The customer intents the agent must handle.
- For each intent: what actions/data lookups are needed, and which business
rules gate which behavior.
- Which intents are independent (separate subagents) vs. variations of one
capability (one subagent).
This becomes your subagent decomposition. Aim for 3–7 subagents for typical agents — fewer means an overloaded subagent; more usually means over-decomposition.
Step 2 — Design the start_agent
start_agent runs at the start of every customer turn, not just the first. Use it for:
- Initializing variables that must always be set (e.g., session timestamps,
channel context).
- Classifying intent and exposing transitions to subagents as tools.
- Filtering — refusing to handle out-of-scope requests with a guarded prompt.
Keep start_agent short. Long classification prompts hurt routing accuracy.
Step 3 — Write each subagent
For each subagent:
- Description first. The description tells the LLM when to pick this
subagent. Be specific and use the same vocabulary the customer would use.
- Variables you depend on. If the subagent assumes the customer is verified,
transition unverified users elsewhere or guard with if.
- Reasoning instructions. Start with the minimum natural language needed
for the LLM to do its job. Layer in logic (->) only where determinism matters.
- Actions and tools. Define actions in
actions:. Expose them to the LLM
only via reasoning.actions: — and only when LLM choice is genuinely useful. Otherwise, call them deterministically with run @actions..
Step 4 — Wire transitions
Map every "and then…" path between subagents:
- Hard handoffs (always go to subagent X next): `transition to
@subagent.x` from the logic block.
- Optional handoffs (LLM decides): expose a
reasoning.actionstool
wrapping @utils.transition to @subagent.x.
- Delegated calls with return (rare): use a direct
@topic.
reference in reasoning.actions. Flow returns to the caller after the delegated subagent completes — this differs from transition to, which is one-way.
Step 5 — Test the prompt that actually reaches the LLM
In Agentforce Builder, preview the conversation and inspect the resolved prompt for each subagent. Most "agent does the wrong thing" bugs are visible in the resolved prompt: variables not interpolating, instructions in the wrong order, prompt instructions that contradict logic-set variables.
Review Checklist
When reviewing an Agent Script file, check in this order:
config.developer_name— unique in the org, follows naming rules
(letters, alphanumerics + underscore, no trailing underscore, no __).
system.welcomeandsystem.errorare present and on-brand.- Subagent descriptions are specific, distinct, and use customer
language. Overlapping descriptions cause routing flakiness.
start_agentis lean — no business logic, just routing and required
variable initialization.
- Variable mutability —
mutableonly where truly needed. Immutable
variables prevent whole classes of state bugs.
- Logic vs. prompt balance — business rules in
->, customer-facing
phrasing in |. Flag any prompt text containing literal numeric thresholds or hard-coded business rules (a smell for misplaced logic).
- Action exposure — every action in
reasoning.actionsshould benefit
from LLM choice. If it always runs, move it to logic with run @actions.
- Transitions — one-way intent is clear. No accidental loops between
subagents. No code "after" a transition that expects to run.
- Conflicting instructions — global
system.instructionsand
subagent-level overrides are not contradictory.
- Indentation — consistent within the file, not mixed spaces/tabs.
For each finding, distinguish correctness (will misbehave), robustness (might misbehave under edge cases), and style (works fine, but violates Salesforce's documented patterns).
Reference Files
Load on demand:
references/syntax-reference.md— Complete language reference: every
block type, every property, all operators, variable types, action targets, utility functions. Read when writing new script or verifying syntax.
references/patterns.md— Idiomatic patterns: identity verification,
slot filling, action chaining, conditional prompting, available-when filtering, system overrides, fetch-data-before-reasoning, required workflows. Read when designing a new subagent or stuck on "how would I express X".
references/antipatterns.md— Common mistakes and why they fail. Read
during reviews and when debugging unexpected agent behavior.
references/builder-and-dx.md— Surrounding tooling: Agentforce
Builder Canvas vs. Script view, Agentforce DX CLI commands, VS Code extension, Agentforce Vibes, authoring bundles, source-control workflow. Read when the question is about how to author or deploy, not what to write.
Verification Pointers
Agent Script is young (Public Beta November 2025, GA still rolling out across features). When in doubt, verify against:
- Canonical reference:
- Agent Script Recipes (sample apps):
- Open-source language tooling:
- Salesforce CLI release notes (weekly):
If a feature is unfamiliar or the syntax shown here looks outdated, prefer fetching the live documentation over relying on this skill's frozen content. Mark uncertain claims as [Unverified] in the response.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: rammc
- Source: rammc/salesforce-agent-script
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.