@elizaos/prompts 2.0.0-beta.1 → 2.0.11-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shaw Walters and elizaOS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -4,18 +4,15 @@ Shared prompt templates and action specs for elizaOS.
4
4
 
5
5
  ## Overview
6
6
 
7
- This package is the single source of truth for prompt templates used by the runtime. Prompts are authored directly as TypeScript modules under `src/` and re-exported from `src/index.ts`.
7
+ This package is the single source of truth for prompt templates used by the runtime. Prompts are authored directly in `src/index.ts`.
8
8
 
9
9
  ## Structure
10
10
 
11
11
  ```
12
12
  packages/prompts/
13
- ├── src/ # TypeScript prompt template modules (source of truth)
14
- ├── reply.ts
15
- ├── choose_option.ts
16
- │ ├── image_generation.ts
17
- │ └── ...
18
- ├── specs/ # Canonical merged action/provider specs (JSON) + generated plugins.generated.json
13
+ ├── src/
14
+ └── index.ts # TypeScript prompt template exports
15
+ ├── specs/ # Merged action/provider specs (JSON) + generated plugins.generated.json
19
16
  └── scripts/ # Spec + docs generators
20
17
  ├── generate-action-docs.js
21
18
  ├── generate-plugin-action-spec.js
@@ -46,8 +43,10 @@ bun run build
46
43
 
47
44
  ## Usage
48
45
 
46
+ Runtime code imports the templates through `@elizaos/core`, which re-exports them and provides `composePrompt` to fill the `{{...}}` placeholders:
47
+
49
48
  ```typescript
50
- import { REPLY_TEMPLATE, CHOOSE_OPTION_TEMPLATE } from "@elizaos/prompts";
49
+ import { REPLY_TEMPLATE, composePrompt } from "@elizaos/core";
51
50
 
