跳到主要内容

Session

beta

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:

SessionIdentity
对话中稳定的 Session、所有者和资源身份。请参阅下方的身份方法。

thread:

SessionThread
活动线程绑定以及线程/消息读取。请参阅下方的线程方法。

mode:

SessionMode
活动模式选择。请参阅下方的模式方法。

model:

SessionModel
活动模型选择,包括按模式持久化。请参阅下方的模型方法。

om:

SessionOM
观测记忆的观察器和反思器模型设置。

permissions:

SessionPermissions
在 Session 状态中表示的 Tool 和类别权限策略。

subagents:

SessionSubagents
全局和按 Agent 类型的子 Agent 模型选择。

run:

SessionRun
进行中运行的运行和 Trace 身份及中止状态。请参阅下方的运行方法。

stream:

SessionStream
Agent 线程流的实时订阅。请参阅下方的流方法。

suspensions:

SessionSuspensions
等待恢复的已停放交互式 Tool 调用。请参阅下方的暂停方法。

followUps:

SessionFollowUps
运行进行期间提交的消息队列。请参阅下方的后续消息方法。

approval:

SessionApproval
待处理的 Tool 审批关卡。请参阅下方的审批方法。

displayState:

SessionDisplayState
UI 用于渲染的规范 AgentControllerDisplayState 快照。请参阅下方的显示状态方法。

state:

AgentControllerRequestState<TState>
由 Session 所有且经过 schema 验证的 AgentController 状态。请参阅下方的状态方法。

browser:

MastraBrowser | undefined
此 Session 的浏览器自动化实例。可在创建时通过 createSession 设置,也可使用 AgentController 配置的默认值。未配置浏览器时为 undefined。

方法
方法的直接链接

身份和事件
身份和事件的直接链接

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()

Workspace
Workspace的直接链接

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 还可在 Session 剩余生命周期内授权该 Tool 的整个类别。

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 idownerIdidownerId 在 Session 的整个生命周期中保持稳定,切换资源 ID 时不会改变。它们对应存储中 SessionRecordidownerId 字段。

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 的 idownerId

线程
线程的直接链接

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' })

消息读取方法 listActiveMessageslistMessagesfirstUserMessage 返回 MastraDBMessage 对象,firstUserMessages 则返回以线程 ID 为键的 Map<string, MastraDBMessage>。每条消息都有 roleidcreatedAt,以及包含 content.formatcontent.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.observersession.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 才会 resolve。

await session.permissions.setForCategory({ category: 'execute', policy: 'ask' })

session.permissions.setForTool({ toolName, policy })
sessionpermissionssetfortool-toolname-policy-的直接链接

为特定 Tool 设置审批策略。按 Tool 策略优先于类别策略。持久化后,Promise 才会 resolve。

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_userrequest_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的直接链接

返回用于 UI 渲染的当前 AgentControllerDisplayState 快照。

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 负责对话中经过 schema 验证的 AgentController 状态。它保存当前快照,并使用传给 AgentController 的 stateSchema 验证更新。更新会被串行处理,每次更改都会发出 state_changed 事件。

session.state.get()
sessionstateget的直接链接

返回当前状态快照的只读副本。

const state = session.state.get()

session.state.set(updates)
sessionstatesetupdates的直接链接

将部分更新合并到状态中。更新会排队,使并发调用按顺序应用;更新经过 schema 验证后,会发出包含已更改键的 state_changed

await session.state.set({ yolo: true })

session.state.update(updater)
sessionstateupdateupdater的直接链接

针对当前快照运行 updater,并在写入队列中以原子方式应用其结果。对于必须读取最新状态的“读取-修改-写入”更改,请使用此方法。updater 返回要合并的 updates、要发出的可选 events,以及 update() 最终 resolve 的 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 映射和自动审批状态仍只存在于内存中。