Agent Framework Overview
Agent Framework Overview
The repository uses a shared descriptor/factory contract while keeping runtime registration in the owning domain or cross-cutting loader. Source and tests are authoritative; generated agent contracts describe the product-domain slice and must not be interpreted as every optional/core/docs agent that could be loaded.
Runtime lifecycle
- A module declares an
AgentDescriptorcontaining stableprofileIdandregistryIdvalues plus code-owned defaults. - Its loader configures injected model, voice, storage, and embedding dependencies.
getAgent()reads the current database profile and calculates its effective content hash.- The factory reuses a matching build promise or rebuilds the agent with the resolved prompt, model, tools/browser, voice, and allowed memory settings.
- The loader returns the agent under its
registryId; the runtime merges all active artifacts with duplicate detection.
profileId keys Core.AgentProfiles. registryId keys the live Mastra
registry. They are intentionally allowed to differ.
Current ownership
| Agent family | Source | Registration owner |
|---|---|---|
| K12 | packages/domain-k12/src/agents/** | K12 loader (loader-core.ts) |
| SDAC | packages/domain-sdac/src/agents/** | packages/domain-sdac/src/loader.ts |
| TAP | packages/domain-tap/src/agents/** | packages/domain-tap/src/loader.ts |
| Handbook | packages/domain-handbook/src/agents/** | packages/domain-handbook/src/loader.ts |
| Shared/core | src/mastra/agents/shared/** | src/mastra/artifacts/core.loader.ts |
| Docs chat | src/mastra/agents/shared/docs-chat-agents.ts | src/mastra/artifacts/docs.loader.ts |
| Reasoning Engine | src/mastra/agents/reasoning-engine/** | src/mastra/artifacts/reasoning-engine.loader.ts |
The generated active-domain barrels are build artifacts. Do not register a
package-owned agent directly in apps/runtime/src/mastra-runtime.ts and do not
edit generated barrels by hand.
Supported module patterns
Most agents expose a descriptor plus five operations:
export const MY_AGENT_DESCRIPTOR: AgentDescriptor = {
profileId: 'example-purpose',
registryId: 'example-purpose-agent',
defaultName: 'Purpose Agent',
defaultPrompt: 'A complete fallback prompt...',
domain: 'Example',
functionalGroup: 'Purpose',
projects: ['testing'],
memoryOptions: null,
};
export function configureMyAgent(deps: AgentDependencies): void;
export function getMyAgentFactory(): IAgentFactory;
export async function getMyAgent(): Promise<Agent>;
export async function buildMyAgentFresh(): Promise<AgentBuildResult>;
export function invalidateMyAgentCache(): void;
Descriptor families may provide keyed versions of those operations. K12 annex
agents are the primary family example. A request-specific agent may use
buildFresh() when its instructions genuinely depend on request context, but it
must still use the shared profile and model resolution path.
Reasoning Engine agents use a transitional family cache. It is supported for that source-owned optional subsystem, but it is not the template for a new package-domain agent.
Profiles, models, and memory
- Code defaults are always required and are used when the current profile is absent or cannot be read.
LlmOverridesJsonis parsed through the shared Zod schema. Supported fields include deployment/model/provider selection, common sampling and token settings, reasoning effort, endpoint/protocol fields, and observational memory settings.- Model capability validation uses
Core.LLMModelCapabilitiesand currentCore.LLMParamsDimdata through the provider stack. - Memory is created only when the descriptor/profile enables it and a compatible
runtime storage dependency exists. Set
memoryOptionsexplicitly; usenull/falsefor agents whose callers manage history. - Caller-provided generation instructions remain runtime input. The model wrapper may normalize unsupported parameters, but it must not replace caller instructions with a build-time prompt.
Registry and contract boundaries
The live descriptor registry used by admin seed/reconcile routes is
packages/platform-runtime/src/server/routes/agent-registry-descriptor-registry.ts.
The static registry in src/mastra/agents/shared/descriptor-registry.ts still
supports conformance and memory tests. Keep both aligned until the test registry
is migrated.
Runtime discovery is target-specific:
GET /agents.jsonlists currently loaded registry IDs.GET /{domain}/routes.jsonlists domain-friendly agent routes.POST /{domain}/agents/{slug}/generateand/streaminvoke agents through the generated domain route surface.
docs/contracts/runtime-agent-contracts.json is generated from the audited
product-domain registry surface. Use live discovery when you need the artifacts
loaded by a particular deployment target.
Debugging
Useful flags include:
MASTRA_DEBUG_AGENT_FACTORY=true
MASTRA_DEBUG_AGENT_PROMPT=true
MASTRA_DEBUG_AGENT_PROMPT_FULL=false
AGENT_PROFILES_DEBUG=true
When a prompt or model appears stale, compare the descriptor profileId, the
current profile's effective hash, the selected deployment target, and the live
/agents.json result. Restarting should not be the first cache-invalidation
strategy: getAgent() checks profile content and rebuilds on a hash change.
Verification
Use the owning domain suite plus the shared guards:
npm run test:agents
npm run test:admin
npm run test:contracts
npm run contracts:check
npm run contracts:bruno
Run npm run test:k12, test:sdac, test:tap, or test:handbook for a
product agent. Loader/export changes also require the applicable target build or
npm run verify:runtime-smoke.