@happyvertical/smrt-prompts 0.37.2 → 0.37.4

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/dist/index.js CHANGED
@@ -1,784 +1,635 @@
1
- import { ObjectRegistry, field, smrt, SmrtObject, SmrtCollection } from "@happyvertical/smrt-core";
1
+ import { ObjectRegistry, SmrtCollection, SmrtObject, field, smrt } from "@happyvertical/smrt-core";
2
2
  import { getPackageConfig } from "@happyvertical/smrt-config";
3
3
  import { getTenantId } from "@happyvertical/smrt-tenancy";
4
- ObjectRegistry.registerPackageManifest(
5
- new URL("./manifest.json", import.meta.url)
6
- );
7
- const PROMPT_CACHE_TTL_MS = 3e4;
8
- const promptCache = /* @__PURE__ */ new Map();
9
- const dbInstanceIds = /* @__PURE__ */ new WeakMap();
10
- let nextDbId = 1;
4
+ //#region \0rolldown/runtime.js
5
+ var __defProp$1 = Object.defineProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp$1(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp$1(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ //#endregion
16
+ //#region src/__smrt-register__.ts
17
+ ObjectRegistry.registerPackageManifest(new URL("./manifest.json", "" + import.meta.url));
18
+ //#endregion
19
+ //#region src/cache.ts
20
+ var PROMPT_CACHE_TTL_MS = 3e4;
21
+ var promptCache = /* @__PURE__ */ new Map();
22
+ var dbInstanceIds = /* @__PURE__ */ new WeakMap();
23
+ var nextDbId = 1;
11
24
  function getDbNamespace(db) {
12
- if (!db) {
13
- return "no-db";
14
- }
15
- if (typeof db === "string") {
16
- return `db:${db}`;
17
- }
18
- if (typeof db === "object") {
19
- const dbObject = db;
20
- if (typeof dbObject.query === "function") {
21
- if (!dbInstanceIds.has(dbObject)) {
22
- dbInstanceIds.set(dbObject, `db-instance:${nextDbId++}`);
23
- }
24
- const namespace = dbInstanceIds.get(dbObject);
25
- if (namespace) {
26
- return namespace;
27
- }
28
- return "db-instance:unknown";
29
- }
30
- try {
31
- return `db-config:${JSON.stringify(dbObject)}`;
32
- } catch {
33
- return "db-config:opaque";
34
- }
35
- }
36
- return "db:unknown";
25
+ if (!db) return "no-db";
26
+ if (typeof db === "string") return `db:${db}`;
27
+ if (typeof db === "object") {
28
+ const dbObject = db;
29
+ if (typeof dbObject.query === "function") {
30
+ if (!dbInstanceIds.has(dbObject)) dbInstanceIds.set(dbObject, `db-instance:${nextDbId++}`);
31
+ const namespace = dbInstanceIds.get(dbObject);
32
+ if (namespace) return namespace;
33
+ return "db-instance:unknown";
34
+ }
35
+ try {
36
+ return `db-config:${JSON.stringify(dbObject)}`;
37
+ } catch {
38
+ return "db-config:opaque";
39
+ }
40
+ }
41
+ return "db:unknown";
37
42
  }
38
43
  function buildCacheKey(key, tenantId, db) {
39
- return `${getDbNamespace(db)}::${key}::${tenantId ?? "app"}`;
44
+ return `${getDbNamespace(db)}::${key}::${tenantId ?? "app"}`;
40
45
  }
41
46
  function getPromptCacheTtlMs() {
42
- return PROMPT_CACHE_TTL_MS;
47
+ return PROMPT_CACHE_TTL_MS;
43
48
  }
44
49
  function getCachedPromptBase(key, tenantId, db) {
45
- const cacheKey = buildCacheKey(key, tenantId, db);
46
- const cached = promptCache.get(cacheKey);
47
- if (!cached) {
48
- return null;
49
- }
50
- if (cached.expiresAt <= Date.now()) {
51
- promptCache.delete(cacheKey);
52
- return null;
53
- }
54
- return cached.value;
50
+ const cacheKey = buildCacheKey(key, tenantId, db);
51
+ const cached = promptCache.get(cacheKey);
52
+ if (!cached) return null;
53
+ if (cached.expiresAt <= Date.now()) {
54
+ promptCache.delete(cacheKey);
55
+ return null;
56
+ }
57
+ return cached.value;
55
58
  }
56
59
  function setCachedPromptBase(key, tenantId, db, value) {
57
- promptCache.set(buildCacheKey(key, tenantId, db), {
58
- expiresAt: Date.now() + PROMPT_CACHE_TTL_MS,
59
- value
60
- });
60
+ promptCache.set(buildCacheKey(key, tenantId, db), {
61
+ expiresAt: Date.now() + PROMPT_CACHE_TTL_MS,
62
+ value
63
+ });
61
64
  }
62
65
  function invalidatePromptCache(key, tenantId, db) {
63
- const dbNamespace = getDbNamespace(db);
64
- if (tenantId !== null && tenantId !== void 0) {
65
- promptCache.delete(buildCacheKey(key, tenantId, db));
66
- return;
67
- }
68
- const keyPrefix = `${dbNamespace}::${key}::`;
69
- for (const cacheKey of promptCache.keys()) {
70
- if (cacheKey.startsWith(keyPrefix)) {
71
- promptCache.delete(cacheKey);
72
- }
73
- }
66
+ const dbNamespace = getDbNamespace(db);
67
+ if (tenantId !== null && tenantId !== void 0) {
68
+ promptCache.delete(buildCacheKey(key, tenantId, db));
69
+ return;
70
+ }
71
+ const keyPrefix = `${dbNamespace}::${key}::`;
72
+ for (const cacheKey of promptCache.keys()) if (cacheKey.startsWith(keyPrefix)) promptCache.delete(cacheKey);
74
73
  }
75
74
  function clearPromptCache() {
76
- promptCache.clear();
77
- }
78
- const DEFAULT_EDITABLE = {
79
- template: false,
80
- profile: false,
81
- model: false,
82
- params: false
75
+ promptCache.clear();
76
+ }
77
+ //#endregion
78
+ //#region src/utils.ts
79
+ var DEFAULT_EDITABLE = {
80
+ template: false,
81
+ profile: false,
82
+ model: false,
83
+ params: false
83
84
  };
84
- const TOP_LEVEL_RESERVED_KEYS = /* @__PURE__ */ new Set([
85
- "key",
86
- "editable",
87
- "template",
88
- "ai",
89
- "profile",
90
- "provider",
91
- "model",
92
- "params",
93
- "temperature",
94
- "maxTokens"
85
+ var TOP_LEVEL_RESERVED_KEYS = /* @__PURE__ */ new Set([
86
+ "key",
87
+ "editable",
88
+ "template",
89
+ "ai",
90
+ "profile",
91
+ "provider",
92
+ "model",
93
+ "params",
94
+ "temperature",
95
+ "maxTokens"
95
96
  ]);
96
- const AI_RESERVED_KEYS = /* @__PURE__ */ new Set([
97
- "profile",
98
- "provider",
99
- "model",
100
- "params",
101
- "temperature",
102
- "maxTokens"
97
+ var AI_RESERVED_KEYS = /* @__PURE__ */ new Set([
98
+ "profile",
99
+ "provider",
100
+ "model",
101
+ "params",
102
+ "temperature",
103
+ "maxTokens"
103
104
  ]);
104
- const AI_ROUTING_PARAM_KEYS = /* @__PURE__ */ new Set([
105
- "profile",
106
- "provider",
107
- "type",
108
- "model",
109
- "defaultModel"
105
+ var AI_ROUTING_PARAM_KEYS = /* @__PURE__ */ new Set([
106
+ "profile",
107
+ "provider",
108
+ "type",
109
+ "model",
110
+ "defaultModel"
110
111
  ]);
111
112
  function isPlainObject(value) {
112
- return !!value && typeof value === "object" && !Array.isArray(value);
113
+ return !!value && typeof value === "object" && !Array.isArray(value);
113
114
  }
114
115
  function normalizeEditableConfig(editable) {
115
- return {
116
- template: editable?.template ?? DEFAULT_EDITABLE.template,
117
- profile: editable?.profile ?? DEFAULT_EDITABLE.profile,
118
- model: editable?.model ?? DEFAULT_EDITABLE.model,
119
- params: editable?.params ?? DEFAULT_EDITABLE.params
120
- };
116
+ return {
117
+ template: editable?.template ?? DEFAULT_EDITABLE.template,
118
+ profile: editable?.profile ?? DEFAULT_EDITABLE.profile,
119
+ model: editable?.model ?? DEFAULT_EDITABLE.model,
120
+ params: editable?.params ?? DEFAULT_EDITABLE.params
121
+ };
121
122
  }
122
123
  function extractPromptParams(source, reservedKeys) {
123
- const params = {};
124
- if (isPlainObject(source.params)) {
125
- Object.assign(params, sanitizePromptParams(source.params));
126
- }
127
- if ("temperature" in source && source.temperature !== void 0) {
128
- params.temperature = source.temperature;
129
- }
130
- if ("maxTokens" in source && source.maxTokens !== void 0) {
131
- params.maxTokens = source.maxTokens;
132
- }
133
- for (const [key, value] of Object.entries(source)) {
134
- if (reservedKeys.has(key) || value === void 0) {
135
- continue;
136
- }
137
- assignPromptParam(params, key, value);
138
- }
139
- return params;
124
+ const params = {};
125
+ if (isPlainObject(source.params)) Object.assign(params, sanitizePromptParams(source.params));
126
+ if ("temperature" in source && source.temperature !== void 0) params.temperature = source.temperature;
127
+ if ("maxTokens" in source && source.maxTokens !== void 0) params.maxTokens = source.maxTokens;
128
+ for (const [key, value] of Object.entries(source)) {
129
+ if (reservedKeys.has(key) || value === void 0) continue;
130
+ assignPromptParam(params, key, value);
131
+ }
132
+ return params;
140
133
  }
141
134
  function assignPromptParam(params, key, value) {
142
- if (AI_ROUTING_PARAM_KEYS.has(key) || value === void 0) {
143
- return;
144
- }
145
- params[key] = value;
135
+ if (AI_ROUTING_PARAM_KEYS.has(key) || value === void 0) return;
136
+ params[key] = value;
146
137
  }
147
138
  function sanitizePromptParams(params) {
148
- const sanitized = {};
149
- if (!params) {
150
- return sanitized;
151
- }
152
- for (const [key, value] of Object.entries(params)) {
153
- assignPromptParam(sanitized, key, value);
154
- }
155
- return sanitized;
139
+ const sanitized = {};
140
+ if (!params) return sanitized;
141
+ for (const [key, value] of Object.entries(params)) assignPromptParam(sanitized, key, value);
142
+ return sanitized;
156
143
  }
157
144
  function mergePromptParams(...paramLayers) {
158
- const merged = {};
159
- for (const layer of paramLayers) {
160
- if (!layer) {
161
- continue;
162
- }
163
- for (const [key, value] of Object.entries(layer)) {
164
- assignPromptParam(merged, key, value);
165
- }
166
- }
167
- return merged;
145
+ const merged = {};
146
+ for (const layer of paramLayers) {
147
+ if (!layer) continue;
148
+ for (const [key, value] of Object.entries(layer)) assignPromptParam(merged, key, value);
149
+ }
150
+ return merged;
168
151
  }
169
152
  function normalizeAIInput(ai) {
170
- if (!isPlainObject(ai)) {
171
- return { params: {} };
172
- }
173
- const profile = typeof ai.profile === "string" || ai.profile === null ? ai.profile : void 0;
174
- const model = typeof ai.model === "string" || ai.model === null ? ai.model : void 0;
175
- return {
176
- profile: profile ?? void 0,
177
- model: model ?? void 0,
178
- params: extractPromptParams(ai, AI_RESERVED_KEYS)
179
- };
153
+ if (!isPlainObject(ai)) return { params: {} };
154
+ const profile = typeof ai.profile === "string" || ai.profile === null ? ai.profile : void 0;
155
+ const model = typeof ai.model === "string" || ai.model === null ? ai.model : void 0;
156
+ return {
157
+ profile: profile ?? void 0,
158
+ model: model ?? void 0,
159
+ params: extractPromptParams(ai, AI_RESERVED_KEYS)
160
+ };
180
161
  }
181
162
  function normalizePromptDefinitionInput(input) {
182
- return {
183
- key: input.key,
184
- template: input.template,
185
- ai: normalizeAIInput(input.ai),
186
- editable: normalizeEditableConfig(input.editable)
187
- };
163
+ return {
164
+ key: input.key,
165
+ template: input.template,
166
+ ai: normalizeAIInput(input.ai),
167
+ editable: normalizeEditableConfig(input.editable)
168
+ };
188
169
  }
189
170
  function normalizePromptLayer(input) {
190
- if (!isPlainObject(input)) {
191
- return {};
192
- }
193
- const nestedAi = isPlainObject(input.ai) ? normalizeAIInput(input.ai) : { params: {} };
194
- const topLevelParams = extractPromptParams(input, TOP_LEVEL_RESERVED_KEYS);
195
- return {
196
- template: input.template === void 0 ? void 0 : input.template === null ? null : String(input.template),
197
- profile: input.profile === void 0 ? nestedAi.profile : input.profile === null ? null : String(input.profile),
198
- model: input.model === void 0 ? nestedAi.model : input.model === null ? null : String(input.model),
199
- params: mergePromptParams(topLevelParams, nestedAi.params)
200
- };
171
+ if (!isPlainObject(input)) return {};
172
+ const nestedAi = isPlainObject(input.ai) ? normalizeAIInput(input.ai) : { params: {} };
173
+ const topLevelParams = extractPromptParams(input, TOP_LEVEL_RESERVED_KEYS);
174
+ return {
175
+ template: input.template === void 0 ? void 0 : input.template === null ? null : String(input.template),
176
+ profile: input.profile === void 0 ? nestedAi.profile : input.profile === null ? null : String(input.profile),
177
+ model: input.model === void 0 ? nestedAi.model : input.model === null ? null : String(input.model),
178
+ params: mergePromptParams(topLevelParams, nestedAi.params)
179
+ };
201
180
  }
202
181
  function mergePromptLayers(...layers) {
203
- let template = "";
204
- let profile;
205
- let model;
206
- let params = {};
207
- for (const layer of layers) {
208
- if (!layer) {
209
- continue;
210
- }
211
- if (layer.template !== void 0 && layer.template !== null) {
212
- template = layer.template;
213
- }
214
- if (layer.profile !== void 0 && layer.profile !== null) {
215
- profile = layer.profile;
216
- }
217
- if (layer.model !== void 0 && layer.model !== null) {
218
- model = layer.model;
219
- }
220
- if (layer.params !== void 0 && layer.params !== null) {
221
- params = mergePromptParams(params, layer.params);
222
- }
223
- }
224
- return {
225
- template,
226
- ai: {
227
- profile,
228
- model,
229
- params
230
- }
231
- };
182
+ let template = "";
183
+ let profile;
184
+ let model;
185
+ let params = {};
186
+ for (const layer of layers) {
187
+ if (!layer) continue;
188
+ if (layer.template !== void 0 && layer.template !== null) template = layer.template;
189
+ if (layer.profile !== void 0 && layer.profile !== null) profile = layer.profile;
190
+ if (layer.model !== void 0 && layer.model !== null) model = layer.model;
191
+ if (layer.params !== void 0 && layer.params !== null) params = mergePromptParams(params, layer.params);
192
+ }
193
+ return {
194
+ template,
195
+ ai: {
196
+ profile,
197
+ model,
198
+ params
199
+ }
200
+ };
232
201
  }
233
202
  function normalizeProfileConfig(profile) {
234
- const source = isPlainObject(profile) ? profile : {};
235
- const params = extractPromptParams(source, /* @__PURE__ */ new Set(["provider", "model"]));
236
- return {
237
- provider: String(profile.provider),
238
- model: String(profile.model),
239
- params
240
- };
203
+ const params = extractPromptParams(isPlainObject(profile) ? profile : {}, /* @__PURE__ */ new Set(["provider", "model"]));
204
+ return {
205
+ provider: String(profile.provider),
206
+ model: String(profile.model),
207
+ params
208
+ };
241
209
  }
242
210
  function validateProfileName(profileName, config) {
243
- if (profileName.trim() === "") {
244
- throw new Error("Prompt profile names cannot be empty");
245
- }
246
- const allowedProfileNames = config.allowedProfileNames;
247
- if (Array.isArray(allowedProfileNames) && !allowedProfileNames.includes(profileName)) {
248
- throw new Error(
249
- `Prompt profile "${profileName}" is not in the allowed profile list`
250
- );
251
- }
252
- if (!config.profiles?.[profileName]) {
253
- throw new Error(`Prompt profile "${profileName}" is not configured`);
254
- }
211
+ if (profileName.trim() === "") throw new Error("Prompt profile names cannot be empty");
212
+ const allowedProfileNames = config.allowedProfileNames;
213
+ if (Array.isArray(allowedProfileNames) && !allowedProfileNames.includes(profileName)) throw new Error(`Prompt profile "${profileName}" is not in the allowed profile list`);
214
+ if (!config.profiles?.[profileName]) throw new Error(`Prompt profile "${profileName}" is not configured`);
255
215
  }
256
216
  function validateModelName(modelName, config) {
257
- if (modelName.trim() === "") {
258
- throw new Error("Prompt model overrides cannot be empty");
259
- }
260
- const allowedModels = config.allowedModels;
261
- if (Array.isArray(allowedModels) && !allowedModels.includes(modelName)) {
262
- throw new Error(
263
- `Prompt model "${modelName}" is not in the allowed model list`
264
- );
265
- }
217
+ if (modelName.trim() === "") throw new Error("Prompt model overrides cannot be empty");
218
+ const allowedModels = config.allowedModels;
219
+ if (Array.isArray(allowedModels) && !allowedModels.includes(modelName)) throw new Error(`Prompt model "${modelName}" is not in the allowed model list`);
266
220
  }
267
221
  function buildResolvedAI(ai, config) {
268
- let provider;
269
- let model = ai.model;
270
- let params = ai.params;
271
- if (ai.profile) {
272
- validateProfileName(ai.profile, config);
273
- const configuredProfile = config.profiles?.[ai.profile];
274
- if (!configuredProfile) {
275
- throw new Error(`Prompt profile "${ai.profile}" is not configured`);
276
- }
277
- const profileConfig = normalizeProfileConfig(configuredProfile);
278
- provider = profileConfig.provider;
279
- model = model ?? profileConfig.model;
280
- params = mergePromptParams(profileConfig.params, params);
281
- }
282
- if (ai.model) {
283
- validateModelName(ai.model, config);
284
- }
285
- if (ai.model && !ai.profile) {
286
- throw new Error(
287
- "Direct prompt model overrides require an effective prompt profile"
288
- );
289
- }
290
- if (model && !ai.model && config.allowedModels) {
291
- validateModelName(model, config);
292
- }
293
- const resolved = {
294
- ...params,
295
- profile: ai.profile,
296
- provider,
297
- model,
298
- ...config.allowedModels ? { allowedModels: [...config.allowedModels] } : {},
299
- params
300
- };
301
- if (typeof params.temperature === "number") {
302
- resolved.temperature = params.temperature;
303
- }
304
- if (typeof params.maxTokens === "number") {
305
- resolved.maxTokens = params.maxTokens;
306
- }
307
- return resolved;
222
+ let provider;
223
+ let model = ai.model;
224
+ let params = ai.params;
225
+ if (ai.profile) {
226
+ validateProfileName(ai.profile, config);
227
+ const configuredProfile = config.profiles?.[ai.profile];
228
+ if (!configuredProfile) throw new Error(`Prompt profile "${ai.profile}" is not configured`);
229
+ const profileConfig = normalizeProfileConfig(configuredProfile);
230
+ provider = profileConfig.provider;
231
+ model = model ?? profileConfig.model;
232
+ params = mergePromptParams(profileConfig.params, params);
233
+ }
234
+ if (ai.model) validateModelName(ai.model, config);
235
+ if (ai.model && !ai.profile) throw new Error("Direct prompt model overrides require an effective prompt profile");
236
+ if (model && !ai.model && config.allowedModels) validateModelName(model, config);
237
+ const resolved = {
238
+ ...params,
239
+ profile: ai.profile,
240
+ provider,
241
+ model,
242
+ ...config.allowedModels ? { allowedModels: [...config.allowedModels] } : {},
243
+ params
244
+ };
245
+ if (typeof params.temperature === "number") resolved.temperature = params.temperature;
246
+ if (typeof params.maxTokens === "number") resolved.maxTokens = params.maxTokens;
247
+ return resolved;
308
248
  }
309
249
  function renderPromptTemplate(template, variables) {
310
- if (!variables || Object.keys(variables).length === 0) {
311
- return template;
312
- }
313
- return template.replace(/\{([^{}]+)\}/g, (_match, rawKey) => {
314
- const key = rawKey.trim();
315
- const value = variables[key];
316
- if (value === void 0 || value === null) {
317
- return "";
318
- }
319
- if (value instanceof Date) {
320
- return value.toISOString();
321
- }
322
- if (Array.isArray(value) || isPlainObject(value)) {
323
- try {
324
- return JSON.stringify(value);
325
- } catch {
326
- return "";
327
- }
328
- }
329
- return String(value);
330
- });
250
+ if (!variables || Object.keys(variables).length === 0) return template;
251
+ return template.replace(/\{([^{}]+)\}/g, (_match, rawKey) => {
252
+ const value = variables[rawKey.trim()];
253
+ if (value === void 0 || value === null) return "";
254
+ if (value instanceof Date) return value.toISOString();
255
+ if (Array.isArray(value) || isPlainObject(value)) try {
256
+ return JSON.stringify(value);
257
+ } catch {
258
+ return "";
259
+ }
260
+ return String(value);
261
+ });
331
262
  }
332
263
  function parsePromptParams(raw) {
333
- if (!raw) {
334
- return {};
335
- }
336
- try {
337
- const parsed = JSON.parse(raw);
338
- return isPlainObject(parsed) ? sanitizePromptParams(parsed) : {};
339
- } catch {
340
- return {};
341
- }
264
+ if (!raw) return {};
265
+ try {
266
+ const parsed = JSON.parse(raw);
267
+ return isPlainObject(parsed) ? sanitizePromptParams(parsed) : {};
268
+ } catch {
269
+ return {};
270
+ }
342
271
  }
343
272
  function serializePromptParams(params) {
344
- if (params === null || params === void 0) {
345
- return null;
346
- }
347
- return JSON.stringify(sanitizePromptParams(params));
273
+ if (params === null || params === void 0) return null;
274
+ return JSON.stringify(sanitizePromptParams(params));
348
275
  }
276
+ //#endregion
277
+ //#region src/prompt-registry.ts
349
278
  function getRegistry() {
350
- if (!globalThis.__smrtPromptRegistry) {
351
- globalThis.__smrtPromptRegistry = /* @__PURE__ */ new Map();
352
- }
353
- return globalThis.__smrtPromptRegistry;
279
+ if (!globalThis.__smrtPromptRegistry) globalThis.__smrtPromptRegistry = /* @__PURE__ */ new Map();
280
+ return globalThis.__smrtPromptRegistry;
354
281
  }
355
282
  function stableStringify(value) {
356
- if (Array.isArray(value)) {
357
- return `[${value.map((item) => stableStringify(item)).join(",")}]`;
358
- }
359
- if (value && typeof value === "object") {
360
- const entries = Object.entries(value).sort(
361
- ([left], [right]) => left.localeCompare(right)
362
- );
363
- return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
364
- }
365
- return JSON.stringify(value);
366
- }
367
- const PromptRegistry = {
368
- register(input) {
369
- if (!input.key || input.key.trim() === "") {
370
- throw new Error("Prompt definitions require a non-empty key");
371
- }
372
- const definition = normalizePromptDefinitionInput(input);
373
- const registry = getRegistry();
374
- const existing = registry.get(definition.key);
375
- if (existing) {
376
- const existingSignature = stableStringify(existing);
377
- const incomingSignature = stableStringify(definition);
378
- if (existingSignature !== incomingSignature) {
379
- throw new Error(
380
- `Prompt "${definition.key}" is already registered with a different definition`
381
- );
382
- }
383
- return existing;
384
- }
385
- registry.set(definition.key, definition);
386
- return definition;
387
- },
388
- get(key) {
389
- return getRegistry().get(key);
390
- },
391
- has(key) {
392
- return getRegistry().has(key);
393
- },
394
- getAll() {
395
- return Array.from(getRegistry().values());
396
- },
397
- clear() {
398
- getRegistry().clear();
399
- }
283
+ if (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(",")}]`;
284
+ if (value && typeof value === "object") return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
285
+ return JSON.stringify(value);
286
+ }
287
+ var PromptRegistry = {
288
+ register(input) {
289
+ if (!input.key || input.key.trim() === "") throw new Error("Prompt definitions require a non-empty key");
290
+ const definition = normalizePromptDefinitionInput(input);
291
+ const registry = getRegistry();
292
+ const existing = registry.get(definition.key);
293
+ if (existing) {
294
+ if (stableStringify(existing) !== stableStringify(definition)) throw new Error(`Prompt "${definition.key}" is already registered with a different definition`);
295
+ return existing;
296
+ }
297
+ registry.set(definition.key, definition);
298
+ return definition;
299
+ },
300
+ get(key) {
301
+ return getRegistry().get(key);
302
+ },
303
+ has(key) {
304
+ return getRegistry().has(key);
305
+ },
306
+ getAll() {
307
+ return Array.from(getRegistry().values());
308
+ },
309
+ clear() {
310
+ getRegistry().clear();
311
+ }
400
312
  };
401
313
  function definePrompt(input) {
402
- return PromptRegistry.register(input);
314
+ return PromptRegistry.register(input);
403
315
  }
316
+ //#endregion
317
+ //#region src/models/PromptOverride.ts
404
318
  var __defProp = Object.defineProperty;
405
319
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
406
320
  var __decorateClass = (decorators, target, key, kind) => {
407
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
408
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
409
- if (decorator = decorators[i])
410
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
411
- if (kind && result) __defProp(target, key, result);
412
- return result;
321
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
322
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
323
+ if (kind && result) __defProp(target, key, result);
324
+ return result;
413
325
  };
414
326
  function getPromptConfig$1() {
415
- return getPackageConfig("prompts", {
416
- profiles: {},
417
- prompts: {}
418
- });
419
- }
420
- let PromptOverride = class extends SmrtObject {
421
- key = "";
422
- tenantId = null;
423
- template = null;
424
- profile = null;
425
- model = null;
426
- params = null;
427
- constructor(options = {}) {
428
- super(options);
429
- if (options.key !== void 0) this.key = options.key;
430
- if (options.tenantId !== void 0) this.tenantId = options.tenantId;
431
- if (options.template !== void 0) this.template = options.template;
432
- if (options.profile !== void 0) this.profile = options.profile;
433
- if (options.model !== void 0) this.model = options.model;
434
- if (options.params !== void 0) {
435
- if (typeof options.params === "string" || options.params === null) {
436
- this.params = options.params;
437
- } else {
438
- this.params = serializePromptParams(options.params);
439
- }
440
- }
441
- }
442
- getParams() {
443
- return parsePromptParams(this.params);
444
- }
445
- setParams(params) {
446
- this.params = serializePromptParams(params);
447
- }
448
- toPromptLayer() {
449
- return {
450
- template: this.template,
451
- profile: this.profile,
452
- model: this.model,
453
- params: this.params === null ? null : this.getParams()
454
- };
455
- }
456
- async save() {
457
- const previousIdentity = await this.getPersistedIdentity();
458
- this.normalizeParamsForPersistence();
459
- await this.validatePromptOverride();
460
- this.context = this.tenantId ?? "__app__";
461
- const identityChanged = previousIdentity && (previousIdentity.key !== this.key || previousIdentity.tenantId !== this.tenantId);
462
- const result = identityChanged && previousIdentity ? await this.saveAfterIdentityChange() : await super.save();
463
- if (identityChanged && previousIdentity) {
464
- invalidatePromptCache(
465
- previousIdentity.key,
466
- previousIdentity.tenantId,
467
- this.db
468
- );
469
- }
470
- invalidatePromptCache(this.key, this.tenantId, this.db);
471
- return result;
472
- }
473
- async saveAfterIdentityChange() {
474
- if (typeof this.db.beginTransaction === "function") {
475
- return this.saveAfterIdentityChangeInTransaction();
476
- }
477
- return this.saveAfterIdentityChangeWithDeferredDelete();
478
- }
479
- async saveAfterIdentityChangeInTransaction() {
480
- const originalDb = this._db;
481
- const originalOptionsDb = this.options.db;
482
- const tx = await this.db.beginTransaction?.();
483
- if (!tx) {
484
- return this.saveAfterIdentityChangeWithDeferredDelete();
485
- }
486
- try {
487
- this._db = tx;
488
- this.options.db = tx;
489
- await super.delete();
490
- const result = await super.save();
491
- await tx.commit();
492
- return result;
493
- } catch (error) {
494
- try {
495
- await tx.rollback();
496
- } catch {
497
- }
498
- throw error;
499
- } finally {
500
- this._db = originalDb;
501
- this.options.db = originalOptionsDb;
502
- }
503
- }
504
- async saveAfterIdentityChangeWithDeferredDelete() {
505
- const previousId = this.id;
506
- if (!previousId) {
507
- return super.save();
508
- }
509
- const replacementId = crypto.randomUUID();
510
- let replacementSaved = false;
511
- this.id = replacementId;
512
- try {
513
- const result = await super.save();
514
- replacementSaved = true;
515
- await this.db.delete(this.tableName, { id: previousId });
516
- return result;
517
- } catch (error) {
518
- if (replacementSaved) {
519
- try {
520
- await this.db.delete(this.tableName, { id: replacementId });
521
- } catch {
522
- }
523
- }
524
- this.id = previousId;
525
- throw error;
526
- }
527
- }
528
- async delete() {
529
- const key = this.key;
530
- const tenantId = this.tenantId;
531
- await super.delete();
532
- invalidatePromptCache(key, tenantId, this.db);
533
- }
534
- async validatePromptOverride() {
535
- if (!this.key || this.key.trim() === "") {
536
- throw new Error("PromptOverride.key is required");
537
- }
538
- const definition = PromptRegistry.get(this.key);
539
- if (!definition) {
540
- throw new Error(`Unknown prompt key "${this.key}"`);
541
- }
542
- const config = getPromptConfig$1();
543
- const editable = definition.editable;
544
- if (this.template !== null && !editable.template) {
545
- throw new Error(`Prompt "${this.key}" does not allow template overrides`);
546
- }
547
- if (this.profile !== null && !editable.profile) {
548
- throw new Error(`Prompt "${this.key}" does not allow profile overrides`);
549
- }
550
- if (this.model !== null && !editable.model) {
551
- throw new Error(`Prompt "${this.key}" does not allow model overrides`);
552
- }
553
- if (this.params !== null && !editable.params) {
554
- throw new Error(`Prompt "${this.key}" does not allow params overrides`);
555
- }
556
- if (this.params !== null) {
557
- try {
558
- const parsed = JSON.parse(this.params);
559
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
560
- throw new Error("Prompt params must be a JSON object");
561
- }
562
- } catch (error) {
563
- throw new Error(
564
- `Prompt "${this.key}" has invalid params JSON: ${error instanceof Error ? error.message : String(error)}`
565
- );
566
- }
567
- }
568
- if (this.profile !== null) {
569
- validateProfileName(this.profile, config);
570
- }
571
- if (this.model !== null) {
572
- validateModelName(this.model, config);
573
- }
574
- const lowerLayers = await this.getLowerPrecedenceLayers();
575
- const currentLayer = this.toPromptLayer();
576
- const merged = mergePromptLayers(...lowerLayers, currentLayer);
577
- if (currentLayer.model && !merged.ai.profile) {
578
- throw new Error(
579
- `Prompt "${this.key}" model overrides require an effective prompt profile`
580
- );
581
- }
582
- }
583
- async getLowerPrecedenceLayers() {
584
- const definition = PromptRegistry.get(this.key);
585
- const config = getPromptConfig$1();
586
- const layers = [];
587
- if (definition) {
588
- layers.push({
589
- template: definition.template,
590
- profile: definition.ai.profile ?? null,
591
- model: definition.ai.model ?? null,
592
- params: definition.ai.params
593
- });
594
- }
595
- layers.push(normalizePromptLayer(config.prompts?.[this.key]));
596
- const { PromptOverrideCollection: PromptOverrideCollection2 } = await Promise.resolve().then(() => PromptOverrideCollection$1);
597
- const collection = await PromptOverrideCollection2.create({
598
- db: this.options.db ?? this.options.persistence
599
- });
600
- if (this.tenantId) {
601
- const appOverride = await collection.getAppOverride(this.key, {
602
- excludeId: this.id ?? void 0
603
- });
604
- if (appOverride) {
605
- layers.push(appOverride.toPromptLayer());
606
- }
607
- }
608
- return layers;
609
- }
610
- normalizeParamsForPersistence() {
611
- const rawParams = this.params;
612
- if (rawParams === null || rawParams === void 0) {
613
- this.params = null;
614
- return;
615
- }
616
- if (typeof rawParams === "string") {
617
- this.params = rawParams;
618
- return;
619
- }
620
- if (typeof rawParams === "object" && !Array.isArray(rawParams)) {
621
- this.params = serializePromptParams(rawParams);
622
- return;
623
- }
624
- throw new Error(
625
- `Prompt "${this.key}" params must be a JSON object or JSON string`
626
- );
627
- }
628
- async getPersistedIdentity() {
629
- if (!this.id) {
630
- return null;
631
- }
632
- const existing = await this.db.get(this.tableName, { id: this.id });
633
- if (!existing) {
634
- return null;
635
- }
636
- return {
637
- key: String(existing.key ?? this.key),
638
- tenantId: existing.tenantId !== void 0 ? existing.tenantId : existing.tenant_id ?? null
639
- };
640
- }
327
+ return getPackageConfig("prompts", {
328
+ profiles: {},
329
+ prompts: {}
330
+ });
331
+ }
332
+ var PromptOverride = class extends SmrtObject {
333
+ key = "";
334
+ tenantId = null;
335
+ template = null;
336
+ profile = null;
337
+ model = null;
338
+ params = null;
339
+ constructor(options = {}) {
340
+ super(options);
341
+ if (options.key !== void 0) this.key = options.key;
342
+ if (options.tenantId !== void 0) this.tenantId = options.tenantId;
343
+ if (options.template !== void 0) this.template = options.template;
344
+ if (options.profile !== void 0) this.profile = options.profile;
345
+ if (options.model !== void 0) this.model = options.model;
346
+ if (options.params !== void 0) if (typeof options.params === "string" || options.params === null) this.params = options.params;
347
+ else this.params = serializePromptParams(options.params);
348
+ }
349
+ getParams() {
350
+ return parsePromptParams(this.params);
351
+ }
352
+ setParams(params) {
353
+ this.params = serializePromptParams(params);
354
+ }
355
+ toPromptLayer() {
356
+ return {
357
+ template: this.template,
358
+ profile: this.profile,
359
+ model: this.model,
360
+ params: this.params === null ? null : this.getParams()
361
+ };
362
+ }
363
+ async save() {
364
+ const previousIdentity = await this.getPersistedIdentity();
365
+ this.normalizeParamsForPersistence();
366
+ await this.validatePromptOverride();
367
+ this.context = this.tenantId ?? "__app__";
368
+ const identityChanged = previousIdentity && (previousIdentity.key !== this.key || previousIdentity.tenantId !== this.tenantId);
369
+ const result = identityChanged && previousIdentity ? await this.saveAfterIdentityChange() : await super.save();
370
+ if (identityChanged && previousIdentity) invalidatePromptCache(previousIdentity.key, previousIdentity.tenantId, this.db);
371
+ invalidatePromptCache(this.key, this.tenantId, this.db);
372
+ return result;
373
+ }
374
+ async saveAfterIdentityChange() {
375
+ if (typeof this.db.beginTransaction === "function") return this.saveAfterIdentityChangeInTransaction();
376
+ return this.saveAfterIdentityChangeWithDeferredDelete();
377
+ }
378
+ async saveAfterIdentityChangeInTransaction() {
379
+ const originalDb = this._db;
380
+ const originalOptionsDb = this.options.db;
381
+ const tx = await this.db.beginTransaction?.();
382
+ if (!tx) return this.saveAfterIdentityChangeWithDeferredDelete();
383
+ try {
384
+ this._db = tx;
385
+ this.options.db = tx;
386
+ await super.delete();
387
+ const result = await super.save();
388
+ await tx.commit();
389
+ return result;
390
+ } catch (error) {
391
+ try {
392
+ await tx.rollback();
393
+ } catch {}
394
+ throw error;
395
+ } finally {
396
+ this._db = originalDb;
397
+ this.options.db = originalOptionsDb;
398
+ }
399
+ }
400
+ async saveAfterIdentityChangeWithDeferredDelete() {
401
+ const previousId = this.id;
402
+ if (!previousId) return super.save();
403
+ const replacementId = crypto.randomUUID();
404
+ let replacementSaved = false;
405
+ this.id = replacementId;
406
+ try {
407
+ const result = await super.save();
408
+ replacementSaved = true;
409
+ await this.db.delete(this.tableName, { id: previousId });
410
+ return result;
411
+ } catch (error) {
412
+ if (replacementSaved) try {
413
+ await this.db.delete(this.tableName, { id: replacementId });
414
+ } catch {}
415
+ this.id = previousId;
416
+ throw error;
417
+ }
418
+ }
419
+ async delete() {
420
+ const key = this.key;
421
+ const tenantId = this.tenantId;
422
+ await super.delete();
423
+ invalidatePromptCache(key, tenantId, this.db);
424
+ }
425
+ async validatePromptOverride() {
426
+ if (!this.key || this.key.trim() === "") throw new Error("PromptOverride.key is required");
427
+ const definition = PromptRegistry.get(this.key);
428
+ if (!definition) throw new Error(`Unknown prompt key "${this.key}"`);
429
+ const config = getPromptConfig$1();
430
+ const editable = definition.editable;
431
+ if (this.template !== null && !editable.template) throw new Error(`Prompt "${this.key}" does not allow template overrides`);
432
+ if (this.profile !== null && !editable.profile) throw new Error(`Prompt "${this.key}" does not allow profile overrides`);
433
+ if (this.model !== null && !editable.model) throw new Error(`Prompt "${this.key}" does not allow model overrides`);
434
+ if (this.params !== null && !editable.params) throw new Error(`Prompt "${this.key}" does not allow params overrides`);
435
+ if (this.params !== null) try {
436
+ const parsed = JSON.parse(this.params);
437
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("Prompt params must be a JSON object");
438
+ } catch (error) {
439
+ throw new Error(`Prompt "${this.key}" has invalid params JSON: ${error instanceof Error ? error.message : String(error)}`);
440
+ }
441
+ if (this.profile !== null) validateProfileName(this.profile, config);
442
+ if (this.model !== null) validateModelName(this.model, config);
443
+ const lowerLayers = await this.getLowerPrecedenceLayers();
444
+ const currentLayer = this.toPromptLayer();
445
+ const merged = mergePromptLayers(...lowerLayers, currentLayer);
446
+ if (currentLayer.model && !merged.ai.profile) throw new Error(`Prompt "${this.key}" model overrides require an effective prompt profile`);
447
+ }
448
+ async getLowerPrecedenceLayers() {
449
+ const definition = PromptRegistry.get(this.key);
450
+ const config = getPromptConfig$1();
451
+ const layers = [];
452
+ if (definition) layers.push({
453
+ template: definition.template,
454
+ profile: definition.ai.profile ?? null,
455
+ model: definition.ai.model ?? null,
456
+ params: definition.ai.params
457
+ });
458
+ layers.push(normalizePromptLayer(config.prompts?.[this.key]));
459
+ const { PromptOverrideCollection } = await Promise.resolve().then(() => PromptOverrideCollection_exports);
460
+ const collection = await PromptOverrideCollection.create({ db: this.options.db ?? this.options.persistence });
461
+ if (this.tenantId) {
462
+ const appOverride = await collection.getAppOverride(this.key, { excludeId: this.id ?? void 0 });
463
+ if (appOverride) layers.push(appOverride.toPromptLayer());
464
+ }
465
+ return layers;
466
+ }
467
+ normalizeParamsForPersistence() {
468
+ const rawParams = this.params;
469
+ if (rawParams === null || rawParams === void 0) {
470
+ this.params = null;
471
+ return;
472
+ }
473
+ if (typeof rawParams === "string") {
474
+ this.params = rawParams;
475
+ return;
476
+ }
477
+ if (typeof rawParams === "object" && !Array.isArray(rawParams)) {
478
+ this.params = serializePromptParams(rawParams);
479
+ return;
480
+ }
481
+ throw new Error(`Prompt "${this.key}" params must be a JSON object or JSON string`);
482
+ }
483
+ async getPersistedIdentity() {
484
+ if (!this.id) return null;
485
+ const existing = await this.db.get(this.tableName, { id: this.id });
486
+ if (!existing) return null;
487
+ return {
488
+ key: String(existing.key ?? this.key),
489
+ tenantId: existing.tenantId !== void 0 ? existing.tenantId : existing.tenant_id ?? null
490
+ };
491
+ }
641
492
  };
642
- __decorateClass([
643
- field({ required: true })
644
- ], PromptOverride.prototype, "key", 2);
645
- __decorateClass([
646
- field({ type: "text", nullable: true })
647
- ], PromptOverride.prototype, "tenantId", 2);
648
- __decorateClass([
649
- field({ type: "text", nullable: true })
650
- ], PromptOverride.prototype, "template", 2);
651
- __decorateClass([
652
- field({ type: "text", nullable: true })
653
- ], PromptOverride.prototype, "profile", 2);
654
- __decorateClass([
655
- field({ type: "text", nullable: true })
656
- ], PromptOverride.prototype, "model", 2);
657
- __decorateClass([
658
- field({ type: "text", nullable: true })
659
- ], PromptOverride.prototype, "params", 2);
660
- PromptOverride = __decorateClass([
661
- smrt({
662
- tableName: "_smrt_prompt_overrides",
663
- conflictColumns: ["key", "context"],
664
- api: { include: ["list", "get", "create", "update", "delete"] },
665
- cli: {
666
- include: ["list", "get", "create", "update", "delete"],
667
- exclude: ["getParams", "setParams", "toPromptLayer"]
668
- },
669
- mcp: { include: [] }
670
- })
671
- ], PromptOverride);
672
- class PromptOverrideCollection extends SmrtCollection {
673
- static _itemClass = PromptOverride;
674
- excludeOverrideId(items, excludeId) {
675
- return items.filter((item) => excludeId ? item.id !== excludeId : true);
676
- }
677
- async getAppOverride(key, options = {}) {
678
- const items = await this.list({ where: { key, tenantId: null } });
679
- return this.excludeOverrideId(items, options.excludeId)[0] ?? null;
680
- }
681
- async getTenantOverride(key, tenantId, options = {}) {
682
- const items = await this.list({ where: { key, tenantId } });
683
- return this.excludeOverrideId(items, options.excludeId)[0] ?? null;
684
- }
685
- async getResolutionLayers(key, tenantId, options = {}) {
686
- const [app, tenant] = await Promise.all([
687
- this.getAppOverride(key, options),
688
- tenantId != null ? this.getTenantOverride(key, tenantId, options) : Promise.resolve(null)
689
- ]);
690
- return {
691
- app,
692
- tenant
693
- };
694
- }
695
- }
696
- const PromptOverrideCollection$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
697
- __proto__: null,
698
- PromptOverrideCollection
699
- }, Symbol.toStringTag, { value: "Module" }));
493
+ __decorateClass([field({ required: true })], PromptOverride.prototype, "key", 2);
494
+ __decorateClass([field({
495
+ type: "text",
496
+ nullable: true
497
+ })], PromptOverride.prototype, "tenantId", 2);
498
+ __decorateClass([field({
499
+ type: "text",
500
+ nullable: true
501
+ })], PromptOverride.prototype, "template", 2);
502
+ __decorateClass([field({
503
+ type: "text",
504
+ nullable: true
505
+ })], PromptOverride.prototype, "profile", 2);
506
+ __decorateClass([field({
507
+ type: "text",
508
+ nullable: true
509
+ })], PromptOverride.prototype, "model", 2);
510
+ __decorateClass([field({
511
+ type: "text",
512
+ nullable: true
513
+ })], PromptOverride.prototype, "params", 2);
514
+ PromptOverride = __decorateClass([smrt({
515
+ tableName: "_smrt_prompt_overrides",
516
+ conflictColumns: ["key", "context"],
517
+ api: { include: [
518
+ "list",
519
+ "get",
520
+ "create",
521
+ "update",
522
+ "delete"
523
+ ] },
524
+ cli: {
525
+ include: [
526
+ "list",
527
+ "get",
528
+ "create",
529
+ "update",
530
+ "delete"
531
+ ],
532
+ exclude: [
533
+ "getParams",
534
+ "setParams",
535
+ "toPromptLayer"
536
+ ]
537
+ },
538
+ mcp: { include: [] }
539
+ })], PromptOverride);
540
+ //#endregion
541
+ //#region src/collections/PromptOverrideCollection.ts
542
+ var PromptOverrideCollection_exports = /* @__PURE__ */ __exportAll({ PromptOverrideCollection: () => PromptOverrideCollection });
543
+ var PromptOverrideCollection = class extends SmrtCollection {
544
+ static _itemClass = PromptOverride;
545
+ excludeOverrideId(items, excludeId) {
546
+ return items.filter((item) => excludeId ? item.id !== excludeId : true);
547
+ }
548
+ async getAppOverride(key, options = {}) {
549
+ const items = await this.list({ where: {
550
+ key,
551
+ tenantId: null
552
+ } });
553
+ return this.excludeOverrideId(items, options.excludeId)[0] ?? null;
554
+ }
555
+ async getTenantOverride(key, tenantId, options = {}) {
556
+ const items = await this.list({ where: {
557
+ key,
558
+ tenantId
559
+ } });
560
+ return this.excludeOverrideId(items, options.excludeId)[0] ?? null;
561
+ }
562
+ async getResolutionLayers(key, tenantId, options = {}) {
563
+ const [app, tenant] = await Promise.all([this.getAppOverride(key, options), tenantId != null ? this.getTenantOverride(key, tenantId, options) : Promise.resolve(null)]);
564
+ return {
565
+ app,
566
+ tenant
567
+ };
568
+ }
569
+ };
570
+ //#endregion
571
+ //#region src/prompt-resolver.ts
700
572
  function getPromptConfig() {
701
- return getPackageConfig("prompts", {
702
- profiles: {},
703
- prompts: {}
704
- });
573
+ return getPackageConfig("prompts", {
574
+ profiles: {},
575
+ prompts: {}
576
+ });
705
577
  }
706
578
  async function loadPromptBase(key, options) {
707
- const definition = PromptRegistry.get(key);
708
- if (!definition) {
709
- throw new Error(`Unknown prompt key "${key}"`);
710
- }
711
- const tenantId = options.tenantId !== void 0 ? options.tenantId : getTenantId() ?? null;
712
- let collection = null;
713
- let cacheDb = options.db;
714
- if (options.db) {
715
- const initializedCollection = await PromptOverrideCollection.create({
716
- db: options.db
717
- });
718
- collection = initializedCollection;
719
- cacheDb = initializedCollection.db;
720
- }
721
- const cached = getCachedPromptBase(key, tenantId, cacheDb);
722
- if (cached) {
723
- return cached;
724
- }
725
- const config = getPromptConfig();
726
- const layers = [
727
- {
728
- template: definition.template,
729
- profile: definition.ai.profile ?? null,
730
- model: definition.ai.model ?? null,
731
- params: definition.ai.params
732
- },
733
- normalizePromptLayer(config.prompts?.[key])
734
- ];
735
- if (collection) {
736
- const stored = await collection.getResolutionLayers(key, tenantId);
737
- if (stored.app) {
738
- layers.push(stored.app.toPromptLayer());
739
- }
740
- if (stored.tenant) {
741
- layers.push(stored.tenant.toPromptLayer());
742
- }
743
- }
744
- const merged = mergePromptLayers(...layers);
745
- const value = {
746
- key,
747
- template: merged.template,
748
- ai: merged.ai
749
- };
750
- setCachedPromptBase(key, tenantId, cacheDb, value);
751
- return value;
579
+ const definition = PromptRegistry.get(key);
580
+ if (!definition) throw new Error(`Unknown prompt key "${key}"`);
581
+ const tenantId = options.tenantId !== void 0 ? options.tenantId : getTenantId() ?? null;
582
+ let collection = null;
583
+ let cacheDb = options.db;
584
+ if (options.db) {
585
+ const initializedCollection = await PromptOverrideCollection.create({ db: options.db });
586
+ collection = initializedCollection;
587
+ cacheDb = initializedCollection.db;
588
+ }
589
+ const cached = getCachedPromptBase(key, tenantId, cacheDb);
590
+ if (cached) return cached;
591
+ const config = getPromptConfig();
592
+ const layers = [{
593
+ template: definition.template,
594
+ profile: definition.ai.profile ?? null,
595
+ model: definition.ai.model ?? null,
596
+ params: definition.ai.params
597
+ }, normalizePromptLayer(config.prompts?.[key])];
598
+ if (collection) {
599
+ const stored = await collection.getResolutionLayers(key, tenantId);
600
+ if (stored.app) layers.push(stored.app.toPromptLayer());
601
+ if (stored.tenant) layers.push(stored.tenant.toPromptLayer());
602
+ }
603
+ const merged = mergePromptLayers(...layers);
604
+ const value = {
605
+ key,
606
+ template: merged.template,
607
+ ai: merged.ai
608
+ };
609
+ setCachedPromptBase(key, tenantId, cacheDb, value);
610
+ return value;
752
611
  }
753
612
  async function resolvePrompt(key, options = {}) {
754
- const config = getPromptConfig();
755
- const base = await loadPromptBase(key, options);
756
- const runtimeOverride = normalizePromptLayer(options.override);
757
- const merged = mergePromptLayers(
758
- {
759
- template: base.template,
760
- profile: base.ai.profile ?? null,
761
- model: base.ai.model ?? null,
762
- params: base.ai.params
763
- },
764
- runtimeOverride
765
- );
766
- return {
767
- key,
768
- template: merged.template,
769
- text: renderPromptTemplate(merged.template, options.variables),
770
- ai: buildResolvedAI(merged.ai, config)
771
- };
772
- }
773
- const PACKAGE_VERSION_INITIALIZED = true;
774
- export {
775
- PACKAGE_VERSION_INITIALIZED,
776
- PromptOverride,
777
- PromptOverrideCollection,
778
- PromptRegistry,
779
- clearPromptCache,
780
- definePrompt,
781
- getPromptCacheTtlMs,
782
- resolvePrompt
783
- };
784
- //# sourceMappingURL=index.js.map
613
+ const config = getPromptConfig();
614
+ const base = await loadPromptBase(key, options);
615
+ const runtimeOverride = normalizePromptLayer(options.override);
616
+ const merged = mergePromptLayers({
617
+ template: base.template,
618
+ profile: base.ai.profile ?? null,
619
+ model: base.ai.model ?? null,
620
+ params: base.ai.params
621
+ }, runtimeOverride);
622
+ return {
623
+ key,
624
+ template: merged.template,
625
+ text: renderPromptTemplate(merged.template, options.variables),
626
+ ai: buildResolvedAI(merged.ai, config)
627
+ };
628
+ }
629
+ //#endregion
630
+ //#region src/index.ts
631
+ var PACKAGE_VERSION_INITIALIZED = true;
632
+ //#endregion
633
+ export { PACKAGE_VERSION_INITIALIZED, PromptOverride, PromptOverrideCollection, PromptRegistry, clearPromptCache, definePrompt, getPromptCacheTtlMs, resolvePrompt };
634
+
635
+ //# sourceMappingURL=index.js.map