SDK 教學 · 6 / 10

接管輸出與活動

Conversation semantics 應留在 Heddle,而產品端決定 streamed text、status、trace evidence 與 final result 要出現在哪裡。

客製化深度

層級 3 · 產品端 presentation

託管深度

單一 process 負責完整 turn

文件狀態

可執行參考範例

前置假設

  • 產品擁有 output sink 或 local UI,但還不需要 remote replay。
  • 單一 process 會在整個 turn 期間保持存活。
  • UI 可以使用 semantic activity,而不需要解析 console text。
Heddle 負責
  • 發出 assistant stream、lifecycle、tool、approval、progress 與 compaction activity。
  • 提供具有 compact 與 verbose rendering mode 的通用 text host。
  • 執行完成後回傳 structured artifact、tool result、failure 與 trace location。
產品端負責
  • 負責 output destination、UI state、tool presentation、telemetry、notification 與 result application。
  • 決定哪些 activity 要顯示給使用者,哪些 evidence 只保留為 operational detail。
  • 在支援 request detach 或 client reconnect 前加入 hosted run layer。

從通用 text host 開始

createConversationTextHost 會處理 assistant stream delta、精簡 activity line、trace label、compaction status 與最終 turn summary:

TypeScript
import { createConversationTextHost } from '@roackb2/heddle'

const textHost = createConversationTextHost({
  activity: 'status',
  trace: 'off',
  compaction: 'status',
  output: (text) => process.stdout.write('[agent] ' + text),
})

const result = await engine.turns.submit({
  sessionId,
  prompt,
  host: textHost.host,
})

textHost.renderTurnResult(result)

每個 output category 會支援相對應的下列 modes:

  • off — 不輸出該 category;
  • status — 精簡且易讀的狀態;
  • verbose — 在支援處加入 serialized payload details。

Custom writer 可以連接 terminal view、local application panel、log collector 或 webhook buffer。不要再解析輸出的文字來更新 product state。

直接使用 semantic activity

產品有自己的 presentation model 時,提供 host callbacks:

TypeScript
import {
  HeddleEventType,
  type ConversationEngineHost,
} from '@roackb2/heddle'

const host: ConversationEngineHost = {
  events: {
    onActivity(activity) {
      if (activity.type === HeddleEventType.assistantStream) {
        renderAssistantDelta(activity.text)
        return
      }

      renderAgentActivity(activity)
    },
  },
  compaction: {
    onStatus(status) {
      renderCompactionStatus(status)
    },
  },
  trace: {
    onEvent(event) {
      recordOperationalEvidence(event)
    },
  },
}

請匯入 HeddleEventType,不要自行複製 event string。把 semantic activity 當成 discriminated contract,並讓 raw trace event 保持為較底層的 evidence,而不是主要 UI model。

用 structured result 收尾

Turn settled 後,使用 result.summaryresult.failureresult.artifactsresult.toolResults 呈現耐久的 product state。Text host 刻意保持通用;產品專屬 success message 應建立在 structured fields 上。

Lifecycle 限制

這個 pattern 假設 caller 與 process 在 turn 期間都保持連線。把輸出送到 webhook 並不會自動產生 replay、cancellation 或 reconnect semantics。當 request 與 subscription 的生命週期不同時,請加入 host-long-lived ConversationRunService,再透過產品 transport 暴露它。

權威來源