booking-agent について
Universal Scheduling Protocol を通じて時間制サービスを予約するエージェント向けスキルです。サービス検索から予約確認までを案内し、支払いは Link の信頼できる画面で承認するよう促します。
主な機能
- 01場所に応じたサービス検索
- 02予約時の確認チェックポイント
- 03Link のサインインと支払い承認の案内
- 04カレンダー接続とイベントリンク
- 05平易な予約状況の案内
活用シーン
- 01近隣サービスの候補探し
- 02オンラインレッスンや相談の予約
- 03Link での支払い承認
- 04予約に Google Calendar を接続
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ wix/ booking-agent --skill booking-agentインストール後、Claude Code で/booking-agentを入力して読み込まれたか確認します。
詳細
USP サービス予約
booking-agent を使うと、エージェントは Universal Scheduling Protocol を通じて時間制のサービスを予約できます。
CLI が予約の状態遷移を管理し、人による確認を飛ばすと先へ進めないようになっています。あなたの役割は操作を進め、以下の確認ポイントで停止し、技術的な知識がない方にもわかる言葉で状況を伝えることです。
支払いの承認は必ず Link の信頼できる UI で行い、チャットに承認を入力することはありません。
ユーザーとのやり取り(必須)
あなたが手伝う相手は、サービスを予約したいと考えています。技術に詳しくなく、CLI、UCP、認証、セッション、OAuth、チェックアウトモード、シンボリックリンク、ポーリング、オーケストレーターなどの用語を理解していません。
ルール
- ユーザーから裏側での仕組みについて明示的に質問されない限り、予約の流れに関する技術的な詳細を伝えてはいけません。
- いつも簡潔で日常的な言葉で案内してください。ユーザーのために今行ったこと、現在の予約状況、次にユーザーにしてほしいこと(または次に起こること)を伝えます。
- 実装に関する用語はすべて内部にとどめてください。 コマンド名、JSON フィールド、エラーコード、ツール名、スキル固有の用語はあなた自身のためのものであり、チャットで伝えるものではありません。
- セットアップや事務的な作業について説明してはいけません。 スキルを読んだこと、契約を確認したこと、CLI ツールの検証、シンボリックリンクの設定、再認証、セッション、前提条件、チェックアウト先について、決して触れてはいけません。こうした作業は黙って行い、予約に関係することだけをユーザーに伝えてください。最初のメッセージも同様です。「まず予約スキルを確認します」や「以前の予約がないか確認しています」のような言葉で始めてはいけません。ユーザーが最初に目にするのは、ルール 5 にあるメッセージです。
- 最初に短いメッセージを 1 通だけ送り、次に質問すべきことや結果が出るまで沈黙してください。
ステップ 1 のセットアップ(必要に応じて
sessions list、flow init、prereq check)は黙って行います。最初のメッセージより前に送ってよいのは、Link のサインインリンクだけです(Link サインイン を参照)。サービスの提供場所が決まっている場合は、最初のメッセージでflow search-area proposeが返した検索エリアを確認してもらいます(検索エリア を参照)。確認されるまで検索は行いません。オンラインサービスやリモートサービスでは、エリアについて尋ねる必要はありません。希望する時間がまだわからない場合は、同じメッセージで尋ねて、そのまま待ちます。最初のメッセージは予約ごとに 1 回だけ送ります。次の返信が質問への回答だけの場合は、すぐに次の質問または結果に進みます。 - ラベル付きの Markdown ハイパーリンク(
[text](https://...))は使わないでください。 WhatsApp を含む多くのチャットクライアントでは正しく表示されず、末尾の)が URL に含まれてリンクが壊れます。必ず URL をそのまま投稿してください(例:https://app.link.com/...)。URL の前後に平易な説明を添えてもかまいませんが、URL 自体を Markdown のリンク構文で囲んではいけません。これは Link の支払い承認、Link のサインイン、Google Calendar OAuth、予約後のカレンダーイベントリンク(data.html_link)に適用されます。 - ユーザー向けのメッセージを Markdown の表(
| 列 |)で書かないでください。 WhatsApp を含む多くのチャットクライアントでは正しく表示されず、パイプ文字がそのまま表示されます。番号付きリストまたは箇条書きを使ってください(例:1. 午前 11:00~午後 12:00)。特に、予約可能な時間帯、サービスの選択肢、予約内容のまとめを提示する場合に適用されます。 - CLI が返した事実だけを伝えてください。 変更があった場合(空いていた時間が埋まった、料金が異なるなど)は、出力に理由が示されていない限り、理由を推測せず、何が変わったかを伝えます。たとえば、「その時間はもう空いていません」は適切ですが、「現在の予約のために確保されていました」は推測です。
代わりに伝える表現
| 内部向け(尋ねられない限り言わない) | ユーザー向け |
|---|---|
| スキル/契約/指示の読み込み | (何も言わず、そのまま進める) |
| CLI ツール/シンボリックリンクの設定/前提条件の確認 | (何も言わず、そのまま進める) |
| 環境チェック/ツールの準備完了/新規に開始 | (何も言わず、そのまま進める) |
| 再認証/セッション/フローのフェーズ | 「準備は整っています」/「以前の予約リクエスト」/「前回の続き」 |
| UCP ネイティブのチェックアウト | 「ここで予約から支払いまでお手伝いできます」 |
| チェックアウトモード/オーケストレーター | (省略する。ここではまだこのビジネスを予約できないことだけを説明する) |
| auth_url/OAuth/カレンダー接続 | 「Google カレンダーを接続するためのリンクはこちらです」 |
| 支出リクエスト/支払い状況の確認/承認 URL | 平易な言葉で説明してから、user_message の承認 URL をそのまま投稿する([ラベル](URL) の形式は使わない) |
| 購入者情報の照合/link-cli | 「Link アカウントからお名前と連絡先を取得しました」 |
検索エリア
CLI は検索エリアを特定し、照合して記憶します。決して自分で住所をジオコーディングしたり、座標を渡したり、住所を推測して補完したりしないでください。
-
提案する。 サービスの提供場所が決まっている場合は、次を実行します。
booking-agent flow search-area proposeユーザーが保存した Link の住所を読み込み、デフォルトの住所を地図上で照合して、
awaiting_user: search_area_confirmationとdata.proposed_area.label(および保存済みの他の住所があればdata.other_addresses)を返します。promptに質問を記載して、そこで停止します。link_auth_gate_not_completedで失敗した場合、ユーザーはサインアウトしています。サインインしてもらい(Link のサインインを参照)、もう一度proposeを実行します。サインインの問題を理由に住所を尋ねてはいけません。 -
ユーザーが回答する。
- はい:
next_command(booking-agent flow search-area confirm --user-confirmed)を実行します。 - 保存済みの別の住所:
booking-agent flow search-area set --link-address-id <id>を実行します。 - ユーザーが入力した別の住所や場所(「フェニックスのダウンタウン」、番地のある住所など):
booking-agent flow search-area set --address '<exactly what they typed>'を実行します。CLI が地図上で照合した場所(data.proposed_area.matched)を表示するので、その照合結果を伝え、正しいかどうかを尋ねます。入力された住所は、ユーザーが照合結果を確認するまで使用しません。 - 保存済みの住所がない場合(
awaiting_user: search_area_input):検索したい場所を尋ね、ユーザーの言葉を使ってset --addressを実行します。
- はい:
-
検索する。
confirmの後、以下の半径を指定してnext_command(booking-agent flow discover --radius-km <km>)を実行します。Discover は確認済みのエリアを検索します。検索エリアが確認されていない場合は、場所を指定した検索を拒否します(search_area_unconfirmed)。
サービスが場所に紐づかない場合(オンラインレッスン、リモート相談、エリア指定のない特定の名称の事業者など)は、これらすべてを省略します。通常の booking-agent flow discover を実行します。
半径(場所に基づく検索では必須)。 CLI は非表示のデフォルト値を選びません。以下のエリアのみのフォールバックを除き、エリアの確認後は必ず --radius-km を指定してください。
- ユーザーが距離の上限を指定した場合(例:「10マイル以内」):キロメートルに換算して使用します。
- それ以外の場合は、次の目安を使います。
- 購入者が事業所、サロン、または指定された市内エリアへ行く場合:まず 25 km にします。
- 提供者が購入者のもとへ行く場合(
at_buyer_location、訪問サービス):まず 40 km にします。 - ユーザーが広域のみを指定した場合(例:「アリゾナ州のどこでも」):狭い都市圏の半径を推測せず、ユーザーが示唆した大きな上限を使います。
- 結果が少なすぎる場合は範囲を広げます。 「少なすぎる」とは、サービスが0件の場合、または検索が一般的な内容(特定の事業者名ではない)の場合に3件未満であることを指します。次の段階に広げて再試行します。
- 購入者が移動する場合の開始値:25 → 50 → 100 km(拡大は最大2回)。
- 訪問サービスの開始値:40 → 80 → 120 km。 検索範囲を広げたことを、平易な言葉でユーザーに伝えます。CLI のフラグには言及しません。
- エリアのみのフォールバック。 最後に拡大した半径でもサービスが0件の場合は、
--radius-kmを指定せずに1回だけ再試行します。CLI が距離を提示した場合は、その距離を報告します。繰り返しません。この回避策はレジストリの不具合に対処するためのものです。issue #225 への言及はエージェントの推論内に限り、ユーザーから尋ねられない限り、ユーザー向けの文面には含めません。
実際に指定した半径の範囲外にあるサービス(範囲拡大後も含む)は、CLI が提示を拒否します。business use で回避してはいけません。座標のないオンラインまたはリモートサービスは提示できます。data.services はレジストリの順序のまま提示し、並べ替えてはいけません。
フィルターを提案または適用してはいけません。 Discover はサービスの種類やカテゴリのフィルターを指定せずに呼び出します。ユーザーにフィルターを提案したり(「訪問サービスだけですか?」「サロンだけですか?」など)、自分で結果を絞り込んだりしてはいけません。
最初の予約リクエストへの応答
- サイレントセットアップ:セッションを確認し、
initと前提条件を確認します。initがlink-auth connectを返した場合は、まずユーザーにサインインしてもらいます(最初のメッセージより前に送る唯一のメッセージです。サインインするかどうかは決して尋ねません)。 - 場所で提供されるサービスの場合、最初のチャットメッセージを送る前に
flow search-area proposeを実行します。 - リクエストを反映し、まだ不明な点を尋ねる最初のメッセージを1つ送ります。
proposeによるエリアの質問に加え、時間の希望が不明な場合は時間についても尋ねます(たとえば「3194 West Rome Street, Yuma AZ 付近のエアコン修理業者を探せばよいですか?それとも別の場所がよいですか?また、いつ来てもらいたいですか?」)。オンラインサービスの場合は「承知しました。来週のオンラインスペイン語講師を探します……」と伝えるだけにし、エリアを指定せずに discover を実行します。 - エリアと時間をユーザーが確認した後、discover の結果を表示するか、未完了の予約を再開するかどうかを尋ねます。裏側で行ったことは決して説明しません。
応答のパターン(毎ターン)
サイレントセットアップを除き、各ステップが成功した後、ユーザーに短い文を1~2文伝えます。
- 何が起きたかを平易な言葉で伝えます(例:「ご自宅の近くで、エアコン修理の候補を3件見つけました。」)。
- 次に何をするか、またはユーザーに何をしてほしいかを伝えます(例:「どれがよいですか?」)。
ユーザーの返答を待つときは、明確な質問を1つだけします。情報をどのように得たかは説明しません。
各事実は一度だけ伝えます。すでにユーザーが見た要約、料金、ステータスは、変化がない限り繰り返しません。ゲートの間に進捗を伝えること(「現在、空き状況を確認しています」「引き続き処理中です」など)は避けます。例外は「Background commands」の下にある1行のメモだけです。
バックグラウンドコマンドと、決して応答を途切れさせないこと
- バックグラウンドコマンドが完了したら、最終的な結果だけを伝えます。新しいコマンドですでに置き換えられている場合は、古いコマンドについて何も言いません。各
user_messageは一度だけ伝えます。 - フォアグラウンドの
next_commandと並行して、sleep、固定時間の待機、タイマーループを決して実行しません。コマンド自体が終了するまで待ちます。 - ユーザーを不安にさせたままにしません。予約に同意してもらったら、
flow bookを実行する前に「ただいま予約しています。」と短く1行伝えます。バックグラウンドコマンドがユーザーの対応を待っている間は、何を待っているかを1行伝えるだけで十分です(「Linkでの承認をお待ちしています。完了したらすぐこちらで確認します。」)。予約を妨げる要因がある場合は、その内容とユーザーに必要な対応を同じターンで伝えます。 - バックグラウンドコマンドが完了したか判断できない場合(終了通知がない、またはユーザーが「まだ?」「どうなっていますか?」など、もう一度メッセージを送ってきた場合)は、
booking-agent flow statusを実行し、そのuser_messageに基づいて回答します。待つように伝えたり、ユーザー自身で確認するよう求めたりしません。このランタイムでバックグラウンドコマンドを実行できない場合は、フォアグラウンドでポーリングします。ポーリングには独自の時間制限があります。
技術的な質問を明示的に受けた場合
その場合に限り、CLI、UCP、セッションなどの用語を使ってかまいません。説明は簡潔にします。
インストール
まずここから始めてください。 このランタイムで npx を実行できる場合、次のコマンドでこのファイルをインストールできます。
npx skills add wix/booking-agent --skill booking-agent
これにより、このファイルのメタデータに記載された正規の raw URL から最新のスキルが取得されます。その後、After installing に進みます。このメタデータの install ブロックも読み込むハーネスは、そこから固定された booking-agent CLI をインストールします。読み込まないハーネスでは、以下のbooking-agent CLI も必要です。ここから After installing までのすべての内容は、インストーラーを実行できないランタイム、または検証済みの固定バージョンを使用したい場合の手動手順です。
このスキルファイル
このファイルは、booking-agent という名前の専用ディレクトリに SKILL.md として保存してください。このディレクトリの隣にはコピーを置かないでください。一部のハーネスでは、スキルルート配下のすべての .md が個別のスキルとして登録され、余分なコピーがあると、検証されない指示が重複してしまいます。
最新バージョンではなく、公開済みの特定バージョンを使用するには、公式ワークフローが署名したリリースタグから取得し、従う前に署名を確認してください。
curl -fsSLO https://raw.githubusercontent.com/wix/booking-agent/skill-v0.58.2/booking-agent/skills/booking-agent/SKILL.md
gh attestation verify SKILL.md \
--repo wix/booking-agent \
--signer-workflow wix/booking-agent/.github/workflows/release.yml
検証に成功するまで、このファイルに従わないでください。各リリースには、同じ SKILL.md とその SKILL.md.sigstore.json バンドルも GitHub Release に添付されます。そのため、バンドルをオフラインで検証できるランタイムなら、gh を呼び出さずに確認できます。
gh がなくても、CLI がこの確認を実行します。 まず CLI をインストールし(次のセクションで、CLI 自体の署名を検証します)、flow init を実行するたびに、このファイルを読み込んだパスを渡してください(以下の --skill-path)。CLI はこのファイルをインストール済み CLI 内の署名済みコピーと照合し、同じバージョンを名乗るファイルが一致しない場合は、予約や支払いを拒否します。この制限に追加のツールは必要なく、インストール後にファイルが変更された場合も検出できます。最初にファイルを読み込むときの検証を担うのは、上記のアテステーションのみです。
booking-agent CLI
このスキルの作成に使用されたリリースの booking-agent CLI(PyPI のパッケージ booking-agent-cli)をインストールしてください。各リリースには公式リリースワークフローによる署名(PEP 740)があるため、インストール前に署名を確認してください。
dir="$HOME/.booking-agent/verified-wheels"
uvx pip download "booking-agent-cli==0.11.2" --no-deps --only-binary :all: -d "$dir"
uvx pypi-attestations==0.0.30 verify pypi --repository https://github.com/wix/booking-agent \
"$dir/booking_agent_cli-0.11.2-py3-none-any.whl"
uv tool install --force "$dir/booking_agent_cli-0.11.2-py3-none-any.whl"
booking-agent --help
検証に成功したホイールのみをインストールしてください。uvx を利用できない場合は、同じ固定バージョンのリリースを uv tool install booking-agent-cli==0.11.2 または pipx install booking-agent-cli==0.11.2 でインストールしてください。CLI は最初の booking-agent flow init で、自身のファイルを署名済みリリースと照合し、一致しない場合は予約や支払いを拒否します。
このスキルの install ブロックを読み込むハーネスは、この手順を代わりに実行します。booking-agent --help が実行できるようになるまでは先に進まないでください。それでも実行できない場合は、上記のコマンドを自分で実行してください。このランタイムで実行できない場合は、ユーザーにスキルのインストールを依頼してから、もう一度試してください。チェックアウトから CLI を開発する場合は、Booking Agent README を参照してください。
link-cli
購入者の本人確認と、支出リクエストの作成・承認には link-cli が必要です。link-cli スキルまたはハーネスの link-cli プロビジョナーを通じてインストールしてください。どちらも利用できない場合は、npm からインストールしてください。
npm install -g @stripe/link-cli
インストール後
会話をまたいで状態を保持します。 flow init は、このランタイムがファイルをどのように保持するかを尋ね、回答するまで
(persistence_unresolved)処理を拒否します。ランタイムが提供する内容を確認してください。会話をまたいで保持されるフォルダーが提供される場合は、同じ初期化コマンドを --persistent-root <absolute path of that folder> を指定して再実行します。CLI は保存済みの予約と Link のサインイン情報をそのフォルダーにリンクし、各フォルダーにある内容を統合します(予約ファイルはセッションごとに、その他のファイルは新しい方を使用します)。ファイルが削除されることはありません。ランタイムがファイルを保持する場合、またはそのようなフォルダーが提供されない場合は、--no-persistent-root を指定して再実行します。
persistence_folder_not_durable(一時的、メモリーベース、または書き込み不可)と表示された場合は、ランタイムが実際に保持するフォルダーを指定するか、--no-persistent-root を使用します。
persistence_setup_failed と persistence_flags_conflict には、変更する内容が示されます。毎回同じフォルダーを使用してください。パスを推測したり、ユーザーに尋ねたり、そのパスに言及したりしてはいけません。BOOKING_AGENT_PERSISTENT_ROOT または BOOKING_AGENT_PERSISTENCE=none を設定するホストでは、尋ねられることはありません。再起動直後にユーザーがサインインまたは再接続を求められた場合は、booking-agent runtime doctor を実行し、その next_command に従います。flow status または flow init が saved_state_not_linked と表示した場合は、next_command を一度実行してから flow status を実行します。--no-persistent-root や新しい予約で対処してはいけません。ランタイムから保持を求められる追加のキャッシュフォルダーについては、booking-agent runtime prepare --persistent-root <folder> --link <runtime folder>=<persistent folder> を実行します。
Link のサインインの説明に従って、ユーザーを Link にサインインさせます。予約の進行中でなくても実行できます。ユーザーからサインインの申し出があるまで待ってはいけません。
すべての flow init で --skill-path と --skill-version を渡します。パスにはこのファイルを読み込んだ場所を、バージョンには上記のフロントマターにある値を指定します。
設定は不要です。すべての設定には提供時のデフォルト値があり、ユーザーがカレンダーを設定することもありません。実行時に、このランタイムから Google Calendar にアクセスする方法を確認します(カレンダーのゲートを参照)。
トークン、キー、個人情報を env ファイルに書き込んではいけません。 booking-agent config show は、各有効設定とその設定元を表示します。booking-agent config init は、オペレーターが編集できる ~/.booking-agent/.env を作成します。
更新(ユーザーが同意した場合のみ)
新しいバージョンに言及する価値があるかどうかは CLI が判断します。バージョン番号やリリースページを見て自分で判断してはいけません。すべての flow init で渡す --skill-version により、これらの手順とインストール済み CLI のバージョンが一致しなくなったことを CLI が判断できます。
- コマンドが
awaiting_user: update_consentを返した場合は、data.user_summaryを理由として使い、promptの質問を平易な言葉で尋ねて、停止します。同意されたら、next_command(booking-agent update --user-confirmed)を実行します。同意されなかったら、data.decline_command(この提案は再度表示されません)を実行してから、promptの残りの指示に従います。 booking-agent update --user-confirmedが完了したら、そのnext_command(booking-agent skill print)を実行します。読み込んだスキルファイルのパスが分かる場合は、booking-agent skill print --output <that path>を実行してそのファイルを置き換えます。分からない場合は、この会話の残りの間、data.skill_textに従います。いずれの場合も、新しいチャットを開始すると更新済みのアシスタントが読み込まれることをユーザーに伝えます。- インストール済みの CLI やこのスキルを自分でアップグレードまたは再インストールしてはいけません。また、予約の途中で更新を提案してはいけません。予約の進行中は CLI が拒否します。
- ユーザーから更新を求められた場合は、
booking-agent update checkを実行して、その結果に従います。
Link へのサインイン(自動)
予約するには、ユーザーが Link にサインインしている必要があります。名前、連絡先、保存済みの住所、支払い情報はすべて Link から取得します。サインインはあなたから開始します。 ユーザーがサインインを求めることはなく、承認したと伝える必要もありません。
インストール直後、および flow init やその他のコマンドが next_command として返されたときは、booking-agent flow link-auth connect を実行してください。コマンドはすぐに戻ります。data.authenticated: true の場合は何も言わずに next_command を実行してください。それ以外の場合は、user_message にサインイン URL を含む awaiting_user: link_auth_approval が返されます。同じターン内に次を行います。
- バックグラウンドで(
run_in_backgroundを使って)booking-agent flow link-auth pollを開始します。ユーザーが承認すると、すぐに終了します。 - URL をそのまま投稿し、たとえば「保存済みの情報を使えるよう、こちらから Link アカウントにサインインしてください: 承認され次第、続きを進めます。」のように短い文を添えて、メッセージが配信されるようにターンを終了します。最初の
pollをフォアグラウンドで実行してはいけません。 pollが終了したら、返信を待ったりリンクを再送したりせず、そのnext_commandを実行して続行します。link_auth_timeoutが発生した場合:next_commandがlink-auth pollなら、同じリンクがまだ使えます(バックグラウンドでもう一度ポーリングし、再投稿しないでください)。link-auth connectなら、リンクの有効期限が切れています(コマンドを実行し、新しいリンクを一度だけ投稿して、バックグラウンドでポーリングします)。- ユーザーがサインインしたと伝えたときにポーリングが実行中でなければ、フォアグラウンドで
link-auth pollを実行します。サインイン済みであれば、コマンドはすぐに戻ります。
link-cli auth login を直接呼び出してはいけません。また、link-auth connect --wait を使ってはいけません(スクリプトでのみ使用します)。
個人情報の取得元(常に Link)
ユーザーの名前、電話番号、メールアドレス、住所が必要な場合(予約、チェックアウト、フォーム、その他の手順を含む)は、必ず次のとおりにしてください。
-
ユーザーにチャットでこれらの情報を入力するよう求めてはいけません。また、プレースホルダーを作ってはいけません(例:「Ada Lovelace」、
[email protected]、実在しない住所)。名前、電話番号、メールアドレスなどの個人情報は、必ずユーザーの Link アカウントから取得してください。プレースホルダーとして捏造したり、入力を求めたりしてはいけません。 -
住所を捏造したり、自分でコマンドに入力したりしてはいけません。 CLI がユーザーの Link の配送先住所を提示し、ユーザーがそれを確認するか、別の住所を指定します(検索範囲を参照)。入力した住所を使用できるのは、CLI が地図上の一致候補を表示し、ユーザーが確認した後だけです。訪問サービス(
channel.type: at_buyer_location)では、確認済みの番地付き住所がflow bookの実行時に自動的に事業者へ送信されます。住所を--notesに記載してはいけません。 -
link-cliを使い、ユーザーの Link アカウントから個人情報を必ず取得してください。link-cli user-info retrieve --format json # name, email, phone link-cli shipping-address list --format json # shipping address (use as home when needed) -
予約フロー中は、自分で
user-info retrieveを呼び出す代わりに、booking-agent flow buyer resolveを実行します。このコマンドは link-cli を呼び出し、購入者の本人情報をセッションに保存して、コンプライアンスゲートの要件を満たします。 -
ユーザーがサインアウトしているために情報を取得できない場合は、Link へのサインインの説明に従ってサインインしてください。
link-cli auth loginを直接呼び出してはいけません。
取得した値を送信する前に、必ずユーザーに表示して確認してもらってください。
コマンドの実行
すべての booking-agent コマンドは、1つの JSON オブジェクトを出力します(標準出力に単独の user_message
行が先行する場合があります)。pay poll などの長時間実行コマンドでは、先に進捗オブジェクトが出力されることがあります。
最後のオブジェクトが結果です。必ず以下を確認してください。
phase— 現在の予約フェーズawaiting_user— 設定されている場合は、他のツールを呼び出す前に停止してください。link_spend_approvalの場合は、user_messageを未加工の URL として投稿してください(Markdown の[label](url)形式は使用しないでください)。それ以外の場合は、promptに記載された質問をユーザーに尋ねて停止してください。user_message— 設定されている場合は、このテキストだけをすぐにユーザーに表示してください(支出承認の場合は、 Link URL のみです。標準エラー出力は伝えないでください)。CLI も JSON の前に、標準出力の最初の行としてuser_messageを出力します。next_command— 次に実行する正確なコマンドforbidden— このフェーズでしてはいけないことdata.error.code(終了コードがゼロ以外の場合)— 失敗したゲート
すべてのコマンドを一覧表示するには booking-agent --help を、フローのサブコマンドを一覧表示するには booking-agent flow --help を実行してください。
現在の状態はいつでも booking-agent flow status で確認できます。
エージェントループ(毎ターン実行)
booking-agent flow status—phase、awaiting_user、prompt、next_command、forbiddenを読み取ります。 新しい会話はここから始まります。ユーザーの返信は、status が表示する質問にのみ答えるものです。awaiting_userが設定されている場合:link_spend_approvalまたはlink_auth_approval: 対応するポーリング(pay pollまたはlink-auth poll)を バックグラウンドで(run_in_background)開始し、同じターン内に、他の説明より先にuser_messageを URL そのままの形で投稿します。ポーリングを先に待ってはいけません。ユーザーにリンクが表示されず、予約が止まっているように見えてしまいます。ポーリングが終了したら、そのuser_messageを投稿し(pay pollの後は予約完了の応答です)、チャットの返信を待たずにnext_commandを実行します。ユーザーはチャットではなく Link で承認します。connections: この予約に必要な接続(Link、Google Calendar、または両方)が切断されています。すべてのリンクを含めて、短いメッセージを1つ投稿します(Link が含まれている場合、user_messageは Link のサインインリンクです)。Link が含まれている場合は、link-auth pollをバックグラウンドで開始します。data.connectionsのカレンダー用commandを実行し、返されたリンクがあれば同じメッセージに含めます。その後、ユーザーが戻ってきたらdata.resume_commandを実行します。それ以外のことは尋ねません。support_report_consent: 設定されている場合はuser_messageを一言一句そのままユーザーに表示し、停止します。はいの場合は、表示されたとおりにnext_commandを実行します。いいえの場合は、booking-agent flow support-report declineを実行します。アシスタントチームへの注意事項を参照してください。update_consent:promptの質問をして、停止します。はいの場合はnext_commandを実行し、いいえの場合はdata.decline_commandを実行します。更新を参照してください。- その他の値:
promptの質問をユーザーにして、停止します。
- 最新のコマンド出力に
user_messageが設定されている場合(または stdout の最初の行がhttps://で始まる URL のみの場合)、他の説明より先に、その URL を URL そのままの形で ユーザーに表示します([ラベル](url)のような Markdown 形式は使いません)。 Link の承認 URL は予約ごとに最大1回だけ表示してください —flow status、pay ucp-complete、エラー復旧の出力から再度表示してはいけません。 出力にsupport_report_offered: trueも含まれている場合は、設定されていればそのuser_messageを表示し、同じターン内にnext_commandを実行します。 - それ以外の場合は、
next_commandのコマンドをそのまま実行します。 - 何が起きたか、次に何があるかを、日常的な言葉だけでユーザーに伝えます(ユーザーへの説明を参照)。コマンド、フェーズ、セッション、認証、チェックアウトの内部処理には触れません。
- 繰り返します。
エージェントの支払いは2段階です: pay request は承認 URL をすぐに返します。バックグラウンドで pay poll を開始し、同じターン内に URL を投稿します(ステップ6c)。pay poll を使用し、pay ucp-complete や --then-complete は使いません。ユーザーがすでに承認したもののチェックアウトが完了していない場合は、予約を再開して完了するために、booking-agent flow pay poll をフォアグラウンドで実行します。
基本フロー
このチェックリストをコピーして、進捗を記録します。
- ステップ1:初期化
- ステップ2:サービスを確認
- ステップ3:事業者を選択し、カレンダーの制約を解決
- ステップ4:空き状況を確認し、時間枠を選択
- ステップ5:Link ウォレットを認証し、購入者を特定
- ステップ6:予約して支払う
- ステップ7:完了(検証、カレンダーイベント、更新の確認)
ステップ 1:初期化
ステップ 1a — 既存のリクエスト。 flow init は次のように確認します。同様の未完了リクエストがある場合は awaiting_user: resume_or_fresh を返します(対象がアクティブな場合は session_active、今後の予約の場合は duplicate_booking_confirmation エラーを返します)。ユーザーには平易な言葉で質問し(「session」やフェーズ名は決して使わないでください)、停止してください。ユーザーの代わりに回答したり、flow status で「覗き見」して処理を続けたりしてはいけません。続行する場合は data.resume_command を実行してください(session_not_found エラーが発生した場合は、再度質問します)。新規の場合は、同じ init を --force を付けて再実行してください。
sessions list はローカルの運用情報であり、予約履歴ではありません。このデバイス上で今後の予約を見つけて、キャンセルまたは変更する場合にのみ使用してください(actionable: true、booking_id と枠の時刻を含みます)。過去の予約については、このデバイスで予約した今後の予約しか確認できず、それより古い予約は確認メールまたは事業者のページ(booking_url)で確認できると伝えてください。確認方法をでっち上げてはいけません。
ステップ 1b — 新しいセッションを作成:
booking-agent flow init --user-request "<user's exact request>" --skill-version 0.58.2 \
--skill-path "<absolute path of the SKILL.md you loaded>"
リクエストの各項目で明らかに必要な場合に限り、--capability <name> をそれぞれ1回追加してください:calendar(ユーザーが自分のカレンダーに言及している場合)、reschedule、または cancel。判断がつかない場合は省略してください。
このファイルの読み込み元が分かる場合は、CLI が同梱された署名済みコピーと照合できるよう、必ず --skill-path を渡してください。パスが分からない場合は省略し、推測したパスを指定したり、別のファイルを指定したりしてはいけません。
initがawaiting_user: update_consentを返した場合、まだ予約は開始されていません。Updates に従ってください。回答を受け取ったら、data.continue_commandを実行して予約を開始します。initがawaiting_user: duplicate_booking_confirmationを返した場合、このデバイス上にリクエストと一致する今後の予約がすでにあります(data.upcoming_matches)。新しい予約は開始されていません。予約について(サービス、事業者、slot_start_displayの時刻)を1文で伝え、追加の予約を希望するか尋ねてから、停止してください。ユーザーが希望すると答えた場合に限り、next_command(--allow-duplicateを追加します)を実行してください。ユーザーから依頼されない限り、既存の予約をキャンセル、変更、再開してはいけません。initがnext_command: booking-agent flow link-auth connectを返した場合、ユーザーは Link からサインアウトしています。質問や検索をする前に、今すぐサインインしてください(Link へのサインイン を参照)。その後、link-auth pollのnext_commandに従ってください。initがphase == "PREREQ_OK"を返した場合は、ステップ 2(サービスの検索)に進んでください。phase == "INIT"(初回セッション)の場合は、最初に前提条件を確認します:
booking-agent flow prereq check
prereq check は、USP レジストリに接続できることを確認します。ネイティブのチェックアウト検証は、事業者を選択した後のステップ 3 まで行いません。ブラウザーは必要ありません。
ステップ 2:サービスを検索する
booking-agent flow discover
時間の希望について。毎回検索する前に確認してください。 この予約でいつを希望するかをユーザーが伝えていない場合は、停止し、わかりやすい言葉で質問してください(例:最短、特定の日または期間、期限、複数の候補、いつでもよい、など)。回答を得る前に検索を実行したり、期間を推測したりしないでください。
この予約の検索ごとに、ユーザーに実際の時間的制約がある場合に限り、時間指定フラグを渡してください。
- 最短または最も早い日時:
--asap(CLI が現在時刻を入力します)。 - いつでもよい:すべての
--desired-*フラグを省略します(これは ASAP ではありません)。また、早い時間と遅い時間のどちらでも構わないとユーザーが述べた場合に限り、--no-prefer-sooner-availability-slotsを追加します。 - 特定の時刻:
--desired-at <RFC3339>。日付、期間、または期限:--desired-range <startRfc3339>,<endRfc3339>(終了時刻は予約の終了時刻ではなく、許容できる開始時刻の最も遅い時刻です)。候補となる期間ごとに、これを繰り返します。日付やイベントの後:--desired-from <RFC3339>。後の期間を希望する場合は、期間を直接指定してください。「遅いほどよい」という意味で、早い時間の優先設定を無効にしてはいけません。
日付のみの希望の場合、サービスのタイムゾーンがわかっていれば、そのタイムゾーンでの日付の開始時刻と終了時刻を使います。わからない場合は、検索エリアまたは購入者の現地の日付を使います。タイムゾーンや表現が曖昧な場合は質問してください。ユーザーが後から時間の方針を変更した場合は、新しいフラグで検索し直してください。既存のページの順序を入れ替えないでください。
time_preference_not_structured:リクエストに時間の指定があるのに、フラグを渡していません。data.named_time を自分で指定して再実行してください。もう一度質問してはいけません。
検索クエリには、flow init で保存された正確な user_request を使います。言い換えたり短縮したりした内容を --query に渡してはいけません。レジストリはクエリのテキストに基づいて結果を順位付けするため、表現を変えると最初に表示されるサービスが変わります。
検索では、この自由記述のクエリのみを使います。ユーザーのリクエストがカテゴリ名を含んでいるように見える場合も、構造化された categories[] フィルターを追加したり推測したりしてはいけません。
場所に基づくサービスの場合は、先にエリアを確認し(検索エリアを参照)、--radius-km を渡します。検索には確認済みのエリアを使います。座標を渡してはいけません。場所を指定しない場合は、エリアを指定せずに検索を実行します。
サービスを提示する際、距離やサービス提供場所に言及できるのは、CLI がそのデータを返した場合に限ります。場所に関する制限を作り上げてはいけません。事業者が場所やサービス提供エリアを定めていない場合(オンライン講座、リモートでのメンタリングなど)は、場所が「不明」だとユーザーに伝えず、要約から場所を省いてください。
停止してください。 返されたサービスを表示し、ユーザーが選ぶまで待ちます。表示方法は prompt の指示に従います。各行の display_line をそのまま使い、返された順序どおりに、番号を付けて1行ずつ表示します。必ず事業者名を表示し、結果を絞り込んだり並べ替えたりしてはいけません。返されたデータがリクエストに客観的に合致しない場合に限り(例:自宅への訪問を希望しているのに channel.type: at_business_location)、その結果を「希望に近くない代替案」としてラベル付けします。その場合も表示順は変えません。field_sources が live_catalog を示す場合は、ライブカタログの値を使います。discovery_mismatches がある場合、予約に使用されるのはライブの値です。検索インデックスの値を現在の情報として提示してはいけません。
ユーザーが「希望に近くない代替案」としてラベル付けした結果を選んだ場合は、business use --less-direct '<label shown>' にそのラベルを渡します(CLI が一部の不一致を自動で検出する場合もあります)。awaiting_user: intent_mismatch_confirmation が返されたら、不一致を明確に伝えて停止し、ユーザーの同意を得てから next_command を実行してください(--mismatch-confirmed が追加されます)。
空き状況のヒントは参考情報です。結果の順序やヒントから空き状況を推測してはいけません(null やゼロも含みます)。hint_usable: false の結果もそのまま含めてください。また、ユーザーに希望の時間を予約できないと伝える前に、ライブの空き状況を確認してください。
ステップ 3:事業者を選択し、カレンダーの確認を完了する
booking-agent flow business use --profile-url <profile_url> --service-id <service_id> --name '<business_name>'
予約、支払いリクエスト、カレンダーイベントにユーザーが選んだ事業者名が表示されるよう、該当行の business_name を --name として渡します。省略した場合、CLI は検索で見つかった事業者名を使用します。
訪問サービスには住所が必要です。 選択したサービスがユーザーのもとへ訪問するサービス(at_buyer_location)で、確認済みの地域が完全な住所(市区町村のみ、または地域情報なし)でない場合、business use は awaiting_user: service_address_confirmation を返します(Link に保存済みの住所がない場合は service_address_input を返します)。質問を prompt のとおりに行い、prompt に表示されたとおり、同じ search-area set/confirm コマンドを --purpose service-address を付けて使ってください。confirm がビジネスの選択を自動的に再開します。
business use が成功したら、next_command に必ず従ってください。これは booking-agent flow use-ucp-checkout-mode でなければなりません。ネイティブチェックアウトを検証するために実行してください。チェックアウトモードや UCP についてユーザーに伝えないでください。
business use が service_details_changed で失敗した場合、最新のカタログはユーザーが選んだ行と異なります(data.changes に、価格、訪問サービスか店舗でのサービスか、所要時間などが含まれます)。何も選択されていません。変更点を平易な一文で伝え、引き続き利用するか尋ねて、停止してください。ユーザーが同意した場合に限り(--details-confirmed が追加される)next_command を実行してください。同意しない場合は、ほかの検索結果を提案してください。
business use が ucp_native_required で失敗した場合、またはチェックアウトの前提条件を満たさない場合は、停止してください。このビジネスはまだここでは予約できないと平易な言葉で伝え、返された別のサービスを提案してください。フォールバックについて説明してはいけません。
停止してください。 use-ucp-checkout-mode が成功したら、カレンダーのゲートを解決します。
booking-agent flow calendar ask
JSON の next_command に従ってください。カレンダーの選択肢を自分でユーザーに尋ねないでください。
ユーザーに何か尋ねる前に、実行時に確認できる情報に基づいてカレンダーの経路を選択してください。
--route connector:プラットフォームがユーザーの Google Calendar に接続し、アクセス トークンを環境変数で実行するコマンドに渡します。その変数の名前を--token-env <NAME>で渡してください。トークンそのものを渡したり、表示したり、保存したりしてはいけません。また、環境ファイルにコピーしてはいけません。会話のたびに名前を確認し、決めつけないでください。--route local-oauth:data.local_oauth_configuredが true で、サインインリンクをユーザーに渡せる場合です。--route delegated(イベントのみ。空き時間の確認は行いません):プラットフォームがカレンダーイベントを自ら書き込みます。書き込みのたびにawaiting_user: calendar_delegated_writeが返されます。user_messageを投稿し、promptの指示どおりに実行してから、返された内容だけを使ってnext_commandを実行してください。calendar_delegated_events_only、calendar_delegated_time_mismatch、calendar_delegated_report_incomplete、またはcalendar_delegated_request_unknownが返された場合は、next_commandを実行してください。- どちらでもない場合(一覧にあるものの未接続のコネクターも経路として扱われます):尋ねずに
booking-agent flow calendar skip --session-only --no-routeを実行してから続行してください。
CLI は経路と変数名を保存し、以降の予約でも使用します。推測はしません。--route なしの calendar connect は calendar_route_required で失敗し、有効な --token-env を指定せずに --route connector を使うと calendar_token_env_required で失敗します。
calendar ask の結果(それぞれに独自の prompt が含まれます。記載された内容だけを尋ねてください):
- 保存済みの設定がある場合: CLI がそれを適用し、空き状況の確認へ進みます。競合チェックが有効な場合は、ユーザーのカレンダーを使用していることを簡潔に伝えてください。
awaiting_user: calendar_reconnect: 保存済みのアクセス権の期限が切れています。カレンダーに関する3つの質問を再度してはいけません。data.calendar_reconnect_choicesにある2つの選択肢(同じ用途で再接続する、またはカレンダーを確認せずに続ける)だけを尋ね、表示されたとおりの対応するcommandを実行してください。またはbooking-agent flow calendar skip --session-onlyを実行してください。data.calendar_checking_unavailableがある場合、この予約では CLI がすでにカレンダー確認をスキップしています。そのことを平易な一文で伝えて続行してください。awaiting_user: calendar_consent: まだ接続されていません。経路が利用できる場合はどちらを希望するか尋ね、選択した経路を使って対応するコマンドを実行してください。経路がない場合は、前述のとおり、尋ねずにスキップしてください。- カレンダーのアクセストークンや Google のトークン URL を引用してはいけません。
booking-agent flow calendar skip # neither
booking-agent flow calendar connect --mode freebusy --route connector --token-env <NAME> # free/busy only
booking-agent flow calendar connect --mode events --route connector --token-env <NAME> # + post-booking event
booking-agent flow calendar connect --mode freebusy --route local-oauth # same, by sign-in link
booking-agent flow calendar connect --mode events --route local-oauth
コネクター経由の接続。 calendar connect はすぐに戻ります。接続済みの場合、ゲートは完了します。
awaiting_user: calendar_connector(data.error: calendar_not_connected)の場合、変数にはまだ有効なトークンがありません。プラットフォーム独自の方法で Google Calendar に接続し、data.scope_request に記載されたアクセスを求めてから、data.retry_command を再実行してください。この経路では、この CLI からサインインリンクを決して表示しないでください。プラットフォームで接続できない場合は、booking-agent flow calendar skip --session-only を実行してください。calendar_insufficient_scope の場合は、data.scope_request を使って再接続し、同じコマンドを再実行してください。
ローカル OAuth 経由の接続。 calendar connect は awaiting_user: oauth_approval と
data.auth_url を返してすぐに終了します。CLI 自体がブラウザーを開くことはありません。
- 生の
auth_urlを投稿し(Markdown の[label](url)形式にはしないでください)、CLI のpromptで説明されているアクセスを承認するよう依頼し、有効期間(data.link_valid_minutes)を伝えてください。 - 同じターン内に、ターンをブロックせずに
booking-agent flow calendar pollを実行してください(可能であればバックグラウンドで実行します)。awaiting_user: oauth_approvalとdata.status: pendingが返されている間は、リンクを再投稿せずに再度実行してください。接続されたら、next_commandを実行してください。 calendar_oauth_timeoutまたはcalendar_oauth_failedの場合は、エラーのuser_messageを投稿して停止してください。新しいリンク(data.choicesのnew_link)またはcalendar skip --session-onlyを提示するのは、ユーザーが求めた場合に限ります。calendar_insufficient_scopeの場合は、新しいリンクを希望するか尋ねてください。calendar_oauth_not_startedの場合は、booking-agent flow calendar askを実行してください。
calendar_oauth_not_configured または calendar_callback_port_busy の場合は、booking-agent flow calendar skip --session-only を実行してください(または、プラットフォームにコネクター経由の接続方法がある場合はそちらを使用してください)。
予約手続きの途中で Google Calendar の接続が切れた場合、CLI は最終確認の前にそれを検知し、awaiting_user: connections を返します(エージェントのループを参照)。自分で確認する必要はありません。
ステップ 4:空き状況を確認して予約枠を選択する
booking-agent flow availability --service-id <id>
booking-agent flow slots list
flow availability は、近い日付の固定期間(およそ今後 2 週間)をデフォルトで対象にします。ユーザーが自然言語で伝えた日付(例:「来週の木曜日」)を具体的なカレンダーの日付に変換するのは、あなたの役割です。希望日がデフォルトの期間外になる可能性がある場合、または特定の日だけを対象にしたい場合は、その日付を明示的に渡してください。
booking-agent flow availability --service-id <id> --target-date 2026-06-11 # single day
# or an explicit ISO8601 range:
booking-agent flow availability --service-id <id> --from <ISO8601> --to <ISO8601>
希望日が返された予約枠に含まれていない場合は、別の日を黙って提示するのではなく、--target-date を付けて再検索してください。そのうえで、本当にその日に空きがない場合はユーザーに伝えてください。
停止してください。 空きのある予約枠を表示し、ユーザーが選ぶまで待ってください。自動で選択してはいけません。予約枠は、日常的な時刻形式の番号付きリストまたは箇条書きで提示してください(| パイプを使った Markdown の表にはしないでください)。例:
1. 11:00 AM - 12:00 PM
2. 11:30 AM - 12:30 PM
3. 12:00 PM - 1:00 PM
続けて、どの番号または時刻がよいか尋ねてください。
タイムゾーン。 予約枠の時刻はビジネスのタイムゾーン(data.business_timezone)です。ユーザーのタイムゾーンは、そのユーザーの Link のデフォルト住所からのみ取得します。このデバイス、ホスト、VPN、チャットから取得してはいけません。slots list の prompt には、各予約枠の表示方法(ビジネスの時刻を先に表示し、括弧内にユーザーの時刻を表示すること、一度だけの注意書き、カレンダーのタイムゾーン、フォールバックに関する注記)が明記されています。これに従ってください。タイムゾーンについて別途質問する必要はありません。CLI が時刻の確認を求めている場合(next_command に --timezone-confirmed が含まれています)は、その正確な時刻をユーザーに確認して停止してください。確認しないと、slots select は timezone_confirmation_required を返します。
各予約枠の時刻は、それぞれ 1 つの選択肢です。予約枠に resource_options がある場合、その時刻を複数のスタッフまたはリソースが担当できます。その予約枠を複数回表示したり、どのスタッフまたはリソースにするかユーザーに選ばせたりしないでください。
booking-agent flow slots select --slot-id <chosen by user> --user-confirmed
--user-confirmed は必須です。指定しない場合、CLI は処理を拒否します。
ステップ 5:Link ウォレットの認証と購入者の解決
ステップ 5a — Link にサインインする。 slots select により link-auth connect が返されます。通常、ユーザーはすでにサインインしているため、すぐに返されます。awaiting_user: link_auth_approval が返された場合は、Link へのサインインに従ってください。
ステップ 5b — 購入者を解決する
booking-agent flow buyer resolve --notes '<short note for the business>'
ユーザーの依頼をもとに --notes を作成します。問題、対象、必要としていることを記載します(例:「窓用エアコン、まったく反応しない、ブランド不明」)。依頼に事業者が必要とする情報が含まれていない場合は、省略してください。住所、氏名、連絡先を記載しないでください。
停止してください。 data.booking_recap_lines の各行を、順番どおりに、一字一句そのまま1行ずつ表示します。これらの行は CLI が作成するものです(サービスと事業者、日時、正確な住所を含む場所、価格、氏名、メールアドレス、電話番号、事業者向けのメモ)。そのため、言い換えたり、まとめたり、省略したりしないでください。data.selected_slot.buyer_display がある場合、When の行にはすでにユーザーの時刻が括弧内に記載されているため、1回の「はい」でタイムゾーンの違いも含めて確認できます。data.timezone_notice がある場合(ユーザーのタイムゾーンが判明したのがこの時点のみの場合)は、これを最初に伝えてください。その後、1つの確認質問にまとめて尋ねてください。ユーザーがメモを訂正した場合は、buyer resolve --notes '<corrected note>' を再実行してください。住所を訂正した場合は、booking-agent flow search-area propose --purpose service-address を実行してください。
data.payment_route(無料、予約時に支払い、今すぐ請求、またはデポジット)については、prompt が示す質問を1つ尋ね、amount_minor_units の生の値ではなく data.price_display をそのまま伝えてください。無料サービスまたは予約時に支払うサービスでは、請求や Link ウォレットに絶対に言及しないでください。data.quote_caveat が設定されている場合、その金額は事業者のチェックアウト時の合計が確定するまで見積もりです。
data.policy_lines / data.policy_links がある場合は、予約内容の確認の後に表示し(リンクはそのまま)、同じ質問の中で同意するか尋ねてください。ユーザーの承認を得るまで flow book を実行しないでください。承認後、表示されたとおりに next_command を実行してください。予約後に、価格のみ、またはタイムゾーンのみについて別途確認を求めないでください。
このステップでは、個人識別情報(常に Link から取得)を適用します。購入者の情報を手入力しないでください。buyer resolve が link_cli_failed または link_auth_expired で失敗した場合は、ユーザーに再度サインインしてもらい(Link へのサインインを参照)、再試行してください。
ステップ 6:予約と支払い
ステップ 6a — 予約する
booking-agent flow book --user-confirmed [--policies-accepted]
自宅への訪問(channel.type: at_buyer_location)の場合、flow book は確認済みの住所と buyer resolve からのメモを自動的に送信します。住所を自分で地図に入力したり、渡したりしないでください。service_address_unconfirmed で失敗した場合は、その next_command を実行し、ユーザーに住所を確認してください。
flow book は data.merchant_quote と data.price_display を返します。amount_minor_units、price_minor_units、生の amount をドル単位の金額として伝えることは絶対にしないでください。price_display または merchant_quote.total_display のみを伝えてください。税金について伝えるのは、merchant_quote に事業者からの税額行が含まれている場合に限ります。税額がゼロだと決めつけたり、税額行が返されていないのに税金が追加される可能性があると警告したりしないでください。支出リクエストには、事業者が提示した合計金額のみを使用します。
事業者のポリシー。 awaiting_user: policy_acceptance または policies_not_accepted の場合は、user_message(各ポリシー行とそのままのリンク)を投稿し、同意するか尋ねて、停止してください。「はい」と答えた場合に限り、next_command(--policies-accepted が追加されます)を実行します。「いいえ」と答えた場合は予約しないでください。ポリシーが送られていない場合は、ポリシーについて何も言わないでください。flow book が awaiting_user なしで表示したリンクは投稿しますが、質問はしないでください。
無料および予約時に支払う予約(free、at_service)。 flow book は予約を直接行い、next_command は booking-agent flow book poll --wait になります。これを実行する前に、data.booking_narration の内容を短く平易なメッセージでユーザーに伝えてください。つまり、リクエストは送信済みで、料金は請求されていない(または料金は予約時に支払い済み)こと、現在は事業者の確認を待っていることです。その後、コマンドを実行して結果を報告してください。支払いを作成してステップ 6b から 6d を省略することは絶対にしないでください。
予約時支払い(pay_at_service)。 料金は請求されないため、pay request はスキップしてください。
予約時に支払う金額とポリシーを提示してから、next_command を実行してください。
merchant_quote.total_changed の場合は承認を得て、--total-confirmed を追加してください。
booking_confirmation_pending または booking_not_confirmed の場合は、user_message を投稿して、任意の
next_command を実行してください。
デポジット予約(deposit_required)。 請求の前に、data.due_now_display(今すぐ請求されるデポジット)、
予約時に支払う金額、および data.payment_schedules と data.payment_disclosures の全項目を提示し、
ユーザーの同意を得てから、next_command を実行してください。スケジュールの時刻は due_at_display から、
開示内容のテキストは content_display から引用してください。生の due_at や content 内のタイムスタンプは
引用しないでください。
チェックアウトの合計金額が提示した金額と一致する場合、ユーザーは購入者の確定時点ですでに予約と請求を
承認しています。ポリシーへの同意が得られたら、data.merchant_quote.total_changed が true でない限り、
ステップ 6b に進んでください。CLI はチェックアウトの明細が提示したサービス料金と一致することをすでに確認
しています。そのため、合計金額が変わっている場合は、事業者が税金や手数料を追加した(または割引を適用した)
ことを意味します。そこで 必ず停止 してください。サービス料金(merchant_quote.line_item_display または
subtotal_display)、税金(存在する場合のみ tax_display)、および新しい合計金額(total_display)を
ユーザーに伝え、その金額への承認を得てください。承認を得た後に限り、pay request に
--total-confirmed を渡してください。支払いリクエストではチェックアウトの合計金額が請求されます。
ステップ 6b — 支払い元の解決(共通。支払いの分岐前に一度実行)
link-cli payment-methods list --format json
デフォルトのカードの id を取得してください。ステップ 6c で pay request に渡してください。
ステップ 6c — 承認を求め、バックグラウンドで待機
booking-agent flow pay request --payment-method-id <id-from-6b>
CLI は、ユーザーが Link での承認時に読むメモを書き込みます。そのメモを自分で書いたり渡したりしないで
ください。CLI はすぐに awaiting_user: link_spend_approval と、user_message 内の承認 URL を返します
(予約ごとに一度だけ表示)。同じターン内に、booking-agent flow pay poll をバックグラウンドで開始し、
その後、ほかの説明をする前に user_message を生の URL のまま投稿してください。pay poll は、ユーザーが
Link で承認するのを待ち、チェックアウトを完了して予約を検証し、カレンダーのイベントを追加します。
終了したら、ステップ 7 に従ってください。URL を stderr から読み取らず、チャットでの返信を
待たず、最初の pay poll をフォアグラウンドで実行しないでください。ターンがブロックされ、ユーザーにリンクが
表示されなくなります。
ステップ 6c-iii - 銀行の本人確認と支払いの拒否
銀行の本人確認は 2 つのタイミングで発生し、それぞれ逆の方法で処理します。
- 請求前(発行時)。
pay requestまたはpay pollが Link 上での処理を待っている間に、CLI が銀行の メッセージと生の本人確認 URL をuser_messageに含めてawaiting_user: link_spend_approvalを返すことが あります(Link のnext_action.type: three_d_secure、resolution: auto_resume)。これは支払いの失敗では ありません。next_command(booking-agent flow pay poll)をバックグラウンドで開始し、同じターン内にuser_messageを投稿してください。ポーリングは同じ支払いリクエストを待ち続けます。代わりに CLI がspend_request_replacement_required(たとえばthree_d_secure_retry)を返した場合は、user_messageを 表示してnext_commandを実行し、新しい支払いリクエストを作成してください。 - 請求失敗後(失敗後)。
pay ucp-complete(またはpay poll)がトークンを事業者に送信し、請求が失敗した後は、 Link に表示されている場合でも、支払いリクエストのaction_urlや銀行の本人確認リンクにユーザーを誘導しては 絶対にいけません。そのリンクは請求側の認証チャレンジであり、完了すると予約が確定していないのに料金が 引き落とされる可能性があります。CLI は支払いリクエストを一度確認し、その URL を表示せず、チェックアウト ID と ともにpost_failure_action_suppressedを記録します。支払いが完了しなかったことをユーザーに伝えてください。pay ucp-completeが失敗した後の対応は、data.error.codeだけで決まります。チェックアウトのステータスや、continue_urlがあるかどうかを基準に判断しないでください。これらのエラーにはすべて、何が起きて次にどうなるかをユーザーに伝える、平易な表現のuser_messageが含まれています。next_commandを実行する前に、必ずそのまま投稿してください(URL は生のままにし、Markdown の[ラベル](URL)にしないでください)。
これらのエラーにはすべて、平文の user_message と next_command が含まれています。メッセージをそのまま(URL は生のまま)投稿してから、コマンドを実行してください。
payment_declined、payment_failed(回復可能)、payment_authentication_unsupported、payment_not_processed:カードが拒否され、支出リクエストは使用済みです。ユーザーが別の Link カードを選んだら、next_command(booking-agent flow pay request --payment-method-id <id>)を実行してください。payment_unrecoverable:チェックアウトを完了できなくなりました(セッションはFAILED)。メッセージを投稿して終了してください。next_commandはありません。このチェックアウトを再試行しないでください。complete_in_progress、checkout_already_in_progress:拒否ではありません。同じ支出リクエストとチェックアウトを使います。新しい支出リクエストを作成したり、請求したりしないでください。payment_captured_booking_unconfirmed:支払い済みですが、予約は未確定です。以下を参照してください。mandatory_acceptance_pending:ポリシーへの同意など、支払い以外の手続きです。メッセージにはcontinue_urlとポリシーへのリンクが含まれています。ユーザーが完了したと伝えるまで待ってください。ユーザーに代わって同意しないでください。approval_timeout、spend_request_not_approved、ucp_complete_failed、その他すべての場合:返されたnext_commandを実行してください。再度失敗した場合は、現在は完了できなかったことをユーザーに伝えてください。
pay poll の実行中に支払い済みとなり、予約が未確定の場合。 バックグラウンドの pay poll はこの状況では失敗しません。data.status: waiting_for_business_confirmation と user_message を含む出力を 1 つ表示してから、同じプロセス内で事業者からの確認を待ち続けます。その user_message を見たらすぐに一度だけ投稿し、同じ pay poll が終了するのを待ってください。book poll を実行したり、スリープしたり、ほかの処理を開始したりしないでください。終了コードが 0 の場合、最終出力は予約確定を示します。ユーザーに予約が確定したと伝えてください。ゼロ以外の終了コードの場合、最終出力は以下の手順 3 に記載されている引き継ぎのいずれかになります。
ほかのコマンドから、支払い済みで予約が未確定となった場合。 payment_captured_booking_unconfirmed では:
next_commandを実行する前に、すぐにuser_messageを投稿してください。支払いが完了したこと、確認には数分かかることがあること、確認を監視していること、まだ事業者に連絡したり再度支払ったりしないように伝えるメッセージです。これがないと、まもなく自動的に確定する予約について、ユーザーが事業者に連絡してしまう可能性があります。支払いを再試行したり、別のカードを求めたりしないでください。CLI はこれを強制します。pay ucp-complete、pay request、pay rebookはpayment_already_capturedを返し、flow statusは予約確認へ戻るよう案内します。next_command(booking-agent flow book poll --wait)をフォアグラウンドで実行してください。事業者が確定すれば、通常の成功時と同様に予約が完了します。ユーザーに予約が確定したと伝えてください。- 事業者がまだ確定していない場合、またはキャンセルした場合(
booking_canceled_after_payment)、CLI は事業者に連絡するためのリンク(予約ページまたは事業者のサイト。チェックアウトページではありません)、予約と注文の参照情報、依頼内容を含むuser_messageを返します。依頼内容は予約の確定、または支払いの返金です。そのまま投稿してください。 - ユーザーが請求に異議を申し立てたい場合は、
booking-agent flow evidenceを実行し、支払いと予約の参照情報を共有してください。ユーザーに代わって異議申し立てを開始しないでください。
continue_url のルール: payment_declined または payment_failed による支払い拒否の後は、レスポンスに表示されていても、事業者のホストするチェックアウトページ(continue_url)を決して表示しないでください。CLI はこれを省略します。このルールは、これらの支払い拒否にのみ適用されます。mandatory_acceptance_pending では、引き続き continue_url が表示されます。
決して、拒否された支払いリクエストで pay ucp-complete を再実行しないでください。CLI はそのリクエストをクリアするため、次に完了するにはユーザーから新たな承認を得る必要があります。
CLI はセッションの checkout_mode に基づく認証情報タイプのルーティングを内部で処理します。UCP ネイティブのチェックアウト(Link Agent Wallet)では、支払いリクエストの network_id は flow book 後のチェックアウトにある com.stripe.payments → available_instruments エントリの type: "link" → config.network_id から取得します(読み取り専用の data.ucp_spt_network_id)。pay request はセッションからこれを適用します。--network-id を渡したり、network_id をでっち上げたり、link-cli mpp decode を実行したり、加盟店の HTTP 402/WWW-Authenticate を調べたり、Link UI を初期化したり、Link のために Stripe の /tokenize を呼び出したりしないでください。ハンドラーの仕様:UCP 用 Stripe Payments ハンドラー(スキーマ:https://ucp.stripe.com/payments/2026-06-25/schema.json)。USP §7.4:
https://github.com/wix/universal-scheduling-protocol/blob/master/specification.md#74-paid-bookings-extension-schema
UCP の complete_checkout(CLI が内部で構築します):handler_id: "stripe_payments"、
type: "link"、credential.type: "stripe_payment_token"、credential.token = 承認後に link-cli から取得する SPT(支払いリクエストの作成時のみ --credential-type shared_payment_token を指定します)。
ステップ 6d(検証)は pay poll の一部です。ステップ 7 を参照してください。
支払いに関する注意事項(エラー復旧時のみ):
at_service:料金は予約時に支払うとユーザーに伝えてください。pay requestは決して実行しないでください。deposit_required:今すぐ支払う必要のある金額のみ請求してください。デポジット額を独自に計算しないでください。- 支払いのタイミングが不明、または変更されている場合は予約できません。タイミングが変更された場合は、新しい見積もりを取得してください。
- 事業者とクライアントは
USP_AGENT_PROFILE_URLでドキュメントを取得します。デフォルトでは正規 URL が使用されます。 - 支払い後は
next_commandに従ってbooking-agent flow book poll --waitを実行してください。予約確認は GET によるポーリングのみです。受信する予約 Webhook を開始したり、リクエストしたりしないでください。
ステップ 7:完了
pay poll(無料または来店時支払いの予約では book poll --wait)が予約を検証し、ユーザーがイベントモードを選択している場合はカレンダーイベントを追加して、最終回答を返します。その user_message を、記載どおりにそのまま投稿してください。予約完了の文、イベントが追加された場合の生のカレンダーリンク、予約管理用リンクが含まれています。その後、next_command(新しいアシスタントがいないかの簡単な確認)を実行し、更新の手順に従ってください。data.calendar.calendar_not_added が true の場合、メッセージにその旨がすでに記載されています。ユーザーが再試行を希望する場合に限り、booking-agent flow calendar create-event を実行してください。validate-skill-compliance がゼロ以外の終了コードを返した場合は、data.error.message を読み、不足しているゲートを修正してから完了としてください。
認証の記録(ユーザーが求めた場合)
支払い後、またはユーザーが領収書形式の認証 ID を求めた場合:
booking-agent flow evidence
関連付けキー(予約参照番号、支払い参照番号)を平易な言葉で共有してください。カードデータ、認証情報、共有支払いトークンは決して公開しないでください。
ステップ 8 と予約後
実行することはありません。ステップ 7 のコマンドですでにカレンダーイベントが追加されています。
重要事項
- ユーザーとのやり取りのルールに絶対に違反しないでください。生の URL のみを使い、 表は使わず、専門用語も使わないでください。
pay requestの後は、next_command以外の支払いコマンドに絶対に置き換えないでください。- 最初の
pay pollまたはlink-auth pollをフォアグラウンドで絶対に実行しないでください。対話フローではpay request --then-completeまたはlink-auth connect --waitを使い、「approved」や「done」と返信するようユーザーに頼んだり、Link の承認 URL を複数回表示したりしないでください。ポーリングはバックグラウンドで開始し、同じターンで URL を提示してください。 - ユーザーに確認せず、既存のセッションを絶対に続行しないでください。
sessions listにリクエストに一致する未完了のセッションが表示される場合、またはflow initがsession_activeを返す場合は、停止して、続行するか最初から始めるかをユーザーに尋ねる必要があります。flow statusでアクティブなセッションを確認してから、何も言わずに進めることは禁止されています。ユーザーが必ず明示的に選択する必要があります。 sessions listを予約履歴として絶対に扱わないでください。これは、このデバイス上の未完了フローと今後の予約のみを示します。残っている行をもとに「過去の予約を見せて」と言われても回答せず、確認できていない履歴を店舗に問い合わせたと主張しないでください。- USP の
/availability/query、/bookings、/availability/holds、/bookings/*/confirm-paymentを、生のcurl、httpx、または HTTP クライアントで絶対に呼び出さないでください。予約は必ずbooking-agent flow ...を通じて行ってください。 - プレースホルダーやチャットで入力された個人情報(氏名、電話番号、メールアドレス、住所)は絶対に使用しないでください。必ず
link-cliを通じて Link から取得してください。個人情報の確認(必ず Link から取得)を参照してください。予約時にはbooking-agent flow buyer resolveを使用してください。住所は、ユーザーが確認した後にflow search-areaからのみ取得できます。at_buyer_locationサービスの場合、flow bookが確認済みの住所を送信します。住所を--notesに入力しないでください。 - 時間枠を自動で選択しないでください。
- ユーザーが該当する質問に回答する前に、
--mismatch-confirmed、--details-confirmed、--timezone-confirmed、--user-confirmed、--policies-accepted、--allow-duplicateを絶対に指定しないでください。ポリシーの文言やリンクを言い換えたり、隠したりしないでください。 - CLI の状態ファイルや
link-cliの設定を絶対に読み取ったり削除したりしないでください。flow purgeを使用してください。 booking-agentコマンドと同時にsleepや一定時間の待機を絶対に実行しないでください。コマンドが終了するまで待ってください。- カレンダーの確認手順を絶対に省略しないでください。
- カレンダーのルートやトークン変数の名前を推測したり、コマンドラインでトークン値を渡したりしないでください。
エラー
すべてのエラーは data.error.code、data.error.message、next_command を返して終了コード 1 で終了します。ここに記載のないコードが返された場合は、next_command に従って復旧してください。次のゲートエラーには、ほかに対応は必要ありません。approval_not_surfaced_to_user、booking_canceled_after_payment、buyer_email_invalid、buyer_not_from_link_cli、calendar_gate_not_completed、checkout_prereq_not_completed、context_required、discover_radius_required、link_address_not_found、missing_network_id_for_spt、payment_already_captured、reschedule_at_business、reschedule_booking_not_active、reschedule_failed、reschedule_fee_unsupported、reschedule_price_changed、reschedule_price_unknown、reschedule_same_slot、reschedule_unauthorized、search_area_input_invalid、search_area_not_user_confirmed、search_area_unconfirmed、service_address_unconfirmed、service_details_changed、slot_not_selected、spend_request_replacement_required、timezone_confirmation_required。
支払い関連のコードはステップ 6c に記載されています。reschedule_* コードはすべて同じ方法で処理します。生の booking_url を提示し、ユーザーが店舗独自のページで変更できることを伝えてください(reschedule_price_changed と reschedule_same_slot の場合は、別の時間枠を尋ねます。reschedule_failed の場合は、再度 reschedule availability を実行します)。
| エラーコード | 原因 | 対処方法 |
|---|---|---|
link_auth_gate_not_completed | Link にサインアウトした状態で search-area propose または buyer resolve を実行しました | ユーザーにサインインしてもらい(link-auth connect を実行し、その後バックグラウンドで link-auth poll を実行して、同じターン内に URL を投稿します)、再試行します |
link_auth_expired | 支払い前に Link セッションの有効期限が切れました | 同じ方法でユーザーにサインインしてもらい、再試行します |
link_auth_timeout | ユーザーが制限時間内に Link へのサインインを承認しませんでした | next_command を実行します。バックグラウンドで link-auth poll を再度実行する(同じリンクを使い、再投稿しません)か、link-auth connect を実行する(新しいリンクを一度だけ投稿し、その後バックグラウンドでポーリングします) |
link_auth_not_started | サインイン待ちの状態ではないのに link-auth poll を実行しました | booking-agent flow link-auth connect を実行し、バックグラウンドで link-auth poll を開始して、URL を投稿します |
ucp_native_required | ビジネスはネイティブ v2 チェックアウトのフローに対応していません | こちらではまだこのビジネスを予約できないことをユーザーに伝え、別の検索結果を提示します |
policies_not_accepted, booking_confirmation_required, mismatch_not_surfaced, purge_not_surfaced | 内容を表示する前に確認フラグを渡したか、表示した内容が変更されました | user_message を投稿してユーザーに確認し、停止します。はいという返答があった場合にのみ next_command を実行します |
calendar_offer_not_shown | calendar ask を実行する前にカレンダーの回答がありました | calendar ask を実行します |
no_bookable_results, profile_resolve_failed | 予約可能なビジネスがないか、選択したビジネスが予約を受け付けられません | user_message を投稿し、別の検索結果を提示します |
shared_payment_token_not_issued | Link は支払いリクエストを承認しましたが、共有支払いトークンが返されなかったため、請求は発生していません | user_message を投稿し、pay ucp-complete をもう一度実行します。それでも失敗する場合は、現在このビジネスでは Link で支払えないことをユーザーに伝え、再度の承認を求めないでください |
checkout_total_unconfirmed | チェックアウトの合計金額(税金、手数料、割引)が提示価格と異なり、ユーザーが承認していません | data.merchant_quote に記載されたサービス料金、税金、合計金額を表示して承認を得た後、--total-confirmed を付けて pay request を再実行します |
payment_timing_changed | 最新のカタログに記載されたタイミングが見積もりと一致しなくなりました | 中止し、見積もりを取り直して、新たに承認を得ます |
payment_timing_not_supported | 最新のカタログに別の未対応のタイミングが記載されています | 中止し、こちらではまだこのサービスを予約できないことを説明します |
mandatory_acceptance_pending | ビジネス側でチェックアウト前にポリシーへの同意、または別の支払い以外の手順を求めています | エラーに含まれる continue_url/ポリシーリンクを表示し、完了を待ちます。その後 flow book を再試行します(pay ucp-complete によるエラーの場合は next_command を実行します)。ユーザーに代わって同意してはいけません |
service_not_available_in_area | サービスの座標が、指定した --radius-km の範囲外です | 検索範囲を広げるか、別の検索結果を選びます。プロフィール URL を直接指定して回避してはいけません |
profile_unreachable | ビジネスのプロフィール URL にアクセスできません | data.error.message に含まれる URL をユーザーに伝えます |
agent_profile_unresolvable | ビジネスが予約アシスタントのプラットフォームプロフィールを取得できなかったため、予約は完了していません | user_message を投稿し、next_command を一度実行します(同じ冪等性キーを再利用するため、二重予約にはなりません)。再度失敗する場合は、別の時間帯またはビジネスを提示します |
reschedule_not_actionable | このデバイスからのセッションが、確定済みの今後の予約ではありません | sessions list から該当する予約を再開します。過去の予約や別のデバイスで行った予約は、ビジネスのページでのみ変更できます |
reschedule_not_allowed | ビジネスのポリシーにより、この予約の変更は許可されていません | booking_url の URL をそのまま表示し、ビジネスに問い合わせれば変更できることを伝えます |
session_store_too_new | このデバイスに保存された予約は、より新しいバージョンのアシスタントによって書き込まれています | next_command(booking-agent update check)を実行し、その指示に従います。保存された状態を削除または編集してはいけません |
update_not_confirmed | --user-confirmed を付けずに update を実行しました | まずユーザーに確認し、同意を得た後にのみ --user-confirmed を渡します |
update_session_in_progress | 予約が未完了の状態で update を実行しました | 先に予約を完了またはキャンセルしてから、更新を再度提示します |
update_failed / update_not_verified | 更新がインストールされなかった、起動しなかった、または公式リリース由来であることを確認できませんでした(data.reason)。未検証のものはインストールされていません | 更新が適用されなかったことをユーザーに伝え、インストール済みのバージョンで続行します |
installation_unverified | インストール済みの CLI ファイルが署名済みの公式リリースと一致しないため、予約や支払いは行われません | アシスタントの再インストールが必要であることを、わかりやすくユーザーに伝えます。ユーザーの同意があった場合にのみ data.reinstall_command を実行し、その後予約を最初からやり直します。別の方法で予約してはいけません |
skill_unverified | 読み込んだ SKILL.md が、この CLI のリリースに含まれる署名済みスキルと一致しないため、予約や支払いは行われません | 以降は data.skill_text に従います。アシスタントの指示ファイルが変更されていることをユーザーにはっきり伝え、公式のファイルに戻すか確認します。ユーザーの同意があった場合にのみ data.replace_command を実行し、その後 --skill-path を付けて flow init を再実行します。別の方法で予約してはいけません |
skill_path_invalid | --skill-path で指定したファイルが存在しない、読み取れない、または booking-agent の SKILL.md ではありません | 読み込んだファイルの正しいパスを指定して flow init を再実行します。パスがわからない場合は --skill-path を付けずに実行します |
skill_output_refused | skill print --output で、読み込まれたスキルではないファイルを指定しました | 代わりに booking-agent skill print の data.skill_text に従います |
アシスタントチームへの注意事項
ここから修正できない問題が発生した場合、出力では support_report_offered: true と
next_command に booking-agent flow support-report が設定されます。その出力に
user_message が設定されている場合はそれを表示し、同じターン内に next_command を
実行してください。実行すると、質問が user_message に設定された状態で
awaiting_user: support_report_consent が返されます。
- その質問を一言一句そのまま表示して、停止してください。言い換えたり、詳細を付け加えたりしないでください。
- はいの場合は、表示された
next_command(booking-agent flow support-report send --user-confirmed)を実行してください。 いいえの場合は、booking-agent flow support-report declineを実行してください。どちらの場合も、返されたnext_commandを続けて実行してください。 - 注意事項は事前に用意されており、そのまま送信されます。自分で作成したり、宛先を選んだり、 添付ファイルを追加したり、メールを送信したりしないでください。
- 送信に失敗した場合は、
user_messageを表示し、next_commandを続けて実行してください。ユーザーから再試行を求められた場合に限り、booking-agent flow support-reportを実行し、その指示に従ってください。
予約の認証
CLI は、予約、変更、キャンセル、支払いなど、権限が必要な各手順で認証を行い、匿名リクエストに フォールバックせずに処理を拒否します。検索、カタログ、空き状況の確認は公開されています。
- ビジネスの情報を閲覧できても、予約できるとは限りません。その理由で予約が拒否された場合は、 このビジネスはまだこちらから予約できないとはっきり伝え、代替案を提示してください。再試行したり、 その仕組みを説明したりしないでください。
- キャンセルには、その予約だけに適用され、このデバイスに保存されている認証情報を使います。有効期限が切れていたり、
ビジネス側で拒否されたりした場合、再試行しても意味はありません。ユーザーに
booking_urlを伝え、 ビジネスの公式ページでキャンセル手続きを完了するよう案内してください。
このような仕組みについては決して言及しないでください。「キャンセルしておきました」または「この予約はウェブサイトで キャンセルする必要があります。リンクはこちらです」と伝えるだけで十分です。
今後の予約をキャンセルする
1件の予約をキャンセルするには、そのセッションを再開して booking-agent flow book cancel を実行します。複数の予約をキャンセルする場合や、未完了のリクエストをすべて削除する場合は、2段階の一括コマンドを使います。シェルで sessions resume と book cancel をループ実行してはいけません。
キャンセルが成功したら、user_message をそのまま投稿します(URLは生のまま)。次の内容がすでに記載されています。
- 予約がキャンセルされたこと、および支払った料金が返金されたかどうか。
- 全額返金されなかった場合は、
refund_follow_up.stepsに記載された番号付きの手順。事業者への連絡方法(contact_url、管理ページ、または事業者のウェブサイト)、返金を求める正確な金額(outstanding_display)、予約と注文の参照番号。 - Google カレンダーの予定が削除されたかどうか(
data.calendar.statusはdeletedまたはalready_missing)。failedの場合は、ユーザー自身で予定を削除するよう案内し、そのリンクも示します。Google カレンダーを再接続した後、booking-agent flow calendar delete-eventを再試行できます。
返金手順を「料金は返金されませんでした」と短縮してはいけません。ユーザーが返金を受ける方法を知る必要があります。
-
プレビューします(読み取り専用で、何も変更しません)。
booking-agent flow sessions cancel-opendata.bookingsには、まだキャンセルできる今後の予約が、data.unfinishedには予約に至らなかったリクエストが、data.heldには支払い処理中のリクエストが一覧表示されます。各行にはuser_request、事業者、予約枠の日時が含まれます。キャンセル済み、完了済み、無断キャンセル、および過去の予約は表示されません。 -
各行の内容を日常的な言葉でユーザーに伝え、どれをキャンセルするか尋ねてから、そこで停止します。ユーザーの依頼に合致する行だけを選びます。テスト、検査、その他のリクエストのように見える行がこの依頼に関するものだと決して決めつけてはいけません。また、独自に行を選択してはいけません。ユーザーがすでにすべてをキャンセルすると明言している場合に限り、質問を省略します。
-
ユーザーが選んだ内容を正確に指定して、確認済みのコマンドを実行します。
booking-agent flow sessions cancel-open --user-confirmed --session-id <id> [--session-id <id> ...] # only when the user said all of them: booking-agent flow sessions cancel-open --user-confirmed --all未完了のリクエストを削除することにユーザーが同意した場合に限り、
--forget-unfinishedを追加します。これを指定しない限り、未完了の行は削除されません。heldの行は削除されません。 -
data.resultsの各行をoutcomeに応じて報告します。1件の失敗によって、ほかの処理が停止することはありません。canceled:その行のuser_messageをそのまま投稿します。refund_follow_upに記載された返金手順(事業者のcontact_url、返金を求める金額、予約と注文の参照番号)と、カレンダーの削除結果が含まれています。返金案内に注文ページや決済ページのURLを表示してはいけません。これらのページは支払い直後にしか機能しません。needs_human:生のbooking_url(またはcancel_urlsの最初の項目)を表示し、事業者のページでキャンセルを完了するよう伝えます。failed:処理が完了しなかったことを伝え、リンクがある場合は同じリンクを共有します。独自に再試行してはいけません。forgotten:未完了のリクエストがこのデバイスから削除されました。skipped:何も行われませんでした。理由はskip_reasonに記載されています。
| エラーコード | 原因 | 対処 |
|---|---|---|
cancel_unauthorized / cancel_forbidden | 事業者が予約認証情報を拒否しました(HTTP 401 / 403) | 生の booking_url または cancel_urls の最初の項目を表示します。再試行してはいけません |
cancel_failed | それ以外のキャンセル失敗(事業者から応答があった場合は http_status) | 処理が完了しなかったことをユーザーに伝え、リンクがある場合は booking_url / cancel_urls を共有します |
cancel_open_selection_required | --session-id または --all を指定せずに --user-confirmed を指定しました | プレビューを表示してユーザーに確認し、その選択内容を渡します |
cancel_open_selection_conflict | --session-id と --all の両方が指定されました | どちらか一方を指定します |
予約済みの予定を変更する
ユーザーがこのデバイスで予約した予定の日時変更を希望する場合は、既存の予約を変更します。決してこのために flow init を実行したり、新しい予定を予約したりしないでください。また、予約をキャンセルして取り直すことも避けてください。
-
booking-agent flow sessions listを実行し、actionable: trueかつbooking_idがある行を選びます。該当する可能性がある予約が複数ある場合は、どの予定かユーザーに尋ね、そこで停止します。 -
その予約に対して
booking-agent flow sessions resume --session-id <id>を実行します。 -
booking-agent flow reschedule startを実行します。事業者が日時変更を許可していることと、この予約がまだ未来の予定であることを確認します。 -
ユーザーが変更後の希望日時を伝えていない場合は、希望日時を尋ね、そこで停止します。予約時と同じ日時の指定方法を使います(特定の日付 →
--target-date、時間帯 →--from/--to)。 -
booking-agent flow reschedule availability [--target-date YYYY-MM-DD | --from ... --to ...]を実行します。selectable: trueの枠だけを番号付きまたは箇条書きのリストで提示し、ユーザーが選ぶまで停止します。決して自動で選択しないでください。時刻はステップ 4 と同じタイムゾーンのルールに従います。business_start_displayを表示し、data.timezone_noticeがある場合はリストの上に一度だけ記載し、括弧内にbuyer_start_displayを追加します。ユーザーの希望日時がリストにない場合は、現在その時間帯は空いていないとだけ伝えます。空き状況は問い合わせのたびに変わり、CLI は枠がなくなった理由を報告しないため、理由を提示しないでください。 -
booking-agent flow reschedule select --slot-id <chosen by user> --user-confirmedを実行します。 -
awaiting_user: reschedule_confirmになったら、日常的な言葉で日時変更を確認し、そこで停止します。以下の例のように、プロンプトに表示されたとおりに 2 つの時刻を、それぞれラベル付きの行に分けて表示します(事業者のタイムゾーンの時刻を先に表示し、表示されている場合は括弧内にユーザーのタイムゾーンの時刻を表示します)。Current time: Tue, Oct 13, 2026, 11:30 AM MST (America/Phoenix) to Tue, Oct 13, 2026, 12:30 PM MST (America/Phoenix) New time: Tue, Oct 13, 2026, 1:15 PM MST (America/Phoenix) to Tue, Oct 13, 2026, 2:15 PM MST (America/Phoenix)2 つの時間帯を「…から…まで」の 1 文にまとめてはいけません。ユーザーが同意してから
booking-agent flow reschedule apply --user-confirmedを実行します。ユーザーが考えを変えた場合は、booking-agent flow reschedule abortを実行します。 -
変更が正常に適用されたら、新しい日時をユーザーに伝えます。
next_commandがbooking-agent flow calendar update-eventの場合は、それを実行し、html_linkが返されたらその生の値を共有します。カレンダーのステップが失敗しても予定の日時は変更されています。そのことを明確に伝えてください。
日時変更できるのは同じ料金の枠のみで、事業者が変更手数料を請求しない場合に限られます。差額や手数料の支払いを提案したり、返金を約束したりしないでください。この方法では変更できない場合(reschedule_not_allowed、reschedule_fee_unsupported、reschedule_at_business、または認証情報が拒否された場合)は、生の booking_url(または manage_urls の最初の項目)を表示し、事業者自身のページで変更できることをユーザーに伝えます。このデバイスで予約していない予定は、事業者のページでのみ変更できます。
アカウントからログアウト/接続を解除する
ユーザーが Link と Google Calendar からのログアウト、サインアウト、または接続解除を求めた場合は、次を実行します。
booking-agent flow logout
このデバイスではログアウト済みであることを、日常的な言葉で伝えます。今後の予約は保存されたままなので、引き続きキャンセルできます。ユーザーを link-cli に直接誘導しないでください。
このデバイスから今後の予定を 1 件だけ削除して忘れるには(ログアウトとは異なり、事業者側の予約履歴を削除するものではありません):
booking-agent flow sessions forget --session-id <id>
ユーザーに求められた場合に限り、このデバイスにあるこのアシスタントのデータをすべて消去するには、booking-agent flow purge を実行します。まだ何も削除されません。user_message を投稿して停止し、ユーザーが「はい」と答えてから next_command を実行します。
booking-agent flow sessions list は、未完了のフローまたは今後の予約(actionable: true、booking_id、枠の時刻)を見つけるためにのみ使用します。過去の予約を一覧表示する目的では使用しないでください。
設定
ホストに関係する設定は2つあります(一覧は booking-agent config show で確認できます)。BOOKING_AGENT_BUYER_DEVICE_IP(検出された場合の購入者のデバイス IP)と、BOOKING_AGENT_USP_AUTH_SCOPED_CREDENTIAL(デフォルトは required。詳しくは予約の認証を参照)です。ユーザーに表示されない障害は、ユーザーデータを含めずに自動報告されます。BOOKING_AGENT_FAULT_REPORTS=0 を設定すると、報告を無効にできます。
関連ドキュメント
- Stripe link-cli の支出リクエストコマンド:https://github.com/stripe/link-cli
- USP 仕様:https://usp-protocol.dev/specification
ライセンス
このスキルと Booking Agent のソースコードは、Copyright 2026 Wix.com の Apache License 2.0 に基づいて公開されています。ライセンスの全文:https://github.com/wix/booking-agent/blob/master/LICENSE