关于 service-itsm-agentic-setup-fulfiller-agent-configure
通过 Salesforce CLI 和 Next-Gen Authoring 流程,基于内置模板创建并激活 IT Service Fulfiller Agent。面向 IT 技术人员的工作,包括事件分流、案例摘要和字段更新。
主要功能
- 01创建 NGA 原生 Fulfiller Agent
- 02基于内置 ITSM 模板构建
- 03发布并激活 Agent bundle
- 04检查现有 Agent,避免重复创建
- 05通过 SOQL 验证活跃状态
适用场景
- 01搭建面向 IT 技术人员的 Agent
- 02支持事件分流和案例摘要
- 03更新字段并自动处理相关记录
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill service-itsm-agentic-setup-fulfiller-agent-configure安装后在 Claude Code 中输入/service-itsm-agentic-setup-fulfiller-agent-configure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/action-availability.mdcli-invocation.mderror-taxonomy.mdreactivation.mdreport-format.mdworkflow-detail.mdscripts/build-create-body.mjsclassify-action-availability.mjsclassify-activate-result.mjsclassify-agent-existence.mjsclassify-preflight.mjscreate-scratch-dir.mjsrender-report.mjsstrip-release-management.mjs详细介绍
创建 IT Service Fulfiller Agent
通过 Salesforce CLI(sf),将 IT Service Fulfiller Agent 创建并激活为 Next-Gen Authoring(NGA)原生 Agent — 基于 Agent-Script(AiAuthoringBundleDefVer/bundle),原生显示在 Agentforce Studio 的 Agents 列表中,且没有外部链接图标。此技能不会调用旧版 /connect/service-itsm/createAgent;而是复用随附的 ITSM Fulfiller 模板中的 agentScript,并将其送入 NGA bundle 流程:
POST /nextgen-authoring/bundles(createBundleWithVersion)— 从模板的 Agent Script 创建 bundle 和首个版本。POST /nextgen-authoring/bundle-versions/{id}/publish— 发布该版本(创建底层的BotDefinition/BotVersion)。POST /nextgen-authoring/bundle-versions/{id}/activate— 激活该版本。
命令:使用 sf api request rest 进行 Connect API GET/POST;使用 sf data query 执行 SOQL 幂等性检查和验证读取。
辅助脚本(通过 Bash 调用)包含所有 JSON 解析和决策规则,因此模型无需人工查看响应正文(A9):classify-preflight.mjs(Studio 访问权限 + 模板预配结果)、classify-agent-existence.mjs(根据 BotDefinition SOQL 检查幂等性 + 是否需要重新激活)、build-create-body.mjs(对模板的 agentScript 进行 HTML 解码,根据组织启用的功能对其进行标准化处理,方法是使用 strip-release-management.mjs,替换 config.developer_name/config.agent_label,并将 bundle 创建正文写入 JSON 文件,避免大型内容和自由文本引号进入内联 shell 字符串)、render-report.mjs(确定性报告渲染器 — 聊天轮次和 harness 文件的唯一报告文本来源)。
Fulfiller Agent 是面向 IT 技术人员的助手 — 用于事件分诊、案例摘要、字段更新和相关记录自动化。面向员工的自助服务入口是 service-itsm-agentic-setup-employee-agent-configure。
范围
- 范围内:读取
agent-templates;提取 Fulfiller 模板的 Agent Script(svc_itsm_intelligence__ITSrvcMgmtFulfiller);通过createBundleWithVersion→publish→activate将 Fulfiller Agent 创建为 NGA 原生 Agent;通过 SOQL 验证其已生效;遇到重复开发者名称时幂等跳过;规范化创建的 Agent Script,使其能在任何 Agentforce-for-IT-Service 组织中顺利激活(内部步骤,不向用户展示 — 见下文)— 全部通过sf完成。 - 范围外:Employee Agent —
svc_emp_intelligence__下的广泛或约 47 种专项配置(service-itsm-agentic-setup-employee-agent-configure);启用组织级功能开关(由service-itsm-agentic-setup-agentforce-studio-validate验证);低级主题/操作编写;权限集分配;内容 bundle 部署;CMDB CRUD;Discovery / Service Graph;旧版createAgent路由。
前提条件
如果未满足以下任一条件,sf 会显示身份验证错误或 401/403/404;原样显示原始错误并停止 — 不得捏造状态。
sfCLI 已通过身份验证并连接到目标组织(sf org display -o <alias>显示 Connected)。所有调用都使用--target-org <alias>;切勿手动提取访问令牌。- API v67.0+ — 固定在 URL 路径中;不得手动编辑为低于最低要求的版本。
- 已预配 ITSM 功能和 Fulfiller 模板(
svc_itsm_intelligence__ITSrvcMgmtFulfiller)。如果agent-templates没有返回任何内容或路由返回 404,请运行service-itsm-agentic-setup-agentforce-studio-validate。 - PATH 中的
node版本为 18 或更高。
操作一览
| 事项 | 命令 | 说明 |
|---|---|---|
| Studio 访问权限(前置条件读取) | sf api request rest "/services/data/v67.0/agentforce-studio/access/Agents" --method GET -o <alias> | hasAccess=false ⇒ 交由前置条件处理 |
| 列出 Agent 模板 + Agent Script(读取) | sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" --method GET -o <alias> | 必须使用 agentType=AgentforceEmployeeAgent;确认 Fulfiller 模板存在且 agentScript 非空 |
| 枚举现有 Agent + 最新版本状态(读取) | 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> --json | 主要通过模板的 botDefinitionId(Phase-1 行)进行匹配;OR AgentTemplate= 是防御性回退,可捕获从 OOTB 源模板(svc_itsm_intelligence__ITSrvcMgmtFulfiller = Phase-1 的 template.id)实例化的现有 Agent,不论其 DeveloperName;OR DeveloperName= 是此处的实际保护措施——用于正常的 Fulfiller 情况(从未预先配置;AgentTemplate 为 null),也用于保护指向已删除目标的失效 Id 链接。由 scripts/classify-agent-existence.mjs 分类;最新版本为 Active ⇒ ALREADY-CREATED;最新版本为 Inactive ⇒ 提供重新激活选项 |
| 创建 NGA bundle(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" --method POST --body @<body-file> -o <alias> | 请求体由 scripts/build-create-body.mjs 构建;响应中的 id = bundle 版本 Id |
| 发布 bundle 版本(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/publish" --method POST --body '{}' -o <alias> | 返回 publishedBotId/publishedBotVersionId——创建底层的 BotDefinition/BotVersion |
| 激活 bundle 版本(写入) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/activate" --method POST --body '{}' -o <alias> | 成功时返回空响应;此时 Agent 已上线并采用 NGA 原生格式 |
| 激活现有的非活动版本(写入) | sf api request rest "/services/data/v67.0/connect/bot-versions/<latestVersionId>/activation" --method POST --body '{"status":"Active"}' -o <alias> | 仅用于重新激活路径(Phase 2b)——跳过创建/发布 |
| 验证 Agent 已上线(读取) | sf data query -q "SELECT ... FROM BotDefinition WHERE Id='<verifyId>'" -o <alias> --json | <verifyId> = 创建路径中的 publishedBotId(Phase-5),或 ALREADY-CREATED / 重新激活时由 Phase-2 分类器返回的匹配项 Id(其 botDefinitionId/agentId)——不是 Phase-1 模板中的 null botDefinitionId,也绝不是收集到的 developerName;确认 BotDefinition 存在且最新版本为 Active |
完整命令格式和 ITSM Connect API 参考见 references/cli-invocation.md;重新激活路径调用及幂等性判定表见 references/reactivation.md;响应正文错误代码和常见问题见 references/error-taxonomy.md。
切勿提取访问令牌。 直接使用
sf api request rest/sf data query——它们会使用 CLI 为目标组织保存的会话。不要从sf org display中提取accessToken,再用它手动构造 HTTP 请求;这会绕过 CLI 会话,并将 bearer token 泄露到 shell 上下文中。
--json规则。sf data query接受--json(结果会放在.result.records[]信封中——分类器依赖此格式)。sf api request rest不接受——在该命令中省略--json;其标准输出中的原始正文已经是 JSON。
已交付的 ITSM 履行者 Agent 模板
| 模板标识符 | 默认开发者名称 |
|---|---|
svc_itsm_intelligence__ITSrvcMgmtFulfiller(masterLabel "IT Service Fulfiller") | IT_Service_Fulfiller_Agent |
agentScript字段才是 NGA 创建操作的事实来源,而不是id。scripts/build-create-body.mjs按masterLabel匹配,对agentScript进行 HTML 解码,并将收集到的<developerName>/<label>替换到config.developer_name/config.agent_label中,然后才将其设为 bundle 的resourceContent。面向员工的 Agent 由service-itsm-agentic-setup-employee-agent-configure处理。
内部模板规范化——绝不向用户展示。 解码后的脚本成为
resourceContent之前,scripts/strip-release-management.mjs会移除topic ReleaseManagement:代码块,以及其go_to_ReleaseManagement:选择器转换和路由条目。该主题唯一的操作svc_itsm_intelligence__SummarizeRelease受组织偏好设置(ReleaseManagementPref)控制;对于尚未启用该设置的组织,/actions/custom/generatePromptResponse不会展示此操作。若将其一并交付,activate会返回 HTTP 200,但响应正文会静默失败,显示{success:false, "... does not exist"}。classify-action-availability.mjs会应用完全相同的转换,以便 Phase 2c 扫描相同的规范化脚本——两个调用方必须保持一致。如果代码块不存在,该转换不会执行任何操作(可安全应对未来的模板修订)。此规范化属于实现细节:聊天说明、写入前确认步骤或报告中都不得提及该规范化、已移除的子 Agent 或 Release Management——管理员只会看到 Agent 已创建并激活。
架构 — 创建阶段
| 阶段 | 操作 | 使用的工具 |
|---|---|---|
| 预检 | 确认有权访问 Studio(agentforce-studio/access/Agents),并确认模板中存在 agentScript | Bash(sf api request rest) |
| 枚举 | 读取 Fulfiller 模板(agent-templates)、现有 Agent 及最新版本状态(对 BotDefinition/BotVersions 执行 SOQL);通过脚本判断幂等性及是否需要重新激活 | Bash(sf、node) |
| 写入前确认 | 显示确切的 developerName + 标签(NGA 创建目标);或者,如果现有 Agent 处于非活动状态,则改为显示重新激活选项,并要求用户明确回复“yes” | AskUserQuestion |
| 创建*(仅创建路径)* | POST createBundleWithVersion(根据解码并替换后的模板 Agent Script 构建 NGA bundle 和首个版本) | Bash(sf api request rest、node) |
| 发布*(仅创建路径)* | POST .../bundle-versions/<id>/publish(创建底层的 BotDefinition/BotVersion) | Bash(sf api request rest) |
| 激活 | POST .../bundle-versions/<id>/activate(创建路径),或 POST .../connect/bot-versions/<latestVersionId>/activation,并传入 {"status":"Active"}(重新激活路径——跳过创建/发布) | Bash(sf api request rest) |
| 验证 | 通过 SOQL 读取 BotDefinition/BotVersions,并确认 Agent 存在且最新版本处于活动状态 | Bash(sf data query) |
幂等性:主要以模板的 botDefinitionId(Phase-1 agent-templates 行——平台权威的模板→BotDefinition 链接)作为键;若无,则依次回退到 BotDefinition 的 AgentTemplate(OOTB 命名空间源模板 = Phase-1 template.id),再回退到收集到的 <developerName>。Phase-2 的读取查询为 BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(OR AgentTemplate= 部分是防御性键,可捕获从源模板实例化的现有 Agent,而不论其 DeveloperName 是什么;OR DeveloperName= 部分既是 botDefinitionId 为空时的回退键——这是 Fulfiller 的常见情况——也是悬空 Id 链接的检查机制,即其目标 BotDefinition 已被删除),并读取最新的 BotVersion.Status(由辅助脚本分类)。结果:所有键均未匹配 ⇒ exists:false ⇒ 创建;latestVersionStatus:"Active" ⇒ 已创建(跳过写入,继续执行 Phase 7 验证);needsActivation:true(最新版本为 Inactive)⇒ 提供重新激活现有版本的选项,而不是创建新 Agent(Phase 2b),而非静默跳过或重复创建。**回退机制为何重要:**Fulfiller 从不会预先配置,而且此技能的创建路径不会写入 templateName,因此模板的 botDefinitionId 和 Agent 的 AgentTemplate 始终为 null——以 <developerName> 为键的回退机制才是实际捕获重复运行的保护措施;若 botDefinitionId 为 null 就直接创建,会导致重复创建并触发 DUPLICATE_VALUE。服务器确实会在发布时拒绝重复的 DeveloperName(唯一约束 → 清理 bundle),但只有此 Phase-2 读取才能将重复运行转为正常跳过,而不是触发此硬错误。
澄清问题
向用户收集以下信息(仅询问对话上下文中尚未提供的信息):
| 字段 | 说明 | 默认值 |
|---|---|---|
| 目标组织 | 要在其中创建 Agent 的 sf 组织别名 | 默认组织(sf config get target-org) |
| 开发者名称 | Agent 唯一的 DeveloperName | IT_Service_Fulfiller_Agent |
| 标签 | 面向用户显示的 Agent 标签 | IT Service Fulfiller Agent |
| 确认写入 | 在创建/发布/激活流程开始前明确确认 | 必填 — 显示 developerName + label,并要求通过 AskUserQuestion 回复“yes” |
幂等性检查主要依据模板的 botDefinitionId(Phase-1 行),如果没有,则回退检查 BotDefinition 的 AgentTemplate(防御性检查——对于从未预先配置的 Fulfiller,该值为 null),再回退到收集的 <developerName>;当该值为 null 时,这是此处实际用于拦截重复操作的检查项。验证读取依据发布响应中的 publishedBotId(创建路径)或模板的 botDefinitionId(已创建/重新激活路径)。收集的 <developerName> 和 <label>(默认值分别为 IT_Service_Fulfiller_Agent / IT Service Fulfiller Agent)也会贯穿 createBundleWithVersion 请求体——包括外层的 apiName / label,以及 Agent Script 内替换后的 config.developer_name / config.agent_label。切勿在一次调用中硬编码名称、另一次调用中再收集名称——如果 bundle 的外层 apiName 与脚本内部的 developer_name 不一致,平台会使两者发生偏离。在组织中创建 Agent 会配置并激活一个实时 Agent;用户必须明确批准写入操作。
工作流
将 <alias> 替换为收集到的目标组织,并将 <developerName> / <label> 替换为收集到的值。完整的命令格式和各阶段的结果分支处理方式见 references/workflow-detail.md——下方的阶段摘要列出了每个步骤及其关键规则;参考文件中包含可直接复制的确切 sf / node 调用。
0. 阶段 0 — 建立 ${SCRATCH_DIR}。 调用确定性辅助脚本(路径以技能根目录为基准,因此无论 shell 的 CWD 为何都能解析):SCRATCH_DIR="$(node "<skill_dir>/scripts/create-scratch-dir.mjs" "${outputDir:-}")"。辅助脚本选择基础目录(${TMPDIR},否则 /tmp,否则将 harness 的 ${outputDir} 作为最后手段 — scratch 保持在计分用的 ${outputDir} 目录树之外),并在 stdout 输出创建的目录。所有临时 JSON 都放在 ${SCRATCH_DIR} 下;持久化的 ${outputDir}/report.md 保留在 harness 目录下。
- 阶段 1 — 预检。 将 Studio 访问读取结果写入
${SCRATCH_DIR}/studio-access.json,并将agent-templates读取结果(带上必需的agentType=AgentforceEmployeeAgent查询参数)写入${SCRATCH_DIR}/agent-templates.json,然后按此参数顺序传入两个文件路径,再传入标签进行分类:node "<skill_dir>/scripts/classify-preflight.mjs" ${SCRATCH_DIR}/studio-access.json ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller"。分类器会从匹配行输出template.botDefinitionId、template.id和template.masterLabel— 请捕获这三项;botDefinitionId是阶段 2 的首要幂等键,template.id(BotDefinition 的AgentTemplate)是第一个备用键,<developerName>是最后一个备用键;masterLabel是报告中的显示标签,不是键。 根据verdict分支:READY⇒ 阶段 2;NOT-READY⇒ 通过AskUserQuestion移交前置条件(回答“是”时委派给service-itsm-agentic-setup-agentforce-studio-validate);ERROR⇒ 呈现错误并停止;studio.signal="CANNOT-CONFIRM"(已确认的 404)不会阻止流程。 - 阶段 2 — 幂等性(首要键
botDefinitionId,备用键依次为AgentTemplate和<developerName>)。 从阶段 1 获取template.botDefinitionId和template.id。若存在botDefinitionId⇒ 执行带有BotVersions子查询的 SOQL:BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(子查询是必需的 — 否则needsActivation将一直为 false;OR子句能让悬空的 Id 链接 — 目标已删除 — 回退到现存 Agent,而不是错误地得到exists:false并重复创建)。若botDefinitionId为空/null(Fulfiller 的常见情况 — 模板行永远不会回填)⇒ 不要跳过检查直接创建;读取BotDefinition WHERE AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(先前运行中自创建的 Agent 的AgentTemplate为 null,因此通过DeveloperName找回它;AgentTemplate可匹配任何 DeveloperName 下假设存在的模板实例化 Agent)。<agentTemplate>是阶段 1 的template.id。无论哪种情况,都通过以下命令分类:node "<skill_dir>/scripts/classify-agent-existence.mjs" ${SCRATCH_DIR}/bot-existing.json "<botDefinitionId-or-empty>" "<developerName>" "<agentTemplate>"。分支:exists:false⇒ 阶段 2c(先检查操作可用性,再创建);exists:true+needsActivation:false⇒ ALREADY-CREATED(直接跳至阶段 7 — 不进行操作可用性检查;现存的已激活 Agent 的操作已配置好);exists:true+needsActivation:true⇒ 阶段 2b。退出码非零 ⇒ 呈现 CLI 错误;绝不要假定记录不存在。备用键的原因: Fulfiller 从不预配置,因此botDefinitionId和AgentTemplate始终为 null — 若不检查 developerName,就会重新创建并遇到DUPLICATE_VALUE。 - 阶段 2b — 提供重新激活选项。 使用
AskUserQuestion提问:“Fulfiller Agent<developerName>已存在,但最新版本处于 Inactive 状态。要激活它吗?”。选择是时:向/connect/bot-versions/<latestVersionId>/activation发送POST,正文为{"status":"Active"},并将结果写入${SCRATCH_DIR}/activate-response.json,然后执行node "<skill_dir>/scripts/classify-activate-result.mjs" ${SCRATCH_DIR}/activate-response.json—PASS⇒ 阶段 7(判定为 ACTIVATED);FAIL⇒ 原样呈现messages[],若消息指出缺少可调用操作,则提供阶段 2c 的 permset 移交选项;不要报告 ACTIVATED;CANNOT-CONFIRM⇒ 转至阶段 7,通过 SOQL 验证。选择否时:停止,不写入任何内容。 - 阶段 2c — 操作可用性预检(仅创建路径;仅在阶段 2 的
exists:false分支中执行)。 将sf api request rest "/services/data/v67.0/actions/custom/generatePromptResponse" --method GET的结果写入${SCRATCH_DIR}/generate-prompt-response.json,然后执行node "<skill_dir>/scripts/classify-action-availability.mjs" ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller" ${SCRATCH_DIR}/generate-prompt-response.json(扫描规范化后的 Agent Script — 即创建步骤使用的相同内部转换,因此其底层操作受组织偏好设置控制的子 Agent 不会被误判为缺失,也不会阻碍激活)。根据verdict分支:READY⇒ 阶段 3;NOT-READY⇒ 在 “Attention” 标题下呈现结果(绝不要称为“Blocker”),并通过AskUserQuestion提供移交给service-itsm-agentic-setup-itsm-agentforce-permset-assign的选项(原样呈现missing[]— 不要继续写入;激活调用会返回 HTTP 200,但响应正文会静默失败并包含{success:false});CANNOT-CONFIRM⇒ 呈现原因并谨慎继续(阶段 6 的激活结果分类器会捕获静默失败响应正文)。完整约定见references/action-availability.md。 - 阶段 3 — 写入前确认(必需,仅创建路径)。 若提供了
${outputDir},先通过render-report.mjs生成检查点文件,设置verdict:"PENDING CONFIRMATION"(交互式运行时跳过)。然后触发AskUserQuestion确认关卡,展示 developerName + 标签 + “基于 Fulfiller 模板 Agent Script 的 NGA 原生 Agent”。仅在明确回答“是”时继续;回答“否”时,重新渲染并设置verdict:"DECLINED"。 - 阶段 4 — 创建。 执行
scripts/build-create-body.mjs ${SCRATCH_DIR}/agent-templates.json "IT Service Fulfiller" "<developerName>" "<label>" ${SCRATCH_DIR}/create-bundle-body.json(辅助脚本会重新读取阶段 1 的模板 JSON,对匹配的agentScript进行 HTML 解码并规范化 — 与阶段 2c 使用相同的内部转换 — 替换内部的config.developer_name/config.agent_label,并将请求正文写入文件),然后执行POST /nextgen-authoring/bundles --body @${SCRATCH_DIR}/create-bundle-body.json。捕获响应中的id— 这是阶段 5–6 使用的bundleVersionId,不是bundleId。遇到403 FUNCTIONALITY_NOT_ENABLED/404⇒ 触发阶段 1 的移交;构建脚本退出码为 3 ⇒ 呈现 stderr。 - 阶段 5 — 发布。 执行
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/publish --body '{}'(必须使用空请求正文)。成功响应:{ lastPublishedOn, publishedBotId, publishedBotVersionId }— 此调用会创建底层的BotDefinition/BotVersion。发生任何错误 ⇒ 原样呈现;绝不要激活尚未发布的版本。 - 阶段 6 — 激活。 执行
POST /nextgen-authoring/bundle-versions/<bundleVersionId>/activate --body '{}',将结果写入${SCRATCH_DIR}/activate-response.json,然后执行node "<skill_dir>/scripts/classify-activate-result.mjs" ${SCRATCH_DIR}/activate-response.json— 当引用的可调用操作未显示出来时,激活可能返回 HTTP 200,但响应正文会静默失败并包含{success:false};分类器会捕获此情况。PASS⇒ 阶段 7;FAIL⇒ 呈现messages[],若消息指出缺少操作,则提供阶段 2c 的 permset 移交选项;不要报告 CREATED;CANNOT-CONFIRM⇒ 转至阶段 7,通过 SOQL 验证。 - 阶段 7 — 验证。 执行 SOQL
BotDefinition WHERE Id='<id>'(并带上BotVersions子查询)并分类 —<id>在创建路径中是阶段 5 捕获的publishedBotId;在 ALREADY-CREATED/重新激活路径中,则是阶段 2 分类器返回的现存匹配 Id(其botDefinitionId/agentId输出 — 即匹配记录的实际BotDefinition.Id),而不是阶段 1 模板的botDefinitionId(对于 Fulfiller,该值始终为 null,因此在命中任何现存 Agent 时,验证会执行WHERE Id='',并在成功跳过/激活后错误地报告失败)。确认exists:true, count:1, latestVersionStatus:"Active"。任何不符之处 ⇒ 原样报告,不要捏造成功结果。 - 阶段 8 — 汇总判定。 通过重新调用
render-report.mjs输出 CREATED / ALREADY-CREATED / ACTIVATED / FAILED(阶段 2b 路径上的判定为 ACTIVATED)— 它是报告文本的唯一来源。绝不要在判定、聊天叙述或报告中暴露内部记录 ID — 包括 bundle 版本id、publishedBotId/BotDefinition或BotVersion— 它们仅用于驱动发布/激活/验证调用,对管理员没有意义。仅按状态/名称报告(“已创建并激活”),不要写“Bundle 已创建(版本 ID …)”/“已发布(BotDefinition …)”。若提供了${outputDir},覆盖${outputDir}/report.md;否则将 stdout 作为本轮报告输出。 - 阶段 9 — 运行时访问移交(现存 Agent 判定时必需)。 若阶段 8 的判定为
CREATED、ALREADY-CREATED或ACTIVATED(此时存在一个现存 Agent),则触发AskUserQuestion— 使用与阶段 1 前置条件和阶段 2c permset 选项相同的强制移交模式 — 询问是否现在设置 Agent 的运行时访问权限:“Agent 已上线,但它的操作会调用平台功能(Prompt Templates、Data Cloud、Unified Catalog),用户必须先获得访问权限才能运行这些功能,否则打开 Agent 时会失败。现在设置运行时访问权限吗?”。选择是时,委派给service-itsm-agentic-setup-agent-runtime-access-assign(该流程会执行自己的目标用户选择和写入前确认关卡)。选择否时,停止 — 报告中的“设置访问权限”后续步骤说明即作为记录。对于PENDING CONFIRMATION、DECLINED或FAILED,不要触发此问题(没有可授予访问权限的现存 Agent)。这是一个强制的AskUserQuestion,而非报告文本 —render-report.mjs仍会原样输出通俗易懂的“设置访问权限”说明;这个问题才能保证每次都实际提出此选项。
Rules / Constraints
| 约束 | 原因 |
|---|---|
所有调用都通过 sf api request rest / sf data query;绝不提取访问令牌 | 会将持有者令牌泄露到 shell 上下文中;CLI 存储的会话才是正确的调用方式 |
幂等性检查主要依据模板的 botDefinitionId(Phase-1 行),若为 null,则回退到收集到的 <developerName>;验证读取依据发布后的 publishedBotId / botDefinitionId;同一个 <developerName> / <label> 也会贯穿创建请求体(外层 apiName / label,以及替换后的 config.developer_name / config.agent_label) | Fulfiller 从未预先配置,且创建流程省略了 templateName,因此其模板 botDefinitionId 始终为 null——<developerName> 回退机制可拦截重复运行(仅按名称查找时若未命中 → DUPLICATE_VALUE)。创建请求体中的硬编码值与收集值不一致,会导致 bundle 的外部标识与脚本内部标识不一致 |
预检、幂等性检查、bundle 请求体构建和报告渲染都在 scripts/*.mjs 中实现,而非写在说明文字中(A9) | JSON 解析、masterLabel 匹配、hasAccess 读取和判定结果输出都是确定性的;约 70KB 的 Agent Script 和自由文本中的撇号无法安全地插入 shell 字符串——辅助脚本中的 JSON.stringify 会对它们进行转义 |
创建的 Agent Script 在发布前会先标准化(strip-release-management.mjs);classify-action-availability.mjs 会应用相同的转换。此标准化仅在内部进行——绝不要在面向用户的输出中提及此操作、被移除的子 Agent 或 Release Management(聊天、写入确认步骤或报告中均不得提及) | 被移除的子 Agent 唯一的操作 svc_itsm_intelligence__SummarizeRelease 受 ReleaseManagementPref 控制;若发布该操作,在任何未启用此偏好的组织中,activate 都会返回 {success:false} 的静默失败响应。移除此操作(而不是强制启用偏好)可让 Fulfiller 在任何 Agentforce-for-IT-Service 组织中顺利激活;两个调用方必须保持同步,否则 Phase 2c 会将已移除的操作误判为缺失 |
按顺序执行三次调用:createBundleWithVersion → publish → activate,并始终使用同一个已捕获的 bundleVersionId(响应中的 id,而非 bundleId) | 平台强制执行 DRAFT → published → active 状态流转;响应体 / 空响应体 / --json / agentType / HTML 解码相关注意事项见 references/error-taxonomy.md |
使用 BotVersions 子查询枚举 BotDefinition;若状态为 Active,则跳过创建;若状态为 Inactive,则提供 Phase-2b 重新激活选项——绝不静默跳过,也绝不重复创建 | 子查询用于区分 Active / Inactive;服务器会在发布时拒绝重复的 DeveloperName(唯一约束冲突 → 清理 bundle),因此正是这次读取让重复运行能够优雅跳过,而不是触发硬错误 |
| 创建流程或重新激活调用前,必须执行写入前确认步骤 | 两者都会更改实时组织状态——必须获得用户的明确批准 |
遇到 hasAccess=false / 403 FUNCTIONALITY_NOT_ENABLED 时,提供就绪情况交接选项——绝不在此处启用功能;绝不调用旧版 /connect/service-itsm/createAgent | 启用功能属于 Setup UI / 管理员操作;createAgent 会生成带外部链接图标的 Setup 页面机器人(不是此技能所需类型的 Agent) |
绝不在聊天叙述、写入确认步骤或报告中显示内部记录 ID——包括 bundle 版本 id(1bZ…)、publishedBotId / BotDefinition(0Xx…)、BotVersion(0Xv…);报告只能按状态 / 名称呈现进度和判定结果 | 捕获这些 ID 仅用于驱动 publish → activate → verify → verify-read 调用;对进行设置的管理员毫无意义,只会造成干扰。render-report.mjs 仅渲染状态行,并会防御性地清除所有 ID;模型也必须避免回显这些内容(绝不要写“Bundle created (version id 1bZ…)” / “Published (BotDefinition 0Xx…)”) |
| 出错时报告 CLI 返回的准确文本 | 便于支持团队诊断故障——这是唯一允许原样错误文本中出现 ID 的位置,用户需要将其转交给支持团队 |
验证清单
- 由
classify-preflight.mjs对预检进行分类(PASS 或已记录的 CANNOT-CONFIRM);若为 FAIL,则提供交接;若为 ERROR,则显示原始错误。 - 幂等性以模板的
botDefinitionId(Phase-1 行)为依据,并以 BotDefinition 的AgentTemplate(Phase-1template.id)作为防御性首选回退值,以收集到的 developerName 作为实际校验依据;读取并分类BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(这些OR条件可涵盖botDefinitionId为 null 或失效的情况;对于AgentTemplate为 null 的、从未预配的 Fulfiller,也可涵盖通过 DeveloperName 自行创建的重复项),以及最新的BotVersion.Status(包含子查询);所有这些操作均须在任何写入之前完成。 - 如果
needsActivation:true,则提供 Phase-2b 重新激活选项 — 不得静默跳过,也不得重复创建。 - 在 Phase 3(创建)或 Phase 2b(重新激活)执行任何写入之前,必须获得用户明确确认。
- 通过
build-create-body.mjs构建 Bundle 正文,并使用收集到的developerName/label,通过--body @<file>发送 POST 请求;或者正确跳过写入。 - 发布和激活使用相同的
bundleVersionId(响应中的id);重新激活使用POST /connect/bot-versions/<id>/activation;绝不调用旧版createAgent。 - Phase-7 验证确认
BotDefinition存在,且最新版本为 Active。 - 对于实时 Agent 结论(CREATED / ALREADY-CREATED / ACTIVATED),必须通过
AskUserQuestion提出 Phase-9 运行时访问权限交接(用户回答“yes”时委派给service-itsm-agentic-setup-agent-runtime-access-assign);对于 PENDING CONFIRMATION / DECLINED / FAILED,则不得提出。 - 绝不提取访问令牌;最终结论中不得显示任何内部记录 ID(Bundle 版本
id、publishedBotId/BotDefinition、BotVersion),包括聊天内容、写入确认步骤或报告 — 仅显示状态/名称(原始 ID 仅可出现在逐字引用的错误中)。
输出格式
报告布局由 scripts/render-report.mjs 确定性生成 — 它是聊天轮次和执行框架的 ${outputDir}/report.md 共用的报告文本唯一来源。绝不要在文字中手动编排布局(A9);始终调用此辅助程序。完整的渲染格式、报告状态 JSON 架构和检查点写入规则见 references/report-format.md。
最终结论:CREATED | ALREADY-CREATED | ACTIVATED | PENDING CONFIRMATION | DECLINED | FAILED。设置 ${outputDir} 时,在 Phase 3、Phase 6(或 Phase 2b)和 Phase 8 写入 — 每次写入都会覆盖同一个文件。在交互式/聊天界面中跳过这些写入。对于实时 Agent 结论,Phase-9 运行时访问权限交接会在 Phase-8 报告之后触发;它不会更改结论,也不会重新渲染报告。
参考文件索引
| 文件 | 阅读时机 |
|---|---|
references/workflow-detail.md | 查看各阶段完整的判定分支说明,SKILL 正文对此进行了概述(Phase-1 ERROR/NOT-READY/CANNOT-CONFIRM、Phase-2 分类器输出、Phase-4 创建响应、错误分支) |
references/report-format.md | 每次调用 render-report.mjs 时查看——${outputDir}/report.md 的渲染格式和三检查点写入策略 |
references/cli-invocation.md | 每个阶段查看——精确的 sf 调用形式、禁止提取令牌规则、ITSM Connect API 参考、三个辅助脚本的契约 |
references/action-availability.md | Phase 2c(操作可用性预检、创建路径)和 Phase 2b/6(激活结果分类器)——静默失败的正文捕获、权限集交接措辞 |
references/reactivation.md | 重新激活路径(needsActivation:true)——直接调用 POST /connect/bot-versions/{id}/activation 以及完整的幂等性判定表 |
references/error-taxonomy.md | 出现任何非 2xx 响应、意外的空正文或脚本非零退出时查看——响应正文错误代码和常见误区 |
scripts/render-report.mjs | 每个写入 ${outputDir}/report.md 的检查点(Phase-3 门控、Phase-6 创建成功、Phase-8 最终阶段)——根据阶段状态 JSON 生成确定性渲染结果 |
scripts/strip-release-management.mjs | 内部 Agent Script 规范化——由 build-create-body.mjs(创建正文)和 classify-action-availability.mjs(Phase 2c 扫描)导入;两者都必须调用它,否则结果会不一致 |