Skip to main content

Database: Agents & prompt management

Why this matters

In this repo, agent instructions are not committed as markdown.

Instead, the canonical system prompt (and optional overrides) live in the database so that:

  • prompts can be updated without redeploying
  • changes are versioned and auditable
  • the Admin UI can manage prompts consistently
note

For information about deploying agents via DACPAC and syncing prompts between environments, see the Database Seeding guide.

The table: Core.AgentProfiles

DDL: db/sqlproj/Mastra.CoreDb/model/Tables/Core.AgentProfiles.sql

This table stores versioned agent profiles.

Key columns (what developers should understand)

  • AgentId — stable agent identifier used by the runtime.
  • AgentAlias — optional human-friendly alias (also unique for current rows).
  • SystemPrompt — the actual system prompt text.
  • LlmOverridesJson — JSON overrides (temperature, max tokens, etc.).
  • MetadataJson — optional JSON for additional metadata.
  • ProfileHash — content hash used to prevent duplicate re-inserts.

Versioning & “current” semantics

  • IsCurrent = 1 indicates the active row for an agent.
  • A unique filtered index enforces at most one current profile per AgentId.
  • Old versions remain for auditability via EffectiveEndUtc, IsCurrent, and VersionNumber.

Why the Admin UI can appear “empty”

Having the table is not enough. The dropdown is backed by “current rows”.

If an agent doesn’t show up:

  • there is likely no row with IsCurrent = 1 for that agent
  • or you’re pointing the Admin UI at a different database/schema than the runtime

How the runtime uses it

At startup, agents fetch their prompt instructions from the agent profile service:

  • the service ensures the table exists (ensureTable())
  • the runtime reads the current row for the agent (getCurrent(agentId))

When DB_CORE_SCHEMA (default Core) is changed, keep:

  • bootstrap script
  • admin tools
  • running server

all pointing to the same schema name.

Prefer runtime tools over manual SQL to avoid breaking versioning rules.

  • Use the Admin tool admin-update-agent-profile (HTTP/Admin MCP surface)

That flow handles:

  • hashing
  • version number increments
  • flipping the previous row to IsCurrent = 0

Troubleshooting checklist

  • Confirm DB_CORE_SCHEMA matches between environments.
  • Run a DB health check:
    • POST /admin/tools/db-health-check with {"data":{"schema":"Core","tables":["Core.AgentProfiles"]}}
  • Enable debug logging if needed:
    • AGENT_PROFILES_DEBUG (or K12_DEBUG_AGENT_OVERRIDES) for verbose override fetch logs.

Useful SQL queries

  • List current profiles:
SELECT AgentId, AgentAlias, VersionNumber, CreatedAtUtc, CreatedBy
FROM Core.AgentProfiles
WHERE IsCurrent = 1
ORDER BY AgentId;
  • Inspect history for one agent:
SELECT AgentId, VersionNumber, IsCurrent, ProfileHash, CreatedAtUtc, UpdatedAtUtc
FROM Core.AgentProfiles
WHERE AgentId = 'k12-safety-agent'
ORDER BY VersionNumber DESC;

(Adjust schema name if DB_CORE_SCHEMA is not Core.)