@dexto/core 1.2.5 → 1.2.6

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.
Files changed (57) hide show
  1. package/dist/agent/schemas.cjs +23 -19
  2. package/dist/agent/schemas.d.ts +111 -107
  3. package/dist/agent/schemas.d.ts.map +1 -1
  4. package/dist/agent/schemas.js +7 -3
  5. package/dist/memory/index.cjs +2 -0
  6. package/dist/memory/index.d.ts +1 -1
  7. package/dist/memory/index.d.ts.map +1 -1
  8. package/dist/memory/index.js +3 -1
  9. package/dist/memory/schemas.cjs +10 -0
  10. package/dist/memory/schemas.d.ts +33 -4
  11. package/dist/memory/schemas.d.ts.map +1 -1
  12. package/dist/memory/schemas.js +9 -0
  13. package/dist/prompts/index.cjs +6 -8
  14. package/dist/prompts/index.d.ts +2 -4
  15. package/dist/prompts/index.d.ts.map +1 -1
  16. package/dist/prompts/index.js +4 -6
  17. package/dist/prompts/prompt-manager.cjs +2 -4
  18. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  19. package/dist/prompts/prompt-manager.js +2 -4
  20. package/dist/prompts/providers/config-prompt-provider.cjs +331 -0
  21. package/dist/prompts/providers/config-prompt-provider.d.ts +34 -0
  22. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -0
  23. package/dist/prompts/providers/config-prompt-provider.js +308 -0
  24. package/dist/prompts/schemas.cjs +42 -23
  25. package/dist/prompts/schemas.d.ts +121 -12
  26. package/dist/prompts/schemas.d.ts.map +1 -1
  27. package/dist/prompts/schemas.js +39 -22
  28. package/dist/prompts/types.d.ts +1 -1
  29. package/dist/prompts/types.d.ts.map +1 -1
  30. package/dist/systemPrompt/in-built-prompts.cjs +0 -5
  31. package/dist/systemPrompt/in-built-prompts.d.ts +1 -2
  32. package/dist/systemPrompt/in-built-prompts.d.ts.map +1 -1
  33. package/dist/systemPrompt/in-built-prompts.js +0 -4
  34. package/dist/systemPrompt/manager.cjs +24 -19
  35. package/dist/systemPrompt/manager.d.ts +2 -2
  36. package/dist/systemPrompt/manager.d.ts.map +1 -1
  37. package/dist/systemPrompt/manager.js +24 -19
  38. package/dist/systemPrompt/registry.cjs +1 -2
  39. package/dist/systemPrompt/registry.d.ts +1 -1
  40. package/dist/systemPrompt/registry.d.ts.map +1 -1
  41. package/dist/systemPrompt/registry.js +1 -2
  42. package/dist/systemPrompt/schemas.cjs +3 -17
  43. package/dist/systemPrompt/schemas.d.ts +13 -189
  44. package/dist/systemPrompt/schemas.d.ts.map +1 -1
  45. package/dist/systemPrompt/schemas.js +3 -17
  46. package/dist/utils/service-initializer.cjs +1 -0
  47. package/dist/utils/service-initializer.d.ts.map +1 -1
  48. package/dist/utils/service-initializer.js +1 -0
  49. package/package.json +1 -1
  50. package/dist/prompts/providers/file-prompt-provider.cjs +0 -401
  51. package/dist/prompts/providers/file-prompt-provider.d.ts +0 -49
  52. package/dist/prompts/providers/file-prompt-provider.d.ts.map +0 -1
  53. package/dist/prompts/providers/file-prompt-provider.js +0 -378
  54. package/dist/prompts/providers/starter-prompt-provider.cjs +0 -172
  55. package/dist/prompts/providers/starter-prompt-provider.d.ts +0 -47
  56. package/dist/prompts/providers/starter-prompt-provider.d.ts.map +0 -1
  57. package/dist/prompts/providers/starter-prompt-provider.js +0 -149
