sandbox:// 交接卡
Agent 在 sandbox 裡開了一個瀏覽器工作階段、或產出了一份檔案時,需要一個方式把使用者
交接過去。做法是讓附件卡片的 defaultAction 指向 sandbox:// 這個自訂 scheme。
SDK 會在走到「開新分頁」的預設行為之前攔截它,解析成一個具型別的 intent,再交給對應的
處理器。原始的 sandbox:// URI 永遠不會被丟進 window.open()。
sandbox:// 交接卡
當附件卡片的 defaultAction 指向 sandbox:// 這個自訂 scheme 時,SDK 會在走到「開新分頁」的預設行為之前先攔截它,解析成一個具型別的 intent,再交給對應的處理器。一般的 https:// 連結不受影響,照常開連結。
<Chatbot
config={{ botProviderEndpoint: '...' }}
customChannelId="my-channel"
// 攔截 sandbox://<name>/open-browser
onSandboxOpenBrowser={(sandboxName) => { /* … */ }}
// 攔截 sandbox://<name>/open-file?absolute_path=…
onSandboxOpenFile={(sandboxName, absolutePath) => { /* … */ }}
/>已派送的 intent
尚未點擊任何 sandbox:// 卡片
點左側前兩張卡片 → 解析出的 intent 會記在下方;第三張是一般連結,不會被攔截。
URI 格式
sandbox://<sandboxName>/<action>?<query>
目前支援兩個 action:
| URI | 解析結果 |
|---|---|
sandbox://sbx-a/open-browser | { kind: 'open-browser', sandboxName: 'sbx-a' } |
sandbox://sbx-a/open-file?absolute_path=%2Fhome%2Fuser%2Freport.md | { kind: 'open-file', sandboxName: 'sbx-a', absolutePath: '/home/user/report.md' } |
absolute_path 必須做 URL 編碼(絕對路徑裡有很多 /)。
接手處理
兩個 action 都可以由整合方覆寫:
<Chatbot
config={{ botProviderEndpoint: "..." }}
customChannelId="my-channel"
// 有給就以你的為準;沒給則走 SDK 預設(取一次性 URL 後開新分頁)
onSandboxOpenBrowser={(sandboxName) => { /* … */ }}
// open-file 的目的地通常是 File Explorer
onSandboxOpenFile={(sandboxName, absolutePath) => {
controller.requestFile(sandboxName, absolutePath);
}}
// 預設處理器開分頁的目標,預設 '_blank'
sandboxBrowserOpenTarget="_blank"
// 想真的接管 open-file 就一定要加這行,理由見下方
fileExplorer="off"
/>
onSandboxOpenBrowser 是真的二選一:有給就以你的為準,沒給才走 SDK 預設。
onSandboxOpenFile 不是。 它是「加上去」而不是「取代掉」——你的 handler 會被呼叫,但內建的
File Explorer 側欄同時也照樣會被拉開,因為那段邏輯只看 fileExplorer
prop,不看你有沒有給 callback。而 fileExplorer 預設就是 'builtin'。
結果是你自己的 controller 和 Chatbot 內部的 controller 會同時收到同一個 requestFile。要真的
接管,必須另外把 fileExplorer 設成 "off"。
自己解析
resolveSandboxUri 也可以單獨使用——例如你自己渲染卡片的時候:
import { resolveSandboxUri } from "@asgard-js/core";
const intent = resolveSandboxUri(uri);
if (intent === null) {
// 不是 sandbox://、action 不認得、或缺 absolute_path
// → 當成一般卡片處理,絕對不要 window.open() 原始 URI
}
回傳型別:
type SandboxUriIntent =
| { kind: "open-browser"; sandboxName: string }
| { kind: "open-file"; sandboxName: string; absolutePath: string };
解析用的是手寫 regex 而不是 new URL()。絕對路徑帶有大量 /,而 WHATWG URL parser 對
非特殊 scheme 的 host 大小寫處理並不可靠;query 的部分仍交給 URLSearchParams 解碼。
一般連結不受影響
https:// 之類的 defaultAction 完全照舊走正常開連結行為——攔截只發生在 sandbox://。
也看看
- File Explorer —
open-file的落點 - 冷啟動 HUD — sandbox 啟動與
launchedSandboxes - 訊息模板 — 附件卡片本身的結構