代理表單

宣告式 API 會透過屬性,將標準 HTML <form> 元素轉換為 WebMCP 工具。瀏覽器會根據表單輸入內容合成 JSON 結構定義,並處理代理互動。

Angular Signal Forms: 請勿將 toolname/tooldescription 新增至使用 @angular/forms/signals 的 form() 建構的表單。請改為在應用程式供應器中加入 provideExperimentalWebMcpForms(),並將 experimentalWebMcpTool: { name, description } 選項傳遞至 form()。接著,Angular 會透過 Imperative API 註冊表單,根據信號模型建構結構定義,並連結至驗證和提交作業。如果同時使用這兩種方法,系統會重複註冊同一個表單。

表單屬性

  • toolname:工具的專屬名稱。
  • tooldescription:工具的作用及代理的使用時機。請勿列出表單的欄位、選項或限制:瀏覽器已將這些內容納入從表單控制項建構的結構定義中。
  • toolautosubmit:(選用) 如果有這個欄位,代理不必等待使用者互動,即可提交表單。
  • toolparamdescription:(選用) 可在 JSON 結構定義中定義屬性說明。請用來解釋值的意義 (例如提供範例值),不要重複控制項的選項或限制。
    • 解析順序:瀏覽器會優先使用 toolparamdescription (如有)。如果沒有,則會使用相關聯 <label> 的 textContent (略過可標籤的子系)。如果沒有標籤,則會改用 aria-description。
    • 分組 (欄位集):如要為一組相關元素 (例如 <input type="radio"> 按鈕) 附加說明,請將 toolparamdescription 放在最接近的父項 <fieldset> 元素上,這樣就能套用至整個參數群組。

範例

<form toolname="search-cars" 
      tooldescription="Perform a car make/model search" 
      toolautosubmit>
  <label for="make">Vehicle Make</label>
  <input type="text" id="make" name="make" required>
  
  <label for="model">Vehicle Model</label>
  <input type="text" id="model" name="model" toolparamdescription="e.g., 330i, F-150" required>
  
  <button type="submit">Search</button>
</form>

在 JavaScript 中處理提交內容

服務專員提交表單時,SubmitEvent 會包含 agentInvoked (布林值) 和 respondWith(promise)。

document.querySelector('form').addEventListener('submit', (event) => {
  event.preventDefault();

  // Validate the form
  const formValidationErrors = myFormIsValid();

  if (formValidationErrors.length > 0) {
    if (event.agentInvoked) {
      const errorString =
        'Validation failed: ' +
        formValidationErrors
          .map((err) => `${err.field} (${err.message})`)
          .join(', ');

      event.respondWith(Promise.resolve(errorString));
    }
    return;
  }

  const resultPromise = performAsyncSearch(new FormData(event.target));

  // Return the result directly to the agent without navigation
  if (event.agentInvoked) {
    event.respondWith(resultPromise);
  }
});

生命週期事件

document.modelContext 會在代理開始或停止與工具互動時發出事件:toolactivated 會在工具開始執行時觸發,toolcancel 則會在工具取消時觸發。

// Starting in Chrome 156, these events are dispatched on `document.modelContext`.
// Older versions dispatch them on `window`. Feature-detect the event handler
// property to pick the right target for backward compatibility.
const targetFor = (type, listener, options) =>
  (`on${type}` in (document.modelContext ?? {}) ? document.modelContext : window)
    .addEventListener(type, listener, options);

targetFor('toolactivated', ({ toolName }) => {
  console.log(`Tool "${toolName}" started execution.`);
});

targetFor('toolcancel', ({ toolName }) => {
  console.log(`Tool "${toolName}" execution is cancelled.`);
});

視覺回饋 (CSS)

使用虛擬類別,在代理程式與表單互動時醒目顯示表單:

  • :tool-form-active:套用至代理主動使用的 <form> 元素。
  • :tool-submit-active:瀏覽器暫停等待使用者審查時,套用至提交按鈕 (如果省略 toolautosubmit)。
form:tool-form-active {
  outline: 2px dashed blue;
  background-color: rgba(0, 0, 255, 0.05);
}

button:tool-submit-active {
  outline: 2px dashed red;
  animation: pulse 2s infinite;
}

表單適用性 (不適合使用的情況)

Declarative API 最適合用於獨立的標準表單。在下列情況下,這並非理想選擇:

  • 高度依賴欄位:表單中的輸入內容會根據其他輸入內容變更選項或顯示設定。合成結構定義無法妥善表達這些依附關係。
  • 自訂 UI 元件:表單依賴非標準輸入內容 (例如畫布、RTF 格式文字編輯器),不會自動序列化值。
  • 多步驟精靈:需要提交多份表單的複雜工作流程。此時,命令式 API 或標準 DOM 互動更適合。

toolautosubmit 的使用時機

  • 唯讀作業和查詢:搜尋、篩選、擷取詳細資料或查看狀態 (例如搜尋車款、搜尋目錄、查看庫存)。
  • 低風險、可復原的操作:使用者可輕鬆復原或手動調整的表單操作 (例如將商品加入購物車、套用優待券代碼、儲存草稿或設定暫時版面配置選項)。

省略 toolautosubmit 的時機

  • 破壞性或不可逆的操作:刪除記錄、重設系統設定或清除資料庫。
  • 財務和交易動作:提交結帳表單、轉帳、授權訂閱付款,或完成下單。
  • 高影響力使用者通訊:提交最終工作申請、傳送電子郵件/訊息給其他真實使用者,或發布公開內容。
  • 敏感帳戶設定:變更密碼、修改使用者角色/權限,或更新帳單/設定檔資訊。

備用策略

WebMCP Declarative API 可在所有瀏覽器中安全使用。不支援 WebMCP 的瀏覽器會忽略 tool* 屬性,而 <form> 會繼續做為一般 HTML 表單運作。不需要偵測功能。