搜尋完整文件

輸入關鍵字,例如 idempotency、proposal lifecycle 或權限。

選擇 開啟
English
瀏覽文件

Govern · 第一則 Reply

協作式 Website 整合

Website path 是 assisted integration reference,不是 Govern self-service 或 SDK quickstart。LINE 是架構已定義的 path,不是目前已有端到端 Govern 驗證的 supported product mode。兩者都保留相同的 Govern effect 契約。

Govern + Relay

一則回覆,兩個系統各自負責

Website path

  1. Host UI

    向 Govern 取得 session material。

  2. Relay

    加入 channel,並使用固定 nonce 傳送訊息。

  3. Govern

    重新驗證 context,產生有界的 reply

  4. Relay

    指派 sequence,並送出 bot message。

模式使用者介面Transport Path目前驗證
Website產品自有 Web UIGovern session → Relay SDK協作式參考整合;Govern 到 Relay 的 reply path 已測試
LINE BotLINE Official AccountLINE webhook → Relay LINE adapter架構已定義;Relay ingress 與 egress 已測試,但尚無端到端 Govern captured proof

模式一:Website Reply

Website path 從產品自有的 conversation UI 開始。Tonetify 為指定的 bot profile 建立 Relay session;Relay 傳送 user message;Govern 解析 runtime context 並產生 reply effect;Relay 再把 bot message 傳回同一個 channel。

Browser
  → POST /session to Govern
  → connect and send through Relay
  → signed message.created webhook to Govern
  → Govern reply effect
  → bot message through Relay

這個組合讓每個系統問題只有一位 owner。Govern 不會另外實作一套 chat transport,Relay 也不會決定 bot 應該說什麼。

成熟度與前置條件

這是協作式 Website integration reference,不是 Govern self-service 或 SDK quickstart。你需要:

  • 已設定的 Govern bot profile;
  • 已設定的 Relay provider credential 與 provider channel;
  • 建置完成的 @tonetify/relay artifact,或自行實作的 Relay client;
  • 從 Relay message.created event 回到 Govern 的 callback path。

Relay SDK 已公開發布為 @tonetify/relay@0.1.0-beta.1。在 Relay 提供 server compatibility matrix 與 upgrade policy 前,請固定使用這個完整的 beta version。

1. 建立 Website Session

使用這個 bot 的 provider-channel installation ID 呼叫 Govern:

const response = await fetch("https://govern.example.com/session", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    provider_channel_id: "govern-provider-channel-id",
    subject: { type: "visitor", id: "visitor-123" },
    actor: { type: "anonymous" }
  })
});

if (!response.ok) throw new Error(`session failed: ${response.status}`);

const { data: session } = await response.json();

Response 會包含 Govern 選定的 Relay connection material:

{
  "data": {
    "token": "host-signed-relay-jwt",
    "tenantId": "relay-tenant-id",
    "channelId": "relay-channel-id",
    "userId": "session-user-id",
    "socketUrl": "wss://relay.example.com/socket",
    "apiUrl": "https://relay.example.com",
    "botName": "Operations Assistant",
    "providerChannelId": "govern-provider-channel-id",
    "organizationName": "Example Organization",
    "botProfileId": "govern-profile-id"
  }
}

POST /session 只建立 transport state,不會直接回傳 model response,也不會執行 Govern turn。

2. 連接 Relay 並傳送訊息

import { ChatClient } from "@tonetify/relay";

const client = new ChatClient({
  url: session.socketUrl,
  apiUrl: session.apiUrl,
  token: session.token,
  userId: session.userId
});

client.connect();

const channel = client.channel(session.channelId, session.tenantId);

channel.on("msg:new", (message) => {
  console.log(message.seq, message.body);
});

await channel.join();
await channel.send("What can you help me with?", {
  nonce: crypto.randomUUID()
});

User message 與 bot reply 都會成為 Relay msg:new event。畫面排序應使用 Relay 由 server 指派的 seq

3. 理解 Govern Turn

Relay 會簽署 message.created 並傳給 Govern,接著 Govern 會:

  1. 驗證 webhook,並取得其 idempotency identity;
  2. 透過 provider channel 解析 organization、bot profile 與 runtime mode;
  3. 把 input 寫入 conversation state;
  4. 執行 InputEnvelope → TurnOrchestrator
  5. 透過 provider adapter dispatch reply
  6. 記錄 runtime trace metadata。

Static-profile bot 可以依照設定好的 rules 與 knowledge 回答。Tool-agent bot 則能先呼叫固定版本的 Host Tool,再決定回傳 replyproposalnoop

模式二:LINE Bot Reply

LINE 使用 Relay 內建的 LINE adapter。Govern 仍然接收 Relay 簽署的 message.created event,並透過同一條 Relay message write path 送出 effect。

LINE user message
  → POST /adapters/line/webhook to Relay
  → X-Line-Signature verification
  → tenant route and per-user LINE channel
  → Relay message.created webhook to Govern
  → Govern reply effect through Relay
  → LINE reply_token when fresh, otherwise push

Provider-specific work 由 Relay 負責:

  • 使用 X-Line-Signature 驗證 LINE 簽署的 exact raw body;
  • 透過 LINE destination 找到對應 tenant;
  • 為每位 external user 建立或重用一個 LINE channel;
  • 保存 inbound reply_token 與有限的有效時間;
  • 透過標準 Relay message path 送出 reply;
  • 一次性使用仍有效的 reply token;沒有可用 token 時,改用 LINE push。

Govern 維持 provider-neutral。它收到 provider: "relay"、Relay tenant ID、channel ID、message ID 與 body,先把這些欄位解析到指定 bot profile,再執行與 website chat 相同的 InputEnvelope → TurnOrchestrator → EffectDispatcher path。

目前的 Integration Boundary

LINE transport 已在 Relay repository 具有 end-to-end test。尚未產品化的是 cross-repo dynamic mapping:Relay 會依需求建立 LINE user channel,但 Govern 目前採 fail-closed;只有完全相符的 Relay tenant 與 channel 已存在 ProviderChannel mapping 時,才會執行 runtime。

因此 LINE Bot Reply 是架構已定義的 path,不是目前已有端到端 Govern 驗證的 supported product mode。尚缺的 close 是自動或 deterministic provider-channel registration,以及一筆 captured LINE → Govern → LINE bot-reply proof。

失敗行為

狀況結果
找不到 provider channel、organization、profile 或 credential404 RFC 9457 problem detail
Provider 不是目前識別為 relay 的 Relay adapter422 unsupported_provider
Relay configuration 不完整422 missing_relay_config
Relay session creation 發生 upstream failure502 upstream_session_failed
Message retry 使用新的 nonceRelay 會視為新的 logical message
LINE signature 或 destination 無效Relay 會在 Govern 執行前拒絕或忽略 provider webhook
LINE channel 沒有 Govern provider mappingGovern 以 runtime_context_not_found fail closed,不會產生 bot reply
LINE reply token 已過期或使用過Relay 不會重用 token,會改用 LINE push
Runtime 無法產生 replyTurn 會記錄 error;Govern 不能自行創造 host truth

權責邊界

  • Browser 負責 presentation 與 session lifecycle。
  • LINE 負責 user identity、webhook event、reply token 與 Messaging API contract。
  • Relay 負責 provider ingress、channel、membership、message order、retry-safe send 與 delivery。
  • Govern 負責 runtime context resolution,以及有界的 replyproposalnoop result。
  • Host 負責 identity、business truth、policy 與 execution。

下一步:了解 Govern 如何選擇 Effect