@astropods/adapter-mastra

中文文档
0.10.1发布于 2026/11/04Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 2348

Each turn's request context carries userName, the sender's name on the source platform (their full name in Slack, or their Astro name in web chat). It is absent when the platform sent none, so check for it. Tell the model how to use the name, or it may

原始使用文档
文档目录7 节
  1. The sender's name
  2. Memory
  3. The chosen model
  4. Files
  5. Sandboxes
  6. What it maps onto
  7. What it does not do

@astropods/adapter-mastra

The sender's name

Each turn's request context carries userName, the sender's name on the source platform (their full name in Slack, or their Astro name in web chat). It is absent when the platform sent none, so check for it. Tell the model how to use the name, or it may repeat it in every reply:

const agent = new Agent({
  id: "greeter",
  name: "Greeter",
  model,
  instructions: ({ requestContext }) => {
    const name = requestContext.get("userName");
    return name
      ? `The user's name is ${name}. Greet them by name in your first reply only; don't repeat it after that.`
      : "You are a helpful assistant.";
  },
});

The request context also carries threadId and resourceId. resourceId is the user who sent the turn.

Memory

The memory thread is the conversation. The memory resource depends on who shares it:

  • In a 1:1 chat, such as a DM or the web chat, the resource is the user, so resource-scoped memory follows them between chats.
  • In a channel conversation, such as a Slack thread, the resource is the conversation. Anyone in the thread can talk to the agent, and nobody's own memory mixes into it.
  • A thread already in memory keeps the resource it was created with, because Mastra rejects a thread used with a different resource.

Working memory and semantic recall default to scope: "resource", which carries a person's memory across their threads. To keep each thread's memory to that thread, set both to scope: "thread":

new Memory({
  storage,
  options: {
    workingMemory: { enabled: true, scope: "thread" },
    semanticRecall: { topK: 5, messageRange: 2, scope: "thread" },
  },
});

The chosen model

Pass the models a chat user can pick from to serve(); the first is the default. With two or more, the web chat shows a model picker, and each turn's request context carries the pick as model. It is absent when no model was picked, as on a Slack turn, so fall back to your default:

const MODELS = [process.env.MODEL_DEFAULT ?? "claude-sonnet-4-6", "claude-opus-4-7"];

const agent = new Agent({
  id: "assistant",
  name: "Assistant",
  instructions: "You are a helpful assistant.",
  model: ({ requestContext }) =>
    gateway.chat(requestContext.get<"model", string | undefined>("model") ?? MODELS[0]),
});

serve(agent, { models: MODELS });

A resumed run, after a tool approval or a form, gets the same request context.

Files

The adapter appends each attached file's name and path to the turn's text. fileTools() gives the model tools that open those paths. They work on files of any size without loading a file into the prompt:

ToolWhat it does
inspect_fileReports a file's kind (PDF, DOCX, XLSX, text), its size, its text length, and for a table each sheet's columns and row count.
read_fileReturns one 20,000-character page of a PDF, DOCX, or text file, with nextOffset for the next page.
read_tableReturns one page of rows from a CSV or XLSX file, 100 by default, with nextOffset for the next page.
create_fileWrites a text file to the files dir, attaches it to the reply with attachFile, and returns its name and the path to read it back.
import { fileTools, serve } from "@astropods/adapter-mastra";

const agent = new Agent({
  id: "assistant",
  name: "Assistant",
  model,
  instructions: "Answer questions about the files the user attaches.",
  tools: { ...fileTools() },
});

serve(agent, { supportsFiles: true });

supportsFiles turns on web chat uploads. Slack sends files either way. The tools open only the files attached to or created in the current conversation, so a follow-up question can go back to an earlier file. The list is saved with the files, so it lasts through a restart. The tools return a file's contents and do no analysis. For counts or totals over a large table, give the agent a query engine such as DuckDB on the attachment's path, as the adapter-core README describes. A scanned PDF has no text layer, so reading one takes your own OCR tool.

Sandboxes

AstroSandbox is a Mastra sandbox provider, so Mastra's own workspace drives it: the filesystem, the mounts and the built-in workspace tools all run against the MicroVM. There is no parallel toolset to learn.

import { AstroSandbox } from "@astropods/adapter-mastra";
import { Workspace } from "@mastra/core/workspace";

const workspace = new Workspace({
  sandbox: new AstroSandbox({ name: threadId }),
});

The name is the sandbox. Use the thread id: one thread is one sandbox, so a conversation that resumes reattaches to its own files and two threads never share a filesystem.

An edited message does not reset the sandbox. When a user edits a message in the web chat, the adapter rebuilds the thread's memory, but a sandbox keyed on the thread keeps the files the replaced turns wrote. The agent can then see work from a version of the conversation the user abandoned. If that matters, pass supportsHistory: false to serve(), which turns off editing for the agent.

What it maps onto

MastraAstro
start()One attach. Reports created on the first call, connected after
executeCommand()A short command, or a background process when you pass onStdout/onStderr, because a plain exec cannot stream
processesspawn, list, get, kill over real background processes
handle.wait()Polls to exit, handing each chunk to your callbacks as it arrives
stop() / destroy()Suspend, and delete
getInfo()Includes timeoutAt, the sandbox's 8 hour ceiling

Mastra starts the sandbox on demand: its process manager calls ensureRunning() before a spawn, so nothing has to start it by hand.

What it does not do

supportsCheckpoints is false. snapshot() suspends, which does snapshot the MicroVM's memory so the next attach resumes from it, but there is only ever the latest state to return to. Persistence past the ceiling is not built yet.

A process has no stdin. sendStdin() throws rather than accepting the write and dropping it; pass input through the command or a file.

版本与发布记录

@astropods/adapter-mastra 共发布 49 个版本,首次发布于 2026/02/25;过去 12 个月发布了 49 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.10.1latest2026/11/043 天前
0.10.1-next.4next2026/11/043 天前
0.10.1-next.32026/11/043 天前
0.10.02026/11/034 天前
0.9.1-next.112026/11/034 天前
0.9.1-next.102026/11/025 天前

关于 @astropods/adapter-mastra 的常见问题

@astropods/adapter-mastra 是什么?

Each turn's request context carries userName, the sender's name on the source platform (their full name in Slack, or their Astro name in web chat). It is absent when the platform sent none, so check for it. Tell the model how to use the name, or it may

如何安装 @astropods/adapter-mastra?

在项目目录运行 npm install @astropods/adapter-mastra,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^3.25.0 || ^4.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@astropods/adapter-mastra 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@astropods/adapter-mastra 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@astropods/adapter-mastra 可以商用吗?

@astropods/adapter-mastra 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@astropods/adapter-mastra 的下载量有多少?

根据 npm 官方下载统计,@astropods/adapter-mastra 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,348 次,日均约 78 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@astropods/adapter-mastra 还在维护吗?

最新版本 0.10.1 发布于 2026/11/04(3 天前);至今共发布 49 个版本,其中过去 12 个月发布了 49 个;首次发布于 2026/02/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。