Core API Reference
@asgard-js/core 提供底層的 SSE client、channel 管理與對話模型。
如果你用 <Chatbot> 元件,這些都已經封裝好了;如果你用
Headless 模式 自己組 UI,則需要直接操作這些 API。
AsgardServiceClient
SSE 連線的核心。負責建立連線、分派事件、上傳檔案。
建構
import { AsgardServiceClient } from "@asgard-js/core";
const client = new AsgardServiceClient({
botProviderEndpoint: "https://api.asgard-ai.com/ns/{namespace}/bot-provider/{id}",
apiKey: "optional-api-key",
customHeaders: { Authorization: "Bearer ..." },
debugMode: false,
});
方法
| 方法 | 簽名 | 說明 |
|---|---|---|
on | on<K>(event: K, listener: SseEvents[K]): void | 註冊事件監聽器,同一事件只保留最後一個 listener |
fetchSse | fetchSse(payload: FetchSsePayload, options?: FetchSseOptions): void | 發起 SSE 串流請求 |
uploadFile | uploadFile(file: File, channelId: string): Promise<BlobUploadResponse> | 上傳檔案到 Blob API |
close | close(): void | 關閉所有連線並清理資源 |
ClientConfig
| 欄位 | 型別 | 說明 |
|---|---|---|
botProviderEndpoint | string | 必填。Bot provider base URL |
endpoint | string | botProviderEndpoint |
apiKey | string | 靜態 API key |
customHeaders | Record<string, string> | 自訂 HTTP headers |
debugMode | boolean | 開啟 debug log |
transformSsePayload | (payload) => payload | 送出前變更 SSE payload |
onRunInit | EventHandler | INIT 事件 handler |
onMessage | EventHandler | MESSAGE 事件 handler |
onToolCall | EventHandler | TOOL_CALL 事件 handler |
onProcess | EventHandler | PROCESS 事件 handler |
onRunDone | EventHandler | DONE 事件 handler |
onRunError | EventHandler | ERROR 事件 handler |
FetchSsePayload
{
customChannelId: string;
customMessageId?: string;
text: string;
payload?: Record<string, unknown> | (() => Record<string, unknown>);
action: FetchSseAction; // RESET_CHANNEL | NONE
blobIds?: string[];
}
FetchSseOptions
{
delayTime?: number; // 事件間隔 ms,預設 50
onSseStart?: () => void;
onSseMessage?: (response: SseResponse<EventType>) => void;
onSseError?: (error: unknown) => void;
onSseCompleted?: () => void;
}
Channel
管理一個對話頻道的 SSE 生命週期。透過靜態工廠方法建立。
建立方式
import { Channel, Conversation } from "@asgard-js/core";
const conversation = new Conversation({ messages: new Map() });
// 方式 1:建立但不重置(保留歷史)
const channel = Channel.create({
client,
customChannelId: "user-123",
conversation,
statesObserver: (states) => {
console.log(states.isConnecting, states.conversation);
},
});
// 方式 2:建立並重置(開始新對話)
const channel = await Channel.reset(
{ client, customChannelId: "user-123", conversation },
{ text: "你好" }, // 可選的初始訊息
);
靜態方法
| 方法 | 簽名 | 說明 |
|---|---|---|
create | static create(config: ChannelConfig): Channel | 建立 channel,不發送 reset |
reset | static async reset(config, payload?, options?): Promise<Channel> | 建立 channel 並發送 RESET_CHANNEL |
實例方法
| 方法 | 簽名 | 說明 |
|---|---|---|
sendMessage | sendMessage(payload, options?): Promise<void> | 送出使用者訊息(支援 text / payload / blobIds / filePreviewUrls) |
close | close(): void | 關閉 channel 並清理訂閱 |
ChannelConfig
| 欄位 | 型別 | 說明 |
|---|---|---|
client | AsgardServiceClient | SSE client 實例 |
customChannelId | string | 頻道唯一 ID |
customMessageId | string | 自訂訊息 ID(可選) |
conversation | Conversation | 初始 conversation 物件 |
statesObserver | (states: ChannelStates) => void | 狀態變化的 observer |
ChannelStates
{ isConnecting: boolean; conversation: Conversation }
Conversation
不可變的對話模型。每次狀態變化都回傳新的 Conversation 實例。
建構
import { Conversation } from "@asgard-js/core";
const conversation = new Conversation({
messages: new Map(), // 或 null
});
屬性
| 屬性 | 型別 | 說明 |
|---|---|---|
messages | Map<string, ConversationMessage> | null | 所有訊息,key 為 messageId |
方法
| 方法 | 說明 |
|---|---|
pushMessage(message) | 加入一筆訊息,回傳新的 Conversation |
onMessage(response) | 處理一個 SSE 事件,自動依 eventType 更新對應訊息,回傳新的 Conversation |
onMessage 內部根據 eventType 分派:
| EventType | 行為 |
|---|---|
MESSAGE_START | 建立新的 bot 訊息(isTyping: true) |
MESSAGE_DELTA | 累加 typingText(串流文字) |
MESSAGE_COMPLETE | 完成訊息(isTyping: false,寫入完整 message) |
TOOL_CALL_START | 建立 tool-call 訊息(isComplete: false) |
TOOL_CALL_COMPLETE | 更新 tool-call 結果(isComplete: true) |
ERROR | 建立 error 訊息 |
EventType
所有 SSE 事件類型:
enum EventType {
INIT = "asgard.run.init"
PROCESS_START = "asgard.process.start"
PROCESS_COMPLETE = "asgard.process.complete"
MESSAGE_START = "asgard.message.start"
MESSAGE_DELTA = "asgard.message.delta"
MESSAGE_COMPLETE = "asgard.message.complete"
TOOL_CALL_START = "asgard.tool_call.start"
TOOL_CALL_COMPLETE = "asgard.tool_call.complete"
DONE = "asgard.run.done"
ERROR = "asgard.run.error"
}
監聽時使用聚合事件:
| 聚合事件 | 包含 |
|---|---|
PROCESS | PROCESS_START + PROCESS_COMPLETE |
MESSAGE | MESSAGE_START + MESSAGE_DELTA + MESSAGE_COMPLETE |
TOOL_CALL | TOOL_CALL_START + TOOL_CALL_COMPLETE |
ConversationMessage
四種訊息類型的 union type,用 type 欄位區分:
user
{ type: "user"; messageId: string; text: string;
blobIds?: string[]; filePreviewUrls?: string[];
documentNames?: string[]; time: Date; traceId?: string }
bot
{ type: "bot"; messageId: string; eventType: EventType;
isTyping: boolean; typingText: string | null;
message: Message; time: Date; traceId?: string; raw: string }
tool-call
{ type: "tool-call"; messageId: string;
eventType: EventType.TOOL_CALL_START | EventType.TOOL_CALL_COMPLETE;
processId: string; callSeq: number; toolName: string;
toolsetName: string; parameter: Record<string, unknown>;
result?: Record<string, unknown>; isComplete: boolean;
time: Date; traceId?: string }
error
{ type: "error"; messageId: string; eventType: EventType;
error: ErrorMessage; time: Date; traceId?: string }
HttpError
import { HttpError, isHttpError } from "@asgard-js/core";
try { /* ... */ } catch (err) {
if (isHttpError(err)) {
console.log(err.status, err.statusText, err.body);
}
}
| 屬性 | 型別 | 說明 |
|---|---|---|
status | number | HTTP 狀態碼 |
statusText | string | 狀態文字 |
body | unknown | 回應 body |