service-itsm-agentic-setup-fulfiller-agent-configure
service-itsm-agentic-setup-fulfiller-agent-configure について
Salesforce CLI と Next-Gen Authoring パイプラインを使い、同梱テンプレートから IT Service Fulfiller Agent を作成・有効化するスキルです。インシデントのトリアージやケース更新など、IT 技術者向けの業務を対象とします。
主な機能
- 01NGA ネイティブ Fulfiller Agent の作成
- 02同梱 ITSM テンプレートからの構築
- 03Agent バンドルの公開と有効化
- 04既存 Agent の確認による重複防止
- 05SOQL による有効状態の検証
活用シーン
- 01IT 技術者向け 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 を作成する
Next-Gen Authoring(NGA)ネイティブエージェント(Agent-Script ベースの AiAuthoringBundleDefVer/バンドル)として IT Service Fulfiller Agent を作成して有効化します。Agentforce Studio の「Agents」リストに外部リンクアイコンなしでネイティブに表示されるエージェントを、すべて Salesforce CLI(sf) から作成します。このスキルはレガシーの /connect/service-itsm/createAgent を呼び出しません。代わりに、提供済みの ITSM Fulfiller テンプレートの agentScript を再利用し、NGA バンドルパイプラインに渡します。
POST /nextgen-authoring/bundles(createBundleWithVersion)— テンプレートの Agent Script からバンドルと最初のバージョンを作成します。POST /nextgen-authoring/bundle-versions/{id}/publish— バージョンを公開します(基盤となるBotDefinition/BotVersionを作成します)。POST /nextgen-authoring/bundle-versions/{id}/activate— 有効化します。
コマンド:Connect API の GET/POST には sf api request rest、SOQL の冪等性チェックと検証には sf data query を使用します。
ヘルパースクリプト(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 を置換します。また、大きなコンテンツやフリーテキスト内の引用符がインラインのシェル文字列に含まれないよう、バンドル作成本文を JSON ファイルに書き込みます)、render-report.mjs(チャットの応答とハーネスファイルで共通のレポートテキストを生成する、決定論的なレポートレンダラー)を使用します。
Fulfiller エージェントは、IT 技術者向けアシスタントです。インシデントのトリアージ、ケースの要約、項目の更新、関連レコードの自動化を行います。従業員向けセルフサービスの窓口は service-itsm-agentic-setup-employee-agent-configure です。
対象範囲
- 対象範囲内:
agent-templatesの読み取り、Fulfiller テンプレート(svc_itsm_intelligence__ITSrvcMgmtFulfiller)の Agent Script 抽出、createBundleWithVersion→publish→activateによる Fulfiller エージェントの NGA ネイティブエージェント としての作成、SOQL による稼働状態の検証、開発者名が重複する場合の冪等なスキップ、作成した Agent Script を任意の Agentforce for IT Service 組織で問題なく有効化できるように正規化(内部処理であり、ユーザーには表示しません。詳細は下記を参照)— すべてsf経由で行います。 - 対象範囲外:Employee エージェント、
svc_emp_intelligence__配下の広範な約 47 種類の専門エージェント(service-itsm-agentic-setup-employee-agent-configure)、組織レベルの機能トグルの有効化(service-itsm-agentic-setup-agentforce-studio-validateで検証)、低レベルのトピック/アクションの作成、権限セットの割り当て、コンテンツバンドルのデプロイ、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 Script の一覧表示(読み取り) | sf api request rest "/services/data/v67.0/connect/service-itsm/agent-templates?agentType=AgentforceEmployeeAgent" --method GET -o <alias> | agentType=AgentforceEmployeeAgent が必須です。Fulfiller テンプレートと空でない agentScript を確認します |
| 既存のエージェントと最新バージョンのステータスを列挙(読み取り) | 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= は、DeveloperName に関係なく、OOTB ソーステンプレート(svc_itsm_intelligence__ITSrvcMgmtFulfiller = Phase-1 の template.id)からインスタンス化された稼働中のエージェントを検出するための防御的なフォールバックです。OR DeveloperName= が実際のガードです。通常の Fulfiller ケース(事前プロビジョニングされておらず、AgentTemplate が null)と、リンク先が削除されている無効な Id リンクに対するガードです。scripts/classify-agent-existence.mjs で分類します。最新バージョンが Active の場合 ⇒ ALREADY-CREATED、Inactive の場合 ⇒ 再アクティブ化を提示します |
| NGA バンドルを作成(書き込み) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundles" --method POST --body @<body-file> -o <alias> | scripts/build-create-body.mjs で本文を構築します。レスポンスの id はバンドルのバージョン Id です |
| バンドルバージョンを公開(書き込み) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/publish" --method POST --body '{}' -o <alias> | publishedBotId/publishedBotVersionId を返します。基盤となる BotDefinition/BotVersion が作成されます |
| バンドルバージョンを有効化(書き込み) | sf api request rest "/services/data/v67.0/nextgen-authoring/bundle-versions/<bundleVersionId>/activate" --method POST --body '{}' -o <alias> | 成功時は空のレスポンスです。エージェントが稼働状態になり、NGA ネイティブになります |
| 既存の非アクティブなバージョンを有効化(書き込み) | sf api request rest "/services/data/v67.0/connect/bot-versions/<latestVersionId>/activation" --method POST --body '{"status":"Active"}' -o <alias> | 再アクティブ化のみの経路(Phase 2b)です。作成/公開をスキップします |
| エージェントが稼働中であることを確認(読み取り) | sf data query -q "SELECT ... FROM BotDefinition WHERE Id='<verifyId>'" -o <alias> --json | <verifyId> は、作成経路では publishedBotId(Phase-5)、ALREADY-CREATED/再アクティブ化では Phase-2 の分類器が返す、照合された稼働中の Id(botDefinitionId/agentId)です。null の Phase-1 テンプレート 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 セッションを迂回することになり、シェルのコンテキストにベアラートークンが漏えいします。
--jsonのルール。sf data queryは--jsonを受け付けます(結果は.result.records[]のエンベロープで返されます。これは分類器が想定する形式です)。sf api request restは受け付けないため、こちらでは--jsonを省略してください。標準出力の生の本文は、すでに JSON 形式です。
出荷済み ITSM Fulfiller エージェントテンプレート
| テンプレート識別子 | デフォルトの開発者名 |
|---|---|
svc_itsm_intelligence__ITSrvcMgmtFulfiller(masterLabel "IT Service Fulfiller") | IT_Service_Fulfiller_Agent |
NGA の作成では、
idではなくagentScriptフィールドが信頼できる唯一の情報源です。scripts/build-create-body.mjsはmasterLabelで照合し、agentScriptを HTML デコードしてから、収集した<developerName>/<label>をconfig.developer_name/config.agent_labelに代入し、バンドルのresourceContentにします。Employee 向けエージェントは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 は同じ正規化済みスクリプトをスキャンします。2 つの呼び出し元は常に足並みをそろえる必要があります。この変換はブロックがない場合は何もしません(将来のテンプレート改訂にも安全です)。この正規化は実装の詳細です。チャットでの説明、書き込み確認の手順、レポートで、これについて、削除されたサブエージェントについて、または Release Management について触れないでください。管理者に表示されるのは、エージェントが作成され、有効化されたことだけです。
アーキテクチャ — 作成ステージ
| ステージ | 処理内容 | 使用するツール |
|---|---|---|
| 事前確認 | Studio へのアクセス権限(agentforce-studio/access/Agents)と、テンプレートの agentScript が存在することを確認します | Bash(sf api request rest) |
| 列挙 | Fulfiller テンプレート(agent-templates)、既存のエージェント、および最新バージョンの状態(BotDefinition/BotVersions に対する SOQL)を読み取り、スクリプトで冪等性と再有効化の必要性を分類します | Bash(sf、node) |
| 書き込み前の確認 | 正確な developerName とラベル(NGA の作成対象)を提示します。または、既存のエージェントが非アクティブな場合は、代わりに再有効化の選択肢を提示し、どちらの場合も明示的な「yes」を求めます | AskUserQuestion |
| 作成 (作成パスのみ) | createBundleWithVersion に POST します(デコードして置換したテンプレートの Agent Script から NGA バンドルと最初のバージョンを作成します) | Bash(sf api request rest、node) |
| 公開 (作成パスのみ) | .../bundle-versions/<id>/publish に POST します(基盤となる BotDefinition/BotVersion を作成します) | Bash(sf api request rest) |
| 有効化 | .../bundle-versions/<id>/activate に POST します(作成パス)。再有効化パスでは {"status":"Active"} を指定して .../connect/bot-versions/<latestVersionId>/activation に POST します(作成と公開を省略します) | Bash(sf api request rest) |
| 検証 | BotDefinition/BotVersions を SOQL で読み取り、エージェントが存在し、最新バージョンが Active であることを確認します | 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= の部分は防御的なキーであり、DeveloperName に関係なくソーステンプレートから作成された稼働中のエージェントを検出します。OR DeveloperName= の部分は、botDefinitionId が null の場合のフォールバック(通常の Fulfiller のケース)であり、リンク先の BotDefinition が削除された リンク切れ に対するガードでもあります)。さらに、最新の BotVersion.Status を取得し、ヘルパースクリプトで分類します。結果:どのキーにも一致しない場合は ⇒ exists:false ⇒ 作成します。latestVersionStatus:"Active" の場合は ⇒ 作成済み(書き込みをスキップし、Phase 7 の検証に進みます)。needsActivation:true(最新バージョンが Inactive)の場合は、黙ってスキップしたり重複作成したりせず、新しいエージェントを作成する代わりに既存バージョンを有効化することを提案します(Phase 2b)。フォールバックが重要な理由: Fulfiller は事前プロビジョニングされることがなく、このスキルの作成パスでは templateName も設定されないため、テンプレートの botDefinitionId とエージェントの AgentTemplate は常に null です。<developerName> をキーとするフォールバックが、再実行を実際に検出するガードとなります。botDefinitionId が null の場合にそのまま作成へ進むと、再作成されて DUPLICATE_VALUE と衝突します。サーバーは公開時に重複した DeveloperName を拒否します(一意制約によりバンドルはクリーンアップされます)が、再実行をこのハードエラーではなく正常なスキップにするのは、この Phase-2 の読み取りだけです。
確認事項
ユーザーから収集します(会話のコンテキストですでに確認できている項目は尋ねません)。
| 項目 | 説明 | デフォルト |
|---|---|---|
| 対象の組織 | エージェントを作成する sf 組織エイリアス | デフォルトの組織(sf config get target-org) |
| 開発者名 | エージェントの一意な DeveloperName | IT_Service_Fulfiller_Agent |
| ラベル | エージェントに表示するラベル | IT Service Fulfiller Agent |
| 書き込みの確認 | 作成/公開/有効化の一連の処理の前に行う明示的な確認 | 必須 — developerName と label を提示し、AskUserQuestion を使って「yes」を求めます |
冪等性の確認では、主にテンプレートの botDefinitionId(Phase-1 の行)をキーにします。 これがない場合は、BotDefinition の AgentTemplate(防御的なフォールバックです。事前プロビジョニングされていない Fulfiller では null)を参照し、それも null の場合は、ここでの再実行を実際に検出するガードとなる、収集済みの <developerName> にフォールバックします。検証時の読み取りでは、公開レスポンスの publishedBotId(作成パス)、またはテンプレートの botDefinitionId(作成済み/再有効化)をキーにします。収集済みの <developerName> と <label>(デフォルトは IT_Service_Fulfiller_Agent/IT Service Fulfiller Agent)は、createBundleWithVersion の本文にも反映します。外側の apiName/label と、Agent Script 内の置換後の config.developer_name/config.agent_label の両方に反映してください。ある呼び出しでは名前をハードコードし、別の呼び出しでは収集する、といったことはしないでください。バンドルの外側の apiName とスクリプト内部の developer_name が一致しないと、プラットフォーム上で両者の値が食い違います。エージェントの作成により、組織上に稼働可能で有効化済みのエージェントがプロビジョニングされます。ユーザーは書き込みを明示的に承認する必要があります。
ワークフロー
<alias> を収集した対象の組織に、<developerName>/<label> を収集した値に置き換えます。フェーズごとのコマンドの形式と判定分岐の処理の詳細は references/workflow-detail.md にあります。以下のフェーズ概要では各ステップと重要なルールを示し、参照ファイルにはそのままコピーできる正確な sf/node の呼び出しを記載しています。
0. フェーズ 0 — ${SCRATCH_DIR} を設定します。 決定論的ヘルパーを呼び出します(パスはスキルルートを基準としているため、シェルの CWD に関係なく解決されます):SCRATCH_DIR="$(node "<skill_dir>/scripts/create-scratch-dir.mjs" "${outputDir:-}")"。ヘルパーはベースディレクトリ(${TMPDIR}、なければ /tmp、それもなければ最終手段としてハーネスの ${outputDir})を選択します(スクラッチ領域は採点対象の ${outputDir} ツリーの外に維持されます)。作成したディレクトリを stdout に出力します。一時的な JSON はすべて ${SCRATCH_DIR} の下に保存され、永続的な ${outputDir}/report.md はハーネスディレクトリの下に維持されます。
- フェーズ 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を出力します。3 つすべてを取得してください。botDefinitionIdはフェーズ 2 の主要な冪等性キー、template.id(BotDefinition のAgentTemplate)は最初のフォールバック、<developerName>は最後のフォールバックです。masterLabelはレポート表示用のラベルであり、キーではありません。verdictに応じて分岐します:READY⇒ フェーズ 2、NOT-READY⇒AskUserQuestionで前提条件の引き継ぎ(「yes」の場合はservice-itsm-agentic-setup-agentforce-studio-validateに委任)、ERROR⇒ 内容を提示して停止します。studio.signal="CANNOT-CONFIRM"(404 を確認済み)の場合はブロックしません。 - フェーズ 2 — 冪等性(主キー
botDefinitionId、フォールバックはAgentTemplate、次に<developerName>)。 フェーズ 1 のtemplate.botDefinitionIdとtemplate.idを使用します。botDefinitionIdが設定されている場合 ⇒BotVersionsサブクエリを含めて SOQLBotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'を実行します(サブクエリは必須です。そうでなければneedsActivationが常に false になります。OR条件により、参照先が存在しない Id リンク(削除済みの対象)の場合も、誤ってexists:falseとして重複作成するのではなく、稼働中のエージェントにフォールバックできます)。botDefinitionIdが空または null(通常の Fulfiller のケース。テンプレート行には値が設定されません)⇒ 作成に進むことを飛ばしてはいけません。BotDefinition WHERE AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'を読み取ります。前回実行時に自己作成されたエージェントのAgentTemplateは null なので、復元にはDeveloperNameが必要です。AgentTemplateなら、どのDeveloperNameであっても、テンプレートから作成された仮のエージェントを検出できます。<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 に直接進みます。アクティブな稼働中エージェントのアクションはすでに接続されているため、アクション利用可能性の確認は不要です)、exists:true+needsActivation:true⇒ フェーズ 2b。終了コードが 0 以外の場合は CLI エラーを提示します。不在と決めつけてはいけません。フォールバックが必要な理由: Fulfiller は事前プロビジョニングされないため、botDefinitionIdとAgentTemplateは常に null です。DeveloperNameの確認が欠けていると再作成され、DUPLICATE_VALUEが発生します。 - フェーズ 2b — 再有効化の提案。
AskUserQuestion:「Fulfiller エージェント<developerName>は存在しますが、最新バージョンは Inactive です。有効化しますか?」。Yes の場合:POST /connect/bot-versions/<latestVersionId>/activationに{"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 の権限セット引き継ぎを提案します。ACTIVATED と報告してはいけません。CANNOT-CONFIRM⇒ フェーズ 7 の SOQL 検証に進みます。No の場合:書き込みを行わず停止します。 - フェーズ 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 をスキャンします。これは作成手順で適用するものと同じ内部変換です。そのため、背後のアクションが組織設定によって制御されているサブエージェントが不足として誤判定されることも、有効化を妨げることもありません)。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"でチェックポイントファイルを生成します(対話型の実行ではスキップします)。その後、developerName + ラベル +「Fulfiller テンプレートの Agent Script を基にした NGA ネイティブ」という内容を提示して、AskUserQuestionによる確認を求めます。明示的に「yes」と回答された場合に限り続行します。「no」の場合は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 の権限セット引き継ぎを提案します。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 です。そのため既存エージェントが見つかったときにこれを使うと、検証でWHERE Id=''が実行され、スキップまたは有効化が成功した後に誤って失敗と報告されます)。exists:true, count:1, latestVersionStatus:"Active"を確認します。相違があればそのまま報告し、成功を捏造してはいけません。 - フェーズ 8 — 最終判定の集約。
render-report.mjsを再実行して、CREATED/ALREADY-CREATED/ACTIVATED(フェーズ 2b のパスでは ACTIVATED)を出力します。これがレポート本文の唯一の情報源です。内部レコード ID(バージョンのid、publishedBotId/BotDefinition、BotVersion)を判定結果、チャットでの説明、レポートに表示してはいけません。 これらは公開/有効化/検証の呼び出しにのみ使用し、管理者にとって意味のない情報です。レポートにはステータス/名前のみで記載します(「作成して有効化しました」など)。「バンドルを作成しました(バージョン ID …)」/「公開しました(BotDefinition …)」のように記載してはいけません。${outputDir}が指定されている場合は${outputDir}/report.mdを上書きします。それ以外の場合は、ターン側のレポートとして stdout に出力します。 - フェーズ 9 — ランタイムアクセスの引き継ぎ(稼働中のエージェントがある判定の場合は必須)。 フェーズ 8 の判定結果が
CREATED、ALREADY-CREATED、ACTIVATEDの場合(稼働中のエージェントが存在する場合)は、AskUserQuestionを使用します。フェーズ 1 の前提条件とフェーズ 2c の権限セットの提案と同じ、必須の引き継ぎパターンです。エージェントのランタイムアクセスを今すぐ設定するか尋ねます:「エージェントは稼働中ですが、そのアクションはプラットフォーム機能(Prompt Templates、Data Cloud、Unified Catalog)を呼び出します。アクセス権を付与するまではユーザーが実行できないため、エージェントを開くと失敗します。今すぐランタイムアクセスを設定しますか?」。Yes の場合はservice-itsm-agentic-setup-agent-runtime-access-assignに委任します(この処理では、対象ユーザーの選択と書き込み前の確認を独自に実行します)。No の場合は停止します。レポートの「アクセスを設定する」という次の手順の行が記録として残ります。PENDING CONFIRMATION、DECLINED、FAILEDの場合(アクセスを付与する稼働中のエージェントがない場合)は、この質問をしてはいけません。これは必須のAskUserQuestionであり、レポート本文での説明ではありません。render-report.mjsは、平易な表現の「アクセスを設定する」という行を変更せずに出力します。この質問によって、毎回確実に提案されるようにします。
Rules / Constraints
| 制約 | 理由 |
|---|---|
すべての呼び出しは sf api request rest / sf data query を経由させます。アクセストークンは決して取り出しません | ベアラートークンがシェルのコンテキストに漏れます。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 になります)。作成ボディのハードコード値と収集値が一致しないと、バンドルの外部 ID とスクリプト内部の ID が食い違います |
事前チェック、冪等性判定、バンドルボディの構築、レポートのレンダリングはすべて説明文ではなく scripts/*.mjs に記述します(A9) | JSON の解析、masterLabel の照合、hasAccess の読み取り、判定結果の出力は決定的に処理できます。約70KBの Agent Script と自由記述のアポストロフィは、シェル文字列に安全に埋め込めません。ヘルパー内の JSON.stringify がそれらをエスケープします |
作成された Agent Script は出荷前に正規化されます(strip-release-management.mjs)。classify-action-availability.mjs にも同一の変換を適用します。この正規化は内部処理です。ユーザー向けの出力(チャット、書き込み前の確認、レポート)では、正規化、削除されたサブエージェント、Release Management に決して触れないでください | 削除されたサブエージェントの唯一のアクション svc_itsm_intelligence__SummarizeRelease は ReleaseManagementPref によって制限されています。これを出荷すると、その設定がないすべての組織で activate が {success:false} のサイレント失敗ボディを返します。(設定を強制的に有効化するのではなく)これを削除すれば、Fulfiller はどの Agentforce-for-IT-Service 組織でも正常に有効化できます。両方の呼び出し元で処理を一致させないと、Phase 2c が削除済みアクションを欠落として誤検出します |
3つの呼び出しを createBundleWithVersion → publish → activate の順に、同じく取得した bundleVersionId(bundleId ではなくレスポンスの id)に対して実行します | プラットフォームは DRAFT → 公開済み → 有効の順序を強制します。レスポンスボディ、空のボディ、--json、agentType、HTML デコードに関する注意点は references/error-taxonomy.md に記載されています |
BotVersions サブクエリを使用して BotDefinition を列挙します。Active の場合は作成をスキップし、Inactive の場合は Phase-2b での再有効化を提案します。通知なしのスキップや重複作成は決して行いません | Active / Inactive の区別にはサブクエリが必要です。サーバーは公開時に重複する DeveloperName を拒否するため(一意制約違反 → バンドルのクリーンアップ)、この読み取りによって、再実行を重大なエラーではなく適切なスキップとして処理できます |
| 作成シーケンスまたは再有効化の呼び出し前に、書き込み前の確認を必須とします | どちらも稼働中の組織の状態を変更するため、明示的なユーザー承認が必要です |
hasAccess=false / 403 FUNCTIONALITY_NOT_ENABLED の場合は、準備状況の確認への引き継ぎを提案します。ここで機能を有効化してはいけません。また、レガシーの /connect/service-itsm/createAgent は呼び出しません | 有効化は Setup UI で管理者が行う操作です。createAgent は外部リンクアイコン付きの Setup ページ用ボットを作成します(このスキルが扱うエージェントの種類とは異なります) |
内部レコード ID、つまりバージョンバンドルの id(1bZ…)、publishedBotId / BotDefinition(0Xx…)、BotVersion(0Xv…)を、チャットでの説明、書き込み前の確認、レポートに決して表示しません。進行状況と判定結果はステータスまたは名前のみで報告します | これらの ID は、公開 → 有効化 → 検証 → 検証時の読み取り呼び出しに使用する目的でのみ取得します。セットアップを行う管理者には意味がなく、ノイズになるだけです。render-report.mjs はステータスのみの行を出力し、ID を防御的に除去します。モデルも同様に ID を繰り返してはいけません(「バンドルを作成しました(バージョン ID 1bZ…)」や「公開しました(BotDefinition 0Xx…)」とは決して出力しません) |
| エラーが発生した場合は、CLI のレスポンステキストを正確に報告します | サポートが失敗の原因を診断できます。生の ID が表示される可能性があるのはここだけで、ユーザーがサポートに伝える必要のある、改変されていないエラー内に限られます |
検証チェックリスト
-
classify-preflight.mjsによって事前チェックが分類されている(PASS または記録済みの CANNOT-CONFIRM)。FAIL の場合は引き継ぎを提示し、ERROR の場合は生のエラーを表示する。 - 冪等性の判定は、テンプレートの
botDefinitionId(Phase-1 の行)をキーとし、BotDefinition のAgentTemplate(Phase-1 のtemplate.id)を防御的な最初のフォールバックとして、収集したdeveloperNameを実際のガードとして行う。BotDefinition WHERE Id='<botDefinitionId>' OR AgentTemplate='<agentTemplate>' OR DeveloperName='<developerName>'(ORは、null/参照切れのbotDefinitionIdと、AgentTemplateが null の未事前プロビジョニング Fulfiller で DeveloperName による自己作成が繰り返されるケースをカバーします)と、最新のBotVersion.Status(サブクエリあり)の読み取りと分類を、書き込みより前に行う。 -
needsActivation:trueの場合、Phase-2b で再アクティベーションを提案する。暗黙にスキップしたり、重複作成したりしない。 - 書き込みの前に、Phase 3(作成)または Phase 2b(再アクティベーション)でユーザーの明示的な確認を得る。
- バンドルの本文を
build-create-body.mjsで構築し、収集したdeveloperName/labelを使って--body @<file>経由で POST する。または、書き込みを正しくスキップする。 - 同じ
bundleVersionId(レスポンスのid)を公開と有効化に使用する。再アクティベーションにはPOST /connect/bot-versions/<id>/activationを使用する。従来のcreateAgentは呼び出さない。 - Phase-7 の検証で、
BotDefinitionの存在と最新バージョンが Active であることを確認する。 - ライブエージェントと判定された場合(CREATED/ALREADY-CREATED/ACTIVATED)、Phase-9 のランタイムアクセス引き継ぎを
AskUserQuestionとして提示する(「yes」の場合はservice-itsm-agentic-setup-agent-runtime-access-assignに委任する)。PENDING CONFIRMATION/DECLINED/FAILED の場合は提示しない。 - アクセストークンを決して抽出しない。最終判定を報告する際、内部レコード ID(バンドルバージョンの
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 で書き込みます。各書き込みは同じファイルを上書きします。対話/チャットの画面では、これらの書き込みをスキップしてください。Phase-9 のランタイムアクセス引き継ぎは、ライブエージェントの判定において Phase-8 のレポート後に実行されます。判定は変更せず、レポートも再レンダリングしません。
リファレンスファイル一覧
| ファイル | 読むタイミング |
|---|---|
references/workflow-detail.md | SKILL 本文で要約されている、フェーズごとの判定分岐の詳細な説明(フェーズ 1 の ERROR/NOT-READY/CANNOT-CONFIRM、フェーズ 2 の分類結果、フェーズ 4 の作成レスポンス、エラー分岐) |
references/report-format.md | render-report.mjs のすべての呼び出し — レンダリング後の形式と、${outputDir}/report.md に対する 3 つのチェックポイントでの書き込みポリシー |
references/cli-invocation.md | すべてのフェーズ — sf の正確な呼び出し形式、トークンを決して抽出しないルール、ITSM Connect API リファレンス、3 つのヘルパースクリプトの契約 |
references/action-availability.md | フェーズ 2c(アクション利用可否の事前確認、作成パス)+フェーズ 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 に書き込む各チェックポイント(フェーズ 3 のゲート、フェーズ 6 の作成成功時、フェーズ 8 の最終処理)— フェーズ状態の JSON から決定論的にレンダリングする |
scripts/strip-release-management.mjs | 内部 Agent Script の正規化 — build-create-body.mjs(作成本文)と classify-action-availability.mjs(フェーズ 2c のスキャン)からインポートされます。どちらからも呼び出す必要があり、呼び出さないと結果に不整合が生じます |