Session
AgentController 功能目前處於 beta 階段,在脫離 beta 狀態前,次要版本可能會有破壞性變更。
Session 是一個資源及可選作用域的隔離執行環境。它擁有自己的事件匯流排、執行緒綁定、狀態、模式及模型選擇、執行控制、核准、暫停、後續訊息和顯示狀態。AgentController 提供共用 Agent、配置、儲存空間、Workspace 和服務。
請透過 controller.createSession() 建立 Session。直接建構及控制器接線方法並非應用程式 API。
如需概念介紹,請參閱 AgentController 概覽。
使用範例使用範例 的直接連結
以下範例使用受支援的控制器至 Session 流程。
await controller.init()
const session = await controller.createSession({ resourceId: 'project-42' })
const unsubscribe = session.subscribe(event => {
if (event.type === 'display_state_changed') {
render(event.displayState)
}
})
await session.sendMessage({ content: 'Review the current project.' })
unsubscribe()
屬性屬性 的直接連結
Session 由多個子物件組成,每個子物件各自擁有一個每次對話狀態領域。
identity:
thread:
mode:
model:
om:
permissions:
subagents:
run:
stream:
suspensions:
followUps:
approval:
displayState:
state:
browser:
方法方法 的直接連結
身分及事件身分及事件 的直接連結
getTags()gettags 的直接連結
傳回建立 Session 時所提供標籤的副本。
const tags = session.getTags()
傳回:Record<string, string>
subscribe(listener)subscribelistener 的直接連結
訂閱此 Session 的隔離事件匯流排。此方法會傳回取消訂閱函數。
const unsubscribe = session.subscribe(event => {
console.log(event.type)
})
unsubscribe()
傳回:() => void
訊息及執行控制訊息及執行控制 的直接連結
sendMessage({ content, files?, requestContext? })sendmessage-content-files-requestcontext- 的直接連結
傳送使用者訊息。如沒有使用中的執行緒,Session 會先建立一個。
await session.sendMessage({
content: 'Summarize this file.',
files: [{ data: fileContents, mediaType: 'text/plain', filename: 'notes.txt' }],
})
steer({ content, requestContext? })steer-content-requestcontext- 的直接連結
將引導內容排入使用中執行的佇列。
await session.steer({ content: 'Focus on the failing tests.' })
followUp({ content, requestContext? })followup-content-requestcontext- 的直接連結
在執行進行時將後續訊息排入佇列,或在閒置時立即傳送。
await session.followUp({ content: 'Then propose a fix.' })
getCurrentRunId()getcurrentrunid 的直接連結
傳回使用中的串流執行識別碼、追蹤中的執行識別碼,或在閒置時傳回 null。
const runId = session.getCurrentRunId()
傳回:string | null
abort()abort 的直接連結
中止使用中的執行,並清除待處理的暫停顯示狀態。
session.abort()
WorkspaceWorkspace 的直接連結
getWorkspace()getworkspace 的直接連結
傳回為此 Session 解析的 Workspace。這會保留 Session 層級覆寫,以及從 Session 作用域選取的 Workspace。
const workspace = session.getWorkspace()
const skill = await workspace.skills?.get('code-review')
傳回:Workspace
Session 授權Session 授權 的直接連結
Session 作用域的授權會自動核准 Tool,而不作提示。授權是暫時性的:Session 重新啟動時便會重設,而且永不持久保存。
grantCategory(category)grantcategorycategory 的直接連結
為目前 Session 授予一個 Tool 類別。此類別中的 Tool 將獲自動核准。
session.grantCategory('edit')
grantTool(toolName)granttooltoolname 的直接連結
為目前 Session 授予特定 Tool。
session.grantTool('mastra_workspace_execute_command')
getGrants()getgrants 的直接連結
傳回目前已授予的類別及 Tool。
const grants = session.getGrants()
// { categories: string[], tools: string[] }
hasCategoryGrant(category)hascategorygrantcategory 的直接連結
傳回某類別是否有記憶體內的 Session 授權。
const allowed = session.hasCategoryGrant('edit')
傳回:boolean
hasToolGrant(toolName)hastoolgranttoolname 的直接連結
傳回某 Tool 是否有記憶體內的 Session 授權。
const allowed = session.hasToolGrant('write_file')
傳回:boolean
Tool 核准Tool 核准 的直接連結
resolveToolApproval(toolName)resolvetoolapprovaltoolname 的直接連結
在套用明確的 Tool 規則、Session 授權及類別規則後,傳回有效政策。
const policy = session.resolveToolApproval('execute_command')
傳回:PermissionPolicy
respondToToolApproval({ decision, toolCallId?, requestContext?, declineContext? })respondtotoolapproval-decision-toolcallid-requestcontext-declinecontext- 的直接連結
回應由 tool_approval_required 事件引發的待處理 Tool 核准要求。傳入 always_allow_category,亦會授予該 Tool 的整個類別,直至 Session 結束。
session.respondToToolApproval({ decision: 'approve' })
session.respondToToolApproval({ decision: 'decline' })
session.respondToToolApproval({ decision: 'always_allow_category' })
respondToToolSuspension({ resumeData, toolCallId?, requestContext? })respondtotoolsuspension-resumedata-toolcallid-requestcontext- 的直接連結
使用應用程式提供的資料恢復已暫停的 Tool。如有多個 Tool 呼叫暫停,請提供 toolCallId。
await session.respondToToolSuspension({
toolCallId: event.toolCallId,
resumeData: ['src'],
})
對於 submit_plan,請傳入 { action: 'approved' } 或 { action: 'rejected', feedback }。在 Tool 恢復前,核准可切換至由 transitionsTo 配置的模式。
Token 使用量Token 使用量 的直接連結
getTokenUsage()gettokenusage 的直接連結
傳回使用中執行緒的累計 token 使用量副本。
const usage = session.getTokenUsage()
// { promptTokens, completionTokens, totalTokens, ... }
身分身分 的直接連結
session.identity 擁有對話的穩定識別碼:資源 ID、Session id 及 ownerId。id 和 ownerId 在 Session 的生命週期內保持不變,切換資源 ID 時亦不會變更。它們對應儲存空間中 SessionRecord 的 id 及 ownerId 欄位。
session.identity.getId()sessionidentitygetid 的直接連結
傳回穩定的 Session 識別碼。
const sessionId = session.identity.getId()
session.identity.getOwnerId()sessionidentitygetownerid 的直接連結
傳回 Session 的穩定擁有者識別碼。
const ownerId = session.identity.getOwnerId()
session.identity.getResourceId()sessionidentitygetresourceid 的直接連結
傳回目前資源 ID。
const resourceId = session.identity.getResourceId()
session.identity.getDefaultResourceId()sessionidentitygetdefaultresourceid 的直接連結
傳回建立 Session 時所使用的資源 ID。
const defaultResourceId = session.identity.getDefaultResourceId()
如要變更資源 ID,請使用 controller.setResourceId();此方法亦會清除使用中的執行緒。切換資源不會影響 Session id 和 ownerId。
執行緒執行緒 的直接連結
session.thread 擁有使用中的執行緒綁定及資源作用域的執行緒操作。如已配置儲存空間,已儲存的執行緒及訊息可在重新建立控制器後繼續保留;即時 Session 及其事件匯流排則不能。
session.thread.create({ title?, id? })sessionthreadcreate-title-id- 的直接連結
建立執行緒、將 Session 綁定至該執行緒,並開啟其事件串流。
const thread = await session.thread.create({
id: 'thread-7',
title: 'Investigate login failure',
})
傳回:Promise<AgentControllerThread>
session.thread.rename({ title })sessionthreadrename-title- 的直接連結
重新命名使用中的已儲存執行緒。
await session.thread.rename({ title: 'Fix login failure' })
session.thread.clone({ sourceThreadId?, title?, resourceId? })sessionthreadclone-sourcethreadid-title-resourceid- 的直接連結
複製自己擁有的執行緒及其訊息,然後將 Session 綁定至副本。
const clone = await session.thread.clone({
sourceThreadId: 'thread-7',
title: 'Alternative approach',
})
傳回:Promise<AgentControllerThread>
session.thread.switch({ threadId, emitEvent? })sessionthreadswitch-threadid-emitevent- 的直接連結
切換至自己擁有的已儲存執行緒,並載入其模式、模型及觀察式記憶設定。
await session.thread.switch({ threadId: 'thread-8' })
session.thread.delete({ threadId })sessionthreaddelete-threadid- 的直接連結
刪除自己擁有的執行緒。刪除使用中的執行緒亦會清除目前綁定。
await session.thread.delete({ threadId: 'thread-8' })
session.thread.getId()sessionthreadgetid 的直接連結
傳回使用中的執行緒 ID;如沒有綁定執行緒,則傳回 null。
const threadId = session.thread.getId()
session.thread.list(options?)sessionthreadlistoptions 的直接連結
列出儲存空間中的執行緒。預設只會傳回目前資源的執行緒,並隱藏暫時分叉的子 Agent 執行緒。
const threads = await session.thread.list()
const allThreads = await session.thread.list({ allResources: true })
const everything = await session.thread.list({ includeForkedSubagents: true })
session.thread.getById({ threadId })sessionthreadgetbyid-threadid- 的直接連結
傳回指定 ID 的單一執行緒;如不存在,則傳回 null。
const thread = await session.thread.getById({ threadId: 'thread-abc123' })
session.thread.listActiveMessages(options?)sessionthreadlistactivemessagesoptions 的直接連結
擷取使用中執行緒的訊息。如沒有綁定執行緒,則傳回空陣列。
const messages = await session.thread.listActiveMessages({ limit: 50 })
session.thread.listMessages({ threadId, limit? })sessionthreadlistmessages-threadid-limit- 的直接連結
擷取指定執行緒的訊息。
const messages = await session.thread.listMessages({ threadId: 'thread-abc123' })
訊息讀取方法 listActiveMessages、listMessages 和 firstUserMessage 會傳回 MastraDBMessage 物件,而 firstUserMessages 則傳回以執行緒 ID 為鍵的 Map<string, MastraDBMessage>。每則訊息都有 role、id、createdAt,以及包含 content.format 和 content.parts 陣列的 content 物件。從 content.parts 讀取文字、推理、Tool 呼叫及附件。系統提示和通知等訊號會以 role: 'signal' 的獨立訊息傳回。
session.thread.firstUserMessage({ threadId })sessionthreadfirstusermessage-threadid- 的直接連結
擷取執行緒的第一則使用者訊息;如沒有,則傳回 null。
const firstMsg = await session.thread.firstUserMessage({
threadId: 'thread-abc123',
})
session.thread.firstUserMessages({ threadIds })sessionthreadfirstusermessages-threadids- 的直接連結
一次擷取多個執行緒的第一則使用者訊息,並以 map 傳回。
const firstByThread = await session.thread.firstUserMessages({
threadIds: ['thread-a', 'thread-b'],
})
session.thread.getSetting({ key })sessionthreadgetsetting-key- 的直接連結
從使用中執行緒的中繼資料讀取設定。
const value = await session.thread.getSetting({ key: 'omThreshold' })
session.thread.setSetting({ key, value })sessionthreadsetsetting-key-value- 的直接連結
將設定寫入使用中執行緒的中繼資料。
await session.thread.setSetting({ key: 'omThreshold', value: 0.8 })
session.thread.deleteSetting({ key })sessionthreaddeletesetting-key- 的直接連結
從使用中執行緒的中繼資料移除設定。
await session.thread.deleteSetting({ key: 'omThreshold' })
模式模式 的直接連結
session.mode 擁有使用中的模式選擇。
session.mode.get()sessionmodeget 的直接連結
傳回使用中的模式 ID。
const modeId = session.mode.get()
session.mode.resolve()sessionmoderesolve 的直接連結
傳回使用中模式的完整 AgentControllerMode 物件,並根據控制器所配置的模式進行解析。
const mode = session.mode.resolve()
session.mode.switch({ modeId })sessionmodeswitch-modeid- 的直接連結
切換至另一個模式。Session 會先儲存即將離開模式的模型,然後在使用中執行緒持久保存新模式。接着,它會還原新模式已選取或預設的模型。Session 會立即發出 mode_changed,並在模型解析後發出 model_changed。
await session.mode.switch({ modeId: 'build' })
模型模型 的直接連結
session.model 擁有使用中的模型選擇,包括按模式保存的模型記憶。
session.model.get()sessionmodelget 的直接連結
傳回使用中的模型 ID。
const modelId = session.model.get()
session.model.displayName()sessionmodeldisplayname 的直接連結
傳回使用中模型 ID 的最後一段,作為簡短顯示名稱。如未選取模型,則傳回 'unknown'。
const name = session.model.displayName()
session.model.hasSelection()sessionmodelhasselection 的直接連結
檢查目前是否已選取模型。
if (session.model.hasSelection()) {
// Ready to send messages
}
session.model.switch({ modelId, scope?, modeId? })sessionmodelswitch-modelid-scope-modeid- 的直接連結
切換使用中的模型。當 scope 為 'thread'(預設值)時,模型 ID 會持久保存為該模式的模型,以便切換回來時還原。此方法會向控制器的 modelUseCountTracker 報告選擇,並發出 model_changed 事件。
// Set for the current session only
await session.model.switch({
modelId: 'anthropic/claude-sonnet-4-6',
scope: 'global',
})
// Persist to the current thread (default)
await session.model.switch({ modelId: 'anthropic/claude-sonnet-4-6' })
觀察式記憶觀察式記憶 的直接連結
觀察式記憶的模型選擇按角色分組於 session.om.observer 和 session.om.reflector 下。兩個角色均公開相同方法。讀取時,如 Session 狀態已有設定,便傳回該值;否則回退至控制器的 omConfig 預設值。
session.om.observer.modelId() / session.om.reflector.modelId()sessionomobservermodelid--sessionomreflectormodelid 的直接連結
傳回角色的模型 ID;如 Session 狀態及 omConfig 均未提供,則傳回 undefined。
const observer = session.om.observer.modelId()
const reflector = session.om.reflector.modelId()
session.om.observer.threshold() / session.om.reflector.threshold()sessionomobserverthreshold--sessionomreflectorthreshold 的直接連結
傳回角色以 token 計算的閾值(觀察者的觀察閾值,或反思者的反思閾值);如未設定,則傳回 undefined。
const observationThreshold = session.om.observer.threshold()
const reflectionThreshold = session.om.reflector.threshold()
session.om.observer.switchModel({ modelId }) / session.om.reflector.switchModel({ modelId })sessionomobserverswitchmodel-modelid---sessionomreflectorswitchmodel-modelid- 的直接連結
切換角色的模型。此設定會持久保存至執行緒中繼資料,並發出 om_model_changed 事件。
await session.om.observer.switchModel({
modelId: 'anthropic/claude-haiku-4-5',
})
await session.om.reflector.switchModel({
modelId: 'anthropic/claude-haiku-4-5',
})
session.om.observer.resolvedModel() / session.om.reflector.resolvedModel()sessionomobserverresolvedmodel--sessionomreflectorresolvedmodel 的直接連結
透過已配置的模型閘道,將角色的模型 ID 解析為模型執行個體;如未設定模型 ID 或未配置解析器,則傳回 undefined。
const observerModel = session.om.observer.resolvedModel()
const reflectorModel = session.om.reflector.resolvedModel()
權限權限 的直接連結
session.permissions 擁有 session.state 中表示的 Tool 核准政策:核准解析期間所查詢的各類別及各 Tool 規則。這些規則與 Session 授權所述的記憶體內授權不同。授權會隨即時 Session 重設。除非主機還原相應的 Session 狀態,否則權限規則不會持久保存。
session.permissions.getRules()sessionpermissionsgetrules 的直接連結
傳回目前權限規則;如未設定,則傳回空規則({ categories: {}, tools: {} })。
const rules = session.permissions.getRules()
// { categories: { execute: 'ask' }, tools: { dangerous_tool: 'deny' } }
session.permissions.setForCategory({ category, policy })sessionpermissionssetforcategory-category-policy- 的直接連結
設定 Tool 類別的核准政策('allow' | 'ask' | 'deny')。變更持久保存至 Session 狀態後,Promise 便會解析。
await session.permissions.setForCategory({ category: 'execute', policy: 'ask' })
session.permissions.setForTool({ toolName, policy })sessionpermissionssetfortool-toolname-policy- 的直接連結
設定特定 Tool 的核准政策。各 Tool 政策的優先級高於類別政策。持久保存後,Promise 便會解析。
await session.permissions.setForTool({ toolName: 'dangerous_tool', policy: 'deny' })
子 Agent子 Agent 的直接連結
session.subagents 擁有子 Agent 配置。目前它在 session.subagents.model 下公開子 Agent 模型選擇。
session.subagents.model.get({ agentType? })sessionsubagentsmodelget-agenttype- 的直接連結
傳回子 Agent 模型 ID。如有提供 agentType,會優先使用該類型的值,然後使用全域子 Agent 模型;如兩者均未設定,則傳回 null。
const modelId = session.subagents.model.get({ agentType: 'explore' })
session.subagents.model.set({ modelId, agentType? })sessionsubagentsmodelset-modelid-agenttype- 的直接連結
設定子 Agent 模型 ID。傳入 agentType 可設定按類型的覆寫值,省略則設定全域預設值。此設定會持久保存至執行緒設定,並發出 subagent_model_changed 事件。
// Set the global subagent model
await session.subagents.model.set({ modelId: 'anthropic/claude-sonnet-4-6' })
// Set a per-type override
await session.subagents.model.set({
modelId: 'anthropic/claude-haiku-4-5',
agentType: 'explore',
})
執行執行 的直接連結
session.run 擁有進行中執行的執行及 Trace 身分,以及中止狀態。
session.run.getRunId() / getTraceId()sessionrungetrunid--gettraceid 的直接連結
傳回目前執行已儲存的執行 ID 及 Trace ID;閒置時傳回 null。
const runId = session.run.getRunId()
const traceId = session.run.getTraceId()
session.run.isRunning()sessionrunisrunning 的直接連結
傳回目前是否有執行正在進行。
if (session.run.isRunning()) {
// A run is active
}
串流串流 的直接連結
session.stream 擁有 Agent 執行緒串流的即時訂閱及其去重鍵。
session.stream.activeRunId()sessionstreamactiverunid 的直接連結
傳回即時串流上使用中的執行 ID;如沒有開啟串流,則傳回 null。
const runId = session.stream.activeRunId()
session.stream.isActive()sessionstreamisactive 的直接連結
傳回串流目前是否有使用中的執行。
if (session.stream.isActive()) {
// The current thread's stream is producing output
}
暫停暫停 的直接連結
session.suspensions 擁有已停放並等待恢復的互動式 Tool 呼叫(例如 ask_user 和 request_access)。
session.suspensions.hasPending()sessionsuspensionshaspending 的直接連結
傳回目前是否有任何 Tool 處於暫停狀態。
if (session.suspensions.hasPending()) {
// At least one interactive tool is waiting for a response
}
session.suspensions.has({ toolCallId })sessionsuspensionshas-toolcallid- 的直接連結
傳回特定 Tool 呼叫是否處於暫停狀態。
const waiting = session.suspensions.has({ toolCallId: event.toolCallId })
使用 session.respondToToolSuspension() 恢復已暫停的 Tool。
後續訊息後續訊息 的直接連結
session.followUps 擁有執行進行期間所提交訊息的 FIFO 佇列。
session.followUps.count()sessionfollowupscount 的直接連結
傳回已排入佇列的後續訊息數目。
const queued = session.followUps.count()
session.followUps.isEmpty()sessionfollowupsisempty 的直接連結
傳回後續訊息佇列是否為空。
if (!session.followUps.isEmpty()) {
// Messages are waiting to be processed
}
核准核准 的直接連結
session.approval 擁有待處理的 Tool 核准關卡。
session.approval.isArmed()sessionapprovalisarmed 的直接連結
傳回目前是否有 Tool 正等待核准決定。
if (session.approval.isArmed()) {
// Show the approval prompt
}
使用 session.respondToToolApproval() 回應。
顯示狀態顯示狀態 的直接連結
session.displayState 擁有 UI 用於呈現畫面的標準 AgentControllerDisplayState 快照,以及讓它與每個 Session 事件保持同步的 reducer。
session.displayState.get()sessiondisplaystateget 的直接連結
傳回目前的 AgentControllerDisplayState 快照,供 UI 呈現畫面。
const displayState = session.displayState.get()
session.displayState.restoreTasks(tasks)sessiondisplaystaterestoretaskstasks 的直接連結
在 UI 重播已持久保存的任務 Tool 歷程記錄後,還原快照中的任務部分。這是快照的純更新,不會發出事件,因此呼叫後請明確重新呈現畫面。
session.displayState.restoreTasks(replayedTasks)
每個事件發生後,Session 都會連同最新快照發出 display_state_changed。請使用 session.subscribe() 訂閱,或從 session.displayState.get() 讀取目前值。
狀態狀態 的直接連結
session.state 擁有對話中經結構描述驗證的 AgentController 狀態。它保存目前快照,並根據傳給 AgentController 的 stateSchema 驗證更新。更新會按序處理,而每項變更都會發出 state_changed 事件。
session.state.get()sessionstateget 的直接連結
傳回目前狀態快照的唯讀副本。
const state = session.state.get()
session.state.set(updates)sessionstatesetupdates 的直接連結
將部分更新合併至狀態。更新會排入佇列,讓並行呼叫按順序套用、根據結構描述驗證,並透過 state_changed 發出已變更的鍵。
await session.state.set({ yolo: true })
session.state.update(updater)sessionstateupdateupdater 的直接連結
針對目前快照執行 updater,並在寫入佇列中以不可分割方式套用其結果。必須讀取最新狀態的「讀取—修改—寫入」變更,應使用此方法。updater 會傳回要合併的 updates、要發出的可選 events,以及 update() 所解析為的 result 值。
const added = await session.state.update(current => ({
updates: { count: (current.count ?? 0) + 1 },
result: (current.count ?? 0) + 1,
}))
持久保存界線持久保存界線 的直接連結
Session 是即時執行環境物件。它的事件匯流排、任意 session.state、權限規則、權限授權、待處理核准、暫停、後續訊息、執行狀態及串流狀態,不會在重新建立控制器或程序後自動保留。重新建立 Session 時,主機必須還原任何此類狀態。
配置儲存空間後,執行緒、訊息及 token 使用量會持久保存。執行緒設定會還原模式及模型選擇,亦可還原觀察式記憶設定和子 Agent 模型選擇,包括按 Agent 類型的覆寫值。聊天頻道可以重新對應至已儲存的執行緒,但 AgentControllerChannels 所保存的頻道至 Session 及自動核准狀態仍會留在記憶體中。