> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # Session > **Beta:** `AgentController` 功能目前处于 beta 阶段。在正式脱离 beta 状态之前,次要版本中可能会包含破坏性变更。 `Session` 是面向单个资源和可选作用域的隔离运行时。它负责自己的事件总线、线程绑定、状态、模式和模型选择、运行控制、审批、暂停、后续消息以及显示状态。[`AgentController`](https://mastra.zisheng.pro/reference/agent-controller/agent-controller-class) 提供共享的 Agent、配置、存储、Workspace 和服务。 请通过 `controller.createSession()` 创建 Session。直接构造和控制器接线方法并不是应用 API。 有关概念介绍,请参阅 [AgentController 概述](https://mastra.zisheng.pro/docs/harness/agent-controller)。 ## 用法示例 以下示例使用受支持的控制器到 Session 流程。 ```typescript 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`): 由 Session 所有且经过 schema 验证的 AgentController 状态。请参阅下方的状态方法。 **browser** (`MastraBrowser | undefined`): 此 Session 的浏览器自动化实例。可在创建时通过 createSession 设置,也可使用 AgentController 配置的默认值。未配置浏览器时为 undefined。 ## 方法 ### 身份和事件 #### `getTags()` 返回创建 Session 时提供的标签副本。 ```typescript const tags = session.getTags() ``` 返回:`Record` #### `subscribe(listener)` 订阅此 Session 的隔离事件总线。该方法返回一个取消订阅函数。 ```typescript const unsubscribe = session.subscribe(event => { console.log(event.type) }) unsubscribe() ``` 返回:`() => void` ### 消息和运行控制 #### `sendMessage({ content, files?, requestContext? })` 发送用户消息。如果没有活动线程,Session 会先创建一个线程。 ```typescript await session.sendMessage({ content: 'Summarize this file.', files: [{ data: fileContents, mediaType: 'text/plain', filename: 'notes.txt' }], }) ``` #### `steer({ content, requestContext? })` 将引导内容排入活动运行。 ```typescript await session.steer({ content: 'Focus on the failing tests.' }) ``` #### `followUp({ content, requestContext? })` 运行处于活动状态时将后续消息排入队列,空闲时则立即发送。 ```typescript await session.followUp({ content: 'Then propose a fix.' }) ``` #### `getCurrentRunId()` 返回活动流的运行标识符、受跟踪的运行标识符,空闲时返回 `null`。 ```typescript const runId = session.getCurrentRunId() ``` 返回:`string | null` #### `abort()` 中止活动运行并清除待处理的暂停显示状态。 ```typescript session.abort() ``` ### Workspace #### `getWorkspace()` 返回为此 Session 解析的 Workspace。此方法会保留 Session 级覆盖项和从 Session 作用域中选择的 Workspace。 ```typescript const workspace = session.getWorkspace() const skill = await workspace.skills?.get('code-review') ``` 返回:`Workspace` ### Session 授权 Session 作用域的授权会自动批准 Tool,无需提示。这些授权是临时的:Session 重启时会重置,且永远不会持久化。 #### `grantCategory(category)` 为当前 Session 授予一个 Tool 类别。此类别中的 Tool 将被自动批准。 ```typescript session.grantCategory('edit') ``` #### `grantTool(toolName)` 为当前 Session 授予特定 Tool。 ```typescript session.grantTool('mastra_workspace_execute_command') ``` #### `getGrants()` 返回当前已授权的类别和 Tool。 ```typescript const grants = session.getGrants() // { categories: string[], tools: string[] } ``` #### `hasCategoryGrant(category)` 返回某个类别是否拥有内存中的 Session 授权。 ```typescript const allowed = session.hasCategoryGrant('edit') ``` 返回:`boolean` #### `hasToolGrant(toolName)` 返回某个 Tool 是否拥有内存中的 Session 授权。 ```typescript const allowed = session.hasToolGrant('write_file') ``` 返回:`boolean` ### Tool 审批 #### `resolveToolApproval(toolName)` 应用显式 Tool 规则、Session 授权和类别规则后,返回最终策略。 ```typescript const policy = session.resolveToolApproval('execute_command') ``` 返回:`PermissionPolicy` #### `respondToToolApproval({ decision, toolCallId?, requestContext?, declineContext? })` 响应由 `tool_approval_required` 事件触发的待处理 Tool 审批请求。传入 `always_allow_category` 还可在 Session 剩余生命周期内授权该 Tool 的整个类别。 ```typescript session.respondToToolApproval({ decision: 'approve' }) session.respondToToolApproval({ decision: 'decline' }) session.respondToToolApproval({ decision: 'always_allow_category' }) ``` #### `respondToToolSuspension({ resumeData, toolCallId?, requestContext? })` 使用应用提供的数据恢复已暂停的 Tool。有多个 Tool 调用处于暂停状态时,请提供 `toolCallId`。 ```typescript await session.respondToToolSuspension({ toolCallId: event.toolCallId, resumeData: ['src'], }) ``` 对于 `submit_plan`,请传入 `{ action: 'approved' }` 或 `{ action: 'rejected', feedback }`。在 Tool 恢复之前,审批可能会切换到 `transitionsTo` 配置的模式。 ### Token 用量 #### `getTokenUsage()` 返回活动线程持续累计的 token 用量副本。 ```typescript const usage = session.getTokenUsage() // { promptTokens, completionTokens, totalTokens, ... } ``` ## 身份 `session.identity` 负责对话的稳定标识符:资源 ID、Session `id` 和 `ownerId`。`id` 和 `ownerId` 在 Session 的整个生命周期中保持稳定,切换资源 ID 时不会改变。它们对应存储中 `SessionRecord` 的 `id` 和 `ownerId` 字段。 ### `session.identity.getId()` 返回稳定的 Session 标识符。 ```typescript const sessionId = session.identity.getId() ``` ### `session.identity.getOwnerId()` 返回 Session 稳定的所有者标识符。 ```typescript const ownerId = session.identity.getOwnerId() ``` ### `session.identity.getResourceId()` 返回当前资源 ID。 ```typescript const resourceId = session.identity.getResourceId() ``` ### `session.identity.getDefaultResourceId()` 返回创建 Session 时使用的资源 ID。 ```typescript const defaultResourceId = session.identity.getDefaultResourceId() ``` 要更改资源 ID,请使用 [`controller.setResourceId()`](https://mastra.zisheng.pro/reference/agent-controller/agent-controller-class),它还会清除活动线程。资源切换不会影响 Session 的 `id` 和 `ownerId`。 ## 线程 `session.thread` 负责活动线程绑定和资源作用域的线程操作。配置存储后,即使重新创建控制器,已存储的线程和消息也可保留;实时 Session 及其事件总线则不会保留。 ### `session.thread.create({ title?, id? })` 创建一个线程,将 Session 绑定到该线程,并打开其事件流。 ```typescript const thread = await session.thread.create({ id: 'thread-7', title: 'Investigate login failure', }) ``` 返回:`Promise` ### `session.thread.rename({ title })` 重命名活动的已存储线程。 ```typescript await session.thread.rename({ title: 'Fix login failure' }) ``` ### `session.thread.clone({ sourceThreadId?, title?, resourceId? })` 克隆一个自有线程及其消息,然后将 Session 绑定到克隆线程。 ```typescript const clone = await session.thread.clone({ sourceThreadId: 'thread-7', title: 'Alternative approach', }) ``` 返回:`Promise` ### `session.thread.switch({ threadId, emitEvent? })` 切换到一个自有的已存储线程,并填充其模式、模型和观测记忆设置。 ```typescript await session.thread.switch({ threadId: 'thread-8' }) ``` ### `session.thread.delete({ threadId })` 删除一个自有线程。删除活动线程还会清除当前绑定。 ```typescript await session.thread.delete({ threadId: 'thread-8' }) ``` ### `session.thread.getId()` 返回活动线程 ID;没有绑定线程时返回 `null`。 ```typescript const threadId = session.thread.getId() ``` ### `session.thread.list(options?)` 列出存储中的线程。默认仅返回当前资源的线程,并隐藏临时的分叉子 Agent 线程。 ```typescript 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 })` 按 ID 返回单个线程;线程不存在时返回 `null`。 ```typescript const thread = await session.thread.getById({ threadId: 'thread-abc123' }) ``` ### `session.thread.listActiveMessages(options?)` 检索活动线程的消息。没有绑定线程时返回空数组。 ```typescript const messages = await session.thread.listActiveMessages({ limit: 50 }) ``` ### `session.thread.listMessages({ threadId, limit? })` 检索特定线程的消息。 ```typescript const messages = await session.thread.listMessages({ threadId: 'thread-abc123' }) ``` 消息读取方法 `listActiveMessages`、`listMessages` 和 `firstUserMessage` 返回 `MastraDBMessage` 对象,`firstUserMessages` 则返回以线程 ID 为键的 `Map`。每条消息都有 `role`、`id`、`createdAt`,以及包含 `content.format` 和 `content.parts` 数组的 `content` 对象。请从 `content.parts` 读取文本、推理、Tool 调用和附件。系统提醒和通知等信号会作为 `role: 'signal'` 的独立消息返回。 ### `session.thread.firstUserMessage({ threadId })` 检索线程的第一条用户消息;没有时返回 `null`。 ```typescript const firstMsg = await session.thread.firstUserMessage({ threadId: 'thread-abc123', }) ``` ### `session.thread.firstUserMessages({ threadIds })` 一次检索多个线程的第一条用户消息,并以 map 形式返回。 ```typescript const firstByThread = await session.thread.firstUserMessages({ threadIds: ['thread-a', 'thread-b'], }) ``` ### `session.thread.getSetting({ key })` 从活动线程元数据中读取设置。 ```typescript const value = await session.thread.getSetting({ key: 'omThreshold' }) ``` ### `session.thread.setSetting({ key, value })` 向活动线程元数据写入设置。 ```typescript await session.thread.setSetting({ key: 'omThreshold', value: 0.8 }) ``` ### `session.thread.deleteSetting({ key })` 从活动线程元数据中移除设置。 ```typescript await session.thread.deleteSetting({ key: 'omThreshold' }) ``` ## 模式 `session.mode` 负责活动模式选择。 ### `session.mode.get()` 返回活动模式 ID。 ```typescript const modeId = session.mode.get() ``` ### `session.mode.resolve()` 返回根据控制器已配置模式解析出的完整 `AgentControllerMode` 对象。 ```typescript const mode = session.mode.resolve() ``` ### `session.mode.switch({ modeId })` 切换到另一个模式。Session 会先保存传出模式的模型,再将新模式持久化到活动线程。随后恢复传入模式已选择的模型或默认模型。Session 会立即发出 `mode_changed`,并在模型解析后发出 `model_changed`。 ```typescript await session.mode.switch({ modeId: 'build' }) ``` ## 模型 `session.model` 负责活动模型选择,包括按模式保存的模型记忆。 ### `session.model.get()` 返回活动模型 ID。 ```typescript const modelId = session.model.get() ``` ### `session.model.displayName()` 返回活动模型 ID 的最后一段作为简短显示名称。未选择模型时返回 `'unknown'`。 ```typescript const name = session.model.displayName() ``` ### `session.model.hasSelection()` 检查当前是否已选择模型。 ```typescript if (session.model.hasSelection()) { // Ready to send messages } ``` ### `session.model.switch({ modelId, scope?, modeId? })` 切换活动模型。当 `scope` 为 `'thread'`(默认值)时,模型 ID 会作为该模式的模型持久化,以便切换回来时恢复。此方法会向控制器的 `modelUseCountTracker` 报告选择,并发出 `model_changed` 事件。 ```typescript // 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()` 返回该角色的模型 ID;如果 Session 状态和 `omConfig` 都未提供,则返回 `undefined`。 ```typescript const observer = session.om.observer.modelId() const reflector = session.om.reflector.modelId() ``` ### `session.om.observer.threshold()` / `session.om.reflector.threshold()` 返回该角色以 token 为单位的阈值(观察器为观察阈值,反思器为反思阈值);未设置时返回 `undefined`。 ```typescript const observationThreshold = session.om.observer.threshold() const reflectionThreshold = session.om.reflector.threshold() ``` ### `session.om.observer.switchModel({ modelId })` / `session.om.reflector.switchModel({ modelId })` 切换该角色的模型。此方法会将设置持久化到线程元数据,并发出 `om_model_changed` 事件。 ```typescript 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()` 通过已配置的模型网关将该角色的模型 ID 解析为模型实例;未设置模型 ID 或未配置解析器时返回 `undefined`。 ```typescript const observerModel = session.om.observer.resolvedModel() const reflectorModel = session.om.reflector.resolvedModel() ``` ## 权限 `session.permissions` 负责 `session.state` 中表示的 Tool 审批策略,即解析审批时查询的按类别和按 Tool 规则。这些规则不同于 [Session 授权](#session-grants)中记录的内存授权。授权会随实时 Session 重置。除非宿主恢复对应的 Session 状态,否则权限规则不会持久保存。 ### `session.permissions.getRules()` 返回当前权限规则;未设置时返回空规则(`{ categories: {}, tools: {} }`)。 ```typescript const rules = session.permissions.getRules() // { categories: { execute: 'ask' }, tools: { dangerous_tool: 'deny' } } ``` ### `session.permissions.setForCategory({ category, policy })` 为 Tool 类别设置审批策略(`'allow' | 'ask' | 'deny'`)。更改持久化到 Session 状态后,Promise 才会 resolve。 ```typescript await session.permissions.setForCategory({ category: 'execute', policy: 'ask' }) ``` ### `session.permissions.setForTool({ toolName, policy })` 为特定 Tool 设置审批策略。按 Tool 策略优先于类别策略。持久化后,Promise 才会 resolve。 ```typescript await session.permissions.setForTool({ toolName: 'dangerous_tool', policy: 'deny' }) ``` ## 子 Agent `session.subagents` 负责子 Agent 配置。目前,它通过 `session.subagents.model` 公开子 Agent 模型选择。 ### `session.subagents.model.get({ agentType? })` 返回子 Agent 模型 ID。提供 `agentType` 时优先使用对应值,其次使用全局子 Agent 模型;两者均未设置时返回 `null`。 ```typescript const modelId = session.subagents.model.get({ agentType: 'explore' }) ``` ### `session.subagents.model.set({ modelId, agentType? })` 设置子 Agent 模型 ID。传入 `agentType` 可设置按类型覆盖项,省略则设置全局默认值。此方法会持久化到线程设置,并发出 `subagent_model_changed` 事件。 ```typescript // 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()` 返回当前运行已存储的运行 ID 和 Trace ID;空闲时返回 `null`。 ```typescript const runId = session.run.getRunId() const traceId = session.run.getTraceId() ``` ### `session.run.isRunning()` 返回当前是否有运行正在进行。 ```typescript if (session.run.isRunning()) { // A run is active } ``` ## 流 `session.stream` 负责 Agent 线程流的实时订阅及其去重键。 ### `session.stream.activeRunId()` 返回实时流上的活动运行 ID;未打开流时返回 `null`。 ```typescript const runId = session.stream.activeRunId() ``` ### `session.stream.isActive()` 返回流当前是否有活动运行。 ```typescript if (session.stream.isActive()) { // The current thread's stream is producing output } ``` ## 暂停 `session.suspensions` 负责等待恢复的已停放交互式 Tool 调用(例如 `ask_user` 和 `request_access`)。 ### `session.suspensions.hasPending()` 返回当前是否有任何 Tool 处于暂停状态。 ```typescript if (session.suspensions.hasPending()) { // At least one interactive tool is waiting for a response } ``` ### `session.suspensions.has({ toolCallId })` 返回特定 Tool 调用是否已暂停。 ```typescript const waiting = session.suspensions.has({ toolCallId: event.toolCallId }) ``` 使用 [`session.respondToToolSuspension()`](#tool-approvals) 恢复已暂停的 Tool。 ## 后续消息 `session.followUps` 负责运行进行期间提交的消息 FIFO 队列。 ### `session.followUps.count()` 返回已排队的后续消息数量。 ```typescript const queued = session.followUps.count() ``` ### `session.followUps.isEmpty()` 返回后续消息队列是否为空。 ```typescript if (!session.followUps.isEmpty()) { // Messages are waiting to be processed } ``` ## 审批 `session.approval` 负责待处理的 Tool 审批关卡。 ### `session.approval.isArmed()` 返回当前是否有 Tool 正在等待审批决定。 ```typescript if (session.approval.isArmed()) { // Show the approval prompt } ``` 使用 [`session.respondToToolApproval()`](#tool-approvals) 响应。 ## 显示状态 `session.displayState` 负责 UI 用于渲染的规范 `AgentControllerDisplayState` 快照,以及使其与每个 Session 事件保持同步的 reducer。 ### `session.displayState.get()` 返回用于 UI 渲染的当前 `AgentControllerDisplayState` 快照。 ```typescript const displayState = session.displayState.get() ``` ### `session.displayState.restoreTasks(tasks)` 在 UI 重放持久化的任务 Tool 历史记录后,恢复快照中的任务部分。这是对快照的纯更新,不会发出事件,因此调用后请显式重新渲染。 ```typescript session.displayState.restoreTasks(replayedTasks) ``` 每个事件之后,Session 都会发出包含最新快照的 `display_state_changed`。可使用 [`session.subscribe()`](#identity-and-events) 订阅,也可从 `session.displayState.get()` 读取当前值。 ## 状态 `session.state` 负责对话中经过 schema 验证的 AgentController 状态。它保存当前快照,并使用传给 AgentController 的 `stateSchema` 验证更新。更新会被串行处理,每次更改都会发出 `state_changed` 事件。 ### `session.state.get()` 返回当前状态快照的只读副本。 ```typescript const state = session.state.get() ``` ### `session.state.set(updates)` 将部分更新合并到状态中。更新会排队,使并发调用按顺序应用;更新经过 schema 验证后,会发出包含已更改键的 `state_changed`。 ```typescript await session.state.set({ yolo: true }) ``` ### `session.state.update(updater)` 针对当前快照运行 updater,并在写入队列中以原子方式应用其结果。对于必须读取最新状态的“读取-修改-写入”更改,请使用此方法。updater 返回要合并的 `updates`、要发出的可选 `events`,以及 `update()` 最终 resolve 的 `result` 值。 ```typescript 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 映射和自动审批状态仍只存在于内存中。 ## 相关内容 - [AgentController 类](https://mastra.zisheng.pro/reference/agent-controller/agent-controller-class) - [AgentController 概述](https://mastra.zisheng.pro/docs/harness/agent-controller) - [线程和状态](https://mastra.zisheng.pro/docs/harness/agent-controller) - [Tool 审批](https://mastra.zisheng.pro/docs/harness/agent-controller)