Skip to content
AdStack Engineering Docs
Esc
navigateopen⌘Jpreview
On this page

Agents and chat

Every capability in AdStack is an agent reachable from chat. This is the catalogue and the rules for adding to it.

The product has one interaction model: the user types, a host LLM decides what to do, and agents produce output. There are no dedicated feature pages. Adding a capability means adding an agent, not adding a screen.

Two registries

They serve different jobs and both must stay in sync with the database.

Registry Answers
lib/registry.ts What modules exist, their stable ids, names, slugs, prompt folders, plus worker, queue, domain, and bucket names
lib/agents/registry.ts Which modules the chat host can call as tools, what each requires, and how its output renders

lib/registry.ts currently lists 33 modules. lib/agents/registry.ts lists 23 agent definitions, because some modules are internal helpers rather than user-facing agents (the attachment summarizer, the character map prompt engine, the cast list extractor, the image prompt engine, the storyboard frames agent, the shared guidelines module).

A module being in the registry does not mean a user can reach it. See what is actually wired up for the audit of live entry points and dead ones.

The agent catalogue

Slug Requires Notes
offer-intelligence a URL Scrapes and analyzes an offer
market-research offer Real customer language from review sources
buyer-persona offer Belief-shift-framework persona
viral-angle-miner offer Angles mined from viral content
Slug Requires
ad-hooks offer
headlines offer
facebook-ads offer
advertorial offer
advertorial-longform offer
in-feed-vsl offer
vsl offer
tsl offer
bullets-fascinations offer
copy-chief -
Slug Requires
landing-page offer
quiz offer
listicle offer
vsl-longform-page offer
upsell offer
Slug Notes
ugc-script-writer Paid video ads. 16 format archetypes, format_slug required - the user picks the format, never the host
viral-shorts Organic short-form content, 15-60s for TikTok, Reels and Shorts. No offer, no ad format, entertainment first
storyboard-director Turns a script into scenes with element and motion notes
cast-list Extracts locations, props, and products from a script

The two script agents are easy to confuse and the host is told the difference explicitly: “content”, “organic”, “post”, “for my TikTok” go to viral-shorts with no format cards at all; “ad”, “creative”, “campaign” go to ugc-script-writer through the format flow.

Slug Notes
campaign-builder Multi-stage pipeline. Excluded from the host’s tool list; it is started explicitly with the start_campaign tool

What an agent definition carries

{
  slug: "ad-hooks",
  displayName: "Ad Hooks",
  actionLabel: "Writing ad hooks",   // shown in the run timeline
  aliases: ["generate_hooks"],       // tolerated older tool names
  requires: { offer: true },         // gates the tool call
  outputRendererKey: "ad-hooks",     // picks the output card component
  supportsRevision: true,            // can be asked to revise its last output
  thinking: true,                    // extended thinking on
}

requires is enforced before the agent runs. If an offer or persona is missing, the host gets a validation error as a tool result, enriched with context: if a persona is currently being generated by a background job, the host is told that instead of being handed an empty picker.

Adding an agent

Registry first

Add the MODULES entry in lib/registry.ts: slug, name, type, promptDir. Nothing else happens until this exists.

Prompt files

Create prompts/<dir>/system.md and user.md. These are the source of truth for prompt content.

Migration

Add a migration in db/migrations/ inserting the module row and a default prompts row. Set is_active false for internal-only modules; getPromptSettings matches on name regardless of active state. Run bun run db:migrate.

Runtime loader

Mirror lib/talking-head-engine.ts or lib/attachment-summarizer.ts: call getPromptSettings(NAME) with an inline fallback so a missing database row never hard-fails.

Agent definition

If the host should be able to call it, add it to AGENT_DEFINITIONS in lib/agents/registry.ts and create an output renderer in components/shared/module-outputs/.

Verify

bun run check:truth must pass, then bun run smoke to confirm the prompt resolves at runtime. Prompt edits after this point are runtime-dead until bun run sync:prompts --apply <slug>.

Last updated on July 30, 2026

Was this page helpful?