@@ -0,0 +1,308 @@
1
+ import "../../chunk-C6A6W6XS.js";
2
+ import { DextoLogComponent } from "../../logger/v2/types.js";
3
+ import { PromptError } from "../errors.js";
4
+ import { expandPlaceholders } from "../utils.js";
5
+ import { assertValidPromptName } from "../name-validation.js";
6
+ import { readFile, realpath } from "fs/promises";
7
+ import { existsSync } from "fs";
8
+ import { dirname, relative, sep } from "path";
9
+ class ConfigPromptProvider {
10
+ prompts = [];
11
+ promptsCache = [];
12
+ promptContent = /* @__PURE__ */ new Map();
13
+ cacheValid = false;
14
+ logger;
15
+ constructor(agentConfig, logger) {
16
+ this.logger = logger.createChild(DextoLogComponent.PROMPT);
17
+ this.prompts = agentConfig.prompts;
18
+ this.buildPromptsCache();
19
+ }
20
+ getSource() {
21
+ return "config";
22
+ }
23
+ invalidateCache() {
24
+ this.cacheValid = false;
25
+ this.promptsCache = [];
26
+ this.promptContent.clear();
27
+ this.logger.debug("ConfigPromptProvider cache invalidated");
28
+ }
29
+ updateConfig(agentConfig) {
30
+ this.prompts = agentConfig.prompts;
31
+ this.invalidateCache();
32
+ this.buildPromptsCache();
33
+ }
34
+ async listPrompts(_cursor) {
35
+ if (!this.cacheValid) {
36
+ await this.buildPromptsCache();
37
+ }
38
+ return {
39
+ prompts: this.promptsCache
40
+ };
41
+ }
42
+ async getPrompt(name, args) {
43
+ if (!this.cacheValid) {
44
+ await this.buildPromptsCache();
45
+ }
46
+ const promptInfo = this.promptsCache.find((p) => p.name === name);
47
+ if (!promptInfo) {
48
+ throw PromptError.notFound(name);
49
+ }
50
+ let content = this.promptContent.get(name);
51
+ if (!content) {
52
+ throw PromptError.missingText();
53
+ }
54
+ content = this.applyArguments(content, args);
55
+ return {
56
+ description: promptInfo.description,
57
+ messages: [
58
+ {
59
+ role: "user",
60
+ content: {
61
+ type: "text",
62
+ text: content
63
+ }
64
+ }
65
+ ]
66
+ };
67
+ }
68
+ async getPromptDefinition(name) {
69
+ if (!this.cacheValid) {
70
+ await this.buildPromptsCache();
71
+ }
72
+ const promptInfo = this.promptsCache.find((p) => p.name === name);
73
+ if (!promptInfo) {
74
+ return null;
75
+ }
76
+ return {
77
+ name: promptInfo.name,
78
+ ...promptInfo.title && { title: promptInfo.title },
79
+ ...promptInfo.description && { description: promptInfo.description },
80
+ ...promptInfo.arguments && { arguments: promptInfo.arguments }
81
+ };
82
+ }
83
+ async buildPromptsCache() {
84
+ const cache = [];
85
+ const contentMap = /* @__PURE__ */ new Map();
86
+ for (const prompt of this.prompts) {
87
+ try {
88
+ if (prompt.type === "inline") {
89
+ const { info, content } = this.processInlinePrompt(prompt);
90
+ cache.push(info);
91
+ contentMap.set(info.name, content);
92
+ } else if (prompt.type === "file") {
93
+ const result = await this.processFilePrompt(prompt);
94
+ if (result) {
95
+ cache.push(result.info);
96
+ contentMap.set(result.info.name, result.content);
97
+ }
98
+ }
99
+ } catch (error) {
100
+ this.logger.warn(
101
+ `Failed to process prompt: ${error instanceof Error ? error.message : String(error)}`
102
+ );
103
+ }
104
+ }
105
+ cache.sort((a, b) => {
106
+ const priorityA = a.metadata?.priority ?? 0;
107
+ const priorityB = b.metadata?.priority ?? 0;
108
+ return priorityB - priorityA;
109
+ });
110
+ this.promptsCache = cache;
111
+ this.promptContent = contentMap;
112
+ this.cacheValid = true;
113
+ this.logger.debug(`Cached ${cache.length} config prompts`);
114
+ }
115
+ processInlinePrompt(prompt) {
116
+ const promptName = `config:${prompt.id}`;
117
+ const promptInfo = {
118
+ name: promptName,
119
+ title: prompt.title,
120
+ description: prompt.description,
121
+ source: "config",
122
+ metadata: {
123
+ type: "inline",
124
+ category: prompt.category,
125
+ priority: prompt.priority,
126
+ showInStarters: prompt.showInStarters,
127
+ originalId: prompt.id
128
+ }
129
+ };
130
+ return { info: promptInfo, content: prompt.prompt };
131
+ }
132
+ async processFilePrompt(prompt) {
133
+ const filePath = prompt.file;
134
+ if (!existsSync(filePath)) {
135
+ this.logger.warn(`Prompt file not found: ${filePath}`);
136
+ return null;
137
+ }
138
+ try {
139
+ const resolvedDir = await realpath(dirname(filePath));
140
+ const resolvedFile = await realpath(filePath);
141
+ const rel = relative(resolvedDir, resolvedFile);
142
+ if (rel.startsWith(".." + sep) || rel === "..") {
143
+ this.logger.warn(
144
+ `Skipping prompt file '${filePath}': path traversal attempt detected (resolved outside directory)`
145
+ );
146
+ return null;
147
+ }
148
+ } catch (realpathError) {
149
+ this.logger.warn(
150
+ `Skipping prompt file '${filePath}': unable to resolve path (${realpathError instanceof Error ? realpathError.message : String(realpathError)})`
151
+ );
152
+ return null;
153
+ }
154
+ try {
155
+ const rawContent = await readFile(filePath, "utf-8");
156
+ const parsed = this.parseMarkdownPrompt(rawContent, filePath);
157
+ try {
158
+ assertValidPromptName(parsed.id, {
159
+ context: `file prompt '${filePath}'`,
160
+ hint: "Use kebab-case in the 'id:' frontmatter field or file name."
161
+ });
162
+ } catch (validationError) {
163
+ this.logger.warn(
164
+ `Invalid prompt name in '${filePath}': ${validationError instanceof Error ? validationError.message : String(validationError)}`
165
+ );
166
+ return null;
167
+ }
168
+ const promptInfo = {
169
+ name: `config:${parsed.id}`,
170
+ title: parsed.title,
171
+ description: parsed.description,
172
+ source: "config",
173
+ ...parsed.arguments && { arguments: parsed.arguments },
174
+ metadata: {
175
+ type: "file",
176
+ filePath,
177
+ category: parsed.category,
178
+ priority: parsed.priority,
179
+ showInStarters: prompt.showInStarters,
180
+ originalId: parsed.id
181
+ }
182
+ };
183
+ return { info: promptInfo, content: parsed.content };
184
+ } catch (error) {
185
+ this.logger.warn(
186
+ `Failed to read prompt file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
187
+ );
188
+ return null;
189
+ }
190
+ }
191
+ parseMarkdownPrompt(rawContent, filePath) {
192
+ const lines = rawContent.trim().split("\n");
193
+ const fileName = filePath.split("/").pop()?.replace(/\.md$/, "") ?? "unknown";
194
+ let id = fileName;
195
+ let title = fileName;
196
+ let description = `File prompt: ${fileName}`;
197
+ let category;
198
+ let priority;
199
+ let argumentHint;
200
+ let contentBody;
201
+ if (lines[0]?.trim() === "---") {
202
+ let frontmatterEnd = 0;
203
+ for (let i = 1; i < lines.length; i++) {
204
+ if (lines[i]?.trim() === "---") {
205
+ frontmatterEnd = i;
206
+ break;
207
+ }
208
+ }
209
+ if (frontmatterEnd > 0) {
210
+ const frontmatterLines = lines.slice(1, frontmatterEnd);
211
+ contentBody = lines.slice(frontmatterEnd + 1).join("\n");
212
+ for (const line of frontmatterLines) {
213
+ const match = (key) => {
214
+ const regex = new RegExp(`${key}:\\s*(?:['"](.+)['"]|(.+))`);
215
+ const m = line.match(regex);
216
+ return m ? (m[1] || m[2] || "").trim() : null;
217
+ };
218
+ if (line.includes("id:")) {
219
+ const val = match("id");
220
+ if (val) id = val;
221
+ } else if (line.includes("title:")) {
222
+ const val = match("title");
223
+ if (val) title = val;
224
+ } else if (line.includes("description:")) {
225
+ const val = match("description");
226
+ if (val) description = val;
227
+ } else if (line.includes("category:")) {
228
+ const val = match("category");
229
+ if (val) category = val;
230
+ } else if (line.includes("priority:")) {
231
+ const val = match("priority");
232
+ if (val) priority = parseInt(val, 10);
233
+ } else if (line.includes("argument-hint:")) {
234
+ const val = match("argument-hint");
235
+ if (val) argumentHint = val;
236
+ }
237
+ }
238
+ } else {
239
+ contentBody = rawContent;
240
+ }
241
+ } else {
242
+ contentBody = rawContent;
243
+ }
244
+ if (title === fileName) {
245
+ for (const line of contentBody.trim().split("\n")) {
246
+ if (line.trim().startsWith("#")) {
247
+ title = line.trim().replace(/^#+\s*/, "");
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ const parsedArguments = argumentHint ? this.parseArgumentHint(argumentHint) : void 0;
253
+ return {
254
+ id,
255
+ title,
256
+ description,
257
+ content: contentBody.trim(),
258
+ ...category !== void 0 && { category },
259
+ ...priority !== void 0 && { priority },
260
+ ...parsedArguments !== void 0 && { arguments: parsedArguments }
261
+ };
262
+ }
263
+ parseArgumentHint(hint) {
264
+ const args = [];
265
+ const argPattern = /\[([^\]]+)\]/g;
266
+ let match;
267
+ while ((match = argPattern.exec(hint)) !== null) {
268
+ const argText = match[1];
269
+ if (!argText) continue;
270
+ const isOptional = argText.endsWith("?");
271
+ const name = isOptional ? argText.slice(0, -1).trim() : argText.trim();
272
+ if (name) {
273
+ args.push({
274
+ name,
275
+ required: !isOptional
276
+ });
277
+ }
278
+ }
279
+ return args;
280
+ }
281
+ applyArguments(content, args) {
282
+ const detectionTarget = content.replaceAll("$$", "");
283
+ const usesPositionalPlaceholders = /\$[1-9](?!\d)/.test(detectionTarget) || detectionTarget.includes("$ARGUMENTS");
284
+ const expanded = expandPlaceholders(content, args).trim();
285
+ if (!args || typeof args !== "object" || Object.keys(args).length === 0) {
286
+ return expanded;
287
+ }
288
+ if (!usesPositionalPlaceholders) {
289
+ if (args._context) {
290
+ const contextString = String(args._context);
291
+ return `${expanded}
292
+
293
+ Context: ${contextString}`;
294
+ }
295
+ const argEntries = Object.entries(args).filter(([key]) => !key.startsWith("_"));
296
+ if (argEntries.length > 0) {
297
+ const formattedArgs = argEntries.map(([key, value]) => `${key}: ${value}`).join(", ");
298
+ return `${expanded}
299
+
300
+ Arguments: ${formattedArgs}`;
301
+ }
302
+ }
303
+ return expanded;
304
+ }
305
+ }
306
+ export {
307
+ ConfigPromptProvider
308
+ };
@@ -18,37 +18,56 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var schemas_exports = {};
20
20
  __export(schemas_exports, {
21
- StarterPromptsSchema: () => StarterPromptsSchema
21
+ FilePromptSchema: () => FilePromptSchema,
22
+ InlinePromptSchema: () => InlinePromptSchema,
23
+ PromptsSchema: () => PromptsSchema
22
24
  });
23
25
  module.exports = __toCommonJS(schemas_exports);
24
26
  var import_zod = require("zod");
25
27
  var import_name_validation = require("./name-validation.js");
26
- const StarterPromptsSchema = import_zod.z.array(
27
- import_zod.z.object({
28
- id: import_zod.z.string().min(1).max(64).regex(import_name_validation.PROMPT_NAME_REGEX, `Starter prompt id must be ${import_name_validation.PROMPT_NAME_GUIDANCE}`).describe("Kebab-case slug id for the starter prompt (e.g., quick-start)"),
29
- title: import_zod.z.string().optional().describe("Display title for the starter prompt"),
30
- description: import_zod.z.string().optional().default("").describe("Description shown on hover or in the UI"),
31
- prompt: import_zod.z.string().describe("The actual prompt text that gets resolved and sent"),
32
- category: import_zod.z.string().optional().default("general").describe(
33
- "Category for organizing starter prompts (e.g., general, coding, analysis, tools, learning)"
34
- ),
35
- priority: import_zod.z.number().optional().default(0).describe("Higher numbers appear first")
36
- }).strict()
37
- ).superRefine((arr, ctx) => {
28
+ const InlinePromptSchema = import_zod.z.object({
29
+ type: import_zod.z.literal("inline").describe("Inline prompt type"),
30
+ id: import_zod.z.string().min(1).max(64).regex(import_name_validation.PROMPT_NAME_REGEX, `Prompt id must be ${import_name_validation.PROMPT_NAME_GUIDANCE}`).describe("Kebab-case slug id for the prompt (e.g., quick-start)"),
31
+ title: import_zod.z.string().optional().describe("Display title for the prompt"),
32
+ description: import_zod.z.string().optional().default("").describe("Description shown on hover or in the UI"),
33
+ prompt: import_zod.z.string().describe("The actual prompt text"),
34
+ category: import_zod.z.string().optional().default("general").describe("Category for organizing prompts (e.g., general, coding, analysis, tools)"),
35
+ priority: import_zod.z.number().optional().default(0).describe("Higher numbers appear first in the list"),
36
+ showInStarters: import_zod.z.boolean().optional().default(false).describe("Show as a clickable button in WebUI starter prompts")
37
+ }).strict().describe("Inline prompt with text defined directly in config");
38
+ const FilePromptSchema = import_zod.z.object({
39
+ type: import_zod.z.literal("file").describe("File-based prompt type"),
40
+ file: import_zod.z.string().describe(
41
+ "Path to markdown file containing prompt (supports ${{dexto.agent_dir}} template)"
42
+ ),
43
+ showInStarters: import_zod.z.boolean().optional().default(false).describe("Show as a clickable button in WebUI starter prompts")
44
+ }).strict().describe("File-based prompt loaded from a markdown file");
45
+ const PromptsSchema = import_zod.z.array(import_zod.z.discriminatedUnion("type", [InlinePromptSchema, FilePromptSchema])).superRefine((arr, ctx) => {
38
46
  const seen = /* @__PURE__ */ new Map();
39
47
  arr.forEach((p, idx) => {
40
- if (seen.has(p.id)) {
41
- ctx.addIssue({
42
- code: import_zod.z.ZodIssueCode.custom,
43
- message: `Duplicate starterPrompt id: ${p.id}`,
44
- path: ["starterPrompts", idx, "id"]
45
- });
46
- } else {
47
- seen.set(p.id, idx);
48
+ if (p.type === "inline") {
49
+ if (seen.has(p.id)) {
50
+ ctx.addIssue({
51
+ code: import_zod.z.ZodIssueCode.custom,
52
+ message: `Duplicate prompt id: ${p.id}`,
53
+ path: [idx, "id"]
54
+ });
55
+ } else {
56
+ seen.set(p.id, idx);
57
+ }
48
58
  }
49
59
  });
50
- }).transform((arr) => arr.map((p) => ({ ...p, title: p.title ?? p.id.replace(/-/g, " ") }))).default([]).describe("Starter prompts that appear as clickable buttons in the WebUI");
60
+ }).transform(
61
+ (arr) => arr.map((p) => {
62
+ if (p.type === "inline") {
63
+ return { ...p, title: p.title ?? p.id.replace(/-/g, " ") };
64
+ }
65
+ return p;
66
+ })
67
+ ).default([]).describe("Agent prompts - inline text or file-based");
51
68
  // Annotate the CommonJS export names for ESM import in node:
52
69
  0 && (module.exports = {
53
- StarterPromptsSchema
70
+ FilePromptSchema,
71
+ InlinePromptSchema,
72
+ PromptsSchema
54
73
  });
@@ -1,65 +1,174 @@
1
1
  /**
2
2
  * Zod schemas for prompt-related configurations
3
+ *
4
+ * Unified prompt system with discriminated union:
5
+ * - type: 'inline' - Prompt text defined directly in config
6
+ * - type: 'file' - Prompt loaded from a markdown file
7
+ *
8
+ * Both support showInStarters flag to control WebUI button display.
3
9
  */
4
10
  import { z } from 'zod';
5
11
  /**
6
- * Schema for starter prompts configuration
7
- *
8
- * Starter prompts appear as clickable buttons in the WebUI, providing users
9
- * with quick-start templates for common tasks and interactions.
12
+ * Schema for inline prompts - text defined directly in config
10
13
  */
11
- export declare const StarterPromptsSchema: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodObject<{
14
+ export declare const InlinePromptSchema: z.ZodObject<{
15
+ type: z.ZodLiteral<"inline">;
12
16
  id: z.ZodString;
13
17
  title: z.ZodOptional<z.ZodString>;
14
18
  description: z.ZodDefault<z.ZodOptional<z.ZodString>>;
15
19
  prompt: z.ZodString;
16
20
  category: z.ZodDefault<z.ZodOptional<z.ZodString>>;
17
21
  priority: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
22
+ showInStarters: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
18
23
  }, "strict", z.ZodTypeAny, {
19
24
  prompt: string;
20
25
  description: string;
26
+ type: "inline";
21
27
  id: string;
22
28
  priority: number;
23
29
  category: string;
30
+ showInStarters: boolean;
24
31
  title?: string | undefined;
25
32
  }, {
26
33
  prompt: string;
34
+ type: "inline";
27
35
  id: string;
28
36
  description?: string | undefined;
29
37
  title?: string | undefined;
30
38
  priority?: number | undefined;
31
39
  category?: string | undefined;
32
- }>, "many">, {
40
+ showInStarters?: boolean | undefined;
41
+ }>;
42
+ /**
43
+ * Schema for file-based prompts - loaded from markdown files
44
+ */
45
+ export declare const FilePromptSchema: z.ZodObject<{
46
+ type: z.ZodLiteral<"file">;
47
+ file: z.ZodString;
48
+ showInStarters: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
49
+ }, "strict", z.ZodTypeAny, {
50
+ file: string;
51
+ type: "file";
52
+ showInStarters: boolean;
53
+ }, {
54
+ file: string;
55
+ type: "file";
56
+ showInStarters?: boolean | undefined;
57
+ }>;
58
+ /**
59
+ * Unified prompts schema - array of inline or file-based prompts
60
+ * Replaces the old StarterPromptsSchema
61
+ */
62
+ export declare const PromptsSchema: z.ZodDefault<z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
63
+ type: z.ZodLiteral<"inline">;
64
+ id: z.ZodString;
65
+ title: z.ZodOptional<z.ZodString>;
66
+ description: z.ZodDefault<z.ZodOptional<z.ZodString>>;
67
+ prompt: z.ZodString;
68
+ category: z.ZodDefault<z.ZodOptional<z.ZodString>>;
69
+ priority: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
70
+ showInStarters: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
71
+ }, "strict", z.ZodTypeAny, {
33
72
  prompt: string;
34
73
  description: string;
74
+ type: "inline";
35
75
  id: string;
36
76
  priority: number;
37
77
  category: string;
78
+ showInStarters: boolean;
38
79
  title?: string | undefined;
39
- }[], {
80
+ }, {
40
81
  prompt: string;
82
+ type: "inline";
41
83
  id: string;
42
84
  description?: string | undefined;
43
85
  title?: string | undefined;
44
86
  priority?: number | undefined;
45
87
  category?: string | undefined;
46
- }[]>, {
88
+ showInStarters?: boolean | undefined;
89
+ }>, z.ZodObject<{
90
+ type: z.ZodLiteral<"file">;
91
+ file: z.ZodString;
92
+ showInStarters: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
93
+ }, "strict", z.ZodTypeAny, {
94
+ file: string;
95
+ type: "file";
96
+ showInStarters: boolean;
97
+ }, {
98
+ file: string;
99
+ type: "file";
100
+ showInStarters?: boolean | undefined;
101
+ }>]>, "many">, ({
102
+ prompt: string;
103
+ description: string;
104
+ type: "inline";
105
+ id: string;
106
+ priority: number;
107
+ category: string;
108
+ showInStarters: boolean;
109
+ title?: string | undefined;
110
+ } | {
111
+ file: string;
112
+ type: "file";
113
+ showInStarters: boolean;
114
+ })[], ({
115
+ prompt: string;
116
+ type: "inline";
117
+ id: string;
118
+ description?: string | undefined;
119
+ title?: string | undefined;
120
+ priority?: number | undefined;
121
+ category?: string | undefined;
122
+ showInStarters?: boolean | undefined;
123
+ } | {
124
+ file: string;
125
+ type: "file";
126
+ showInStarters?: boolean | undefined;
127
+ })[]>, ({
128
+ file: string;
129
+ type: "file";
130
+ showInStarters: boolean;
131
+ } | {
47
132
  title: string;
48
133
  prompt: string;
49
134
  description: string;
135
+ type: "inline";
50
136
  id: string;
51
137
  priority: number;
52
138
  category: string;
53
- }[], {
139
+ showInStarters: boolean;
140
+ })[], ({
54
141
  prompt: string;
142
+ type: "inline";
55
143
  id: string;
56
144
  description?: string | undefined;
57
145
  title?: string | undefined;
58
146
  priority?: number | undefined;
59
147
  category?: string | undefined;
60
- }[]>>;
148
+ showInStarters?: boolean | undefined;
149
+ } | {
150
+ file: string;
151
+ type: "file";
152
+ showInStarters?: boolean | undefined;
153
+ })[]>>;
154
+ /**
155
+ * Type for a single inline prompt (validated)
156
+ */
157
+ export type ValidatedInlinePrompt = z.output<typeof InlinePromptSchema>;
158
+ /**
159
+ * Type for a single file-based prompt (validated)
160
+ */
161
+ export type ValidatedFilePrompt = z.output<typeof FilePromptSchema>;
162
+ /**
163
+ * Type for a single prompt (either inline or file)
164
+ */
165
+ export type ValidatedPrompt = ValidatedInlinePrompt | ValidatedFilePrompt;
166
+ /**
167
+ * Validated prompts configuration type
168
+ */
169
+ export type ValidatedPromptsConfig = z.output<typeof PromptsSchema>;
61
170
  /**
62
- * Validated starter prompts configuration type
171
+ * Input type for prompts configuration (before validation)
63
172
  */
64
- export type ValidatedStarterPromptsConfig = z.output<typeof StarterPromptsSchema>;
173
+ export type PromptsConfig = z.input<typeof PromptsSchema>;
65
174
  //# sourceMappingURL=schemas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/prompts/schemas.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4C6C,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/prompts/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCoC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAeiC,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA6BgC,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
@@ -1,31 +1,48 @@
1
1
  import "../chunk-C6A6W6XS.js";
2
2
  import { z } from "zod";
3
3
  import { PROMPT_NAME_REGEX, PROMPT_NAME_GUIDANCE } from "./name-validation.js";
4
- const StarterPromptsSchema = z.array(
5
- z.object({
6
- id: z.string().min(1).max(64).regex(PROMPT_NAME_REGEX, `Starter prompt id must be ${PROMPT_NAME_GUIDANCE}`).describe("Kebab-case slug id for the starter prompt (e.g., quick-start)"),
7
- title: z.string().optional().describe("Display title for the starter prompt"),
8
- description: z.string().optional().default("").describe("Description shown on hover or in the UI"),
9
- prompt: z.string().describe("The actual prompt text that gets resolved and sent"),
10
- category: z.string().optional().default("general").describe(
11
- "Category for organizing starter prompts (e.g., general, coding, analysis, tools, learning)"
12
- ),
13
- priority: z.number().optional().default(0).describe("Higher numbers appear first")
14
- }).strict()
15
- ).superRefine((arr, ctx) => {
4
+ const InlinePromptSchema = z.object({
5
+ type: z.literal("inline").describe("Inline prompt type"),
6
+ id: z.string().min(1).max(64).regex(PROMPT_NAME_REGEX, `Prompt id must be ${PROMPT_NAME_GUIDANCE}`).describe("Kebab-case slug id for the prompt (e.g., quick-start)"),
7
+ title: z.string().optional().describe("Display title for the prompt"),
8
+ description: z.string().optional().default("").describe("Description shown on hover or in the UI"),
9
+ prompt: z.string().describe("The actual prompt text"),
10
+ category: z.string().optional().default("general").describe("Category for organizing prompts (e.g., general, coding, analysis, tools)"),
11
+ priority: z.number().optional().default(0).describe("Higher numbers appear first in the list"),
12
+ showInStarters: z.boolean().optional().default(false).describe("Show as a clickable button in WebUI starter prompts")
13
+ }).strict().describe("Inline prompt with text defined directly in config");
14
+ const FilePromptSchema = z.object({
15
+ type: z.literal("file").describe("File-based prompt type"),
16
+ file: z.string().describe(
17
+ "Path to markdown file containing prompt (supports ${{dexto.agent_dir}} template)"
18
+ ),
19
+ showInStarters: z.boolean().optional().default(false).describe("Show as a clickable button in WebUI starter prompts")
20
+ }).strict().describe("File-based prompt loaded from a markdown file");
21
+ const PromptsSchema = z.array(z.discriminatedUnion("type", [InlinePromptSchema, FilePromptSchema])).superRefine((arr, ctx) => {
16
22
  const seen = /* @__PURE__ */ new Map();
17
23
  arr.forEach((p, idx) => {
18
- if (seen.has(p.id)) {
19
- ctx.addIssue({
20
- code: z.ZodIssueCode.custom,
21
- message: `Duplicate starterPrompt id: ${p.id}`,
22
- path: ["starterPrompts", idx, "id"]
23
- });
24
- } else {
25
- seen.set(p.id, idx);
24
+ if (p.type === "inline") {
25
+ if (seen.has(p.id)) {
26
+ ctx.addIssue({
27
+ code: z.ZodIssueCode.custom,
28
+ message: `Duplicate prompt id: ${p.id}`,
29
+ path: [idx, "id"]
30
+ });
31
+ } else {
32
+ seen.set(p.id, idx);
33
+ }
26
34
  }
27
35
  });
28
- }).transform((arr) => arr.map((p) => ({ ...p, title: p.title ?? p.id.replace(/-/g, " ") }))).default([]).describe("Starter prompts that appear as clickable buttons in the WebUI");
36
+ }).transform(
37
+ (arr) => arr.map((p) => {
38
+ if (p.type === "inline") {
39
+ return { ...p, title: p.title ?? p.id.replace(/-/g, " ") };
40
+ }
41
+ return p;
42
+ })
43
+ ).default([]).describe("Agent prompts - inline text or file-based");
29
44
  export {
30
- StarterPromptsSchema
45
+ FilePromptSchema,
46
+ InlinePromptSchema,
47
+ PromptsSchema
31
48
  };
@@ -22,7 +22,7 @@ export interface PromptDefinition {
22
22
  * Enhanced prompt info with MCP-compliant structure
23
23
  */
24
24
  export interface PromptInfo extends PromptDefinition {
25
- source: 'mcp' | 'file' | 'starter' | 'custom';
25
+ source: 'mcp' | 'config' | 'custom';
26
26
  metadata?: Record<string, unknown>;
27
27
  }
28
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prompts/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAChD,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,SAAS,IAAI,MAAM,CAAC;IAEpB;;OAEG;IACH,eAAe,IAAI,IAAI,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAElF;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACvE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prompts/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,gBAAgB;IAChD,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B;;OAEG;IACH,SAAS,IAAI,MAAM,CAAC;IAEpB;;OAEG;IACH,eAAe,IAAI,IAAI,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAElF;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACvE"}