creating-agents-in-medusa
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreating Agents in Medusa
在Medusa中创建Agent
This skill covers the full stack for adding an internal, admin-facing AI agent to a Medusa project. These agents are used by merchants and store operators through the Medusa admin dashboard — not by customers on a storefront. For customer-facing agents (e.g. a storefront chatbot), a different architecture is needed: public API routes, no MedusaExec, and storefront auth.
本技能涵盖了在Medusa项目中添加面向内部管理员的AI Agent的全栈内容。这些Agent由商家和店铺运营人员通过Medusa管理后台使用,而非店铺前端的客户。对于面向客户的Agent(如店铺前端聊天机器人),则需要不同的架构:公开API路由、不使用MedusaExec,以及前端身份验证。
Constraints
约束条件
- Internal use only — this architecture is for admin users (merchants, operators, support staff), not customers. Routes live under , the UI lives in the Medusa admin dashboard, and access is gated by admin authentication throughout.
src/api/admin/ - Authentication is non-negotiable — MedusaExec runs arbitrary TypeScript with full database access. All agent routes must use and live under
AuthenticatedMedusaRequest. An unauthenticated endpoint is a remote code execution vulnerability.src/api/admin/ - Use MedusaExec, not custom tools — for any data operation, the agent writes TypeScript and executes it via MedusaExec. Only build a custom tool for capabilities that cannot be expressed as executable TypeScript (e.g. calling an external API with a secret key).
- One shared module, multiple agents — and
AgentSessionare shared infrastructure. UseAgentMessageto distinguish sessions per agent. Never create separate models per agent.agent_type - Pass via
MedusaContainer— never import services directly in tool files; that causes circular dependencies.experimental_context - Stream format is NDJSON — , one JSON object per line followed by
Content-Type: application/x-ndjson.\n - Run migrations after adding or changing models ().
npx medusa db:generate agent && npx medusa db:migrate - Tool descriptions live in config, not inline in — the config object overrides them at runtime.
tool()
- 仅限内部使用 — 该架构面向管理员用户(商家、运营人员、客服人员),而非客户。路由位于目录下,UI集成在Medusa管理后台中,全程通过管理员身份验证控制访问权限。
src/api/admin/ - 身份验证必不可少 — MedusaExec可运行任意TypeScript代码并拥有完整数据库访问权限。所有Agent路由必须使用且位于
AuthenticatedMedusaRequest目录下。未验证的端点会导致远程代码执行漏洞。src/api/admin/ - 使用MedusaExec而非自定义工具 — 任何数据操作都应由Agent编写TypeScript代码并通过MedusaExec执行。仅当功能无法通过可执行TypeScript实现时(如使用密钥调用外部API),才需构建自定义工具。
- 一个共享模块,多个Agent — 和
AgentSession是共享基础设施。使用AgentMessage区分不同Agent的会话。切勿为每个Agent创建单独的模型。agent_type - 通过传递
experimental_context— 切勿在工具文件中直接导入服务,这会导致循环依赖。MedusaContainer - 流式格式为NDJSON — ,每行一个JSON对象,后跟
Content-Type: application/x-ndjson。\n - 添加或修改模型后运行迁移()。
npx medusa db:generate agent && npx medusa db:migrate - 工具描述存于配置中,而非内联代码 — 配置对象会在运行时覆盖这些描述。
tool()
CRITICAL: Load Reference Files When Needed
重要提示:按需加载参考文件
⚠️ The quick reference below is NOT sufficient for implementation. Load the relevant reference file before writing any code.
| Task | Load this file |
|---|---|
| Defining conversation models | |
| Setting up the module service | |
| Configuring tools, prompt, streamText | |
| Building the POST chat endpoint | |
| Implementing NDJSON streaming | |
| Building the admin chat UI | |
| Giving the agent code execution capability | |
Minimum requirement: Load at least the reference file matching your current task before writing code.
⚠️ 以下快速参考不足以支撑实现工作。 在编写任何代码前,请加载相关参考文件。
| 任务 | 加载对应文件 |
|---|---|
| 定义对话模型 | |
| 设置模块服务 | |
| 配置工具、提示词、streamText | |
| 构建POST聊天端点 | |
| 实现NDJSON流式传输 | |
| 构建管理端聊天UI | |
| 赋予Agent代码执行能力 | |
最低要求: 在编写代码前,至少加载与当前任务匹配的参考文件。
Related Skills
相关技能
Load these alongside this skill when relevant:
- — Medusa module patterns, workflows, data model conventions. Load when implementing the module service or custom backend logic.
building-with-medusa - — Admin UI component patterns, TanStack Query, route registration. Load when building or extending the admin chat UI.
building-admin-dashboard-customizations
在相关场景下,可结合以下技能使用:
- — Medusa模块模式、工作流、数据模型约定。在实现模块服务或自定义后端逻辑时加载。
building-with-medusa - — 管理端UI组件模式、TanStack Query、路由注册。在构建或扩展管理端聊天UI时加载。
building-admin-dashboard-customizations
Architecture Overview
架构概览
src/modules/agent/
index.ts ← Module() export + AGENT_MODULE constant
service.ts ← MedusaService + Anthropic client + stream(messages, container, config)
models/
session.ts ← AgentSession (shared across all agents, filtered by agent_type)
message.ts ← AgentMessage
agents/index.ts ← streamText() orchestration
tools/
medusa-exec.ts ← MedusaExec tool (primary tool for all data operations)
todo-write.ts ← TodoWrite tool
config/
<agent-type>.ts ← per-agent system prompt + tool descriptions
src/api/admin/agent/<agent-type>/
route.ts ← POST (AuthenticatedMedusaRequest, session lifecycle, NDJSON stream)
sessions/route.ts ← GET session list (filtered by agent_type)
sessions/[id]/route.ts ← GET messages for a session
src/admin/routes/<agent-type>/
page.tsx ← React chat UI (admin extension)
src/lib/code-mode/
executor.ts ← sandboxed TypeScript executor used by MedusaExecsrc/modules/agent/
index.ts ← Module() export + AGENT_MODULE constant
service.ts ← MedusaService + Anthropic client + stream(messages, container, config)
models/
session.ts ← AgentSession (shared across all agents, filtered by agent_type)
message.ts ← AgentMessage
agents/index.ts ← streamText() orchestration
tools/
medusa-exec.ts ← MedusaExec tool (primary tool for all data operations)
todo-write.ts ← TodoWrite tool
config/
<agent-type>.ts ← per-agent system prompt + tool descriptions
src/api/admin/agent/<agent-type>/
route.ts ← POST (AuthenticatedMedusaRequest, session lifecycle, NDJSON stream)
sessions/route.ts ← GET session list (filtered by agent_type)
sessions/[id]/route.ts ← GET messages for a session
src/admin/routes/<agent-type>/
page.tsx ← React chat UI (admin extension)
src/lib/code-mode/
executor.ts ← sandboxed TypeScript executor used by MedusaExecCommon Mistakes
常见错误
Verify you are NOT doing these:
Security:
- Agent route uses instead of
MedusaRequestAuthenticatedMedusaRequest - Agent route placed outside
src/api/admin/
Architecture:
- Creating separate /
AgentSessionmodels per agent instead of usingAgentMessageagent_type - Importing services directly in tool files instead of resolving from
experimental_context - Building a custom tool for a data operation instead of using MedusaExec
Streaming:
- Missing after the stream loop (response never closes)
res.end() - Missing or
Transfer-Encoding: chunkedheadersContent-Type: application/x-ndjson - Not buffering incomplete lines on the client (JSON parse errors on split packets)
Module:
- Forgetting to register the module in
medusa-config.ts - Forgetting to run migrations after changing models
- Hardcoding tool descriptions in instead of the config object
tool()
请确认你未出现以下情况:
安全问题:
- Agent路由使用而非
MedusaRequestAuthenticatedMedusaRequest - Agent路由放置在目录之外
src/api/admin/
架构问题:
- 为每个Agent创建单独的/
AgentSession模型,而非使用AgentMessage区分agent_type - 在工具文件中直接导入服务,而非从中解析
experimental_context - 为数据操作构建自定义工具,而非使用MedusaExec
流式传输问题:
- 流式循环后缺少(响应永远不会关闭)
res.end() - 缺少或
Transfer-Encoding: chunked请求头Content-Type: application/x-ndjson - 客户端未缓冲不完整行(数据包拆分导致JSON解析错误)
模块问题:
- 忘记在中注册模块
medusa-config.ts - 修改模型后忘记运行迁移
- 在中硬编码工具描述,而非使用配置对象
tool()
Reference Files Available
可用参考文件
reference/data-models.md - model.define(), agent_type discriminator, relationships, migrations
reference/service.md - MedusaService extension, Anthropic init, stream(), module index, config registration
reference/agent-setup.md - streamText(), MedusaExec tool wiring, system prompt, context passing
reference/api-route.md - POST route, session lifecycle, message persistence, streaming headers
reference/streaming.md - NDJSON emission, fullStream iteration, chunk types, client-side parsing
reference/admin-extension.md - React chat UI, streaming fetch, message rendering, tool call display, session sidebar
reference/medusa-exec.md - Executor setup, MedusaExec tool, query.graph() patterns, error codesreference/data-models.md - model.define(), agent_type discriminator, relationships, migrations
reference/service.md - MedusaService extension, Anthropic init, stream(), module index, config registration
reference/agent-setup.md - streamText(), MedusaExec tool wiring, system prompt, context passing
reference/api-route.md - POST route, session lifecycle, message persistence, streaming headers
reference/streaming.md - NDJSON emission, fullStream iteration, chunk types, client-side parsing
reference/admin-extension.md - React chat UI, streaming fetch, message rendering, tool call display, session sidebar
reference/medusa-exec.md - Executor setup, MedusaExec tool, query.graph() patterns, error codesTesting
测试
Once the agent is implemented, test it end-to-end directly in the admin dashboard:
- Start the Medusa dev server ()
npx medusa develop - Open the admin dashboard and navigate to the agent's page in the sidebar (the label set in )
defineRouteConfig - Type a simple read-only prompt — e.g. "How many products are in the store?" — and submit
- Verify the response streams in and a new session appears in the sidebar
- Send a follow-up message in the same session to confirm conversation history is preserved
- Reload the page, select the session from the sidebar, and confirm the message history is restored from the database
If anything is broken, check:
- Browser network tab — the POST request should return with chunked lines
Content-Type: application/x-ndjson - Server logs — and
[agent] tool_calllines confirm the agent is running[agent] step_finish - Database — and
agent_sessiontables should have rows with the correctagent_messageagent_type
Agent实现完成后,直接在管理后台进行端到端测试:
- 启动Medusa开发服务器()
npx medusa develop - 打开管理后台,导航至侧边栏中的Agent页面(标签在中设置)
defineRouteConfig - 输入一个简单的只读提示词——例如*“店铺中有多少件商品?”*——并提交
- 验证响应是否流式返回,且侧边栏中出现新会话
- 在同一会话中发送跟进消息,确认对话历史已被保留
- 刷新页面,从侧边栏选择该会话,确认消息历史已从数据库中恢复
若出现问题,请检查:
- 浏览器网络标签页 — POST请求应返回,且包含分块内容
Content-Type: application/x-ndjson - 服务器日志 — 和
[agent] tool_call日志行确认Agent正在运行[agent] step_finish - 数据库 — 和
agent_session表应包含带有正确agent_message的行agent_type