9.6 KiB
@elizaos/prompts
Single source of truth for the LLM prompt templates the elizaOS runtime uses, plus the action/provider spec + docs codegen that derives compressed action descriptions from those templates.
Purpose / role
- Holds every shared prompt template as a plain string export in
src/index.ts.@elizaos/corere-exports these viapackages/core/src/prompts.ts, andpackages/core/src/features/autonomy/service.tsconsumes the autonomy templates. The runtime fills{{...}}placeholders withcomposePromptfrom core. - Owns
compressPromptDescriptioninsrc/prompt-compression.ts; core re-exports it for backward compatibility. This keeps prompts tooling from depending back on core. - Also owns the action/provider specs under
specs/and the generators inscripts/that build a merged plugin action spec and emitpackages/core/src/generated/action-docs.ts. - This package ships no compiled JS for
src/—main/exports['.']point atsrc/index.tsdirectly (consumed by TS tooling / bundlers in the monorepo). Thedist/subpath mappings inexports(./*.cssand./*) exist for potential subpath consumers; no codegen script in this package writes todist/.
Layout
packages/prompts/
src/index.ts ~40 prompt templates; each exported twice:
camelCaseTemplate + UPPER_SNAKE_CASE_TEMPLATE alias.
Also re-exports compressPromptDescription.
src/prompt-compression.ts deterministic action/provider description compressor
specs/
actions/core.json hand-maintained core action spec
actions/plugins.generated.json GENERATED by generate-plugin-action-spec.js (do not hand-edit)
providers/core.json hand-maintained core provider spec
scripts/
generate-plugin-action-spec.js scans plugins/**/*.ts for `export const …: Action`,
merges with core.json → specs/actions/plugins.generated.json
generate-action-docs.js reads specs/* → writes packages/core/src/generated/action-docs.ts
(imports compressPromptDescription from this package)
check-secrets.js scans prompt .ts files for embedded secrets/PII
file-utils.js readJson/readText/ensureDirectory helpers for the scripts
test/prompts.test.js regression assertions on template wording (bun test)
Key exports / surface
src/index.ts only. Each template is exported under two names — the camelCase form and an UPPER_SNAKE_CASE alias (e.g. replyTemplate / REPLY_TEMPLATE). Notable ones: MESSAGE_HANDLER_TEMPLATE, REPLY_TEMPLATE, SHOULD_RESPOND_TEMPLATE, SHOULD_RESPOND_WITH_CONTEXT_TEMPLATE, PLANNER_TEMPLATE, REFLECTION_TEMPLATE, FACT_EXTRACTION_TEMPLATE, DEFAULT_CHARACTER_SYSTEM_TEMPLATE, the AUTONOMY_* family, the SHOULD_(FOLLOW|MUTE|UNFOLLOW|UNMUTE)_ROOM_TEMPLATE set, the contact templates (ADD_/REMOVE_/UPDATE_CONTACTS / SEARCH_CONTACTS), BOOLEAN_FOOTER, and compressPromptDescription. Import templates from @elizaos/core in runtime code; prompts package tooling and tests import directly from @elizaos/prompts / src/index.ts.
Commands
bun run --cwd packages/prompts build # gen plugin spec, format it, gen action-docs
bun run --cwd packages/prompts build:plugin-action-spec # only regen specs/actions/plugins.generated.json
bun run --cwd packages/prompts build:action-docs # only regen packages/core/src/generated/action-docs.ts
bun run --cwd packages/prompts check:secrets # scan prompt files for secrets/PII
bun run --cwd packages/prompts test # bun test ./test
bun run --cwd packages/prompts lint # biome check --write
bun run --cwd packages/prompts lint:check # biome check (no write)
bun run --cwd packages/prompts format:check # biome format check
bun run --cwd packages/prompts clean # rm -rf dist
typecheck only prints its status because this package has no standalone TypeScript program beyond the prompt string module.
Config / env vars
No required configuration. The generators resolve repo paths from import.meta.url (REPO_ROOT = path.resolve(__dirname, "../../.."), scanning plugins/ and writing into packages/core).
DEBUG_ACTION_SPEC— optional. When set,generate-plugin-action-spec.jslogs each scanned.tsfile path to stderr during the plugin-action-spec scan.
How to extend
Add a prompt template:
- In
src/index.ts, addexport const fooTemplate = \...`;thenexport const FOO_TEMPLATE = fooTemplate;` (always export both names). - Use
{{camelCaseVar}}placeholders,{{#each}}/{{#if}}, and end with the JSON-only output instruction other templates use. - Re-export from
@elizaos/core(packages/core/src/prompts.ts) if runtime code needs it, then add/adjust a wording assertion intest/prompts.test.js.
Regenerate the plugin action spec after adding or renaming a plugin Action:
- Run
build:plugin-action-spec. It scansplugins/**/*.ts; never hand-editspecs/actions/plugins.generated.json. Actions intentionally excluded from the public surface live in theRETIRED_IMPLEMENTATION_ONLY_ACTIONSset inscripts/generate-plugin-action-spec.js.
Conventions / gotchas
plugins.generated.jsonis generated output — edits are overwritten bybuild. Change the sourceActionor the generator, not the JSON.core.json(actions + providers) is hand-maintained; the generators merge it with the scanned plugin actions.- The doc generator writes OUTSIDE this package, into
packages/core/src/generated/action-docs.ts. That is intentional codegen, not a layering break —build:action-docsowns it. - Plugin-local
prompts/*.json(e.g.actions.json) underplugins/**are hand-edited inputs to each plugin's own codegen and are NOT read bygenerate-plugin-action-spec.js, which only scans*.ts. - Never embed secrets or PII in templates (they are source-controlled); use placeholders.
check:secretsenforces this over prompt.tsfiles — see the path/regex list inscripts/check-secrets.js. - Repo-wide rules (logger-only, ESM, naming, architecture) live in the root AGENTS.md; not repeated here.
⛔ NON-NEGOTIABLE — evidence, trajectories & real end-to-end tests
The binding, repo-wide standard is AGENTS.md. Read it. Nothing in this package is done until it is proven done — a reviewer must confirm it works without reading the code, from the artifacts you attach. This applies to every feature, fix, refactor, and chore here. "Tests pass" is not proof; "CI is green" is not proof.
- Record AND read model trajectories. Capture the actual inputs and outputs of the model
from a live LLM — not the deterministic proxy, not a mock: the prompt, the
providers/context, the raw model output, every tool/action call, and the result. Then open
the trajectory and review it by hand. A captured-but-unread trajectory is not evidence
(
packages/scenario-runner/bin/eliza-scenarios run <scenario> --report <out>). - Real, full-featured E2E — no larp. Every feature ships detailed end-to-end tests that drive the real path end to end. Not the happy "front door" only: cover error paths, edge/empty/invalid input, concurrency, roles/permissions, and adversarial input. A test that asserts against a mock/stub/fixture standing in for the thing under test does not count. If the real model/device/chain/connector/account is hard to reach, make it reachable — that is the work, not an excuse to mock. If the existing tests here are shallow or mocked, fixing them is part of your change.
- Screenshots + logs at every phase, plus a complete walkthrough video/run-through of
the entire feature or view, start to finish (
bun run test:e2e:record). - Manually review every artifact the change touches — never just the green check: client
logs (console + network), server logs (
[ClassName] …), the model trajectories in and out, before/after full-page screenshots, and the domain artifacts listed below for this package. - No residuals. No shortcuts. The goal is not "done" — it is everything done. Clear every blocker by the hard path: build the real architecture, stand up the real model/device/service, actually test it. Never leave a TODO, a stub, a stepping-stone, or a "follow-up." When unsure, research thoroughly, weigh the options, and ship the best, highest-effort, production-ready version. Keep going until every possibility is exhausted.
Artifacts → attached inline in the PR (MP4 video, JPG screenshots, logs in <details>); attach each evidence type or
explicitly mark it N/A with a reason — never leave it blank. If develop moved and changed
behavior, re-capture evidence; stale proof is worse than none.
Capture & manually review for this package — runtime / framework:
- A live-LLM scenario trajectory for the runtime path you touched — provider → model → action → evaluator — with the raw
<response>XML and every tool/action call visible and read. - Backend
[ClassName]logs proving the message loop, task scheduler, or service actually fired end to end. - The memory/state artifacts produced — rows written, embeddings, room/world/entity records, scheduled-task rows — inspected, not assumed.
- For shared modules:
build:nodevs fullbuildso the browser/edge bundles still compile.