REFERENCE
SDK 範例
@asgard-js/core 與 @asgard-js/react 的用法與可以直接操作的範例。
自行停靠 run-chrome
Task Check List 與子代理清單 屬於 run 層級的介面——它們描述的是整個回合的狀態,不是某一則訊息。所以 SDK 把它們停靠在 一條固定區裡:位於對話串的捲動框之外、輸入框之上。
為什麼在捲動框之外
早期這兩個面板渲染在對話串的尾端,跟著訊息一起捲。結果是:串流進行中對話不斷長高、又自動 捲到底,面板就被推來推去。移到固定區之後,串流時它們穩穩待在原地。
固定區還有兩個規則:
- 封頂在內容區高度的 50%,超過就自己內部捲動——對話區永遠保得住另一半
- 完全沒有面板時整條不存在、不占位,輸入框直接貼齊最後一則訊息
換成自己擺
<Chatbot hideRunChrome {...rest} />設成
true之後內建面板不再渲染,你可以把外露的<TaskList>/<SubagentList>放到 版面任何位置——右側欄、抽屜、另一個分頁都行。import { TaskList, SubagentList, AsgardThemeScope } from "@asgard-js/react";
import { deriveTasks, deriveSubagents } from "@asgard-js/core";
// conversation 來自 useAsgardContext()
const tasks = deriveTasks(conversation);
const subagents = deriveSubagents(conversation);
<AsgardThemeScope theme={theme}>
<SubagentList subagents={subagents} locale="zh-TW" />
<TaskList tasks={tasks} locale="zh-TW" />
</AsgardThemeScope>一定要包AsgardThemeScope面板放在
<Chatbot>之外就拿不到聊天外殼掛上的設計 token,會退回淺色預設值。 詳見在聊天外殼之外重建主題。資料從哪來
兩個面板都收純陣列,跟 SDK 的狀態沒有耦合:
function TaskList(props: { tasks: Task[]; locale?: Locale }): ReactNode;
function SubagentList(props: { subagents: Subagent[]; locale?: Locale }): ReactNode;deriveTasks/deriveSubagents從Conversation折出這兩份資料。想訂閱而不是每次重算的話, core 另有createDerivedStores,並附tasksEqual/subagentsEqual供比較。import {
deriveTasks, deriveSubagents,
tasksEqual, subagentsEqual,
createDerivedStores,
} from "@asgard-js/core";型別
interface Task {
id: string;
subject: string; // 名詞形標題,非進行中時顯示
activeForm?: string; // 進行式標籤,進行中時優先顯示
description?: string; // 展開後的完整說明
status: "pending" | "in_progress" | "completed";
}
interface Subagent {
parentToolUseId: string; // 對應鍵=派出它的 Agent 工具呼叫
agentId?: string;
subagentType?: string; // 例如 general-purpose
description?: string;
status: "running" | "completed" | "failed" | "cancelled";
summary?: string;
tools: SubagentToolCall[]; // 這個子代理自己跑的工具
}子代理的終止狀態只來自
subagent.complete事件——不會從Agent工具呼叫本身的完成推斷 (非同步子代理的工具呼叫會以async_launched提早完成)。也看看
- Task Check List、子代理清單 — 內建版本
- 在聊天外殼之外重建主題
- 多語系 — 面板各自的
locale - Headless 模式 — 完全自己畫