52
51
  const prompt = composePrompt({
53
52
  state: { agentName: "Alice" },
@@ -55,10 +54,12 @@ const prompt = composePrompt({
55
54
  });
56
55
  ```
57
56
 
57
+ Import directly from `@elizaos/prompts` only inside this package's tooling and tests.
58
+
58
59
  ## Adding New Prompts
59
60
 
60
- 1. Create a new `.ts` file in `src/` exporting a `*_TEMPLATE` constant.
61
- 2. Re-export it from `src/index.ts`.
61
+ 1. Add a `camelCaseTemplate` string export in `src/index.ts`.
62
+ 2. Add the paired `UPPER_SNAKE_CASE_TEMPLATE` export.
62
63
 
63
64
  ## Template Guidelines
64
65
 
@@ -77,7 +78,7 @@ const prompt = composePrompt({
77
78
  ### Secret scan
78
79
 
79
80
  ```bash
80
- npm run check:secrets
81
+ bun run check:secrets
81
82
  ```
82
83
 
83
84
  Scans `packages/prompts/src/**/*.ts`, plugin prompt TS modules (paths matching `prompts/**/*.ts`, `workflow-prompts/**/*.ts`, etc.), and a few explicit files — see `scripts/check-secrets.js`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elizaos/prompts",
3
3
  "private": false,
4
- "version": "2.0.0-beta.1",
4
+ "version": "2.0.11-beta.7",
5
5
  "description": "Shared prompt templates for elizaOS across TypeScript, Python, and Rust",
6
6
  "type": "module",
7
7
  "main": "./src/index.ts",
@@ -10,6 +10,12 @@
10
10
  ".": {
11
11
  "types": "./src/index.ts",
12
12
  "import": "./src/index.ts"
13
+ },
14
+ "./*.css": "./dist/*.css",
15
+ "./*": {
16
+ "types": "./dist/*.d.ts",
17
+ "import": "./dist/*.js",
18
+ "default": "./dist/*.js"
13
19
  }
14
20
  },
15
21
  "scripts": {
@@ -20,7 +26,9 @@
20
26
  "clean": "rm -rf dist",
21
27
  "lint": "bunx @biomejs/biome check --write .",
22
28
  "lint:check": "bunx @biomejs/biome check .",
23
- "typecheck": "echo 'No TypeScript source files to check'"
29
+ "format:check": "bunx @biomejs/biome format .",
30
+ "typecheck": "echo 'No TypeScript source files to check'",
31
+ "test": "bun test ./test"
24
32
  },
25
33
  "files": [
26
34
  "src/",
@@ -38,5 +46,5 @@
38
46
  "publishConfig": {
39
47
  "access": "public"
40
48
  },
41
- "gitHead": "cb192f7b21c441e9463d1af2f890c145814baad2"
49
+ "gitHead": "cdbc876f793d96073d7eb0d09715a031ce0cd32e"
42
50
  }
@@ -1,23 +1,4 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * Secret/credential scanner for prompt templates.
4
- *
5
- * This is intentionally conservative: it only fails on patterns that strongly
6
- * resemble real credentials (or private key material) to avoid false positives.
7
- *
8
- * Wave 1 of the prompt migration moved every prompt body from a sibling
9
- * `.txt` file to a TypeScript template-literal export. The scanner now walks
10
- * those TS prompt-source locations directly.
11
- *
12
- * Scans:
13
- * - packages/prompts/src/**\/*.ts
14
- * - packages/core/src/prompts.ts and packages/core/src/services/message.ts
15
- * - plugins/* TS modules whose path matches `prompts.ts`,
16
- * `prompts/<name>.ts`, `workflow-prompts/<name>.ts`, or `templates.ts`
17
- *
18
- * Generated mirrors and test files are skipped.
19
- */
20
-
21
2
  import fs from "node:fs/promises";
22
3
  import path from "node:path";
23
4
  import { fileURLToPath } from "node:url";
@@ -28,15 +9,12 @@ const __dirname = path.dirname(__filename);
28
9
  const PROMPTS_PKG_DIR = path.resolve(__dirname, "..");
29
10
  const REPO_ROOT = path.resolve(PROMPTS_PKG_DIR, "..", "..");
30
11
 
31
- // Roots under which to look for prompt-bearing TS files.
32
12
  const PROMPT_SCAN_TS_ROOTS = [
33
13
  "packages/prompts/src",
34
14
  "packages/core/src",
35
15
  "plugins",
36
16
  ];
37
17
 
38
- // Always include these high-traffic prompt modules even if they don't match
39
- // the heuristic file-name patterns above.
40
18
  const PROMPT_SCAN_FILES = [
41
19
  "packages/core/src/prompts.ts",
42
20
  "packages/core/src/services/message.ts",
@@ -69,7 +47,7 @@ const SKIP_DIR_NAMES = new Set([
69
47
  * @param {(absPath: string, relPath: string) => boolean} predicate
70
48
  * @returns {Promise<string[]>}
71
49
  */
72
- async function walkFiles(root, predicate) {
50
+ export async function walkFiles(root, predicate) {
73
51
  /** @type {string[]} */
74
52
  const out = [];
75
53
 
@@ -102,7 +80,7 @@ async function walkFiles(root, predicate) {
102
80
  /**
103
81
  * @returns {Promise<string[]>}
104
82
  */
105
- async function listPromptTsFiles() {
83
+ export async function listPromptTsFiles() {
106
84
  /** @type {Set<string>} */
107
85
  const set = new Set();
108
86
  for (const file of PROMPT_SCAN_FILES) {
@@ -126,7 +104,7 @@ async function listPromptTsFiles() {
126
104
  * @param {string} content
127
105
  * @returns {{errors: string[], warnings: string[]}}
128
106
  */
129
- function scanContent(filePath, content) {
107
+ export function scanContent(filePath, content) {
130
108
  /** @type {string[]} */
131
109
  const errors = [];
132
110
  /** @type {string[]} */
@@ -181,13 +159,21 @@ function scanContent(filePath, content) {
181
159
 
182
160
  for (let i = 0; i < lines.length; i++) {
183
161
  const line = lines[i];
162
+ let hasError = false;
163
+ /** @type {string[]} */
164
+ const lineWarnings = [];
184
165
  for (const rule of rules) {
185
166
  if (rule.re.test(line)) {
186
167
  const msg = `${filePath}:${i + 1} ${rule.name}: ${line.trim()}`;
187
- if (rule.severity === "error") errors.push(msg);
188
- else warnings.push(msg);
168
+ if (rule.severity === "error") {
169
+ errors.push(msg);
170
+ hasError = true;
171
+ } else {
172
+ lineWarnings.push(msg);
173
+ }
189
174
  }
190
175
  }
176
+ if (!hasError) warnings.push(...lineWarnings);
191
177
  }
192
178
 
193
179
  return { errors, warnings };
@@ -229,7 +215,9 @@ async function main() {
229
215
  }
230
216
  }
231
217
 
232
- main().catch((err) => {
233
- console.error(err);
234
- process.exit(2);
235
- });
218
+ if (process.argv[1] && path.resolve(process.argv[1]) === __filename) {
219
+ main().catch((err) => {
220
+ console.error(err);
221
+ process.exit(2);
222
+ });
223
+ }
@@ -0,0 +1,13 @@
1
+ import fs from "node:fs";
2
+
3
+ export function readText(filePath) {
4
+ return fs.readFileSync(filePath, "utf-8");
5
+ }
6
+
7
+ export function readJson(filePath) {
8
+ return JSON.parse(readText(filePath));
9
+ }
10
+
11
+ export function ensureDirectory(dir) {
12
+ fs.mkdirSync(dir, { recursive: true });
13
+ }
@@ -1,17 +1,9 @@
1
1
  #!/usr/bin/env node
2
- /**
3
- * Action/Provider Docs Generator
4
- *
5
- * Reads canonical specs from packages/prompts/specs/** and generates
6
- * TypeScript docs modules under packages/core/src/generated.
7
- *
8
- * This is intentionally dependency-free (no zod/yup) to keep builds lightweight.
9
- */
10
-
11
2
  import { execFileSync } from "node:child_process";
12
3
  import fs from "node:fs";
13
4
  import path from "node:path";
14
5
  import { fileURLToPath } from "node:url";
6
+ import { ensureDirectory, readJson } from "./file-utils.js";
15
7
  import { compressPromptDescription } from "./prompt-compression.js";
16
8
 
17
9
  const __filename = fileURLToPath(import.meta.url);
@@ -238,15 +230,6 @@ function assertProviderDoc(provider, name) {
238
230
  }
239
231
  }
240
232
 
241
- /**
242
- * @param {string} filePath
243
- * @returns {unknown}
244
- */
245
- function readJson(filePath) {
246
- const raw = fs.readFileSync(filePath, "utf-8");
247
- return JSON.parse(raw);
248
- }
249
-
250
233
  /**
251
234
  * Recursively list .json files in a directory.
252
235
  * @param {string} rootDir
@@ -335,10 +318,7 @@ function assertUniqueNames(docs, label) {
335
318
  */
336
319
  function loadSpecs(dir, corePath, kind) {
337
320
  if (!fs.existsSync(corePath)) {
338
- return {
339
- core: { version: "1.0.0", items: [] },
340
- all: { version: "1.0.0", items: [] },
341
- };
321
+ throw new Error(`Missing ${kind} core spec: ${corePath}`);
342
322
  }
343
323
 
344
324
  const coreRoot = readJson(corePath);
@@ -388,26 +368,14 @@ function loadSpecs(dir, corePath, kind) {
388
368
  };
389
369
  }
390
370
 
391
- /**
392
- * Ensures a directory exists, creating it and parent directories if necessary.
393
- * @param {string} dir - The directory path to ensure exists
394
- * @throws {Error} If the directory path is empty or whitespace-only
395
- */
396
- function ensureDir(dir) {
397
- if (!dir || dir.trim() === "") {
398
- throw new Error("Directory path cannot be empty");
399
- }
400
- fs.mkdirSync(dir, { recursive: true });
401
- }
402
-
403
371
  /**
404
372
  * @param {Record<string, unknown>} doc
405
373
  * @returns {string | undefined}
406
374
  */
407
375
  function getCompressedAlias(doc) {
408
- const canonical = doc.descriptionCompressed;
409
- if (typeof canonical === "string" && canonical.trim()) {
410
- return canonical;
376
+ const preferred = doc.descriptionCompressed;
377
+ if (typeof preferred === "string" && preferred.trim()) {
378
+ return preferred;
411
379
  }
412
380
  const alias = doc.compressedDescription;
413
381
  if (typeof alias === "string" && alias.trim()) {
@@ -475,7 +443,7 @@ function normalizeSpecsInPlace(actionsSpec, providersSpec) {
475
443
 
476
444
  function generateTypeScript(actionsSpec, providersSpec) {
477
445
  const outDir = path.join(REPO_ROOT, "packages", "core", "src", "generated");
478
- ensureDir(outDir);
446
+ ensureDirectory(outDir);
479
447
 
480
448
  const actionsJson = JSON.stringify(
481
449
  { version: actionsSpec.core.version, actions: actionsSpec.core.items },
@@ -502,7 +470,7 @@ function generateTypeScript(actionsSpec, providersSpec) {
502
470
  );
503
471
 
504
472
  const content = `/**
505
- * Auto-generated canonical action/provider docs.
473
+ * Auto-generated action/provider docs.
506
474
  * DO NOT EDIT - Generated from packages/prompts/specs/**.
507
475
  */
508
476
 
@@ -596,8 +564,8 @@ export const allProviderDocs: readonly ProviderDoc[] = allProvidersSpec.provider
596
564
  ["@biomejs/biome", "check", "--write", actionDocsPath],
597
565
  { cwd: REPO_ROOT, stdio: "pipe" },
598
566
  );
599
- } catch {
600
- // Biome may be unavailable in stripped-down environments.
567
+ } catch (error) {
568
+ throw new Error(`Failed to format ${actionDocsPath}`, { cause: error });
601
569
  }
602
570
  }
603
571