AIエージェントへの基本指示を、担当する成果・開始条件・完了基準から設計し、ツール不足時の対応や最終報告まで抜け漏れを点検するスキル。
- 新しいエージェントの基本指示の設計
- 保存前のプロンプトの最終点検
- ツールや権限が不足した際の対応設計
Use when fixing a bug, writing or reviewing tests, or adding a regression test anywhere in Mastra (core, storage adapters, server adapters, memory, client SDKs, integrations). Especially use before mocking a class, model, storage, or server; before writing a unit test that only checks wiring or that a value is defined; before writing a one-off test for a single engine, adapter, or code path; before adding a recorded (__recordings__) fixture; or when a test passes but you aren't sure it reproduces the real failure.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Tests exist to make Mastra work for the people building on it. A test earns its place only if it would have caught a bug a user hit, or will catch the next one. A test that passes while the real app is broken is worse than no test: it says things are fine, it costs time to run and maintain, and it breaks on harmless refactors.
Every test you add should answer: what real failure does this protect against? If you can't name one, don't write the test.
Don't write these. When you find them next to code you're changing, replace or delete them.
expect(result.runId).toBeDefined(), expect(fn).not.toThrow(), "it returns something".vi.fn() storage, stubbed fetch, fake Mastra or agent classes, mocked processors. The bug usually lives in the code you mocked away.Unit tests are fine for pure logic with real edge cases (a parser, a schema converter, a scheduling or retry calculation) where inputs and outputs are the contract. Test those inputs and outputs, not the steps in between.
vi.fn() stores. A real Inngest dev server for Inngest. Real processors, tools, Mastra instances, and the public API. Mock only at the outermost edge you can't run (a paid LLM, a third-party API), and mock it at the wire level so everything inside runs for real.it.fails) with a comment. Only write a cause if you've verified it; otherwise say "not yet investigated". Only pin deterministic failures: run the case several times first. If it passes some runs and fails others, use it.skip with a comment saying the result is nondeterministic. Never delete or skip a deterministically failing case to get green. File an issue for real bugs you find along the way.Add to the shared suite for the area before writing a standalone file.
| Area | Shared suite |
|---|---|
Agent behavior in @mastra/core (loop, streaming, tools, approval/suspend/resume, processors, memory threads, subagents, structured output) | aimock scenarios, below |
Storage adapters (stores/*) | createTestSuite from @internal/storage-test-utils (stores/_test-utils), run against the adapter's real database |
Server adapters (server-adapters/*) | server-adapters/server-adapters-test-suite, over real HTTP |
If an area has no shared suite and the same case would apply to several implementations, write the case once in a reusable form instead of copying it per implementation.
Scenarios live in packages/core/src/loop/test-utils/aimock/scenarios/*.scenario.test.ts. Read packages/core/src/loop/test-utils/aimock/README.md for the full API. Don't write durable-agent-*.test.ts one-offs or new recorded e2e cases for agent behavior.
Scenarios run against a real HTTP mock LLM (@copilotkit/aimock). From packages/core, describeForAllEngines runs each scenario on normal, durable, evented, and fs. The workflows/inngest project runs the same scenarios on inngest only, against a real dev server. Full coverage needs both commands.
describeForAllEngines('Support agent ...', engine => {
const getMock = useLoopScenarioAimock();
const itFailsOnInngest = engine === 'inngest' ? it.fails : it;
// Technical: <mechanism>. (#12345)
it('<what the user sees> (#12345)', async () => {
const { output, requests } = await runLoopScenario({
engine,
llm: getMock(),
prompt: '...',
tools,
fixtures: llm => {
llm.on({ endpoint: 'chat', sequenceIndex: 0 }, { content: '...' });
},
});
expect(output.text).toBe('...');
expect(JSON.stringify(requests[1].body.messages)).toContain('...');
});
});
Harness notes:
createSharedAgent keeps one agent across calls (suspend/resume, multi-turn). runApprovalScenario drives approvals on every engine.sequenceIndex, toolName, toolCallId, hasToolResult, message regexes, or a predicate.tools object keys, not the tool id. Auto-resume fixtures must include suspendedToolCallId.Running:
# In-process engines, seconds. Use while iterating.
cd packages/core && npx vitest run src/loop/test-utils/aimock/scenarios/<name>.scenario.test.ts
# Inngest, real dev servers. Targeted only; a full run is ~90s, don't repeat it casually.
cd workflows/inngest && AIMOCK_SCENARIOS='{name-a,name-b}' npx vitest run --project e2e:workflows/inngest:aimock
Run a new scenario file on Inngest once and pin anything that diverges.
it.fails, nondeterministic ones skipped, each with an honest comment; real bugs found are filedまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
AIエージェントへの基本指示を、担当する成果・開始条件・完了基準から設計し、ツール不足時の対応や最終報告まで抜け漏れを点検するスキル。
現在の作業ツリーにつないだ専用プロジェクトを作り、Agent Builderのエージェント・スキル管理、権限、APIや画面の基本動作を検証するスキル。
プルリクエストのコードを不具合・保守性・記述ルールの順に確認し、統合前に直すべき問題と改善案、良い実装を、ファイル名や行番号を添えて整理するスキル。
コード作成・修正・レビューを担うエージェントの指示文を設計します。ファイル操作の可否に応じた動作や必要なツール、検証方法、完了条件を具体化します。
Factoryのボードごとの段階移動や処理ルール、GitHub・Linearのイベント対応を、既存の型付き設定とテストを確認しながら変更します。
ブログやSNS投稿、広告文を書くエージェントを設計するスキル。読者やブランドの文体、文字数、禁止表現、納品形式を定め、公開用の原稿を仕上げる手順を整えます。