@happyvertical/smrt-prompts 0.55.5 → 0.55.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.
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var __exportAll = (all, no_symbols) => {
15
15
  };
16
16
  //#endregion
17
17
  //#region src/__smrt-register__.ts
18
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-prompts","packageVersion":"0.55.5","objects":{"@happyvertical/smrt-prompts:PromptOverrideCollection":{"name":"promptoverridecollection","className":"PromptOverrideCollection","qualifiedName":"@happyvertical/smrt-prompts:PromptOverrideCollection","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts","packageName":"@happyvertical/smrt-prompts","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"getOverrideMapForKeys":{"name":"getOverrideMapForKeys","async":true,"parameters":[{"name":"keys","type":"string[]","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<Map<string, PromptOverride>>","isStatic":false,"isPublic":true},"findByScope":{"name":"findByScope","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"setTemplateOverride":{"name":"setTemplateOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false},{"name":"template","type":"string | null","optional":false,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<PromptOverride>","isStatic":false,"isPublic":true},"removeOverride":{"name":"removeOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<boolean>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"PromptOverride","exportName":"PromptOverrideCollection","collectionExportName":"PromptOverrideCollectionCollection","schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"},"@happyvertical/smrt-prompts:PromptOverride":{"name":"promptoverride","className":"PromptOverride","qualifiedName":"@happyvertical/smrt-prompts:PromptOverride","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts","packageName":"@happyvertical/smrt-prompts","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":false,"_meta":{"nullable":true}},"profile":{"type":"text","required":false,"_meta":{"nullable":true}},"model":{"type":"text","required":false,"_meta":{"nullable":true}},"params":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"getParams":{"name":"getParams","async":false,"parameters":[],"returnType":"PromptParams","isStatic":false,"isPublic":true},"setParams":{"name":"setParams","async":false,"parameters":[{"name":"params","type":"PromptParams | null","optional":false,"unionBranches":[{"type":"PromptParams"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"toPromptLayer":{"name":"toPromptLayer","async":false,"parameters":[],"returnType":"PromptLayer","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","conflictColumns":["key","context"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"PromptOverride","collectionExportName":"PromptOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy"],"stampsConstructors":true}`));
18
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-prompts","packageVersion":"0.55.6","objects":{"@happyvertical/smrt-prompts:PromptOverrideCollection":{"name":"promptoverridecollection","className":"PromptOverrideCollection","qualifiedName":"@happyvertical/smrt-prompts:PromptOverrideCollection","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts","packageName":"@happyvertical/smrt-prompts","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]},{"name":"options","type":"object","optional":true,"memberTypes":["string"]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"getOverrideMapForKeys":{"name":"getOverrideMapForKeys","async":true,"parameters":[{"name":"keys","type":"string[]","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<Map<string, PromptOverride>>","isStatic":false,"isPublic":true},"findByScope":{"name":"findByScope","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<PromptOverride | null>","isStatic":false,"isPublic":true},"setTemplateOverride":{"name":"setTemplateOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false},{"name":"template","type":"string | null","optional":false,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<PromptOverride>","isStatic":false,"isPublic":true},"removeOverride":{"name":"removeOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"scopeType","type":"PromptOverrideScopeType","optional":false},{"name":"scopeId","type":"string","optional":false}],"returnType":"Promise<boolean>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"PromptOverride","exportName":"PromptOverrideCollection","collectionExportName":"PromptOverrideCollectionCollection","schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"},"@happyvertical/smrt-prompts:PromptOverride":{"name":"promptoverride","className":"PromptOverride","qualifiedName":"@happyvertical/smrt-prompts:PromptOverride","collection":"promptoverrides","filePath":"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts","packageName":"@happyvertical/smrt-prompts","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":false,"_meta":{"nullable":true}},"profile":{"type":"text","required":false,"_meta":{"nullable":true}},"model":{"type":"text","required":false,"_meta":{"nullable":true}},"params":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"getParams":{"name":"getParams","async":false,"parameters":[],"returnType":"PromptParams","isStatic":false,"isPublic":true},"setParams":{"name":"setParams","async":false,"parameters":[{"name":"params","type":"PromptParams | null","optional":false,"unionBranches":[{"type":"PromptParams"},{"type":"null"}]}],"returnType":"void","isStatic":false,"isPublic":true},"toPromptLayer":{"name":"toPromptLayer","async":false,"parameters":[],"returnType":"PromptLayer","isStatic":false,"isPublic":true},"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_prompt_overrides","conflictColumns":["key","context"],"api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"PromptOverride","collectionExportName":"PromptOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_prompt_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_prompt_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT,\\n \\"profile\\" TEXT,\\n \\"model\\" TEXT,\\n \\"params\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":false,"unique":false},"profile":{"type":"TEXT","notNull":false,"unique":false},"model":{"type":"TEXT","notNull":false,"unique":false},"params":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_prompt_overrides_key_context_idx","columns":["key","context"],"unique":true},{"name":"_smrt_prompt_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_prompt_overrides_created_at_idx","columns":["created_at"]}],"version":"38f505e7"},"importPath":"@happyvertical/smrt-prompts"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-tenancy"],"stampsConstructors":true}`));
19
19
  //#endregion
20
20
  //#region src/cache.ts
21
21
  var PROMPT_CACHE_TTL_MS = 3e4;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/cache.ts","../src/utils.ts","../src/prompt-registry.ts","../src/models/PromptOverride.ts","../src/collections/PromptOverrideCollection.ts","../src/prompt-override-service.ts","../src/prompt-resolver.ts","../src/prompt-settings.ts","../src/index.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"packageVersion\\\":\\\"0.55.5\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-prompts:PromptOverrideCollection\\\":{\\\"name\\\":\\\"promptoverridecollection\\\",\\\"className\\\":\\\"PromptOverrideCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-prompts:PromptOverrideCollection\\\",\\\"collection\\\":\\\"promptoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getAppOverride\\\":{\\\"name\\\":\\\"getAppOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTenantOverride\\\":{\\\"name\\\":\\\"getTenantOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getResolutionLayers\\\":{\\\"name\\\":\\\"getResolutionLayers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":true,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOverrideMapForKeys\\\":{\\\"name\\\":\\\"getOverrideMapForKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"keys\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Map<string, PromptOverride>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByScope\\\":{\\\"name\\\":\\\"findByScope\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTemplateOverride\\\":{\\\"name\\\":\\\"setTemplateOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"template\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":false,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"Promise<PromptOverride>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeOverride\\\":{\\\"name\\\":\\\"removeOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"PromptOverride\\\",\\\"exportName\\\":\\\"PromptOverrideCollection\\\",\\\"collectionExportName\\\":\\\"PromptOverrideCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_prompt_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT,\\\\n \\\\\\\"profile\\\\\\\" TEXT,\\\\n \\\\\\\"model\\\\\\\" TEXT,\\\\n \\\\\\\"params\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"params\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_prompt_overrides_key_context_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_prompt_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_prompt_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"38f505e7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-prompts\\\"},\\\"@happyvertical/smrt-prompts:PromptOverride\\\":{\\\"name\\\":\\\"promptoverride\\\",\\\"className\\\":\\\"PromptOverride\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-prompts:PromptOverride\\\",\\\"collection\\\":\\\"promptoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"fields\\\":{\\\"key\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true}},\\\"template\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"profile\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"model\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"params\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"getParams\\\":{\\\"name\\\":\\\"getParams\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"PromptParams\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setParams\\\":{\\\"name\\\":\\\"setParams\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"params\\\",\\\"type\\\":\\\"PromptParams | null\\\",\\\"optional\\\":false,\\\"unionBranches\\\":[{\\\"type\\\":\\\"PromptParams\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"toPromptLayer\\\":{\\\"name\\\":\\\"toPromptLayer\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"PromptLayer\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"conflictColumns\\\":[\\\"key\\\",\\\"context\\\"],\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"PromptOverride\\\",\\\"collectionExportName\\\":\\\"PromptOverrideCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"key\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_prompt_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT,\\\\n \\\\\\\"profile\\\\\\\" TEXT,\\\\n \\\\\\\"model\\\\\\\" TEXT,\\\\n \\\\\\\"params\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"params\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_prompt_overrides_key_context_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_prompt_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_prompt_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"38f505e7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-prompts\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"stampsConstructors\\\":true}\"));\n","import type { DatabaseInterface } from '@happyvertical/sql';\nimport type { PromptCacheValue } from './types.js';\n\nconst PROMPT_CACHE_TTL_MS = 30_000;\n\ntype CacheEntry = {\n expiresAt: number;\n value: PromptCacheValue;\n};\n\nconst promptCache = new Map<string, CacheEntry>();\n/** Monotonic per-`(db, key)` invalidation counter; see getPromptCacheGeneration. */\nconst cacheGenerations = new Map<string, number>();\n/**\n * Source of every generation value. Drawing from one counter instead of\n * incrementing each key independently makes a generation unique across every\n * key and every clear, which is what lets `clearedThrough` work as a floor.\n */\nlet nextGeneration = 1;\n/**\n * Floor that `clearPromptCache()` raises for *every* key, including keys with\n * no map entry. A key that has never been invalidated in this process reads as\n * generation 0, so a resolution that captured 0 before a clear would still see\n * 0 after it and write its pre-clear value back — the flush would be silently\n * undone for the rest of the TTL.\n */\nlet clearedThrough = 0;\nconst dbInstanceIds = new WeakMap<object, string>();\nlet nextDbId = 1;\n\nfunction getDbNamespace(db: unknown): string {\n if (!db) {\n return 'no-db';\n }\n\n if (typeof db === 'string') {\n return `db:${db}`;\n }\n\n if (typeof db === 'object') {\n const dbObject = db as Record<string, unknown>;\n if (typeof dbObject.query === 'function') {\n if (!dbInstanceIds.has(dbObject)) {\n dbInstanceIds.set(dbObject, `db-instance:${nextDbId++}`);\n }\n const namespace = dbInstanceIds.get(dbObject);\n if (namespace) {\n return namespace;\n }\n\n return 'db-instance:unknown';\n }\n\n try {\n return `db-config:${JSON.stringify(dbObject)}`;\n } catch {\n return 'db-config:opaque';\n }\n }\n\n return 'db:unknown';\n}\n\nfunction buildCacheKey(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): string {\n return `${getDbNamespace(db)}::${key}::${tenantId ?? 'app'}`;\n}\n\nfunction buildGenerationKey(\n key: string,\n db: DatabaseInterface | unknown,\n): string {\n return `${getDbNamespace(db)}::${key}`;\n}\n\nfunction bumpGeneration(key: string, db: DatabaseInterface | unknown): void {\n cacheGenerations.set(buildGenerationKey(key, db), nextGeneration++);\n}\n\nexport function getPromptCacheTtlMs(): number {\n return PROMPT_CACHE_TTL_MS;\n}\n\nexport function getCachedPromptBase(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): PromptCacheValue | null {\n const cacheKey = buildCacheKey(key, tenantId, db);\n const cached = promptCache.get(cacheKey);\n\n if (!cached) {\n return null;\n }\n\n if (cached.expiresAt <= Date.now()) {\n promptCache.delete(cacheKey);\n return null;\n }\n\n return cached.value;\n}\n\n/**\n * Reads the current invalidation generation for a key.\n *\n * A resolution captures this *before* its asynchronous layer loads and hands\n * it back to {@link setCachedPromptBase}. Any write that lands while those\n * loads are in flight bumps the generation, so the in-flight resolution —\n * which read the pre-write layers — is refused the cache write instead of\n * repopulating the key it just invalidated. Without this, a read that raced a\n * write served the pre-write value for the full TTL, and a raced `delete()`\n * resurrected the deleted override.\n *\n * Tracked per `(db, key)` rather than per `(db, key, tenantId)`: an app-level\n * row is inherited by every tenant, so a write to any scope of a key must\n * invalidate every scope of it. This matches the coarsest fan-out of\n * {@link invalidatePromptCache}.\n *\n * A key with no entry of its own reports the {@link clearPromptCache} floor\n * rather than a bare 0, so a clear refuses in-flight writes for keys that have\n * never been invalidated too.\n */\nexport function getPromptCacheGeneration(\n key: string,\n db: DatabaseInterface | unknown,\n): number {\n const generation = cacheGenerations.get(buildGenerationKey(key, db)) ?? 0;\n return generation > clearedThrough ? generation : clearedThrough;\n}\n\nexport function setCachedPromptBase(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n value: PromptCacheValue,\n loadedAtGeneration: number,\n): void {\n if (getPromptCacheGeneration(key, db) !== loadedAtGeneration) {\n // A write landed while this resolution was loading. Its value is already\n // stale, so drop it rather than poison the key for the whole TTL.\n return;\n }\n\n promptCache.set(buildCacheKey(key, tenantId, db), {\n expiresAt: Date.now() + PROMPT_CACHE_TTL_MS,\n value,\n });\n}\n\n/**\n * Invalidates a cached resolution. An app-level write (tenantId null) clears\n * every tenant's entry for that key, because each tenant inherits from it.\n */\nexport function invalidatePromptCache(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): void {\n const dbNamespace = getDbNamespace(db);\n bumpGeneration(key, db);\n\n if (tenantId !== null && tenantId !== undefined) {\n promptCache.delete(buildCacheKey(key, tenantId, db));\n return;\n }\n\n const keyPrefix = `${dbNamespace}::${key}::`;\n for (const cacheKey of promptCache.keys()) {\n if (cacheKey.startsWith(keyPrefix)) {\n promptCache.delete(cacheKey);\n }\n }\n}\n\nexport function clearPromptCache(): void {\n promptCache.clear();\n // Raise the floor instead of resetting counters: a resolution that started\n // before the clear must be refused its write, and raising a single floor\n // covers keys with no generation entry, which a per-key bump cannot reach.\n // With the floor carrying the refusal, the per-key entries can be dropped.\n clearedThrough = nextGeneration++;\n cacheGenerations.clear();\n}\n","import type {\n NormalizedPromptAI,\n PromptAIInput,\n PromptConfigOverrideInput,\n PromptDefinitionInput,\n PromptEditableConfig,\n PromptLayer,\n PromptPackageConfig,\n PromptParams,\n PromptProfileConfig,\n ResolvedPromptAI,\n} from './types.js';\n\nconst DEFAULT_EDITABLE: PromptEditableConfig = {\n template: false,\n profile: false,\n model: false,\n params: false,\n};\n\nconst TOP_LEVEL_RESERVED_KEYS = new Set([\n 'key',\n 'editable',\n 'template',\n 'ai',\n 'profile',\n 'provider',\n 'model',\n 'params',\n 'temperature',\n 'maxTokens',\n]);\n\nconst AI_RESERVED_KEYS = new Set([\n 'profile',\n 'provider',\n 'model',\n 'params',\n 'temperature',\n 'maxTokens',\n]);\n\nconst AI_ROUTING_PARAM_KEYS = new Set([\n 'profile',\n 'provider',\n 'type',\n 'model',\n 'defaultModel',\n]);\n\nexport function isPlainObject(\n value: unknown,\n): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function normalizeEditableConfig(\n editable?: Partial<PromptEditableConfig>,\n): PromptEditableConfig {\n return {\n template: editable?.template ?? DEFAULT_EDITABLE.template,\n profile: editable?.profile ?? DEFAULT_EDITABLE.profile,\n model: editable?.model ?? DEFAULT_EDITABLE.model,\n params: editable?.params ?? DEFAULT_EDITABLE.params,\n };\n}\n\nfunction extractPromptParams(\n source: Record<string, unknown>,\n reservedKeys: Set<string>,\n): PromptParams {\n const params: PromptParams = {};\n\n if (isPlainObject(source.params)) {\n Object.assign(params, sanitizePromptParams(source.params));\n }\n\n if ('temperature' in source && source.temperature !== undefined) {\n params.temperature = source.temperature;\n }\n\n if ('maxTokens' in source && source.maxTokens !== undefined) {\n params.maxTokens = source.maxTokens;\n }\n\n for (const [key, value] of Object.entries(source)) {\n if (reservedKeys.has(key) || value === undefined) {\n continue;\n }\n assignPromptParam(params, key, value);\n }\n\n return params;\n}\n\nfunction assignPromptParam(\n params: PromptParams,\n key: string,\n value: unknown,\n): void {\n if (AI_ROUTING_PARAM_KEYS.has(key) || value === undefined) {\n return;\n }\n\n params[key] = value;\n}\n\nexport function sanitizePromptParams(\n params: PromptParams | null | undefined,\n): PromptParams {\n const sanitized: PromptParams = {};\n\n if (!params) {\n return sanitized;\n }\n\n for (const [key, value] of Object.entries(params)) {\n assignPromptParam(sanitized, key, value);\n }\n\n return sanitized;\n}\n\nexport function mergePromptParams(\n ...paramLayers: Array<PromptParams | null | undefined>\n): PromptParams {\n const merged: PromptParams = {};\n\n for (const layer of paramLayers) {\n if (!layer) {\n continue;\n }\n\n for (const [key, value] of Object.entries(layer)) {\n assignPromptParam(merged, key, value);\n }\n }\n\n return merged;\n}\n\nfunction normalizeAIInput(ai?: PromptAIInput | null): NormalizedPromptAI {\n if (!isPlainObject(ai)) {\n return { params: {} };\n }\n\n const profile =\n typeof ai.profile === 'string' || ai.profile === null\n ? ai.profile\n : undefined;\n const model =\n typeof ai.model === 'string' || ai.model === null ? ai.model : undefined;\n\n return {\n profile: profile ?? undefined,\n model: model ?? undefined,\n params: extractPromptParams(ai, AI_RESERVED_KEYS),\n };\n}\n\nexport function normalizePromptDefinitionInput(input: PromptDefinitionInput): {\n key: string;\n template: string;\n description: string;\n ai: NormalizedPromptAI;\n editable: PromptEditableConfig;\n} {\n return {\n key: input.key,\n template: input.template,\n description: input.description ?? '',\n ai: normalizeAIInput(input.ai),\n editable: normalizeEditableConfig(input.editable),\n };\n}\n\nexport function normalizePromptLayer(\n input?: PromptConfigOverrideInput | null,\n): PromptLayer {\n if (!isPlainObject(input)) {\n return {};\n }\n\n const nestedAi = isPlainObject(input.ai)\n ? normalizeAIInput(input.ai)\n : { params: {} };\n const topLevelParams = extractPromptParams(input, TOP_LEVEL_RESERVED_KEYS);\n\n return {\n template:\n input.template === undefined\n ? undefined\n : input.template === null\n ? null\n : String(input.template),\n profile:\n input.profile === undefined\n ? nestedAi.profile\n : input.profile === null\n ? null\n : String(input.profile),\n model:\n input.model === undefined\n ? nestedAi.model\n : input.model === null\n ? null\n : String(input.model),\n params: mergePromptParams(topLevelParams, nestedAi.params),\n };\n}\n\nexport function mergePromptLayers(\n ...layers: Array<PromptLayer | null | undefined>\n): {\n template: string;\n ai: NormalizedPromptAI;\n} {\n let template = '';\n let profile: string | undefined;\n let model: string | undefined;\n let params: PromptParams = {};\n\n for (const layer of layers) {\n if (!layer) {\n continue;\n }\n\n if (layer.template !== undefined && layer.template !== null) {\n template = layer.template;\n }\n\n if (layer.profile !== undefined && layer.profile !== null) {\n profile = layer.profile;\n }\n\n if (layer.model !== undefined && layer.model !== null) {\n model = layer.model;\n }\n\n if (layer.params !== undefined && layer.params !== null) {\n params = mergePromptParams(params, layer.params);\n }\n }\n\n return {\n template,\n ai: {\n profile,\n model,\n params,\n },\n };\n}\n\nexport function normalizeProfileConfig(profile: PromptProfileConfig): {\n provider: string;\n model: string;\n params: PromptParams;\n} {\n const source = isPlainObject(profile) ? profile : {};\n const params = extractPromptParams(source, new Set(['provider', 'model']));\n\n return {\n provider: String(profile.provider),\n model: String(profile.model),\n params,\n };\n}\n\nexport function validateProfileName(\n profileName: string,\n config: PromptPackageConfig,\n): void {\n if (profileName.trim() === '') {\n throw new Error('Prompt profile names cannot be empty');\n }\n\n const allowedProfileNames = config.allowedProfileNames;\n if (\n Array.isArray(allowedProfileNames) &&\n !allowedProfileNames.includes(profileName)\n ) {\n throw new Error(\n `Prompt profile \"${profileName}\" is not in the allowed profile list`,\n );\n }\n\n if (!config.profiles?.[profileName]) {\n throw new Error(`Prompt profile \"${profileName}\" is not configured`);\n }\n}\n\nexport function validateModelName(\n modelName: string,\n config: PromptPackageConfig,\n): void {\n if (modelName.trim() === '') {\n throw new Error('Prompt model overrides cannot be empty');\n }\n\n const allowedModels = config.allowedModels;\n if (Array.isArray(allowedModels) && !allowedModels.includes(modelName)) {\n throw new Error(\n `Prompt model \"${modelName}\" is not in the allowed model list`,\n );\n }\n}\n\nexport function buildResolvedAI(\n ai: NormalizedPromptAI,\n config: PromptPackageConfig,\n): ResolvedPromptAI {\n let provider: string | undefined;\n let model = ai.model;\n let params = ai.params;\n\n if (ai.profile) {\n validateProfileName(ai.profile, config);\n const configuredProfile = config.profiles?.[ai.profile];\n if (!configuredProfile) {\n throw new Error(`Prompt profile \"${ai.profile}\" is not configured`);\n }\n const profileConfig = normalizeProfileConfig(configuredProfile);\n provider = profileConfig.provider;\n model = model ?? profileConfig.model;\n params = mergePromptParams(profileConfig.params, params);\n }\n\n if (ai.model) {\n validateModelName(ai.model, config);\n }\n\n if (ai.model && !ai.profile) {\n throw new Error(\n 'Direct prompt model overrides require an effective prompt profile',\n );\n }\n\n if (model && !ai.model && config.allowedModels) {\n validateModelName(model, config);\n }\n\n const resolved: ResolvedPromptAI = {\n ...params,\n profile: ai.profile,\n provider,\n model,\n ...(config.allowedModels\n ? { allowedModels: [...config.allowedModels] }\n : {}),\n params,\n };\n\n if (typeof params.temperature === 'number') {\n resolved.temperature = params.temperature;\n }\n\n if (typeof params.maxTokens === 'number') {\n resolved.maxTokens = params.maxTokens;\n }\n\n return resolved;\n}\n\nexport function renderPromptTemplate(\n template: string,\n variables?: Record<string, unknown>,\n): string {\n if (!variables || Object.keys(variables).length === 0) {\n return template;\n }\n\n return template.replace(/\\{([^{}]+)\\}/g, (_match, rawKey: string) => {\n const key = rawKey.trim();\n const value = variables[key];\n\n if (value === undefined || value === null) {\n return '';\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (Array.isArray(value) || isPlainObject(value)) {\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n }\n\n return String(value);\n });\n}\n\nexport function parsePromptParams(\n raw: string | null | undefined,\n): PromptParams {\n if (!raw) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(raw);\n return isPlainObject(parsed) ? sanitizePromptParams(parsed) : {};\n } catch {\n return {};\n }\n}\n\nexport function serializePromptParams(\n params: PromptParams | null | undefined,\n): string | null {\n if (params === null || params === undefined) {\n return null;\n }\n\n return JSON.stringify(sanitizePromptParams(params));\n}\n","import type { PromptDefinition, PromptDefinitionInput } from './types.js';\nimport { normalizePromptDefinitionInput } from './utils.js';\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __smrtPromptRegistry: Map<string, PromptDefinition> | undefined;\n}\n\nfunction getRegistry(): Map<string, PromptDefinition> {\n if (!globalThis.__smrtPromptRegistry) {\n globalThis.__smrtPromptRegistry = new Map<string, PromptDefinition>();\n }\n\n return globalThis.__smrtPromptRegistry;\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item)).join(',')}]`;\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([left], [right]) => left.localeCompare(right),\n );\n return `{${entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)\n .join(',')}}`;\n }\n\n return JSON.stringify(value);\n}\n\nexport const PromptRegistry = {\n register(input: PromptDefinitionInput): PromptDefinition {\n if (!input.key || input.key.trim() === '') {\n throw new Error('Prompt definitions require a non-empty key');\n }\n\n const definition = normalizePromptDefinitionInput(input);\n const registry = getRegistry();\n const existing = registry.get(definition.key);\n\n if (existing) {\n const existingSignature = stableStringify(existing);\n const incomingSignature = stableStringify(definition);\n\n if (existingSignature !== incomingSignature) {\n throw new Error(\n `Prompt \"${definition.key}\" is already registered with a different definition`,\n );\n }\n\n return existing;\n }\n\n registry.set(definition.key, definition);\n return definition;\n },\n\n get(key: string): PromptDefinition | undefined {\n return getRegistry().get(key);\n },\n\n has(key: string): boolean {\n return getRegistry().has(key);\n },\n\n getAll(): PromptDefinition[] {\n return Array.from(getRegistry().values());\n },\n\n clear(): void {\n getRegistry().clear();\n },\n};\n\nexport function definePrompt(input: PromptDefinitionInput): PromptDefinition {\n return PromptRegistry.register(input);\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { invalidatePromptCache } from '../cache.js';\nimport { PromptRegistry } from '../prompt-registry.js';\nimport {\n APP_PROMPT_SCOPE_ID,\n type PromptLayer,\n type PromptPackageConfig,\n type PromptParams,\n} from '../types.js';\nimport {\n mergePromptLayers,\n normalizePromptLayer,\n parsePromptParams,\n serializePromptParams,\n validateModelName,\n validateProfileName,\n} from '../utils.js';\n\nexport interface PromptOverrideOptions extends SmrtObjectOptions {\n key?: string;\n tenantId?: string | null;\n template?: string | null;\n profile?: string | null;\n model?: string | null;\n params?: string | PromptParams | null;\n}\n\ntype PromptOverrideIdentity = {\n key: string;\n tenantId: string | null;\n};\n\ntype PromptTransactionHandle = DatabaseInterface & {\n commit: () => Promise<void>;\n rollback: () => Promise<void>;\n};\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\n// Override rows are authorization state: any scope (app-wide, or another\n// tenant) can be written, and the object is not tenant-scoped by the request\n// context — `tenantId` is an ordinary settable field. Generated REST routes\n// and MCP tools only check authentication, so they are closed (#3013, mirrored\n// from `@happyvertical/smrt-features`). Hosts write overrides server-side\n// through `PromptOverrideService`, which requires an explicit authorizer for\n// every write (or `PromptOverrideCollection.setTemplateOverride()` /\n// `removeOverride()` after their own authorization decision). The CLI is\n// closed too: generated CLI commands dispatch through the generated API.\n@smrt({\n tableName: '_smrt_prompt_overrides',\n conflictColumns: ['key', 'context'],\n api: false,\n cli: false,\n mcp: false,\n})\nexport class PromptOverride extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-prompts\";\n @field({ required: true })\n key: string = '';\n\n // Not tenant-scoped (any scope is writable), but the value is a tenant id:\n // uuid on Postgres, so it compares with every other tenant_id column.\n @field({ sqlType: 'UUID', nullable: true })\n tenantId: string | null = null;\n\n @field({ type: 'text', nullable: true })\n template: string | null = null;\n\n @field({ type: 'text', nullable: true })\n profile: string | null = null;\n\n @field({ type: 'text', nullable: true })\n model: string | null = null;\n\n @field({ type: 'text', nullable: true })\n params: string | null = null;\n\n constructor(options: PromptOverrideOptions = {}) {\n super(options);\n\n if (options.key !== undefined) this.key = options.key;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.template !== undefined) this.template = options.template;\n if (options.profile !== undefined) this.profile = options.profile;\n if (options.model !== undefined) this.model = options.model;\n if (options.params !== undefined) {\n if (typeof options.params === 'string' || options.params === null) {\n this.params = options.params;\n } else {\n this.params = serializePromptParams(options.params);\n }\n }\n }\n\n getParams(): PromptParams {\n return parsePromptParams(this.params);\n }\n\n setParams(params: PromptParams | null): void {\n this.params = serializePromptParams(params);\n }\n\n toPromptLayer(): PromptLayer {\n return {\n template: this.template,\n profile: this.profile,\n model: this.model,\n params: this.params === null ? null : this.getParams(),\n };\n }\n\n override async save(): Promise<this> {\n const previousIdentity = await this.getPersistedIdentity();\n this.normalizeParamsForPersistence();\n await this.validatePromptOverride();\n // Use context as the uniqueness scope so app-level rows remain unique even\n // though tenantId is nullable and would otherwise allow multiple NULL rows.\n this.context = this.tenantId ?? APP_PROMPT_SCOPE_ID;\n const identityChanged =\n previousIdentity &&\n (previousIdentity.key !== this.key ||\n previousIdentity.tenantId !== this.tenantId);\n\n const result =\n identityChanged && previousIdentity\n ? await this.saveAfterIdentityChange()\n : await super.save();\n\n if (identityChanged && previousIdentity) {\n invalidatePromptCache(\n previousIdentity.key,\n previousIdentity.tenantId,\n this.db,\n );\n }\n invalidatePromptCache(this.key, this.tenantId, this.db);\n return result;\n }\n\n private async saveAfterIdentityChange(): Promise<this> {\n if (typeof this.db.beginTransaction === 'function') {\n return this.saveAfterIdentityChangeInTransaction();\n }\n\n return this.saveAfterIdentityChangeWithDeferredDelete();\n }\n\n private async saveAfterIdentityChangeInTransaction(): Promise<this> {\n const originalDb = this._db;\n const originalOptionsDb = this.options.db;\n const tx = (await this.db.beginTransaction?.()) as\n | PromptTransactionHandle\n | undefined;\n\n if (!tx) {\n return this.saveAfterIdentityChangeWithDeferredDelete();\n }\n\n try {\n this._db = tx;\n this.options.db = tx;\n await super.delete();\n const result = await super.save();\n await tx.commit();\n return result;\n } catch (error) {\n try {\n await tx.rollback();\n } catch {\n // Preserve the original save error; rollback failures are secondary.\n }\n throw error;\n } finally {\n this._db = originalDb;\n this.options.db = originalOptionsDb;\n }\n }\n\n private async saveAfterIdentityChangeWithDeferredDelete(): Promise<this> {\n const previousId = this.id;\n if (!previousId) {\n return super.save();\n }\n\n const replacementId = crypto.randomUUID();\n let replacementSaved = false;\n this.id = replacementId;\n\n try {\n const result = await super.save();\n replacementSaved = true;\n await this.db.delete(this.tableName, { id: previousId });\n return result;\n } catch (error) {\n if (replacementSaved) {\n try {\n await this.db.delete(this.tableName, { id: replacementId });\n } catch {\n // Best effort cleanup keeps the original row as the source of truth.\n }\n }\n\n this.id = previousId;\n throw error;\n }\n }\n\n override async delete(): Promise<void> {\n const key = this.key;\n const tenantId = this.tenantId;\n await super.delete();\n invalidatePromptCache(key, tenantId, this.db);\n }\n\n private async validatePromptOverride(): Promise<void> {\n if (!this.key || this.key.trim() === '') {\n throw new Error('PromptOverride.key is required');\n }\n\n const definition = PromptRegistry.get(this.key);\n if (!definition) {\n throw new Error(`Unknown prompt key \"${this.key}\"`);\n }\n\n const config = getPromptConfig();\n const editable = definition.editable;\n\n if (this.template !== null && !editable.template) {\n throw new Error(`Prompt \"${this.key}\" does not allow template overrides`);\n }\n\n if (this.profile !== null && !editable.profile) {\n throw new Error(`Prompt \"${this.key}\" does not allow profile overrides`);\n }\n\n if (this.model !== null && !editable.model) {\n throw new Error(`Prompt \"${this.key}\" does not allow model overrides`);\n }\n\n if (this.params !== null && !editable.params) {\n throw new Error(`Prompt \"${this.key}\" does not allow params overrides`);\n }\n\n if (this.params !== null) {\n try {\n const parsed = JSON.parse(this.params);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('Prompt params must be a JSON object');\n }\n } catch (error) {\n throw new Error(\n `Prompt \"${this.key}\" has invalid params JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (this.profile !== null) {\n validateProfileName(this.profile, config);\n }\n\n if (this.model !== null) {\n validateModelName(this.model, config);\n }\n\n const lowerLayers = await this.getLowerPrecedenceLayers();\n const currentLayer = this.toPromptLayer();\n const merged = mergePromptLayers(...lowerLayers, currentLayer);\n\n if (currentLayer.model && !merged.ai.profile) {\n throw new Error(\n `Prompt \"${this.key}\" model overrides require an effective prompt profile`,\n );\n }\n }\n\n private async getLowerPrecedenceLayers(): Promise<PromptLayer[]> {\n const definition = PromptRegistry.get(this.key);\n const config = getPromptConfig();\n const layers: PromptLayer[] = [];\n\n if (definition) {\n layers.push({\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n });\n }\n\n layers.push(normalizePromptLayer(config.prompts?.[this.key]));\n\n const { PromptOverrideCollection } = await import(\n '../collections/PromptOverrideCollection.js'\n );\n const collection = await PromptOverrideCollection.create({\n db: this.options.db ?? this.options.persistence,\n });\n\n if (this.tenantId) {\n const appOverride = await collection.getAppOverride(this.key, {\n excludeId: this.id ?? undefined,\n });\n if (appOverride) {\n layers.push(appOverride.toPromptLayer());\n }\n }\n\n return layers;\n }\n\n private normalizeParamsForPersistence(): void {\n const rawParams = this.params as unknown;\n\n if (rawParams === null || rawParams === undefined) {\n this.params = null;\n return;\n }\n\n if (typeof rawParams === 'string') {\n this.params = rawParams;\n return;\n }\n\n if (typeof rawParams === 'object' && !Array.isArray(rawParams)) {\n this.params = serializePromptParams(rawParams as PromptParams);\n return;\n }\n\n throw new Error(\n `Prompt \"${this.key}\" params must be a JSON object or JSON string`,\n );\n }\n\n private async getPersistedIdentity(): Promise<PromptOverrideIdentity | null> {\n if (!this.id) {\n return null;\n }\n\n const existing = await this.db.get(this.tableName, { id: this.id });\n if (!existing) {\n return null;\n }\n\n return {\n key: String((existing as Record<string, unknown>).key ?? this.key),\n tenantId:\n (existing as Record<string, unknown>).tenantId !== undefined\n ? ((existing as Record<string, unknown>).tenantId as string | null)\n : (((existing as Record<string, unknown>).tenant_id as\n | string\n | null\n | undefined) ?? null),\n };\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { PromptOverride } from '../models/PromptOverride.js';\nimport type { PromptOverrideScopeType } from '../types.js';\n\nexport class PromptOverrideCollection extends SmrtCollection<PromptOverride> {\n static readonly _itemClass = PromptOverride;\n\n private excludeOverrideId(\n items: PromptOverride[],\n excludeId?: string,\n ): PromptOverride[] {\n return items.filter((item) => (excludeId ? item.id !== excludeId : true));\n }\n\n async getAppOverride(\n key: string,\n options: { excludeId?: string } = {},\n ): Promise<PromptOverride | null> {\n const items = await this.list({ where: { key, tenantId: null } });\n return this.excludeOverrideId(items, options.excludeId)[0] ?? null;\n }\n\n async getTenantOverride(\n key: string,\n tenantId: string,\n options: { excludeId?: string } = {},\n ): Promise<PromptOverride | null> {\n const items = await this.list({ where: { key, tenantId } });\n return this.excludeOverrideId(items, options.excludeId)[0] ?? null;\n }\n\n async getResolutionLayers(\n key: string,\n tenantId?: string | null,\n options: { excludeId?: string } = {},\n ): Promise<{ app: PromptOverride | null; tenant: PromptOverride | null }> {\n const [app, tenant] = await Promise.all([\n this.getAppOverride(key, options),\n tenantId != null\n ? this.getTenantOverride(key, tenantId, options)\n : Promise.resolve(null),\n ]);\n\n return {\n app,\n tenant,\n };\n }\n\n /**\n * The override row for every key in `keys` at one scope, in a single query.\n *\n * Used by `PromptSettingsService.listPromptSettings()` to enumerate the\n * whole registry's override state without one round trip per key. Because\n * this is an enumeration read — a host-configured\n * `defaultListLimit`/`maxListLimit` on the collection's options would\n * silently drop keys past the cap, changing which prompts a management\n * screen reports as overridden, with no error (the #3056 hazard class in\n * `@happyvertical/smrt-features`'s `getOverrideMap`) — callers that need the\n * full map construct this collection through\n * `PromptSettingsService.create()`, which strips those bounds.\n */\n async getOverrideMapForKeys(\n keys: string[],\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<Map<string, PromptOverride>> {\n const result = new Map<string, PromptOverride>();\n if (keys.length === 0) {\n return result;\n }\n\n const tenantId = scopeType === 'app' ? null : scopeId;\n const rows = await this.list({ where: { key: keys, tenantId } });\n for (const row of rows) {\n result.set(row.key, row);\n }\n\n return result;\n }\n\n /** The override row for a scope request, in the vocabulary used at the write boundary. */\n async findByScope(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<PromptOverride | null> {\n return scopeType === 'app'\n ? this.getAppOverride(key)\n : this.getTenantOverride(key, scopeId);\n }\n\n /**\n * Set (or clear, with `template: null`) the `template` field of the override\n * row for one scope, creating the row if it did not exist. Other fields\n * (`profile`, `model`, `params`) on an existing row are left untouched, per\n * this package's field-by-field inheritance model.\n */\n async setTemplateOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n const existing = await this.findByScope(key, scopeType, scopeId);\n\n if (existing) {\n existing.template = template;\n await existing.save();\n return existing;\n }\n\n const created = await this.create({\n key,\n tenantId: scopeType === 'app' ? null : scopeId,\n template,\n });\n await created.save();\n return created;\n }\n\n /** Remove the override row for one scope entirely, if one exists. */\n async removeOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<boolean> {\n const existing = await this.findByScope(key, scopeType, scopeId);\n if (!existing) {\n return false;\n }\n\n await existing.delete();\n return true;\n }\n}\n","import type { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport type { PromptOverride } from './models/PromptOverride.js';\nimport { APP_PROMPT_SCOPE_ID, type PromptOverrideScopeType } from './types.js';\n\n/** One override write the host must authorize before it runs (mirrors #3013). */\nexport interface PromptOverrideWriteRequest {\n operation: 'set' | 'remove';\n key: string;\n scopeType: PromptOverrideScopeType;\n scopeId: string;\n /** Present for `set`. `null` clears the template field. */\n template?: string | null;\n}\n\n/**\n * The host's explicit authorization decision for one override write. Return\n * `true` only when the current caller may write that exact scope; anything\n * else denies.\n */\nexport type PromptOverrideAuthorizer = (\n request: PromptOverrideWriteRequest,\n) => boolean | Promise<boolean>;\n\n/** Thrown when the authorizer does not return `true`. Nothing is written. */\nexport class PromptOverrideAuthorizationError extends Error {\n readonly status = 403;\n constructor(readonly request: PromptOverrideWriteRequest) {\n super(\n `Prompt override ${request.operation} denied for ${request.scopeType} scope`,\n );\n this.name = 'PromptOverrideAuthorizationError';\n }\n}\n\n/**\n * Thrown when a write names a scope the resolver never reads: an unknown scope\n * type, an app scope other than {@link APP_PROMPT_SCOPE_ID}, or a blank /\n * untrimmed / non-string tenant id. Checked before the authorizer runs, so a\n * malformed tenant scope can never resolve to the app-wide row. Nothing is\n * written.\n */\nexport class InvalidPromptScopeError extends Error {\n readonly status = 400;\n constructor(\n readonly scopeType: string,\n readonly scopeId: string,\n reason: string,\n ) {\n super(`Invalid prompt override scope (${scopeType}): ${reason}`);\n this.name = 'InvalidPromptScopeError';\n }\n}\n\n/** Reject any scope the resolver does not read (see {@link InvalidPromptScopeError}). */\nexport function assertValidPromptScope(\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n): void {\n if (scopeType !== 'app' && scopeType !== 'tenant') {\n throw new InvalidPromptScopeError(\n String(scopeType),\n String(scopeId),\n 'scope type must be \"app\" or \"tenant\"',\n );\n }\n if (typeof scopeId !== 'string') {\n throw new InvalidPromptScopeError(\n scopeType,\n String(scopeId),\n 'scope id must be a string',\n );\n }\n if (scopeType === 'app' && scopeId !== APP_PROMPT_SCOPE_ID) {\n throw new InvalidPromptScopeError(\n scopeType,\n scopeId,\n `the app scope is only ever \"${APP_PROMPT_SCOPE_ID}\"`,\n );\n }\n if (\n scopeType === 'tenant' &&\n (!scopeId.trim() ||\n scopeId !== scopeId.trim() ||\n scopeId === APP_PROMPT_SCOPE_ID)\n ) {\n throw new InvalidPromptScopeError(\n scopeType,\n scopeId,\n 'a tenant scope id must be non-blank, already trimmed, and not the app scope id',\n );\n }\n}\n\n/**\n * Authorized write path for prompt overrides (mirrors `FeatureOverrideService`,\n * #3013). Override rows are authorization state for every scope and\n * `PromptOverride` is not tenant-scoped by the request context, so generated\n * surfaces are closed. Hosts that let callers change prompt text construct\n * this service with an authorizer bound to the current caller and write\n * through it; every write asks the authorizer first and fails closed.\n */\nexport class PromptOverrideService {\n constructor(\n private readonly overrides: PromptOverrideCollection,\n private readonly authorize: PromptOverrideAuthorizer,\n ) {}\n\n async setTemplateOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n await this.require({ operation: 'set', key, scopeType, scopeId, template });\n return this.overrides.setTemplateOverride(\n key,\n scopeType,\n scopeId,\n template,\n );\n }\n\n async removeOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<boolean> {\n await this.require({ operation: 'remove', key, scopeType, scopeId });\n return this.overrides.removeOverride(key, scopeType, scopeId);\n }\n\n private async require(request: PromptOverrideWriteRequest): Promise<void> {\n assertValidPromptScope(request.scopeType, request.scopeId);\n let allowed = false;\n try {\n allowed = (await this.authorize(request)) === true;\n } catch {\n allowed = false;\n }\n if (!allowed) throw new PromptOverrideAuthorizationError(request);\n }\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n getCachedPromptBase,\n getPromptCacheGeneration,\n setCachedPromptBase,\n} from './cache.js';\nimport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport { PromptRegistry } from './prompt-registry.js';\nimport type {\n PromptCacheValue,\n PromptPackageConfig,\n ResolvedPrompt,\n ResolvePromptOptions,\n} from './types.js';\nimport {\n buildResolvedAI,\n mergePromptLayers,\n normalizePromptLayer,\n renderPromptTemplate,\n} from './utils.js';\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\nasync function loadPromptBase(\n key: string,\n options: ResolvePromptOptions,\n): Promise<PromptCacheValue> {\n const definition = PromptRegistry.get(key);\n if (!definition) {\n throw new Error(`Unknown prompt key \"${key}\"`);\n }\n\n const tenantId =\n options.tenantId !== undefined ? options.tenantId : (getTenantId() ?? null);\n\n let collection: PromptOverrideCollection | null = null;\n let cacheDb: ResolvePromptOptions['db'] | undefined = options.db;\n if (options.db) {\n const initializedCollection = await PromptOverrideCollection.create({\n db: options.db,\n });\n collection = initializedCollection;\n cacheDb = initializedCollection.db as ResolvePromptOptions['db'];\n }\n\n const cached = getCachedPromptBase(key, tenantId, cacheDb);\n if (cached) {\n return cached;\n }\n\n // Capture the invalidation generation before the asynchronous layer loads. A\n // write that lands while they are in flight bumps it, and the cache write\n // below is then refused rather than repopulating the key the write just\n // invalidated with the pre-write value.\n const loadedAtGeneration = getPromptCacheGeneration(key, cacheDb);\n\n const config = getPromptConfig();\n const layers = [\n {\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n },\n normalizePromptLayer(config.prompts?.[key]),\n ];\n\n if (collection) {\n const stored = await collection.getResolutionLayers(key, tenantId);\n\n if (stored.app) {\n layers.push(stored.app.toPromptLayer());\n }\n\n if (stored.tenant) {\n layers.push(stored.tenant.toPromptLayer());\n }\n }\n\n const merged = mergePromptLayers(...layers);\n const value: PromptCacheValue = {\n key,\n template: merged.template,\n ai: merged.ai,\n };\n\n setCachedPromptBase(key, tenantId, cacheDb, value, loadedAtGeneration);\n return value;\n}\n\nexport async function resolvePrompt(\n key: string,\n options: ResolvePromptOptions = {},\n): Promise<ResolvedPrompt> {\n const config = getPromptConfig();\n const base = await loadPromptBase(key, options);\n const runtimeOverride = normalizePromptLayer(options.override);\n const merged = mergePromptLayers(\n {\n template: base.template,\n profile: base.ai.profile ?? null,\n model: base.ai.model ?? null,\n params: base.ai.params,\n },\n runtimeOverride,\n );\n\n return {\n key,\n template: merged.template,\n text: renderPromptTemplate(merged.template, options.variables),\n ai: buildResolvedAI(merged.ai, config),\n };\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport type {\n SmrtClassOptions,\n SmrtCollectionOptions,\n} from '@happyvertical/smrt-core';\nimport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport type { PromptOverride } from './models/PromptOverride.js';\nimport {\n assertValidPromptScope,\n type PromptOverrideAuthorizer,\n PromptOverrideService,\n} from './prompt-override-service.js';\nimport { PromptRegistry } from './prompt-registry.js';\nimport {\n APP_PROMPT_SCOPE_ID,\n type PromptDefinition,\n type PromptEditableConfig,\n type PromptLayer,\n type PromptOverrideScopeType,\n type PromptPackageConfig,\n} from './types.js';\nimport { mergePromptLayers, normalizePromptLayer } from './utils.js';\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\n/**\n * The caller's options with its list bounds removed.\n *\n * `SmrtCollection.create()` forwards `defaultListLimit`/`maxListLimit` from\n * any options bag it is handed (#2367), so a host that sets those\n * application-wide would silently cap the bulk override-enumeration read\n * {@link PromptSettingsService.listPromptSettings} runs\n * (`getOverrideMapForKeys`) — a management screen showing every prompt, not a\n * user-facing page of results. A dropped row here is an override an operator\n * cannot see, and the prompt then reports as unoverridden, silently (the\n * `#3056` hazard class in `@happyvertical/smrt-features`'s `getOverrideMap`,\n * applied here proactively rather than left for a follow-up). Only the list\n * bounds are stripped; the database and every other option still apply.\n */\nfunction withoutListBounds(\n options: SmrtClassOptions | SmrtCollectionOptions,\n): SmrtCollectionOptions {\n return { ...options, defaultListLimit: undefined, maxListLimit: undefined };\n}\n\n/** The level that supplied a prompt's effective template. */\nexport type PromptSettingsLevel = 'default' | 'config' | 'app' | 'tenant';\n\n/**\n * One prompt, rendered for a management screen: the code-owned definition,\n * the text actually in effect for the requested tenant, and the raw override\n * state at each scope so the UI can show *why* it is in effect and what\n * reverting a scope produces.\n */\nexport interface PromptSettingsRow {\n /**\n * The persisted identifier. Renaming it orphans every existing override —\n * see the warning on {@link PromptSettingsService}.\n */\n key: string;\n /** Human description from the definition; may be empty. */\n description: string;\n /** Which fields a stored override may change, from the definition. */\n editable: PromptEditableConfig;\n /** The code-registered template, before the config layer or any override. */\n defaultTemplate: string;\n /**\n * What {@link resolvePrompt} resolves the template to for the requested\n * context — the text the application actually uses (unrendered: no\n * `{variable}` substitution).\n */\n effectiveTemplate: string;\n /** The app-level override row's `template` field, or `null` when there is none. */\n appTemplate: string | null;\n /**\n * The tenant-level override row's `template` field, or `null` when there is\n * none (or when no `tenantId` was requested).\n */\n tenantTemplate: string | null;\n /**\n * What the **app** scope's \"revert to default\" produces: the code default\n * merged with the config-file layer. Always knowable — nothing sits above\n * the app scope — unlike {@link inheritedTemplate}.\n */\n appDefaultTemplate: string;\n /**\n * What the **tenant** scope's \"revert to default\" produces: the code\n * default, the config-file layer, and the app-level override, merged with\n * no tenant override of its own. `null` when no `tenantId` was requested.\n *\n * This is the value a \"revert to default\" control for the tenant scope must\n * show or apply — never {@link defaultTemplate}, which ignores the config\n * layer and any app-level override and would silently discard them.\n */\n inheritedTemplate: string | null;\n /** Which level supplied {@link effectiveTemplate}. */\n supplyingLevel: PromptSettingsLevel;\n}\n\n/** Selection for {@link PromptSettingsService.listPromptSettings}. */\nexport interface ListPromptSettingsOptions {\n /**\n * Tenant whose overrides and effective template to report. Omit for an\n * app-only view.\n */\n tenantId?: string | null;\n /**\n * Restrict to an explicit allowlist of keys. Keys with no definition are\n * simply absent from the result — this filters, it does not validate.\n */\n keys?: string[];\n}\n\n/** One override write requested through {@link PromptSettingsService}. */\nexport interface SetPromptOverrideRequest {\n key: string;\n scopeType: PromptOverrideScopeType;\n scopeId: string;\n /** `null` clears the override, returning the scope to whatever it inherits. */\n template: string | null;\n}\n\n/**\n * Thrown when a write names a `key` that has no registered {@link PromptDefinition}.\n * Nothing is written.\n *\n * This is the generalized form of the per-app \"is this one of my keys?\" guard\n * every consumer would otherwise hand-roll to keep a form post from creating an\n * override for an arbitrary string.\n */\nexport class UnknownPromptKeyError extends Error {\n readonly status = 400;\n constructor(readonly key: string) {\n super(`Unknown prompt key: ${key}`);\n this.name = 'UnknownPromptKeyError';\n }\n}\n\n/**\n * Thrown when a write would set a field the definition's `editable` config\n * does not allow overriding. Nothing is written.\n */\nexport class PromptFieldNotEditableError extends Error {\n readonly status = 400;\n constructor(\n readonly key: string,\n readonly field: string,\n ) {\n super(`Prompt \"${key}\" does not allow ${field} overrides`);\n this.name = 'PromptFieldNotEditableError';\n }\n}\n\n/** Options for {@link PromptSettingsService.create}. */\nexport interface PromptSettingsServiceOptions {\n /**\n * The host's authorization decision for each override write, bound to the\n * current caller. **Omitting it makes the service read-only**: every write\n * then fails closed with `PromptOverrideAuthorizationError`. This package\n * never decides who may write.\n */\n authorize?: PromptOverrideAuthorizer;\n}\n\n/**\n * Read and write side of a prompt management screen, so consumers do not\n * re-derive the row shape or the unknown-key guard.\n *\n * **Authorization stays with the consumer.** This service makes no\n * authorization decision of its own: reads are unfiltered, and every write is\n * delegated to {@link PromptOverrideService}, which asks the host-supplied\n * {@link PromptOverrideAuthorizer} first and fails closed. Call it only from\n * server code that has already established who the caller is. See\n * `packages/prompts/README.md` for the consumer recipe.\n *\n * **Prompt keys are persisted identifiers.** Overrides are stored keyed by the\n * exact `key` string and resolved by that string at runtime. Renaming a key\n * orphans every existing override, silently reverting all tenants to the\n * registry default. Treat a key as immutable once shipped; a rename needs a\n * data migration, not an edit.\n */\nexport class PromptSettingsService {\n private readonly writes: PromptOverrideService;\n\n constructor(\n private readonly overrides: PromptOverrideCollection,\n authorize?: PromptOverrideAuthorizer,\n ) {\n this.writes = new PromptOverrideService(\n overrides,\n authorize ?? (() => false),\n );\n }\n\n /**\n * Build a service over the given database options.\n *\n * The internal bulk override-enumeration read {@link listPromptSettings}\n * runs is always issued without the caller's\n * `defaultListLimit`/`maxListLimit` — see {@link withoutListBounds}. Only\n * that read is affected; a `db` option is still honored.\n *\n * @param options - SMRT database options, as passed to any collection.\n * @param serviceOptions - Host authorizer. Omit for a read-only (load-function) service.\n */\n static async create(\n options: SmrtClassOptions = {},\n serviceOptions: PromptSettingsServiceOptions = {},\n ): Promise<PromptSettingsService> {\n const overrides = await PromptOverrideCollection.create(\n withoutListBounds(options),\n );\n return new PromptSettingsService(\n overrides as PromptOverrideCollection,\n serviceOptions.authorize,\n );\n }\n\n /**\n * One {@link PromptSettingsRow} per matching registered prompt, ordered by\n * key, so a rendered list is stable across loads.\n *\n * Makes no authorization decision — the caller has already decided that this\n * principal may see this tenant's prompts.\n */\n async listPromptSettings(\n options: ListPromptSettingsOptions = {},\n ): Promise<PromptSettingsRow[]> {\n const definitions = this.loadDefinitions(options);\n const keys = definitions.map((definition) => definition.key);\n const tenantId = options.tenantId;\n\n // Two bulk reads instead of up to 2N: see getOverrideMapForKeys for why\n // these must run through a bounds-stripped collection (#3056 class).\n const [appOverrides, tenantOverrides] = await Promise.all([\n this.overrides.getOverrideMapForKeys(keys, 'app', APP_PROMPT_SCOPE_ID),\n tenantId\n ? this.overrides.getOverrideMapForKeys(keys, 'tenant', tenantId)\n : Promise.resolve(new Map<string, PromptOverride>()),\n ]);\n\n return definitions.map((definition) =>\n this.toRow(\n definition,\n tenantId,\n appOverrides.get(definition.key) ?? null,\n tenantOverrides.get(definition.key) ?? null,\n ),\n );\n }\n\n /** The single row for one key, or `null` when no definition owns that key. */\n async getPromptSetting(\n key: string,\n tenantId?: string | null,\n ): Promise<PromptSettingsRow | null> {\n const definition = PromptRegistry.get(key);\n if (!definition) {\n return null;\n }\n\n const [appOverride, tenantOverride] = await Promise.all([\n this.overrides.getAppOverride(key),\n tenantId\n ? this.overrides.getTenantOverride(key, tenantId)\n : Promise.resolve(null),\n ]);\n\n return this.toRow(definition, tenantId, appOverride, tenantOverride);\n }\n\n /**\n * Apply one override change to the `template` field.\n *\n * Refuses any `key` without a registered {@link PromptDefinition}, any scope\n * the resolver would never read back, and a non-`null` template when the\n * definition's `editable.template` is `false`, then delegates to\n * {@link PromptOverrideService} so the host authorizer decides whether this\n * caller may write this scope. `template: null` clears the override.\n *\n * @throws {UnknownPromptKeyError} when the key has no definition.\n * @throws {InvalidPromptScopeError} when the scope is not one the resolver reads.\n * @throws {PromptFieldNotEditableError} when the definition disallows template overrides.\n * @throws `PromptOverrideAuthorizationError` when the authorizer declines.\n */\n async setPromptOverride(\n request: SetPromptOverrideRequest,\n ): Promise<PromptOverride> {\n const { key, scopeType, scopeId, template } = request;\n\n assertValidPromptScope(scopeType, scopeId);\n const definition = this.assertKnownPromptKey(key);\n\n if (template !== null && !definition.editable.template) {\n throw new PromptFieldNotEditableError(key, 'template');\n }\n\n return this.writes.setTemplateOverride(key, scopeType, scopeId, template);\n }\n\n /** {@link setPromptOverride} for the app-wide scope. */\n async setAppPromptOverride(\n key: string,\n template: string | null,\n ): Promise<PromptOverride> {\n return this.setPromptOverride({\n key,\n scopeType: 'app',\n scopeId: APP_PROMPT_SCOPE_ID,\n template,\n });\n }\n\n /** {@link setPromptOverride} for one tenant. */\n async setTenantPromptOverride(\n key: string,\n tenantId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n return this.setPromptOverride({\n key,\n scopeType: 'tenant',\n scopeId: tenantId,\n template,\n });\n }\n\n private assertKnownPromptKey(key: string): PromptDefinition {\n const trimmed = typeof key === 'string' ? key.trim() : '';\n if (!trimmed || trimmed !== key) {\n throw new UnknownPromptKeyError(String(key));\n }\n const definition = PromptRegistry.get(trimmed);\n if (!definition) {\n throw new UnknownPromptKeyError(trimmed);\n }\n return definition;\n }\n\n private loadDefinitions(\n options: ListPromptSettingsOptions,\n ): PromptDefinition[] {\n const all = PromptRegistry.getAll();\n const allowed = options.keys ? new Set(options.keys) : null;\n const selected = allowed\n ? all.filter((definition) => allowed.has(definition.key))\n : all;\n\n return [...selected].sort((a, b) => a.key.localeCompare(b.key));\n }\n\n private toRow(\n definition: PromptDefinition,\n tenantId: string | null | undefined,\n appOverride: PromptOverride | null,\n tenantOverride: PromptOverride | null,\n ): PromptSettingsRow {\n const { key } = definition;\n const config = getPromptConfig();\n\n const registryLayer: PromptLayer = {\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n };\n const configLayer = normalizePromptLayer(config.prompts?.[key]);\n\n const appLayer = appOverride ? appOverride.toPromptLayer() : null;\n const tenantLayer = tenantOverride ? tenantOverride.toPromptLayer() : null;\n\n // What the \"app\" scope's own revert-to-default produces: registry + config\n // only. This intentionally excludes the app override itself, so it must\n // NOT be reused as the app-only effective value below (that bug shipped\n // and broke both `effectiveTemplate` when no tenant is requested and every\n // tenant's inherited fallback until caught by this package's own tests).\n const appDefaultMerge = mergePromptLayers(registryLayer, configLayer);\n const inheritedMerge = tenantId\n ? mergePromptLayers(registryLayer, configLayer, appLayer)\n : null;\n // The effective template always includes the app override when present;\n // only the tenant layer is conditional on a requested tenantId.\n const effectiveMerge = mergePromptLayers(\n registryLayer,\n configLayer,\n appLayer,\n tenantId ? tenantLayer : null,\n );\n\n const appTemplate = appOverride?.template ?? null;\n const tenantTemplate = tenantId ? (tenantOverride?.template ?? null) : null;\n\n let supplyingLevel: PromptSettingsLevel = 'default';\n if (tenantId && tenantTemplate != null) {\n supplyingLevel = 'tenant';\n } else if (appTemplate != null) {\n supplyingLevel = 'app';\n } else if (configLayer.template != null) {\n supplyingLevel = 'config';\n }\n\n return {\n key,\n description: definition.description,\n editable: definition.editable,\n defaultTemplate: definition.template,\n effectiveTemplate: effectiveMerge.template,\n appTemplate,\n tenantTemplate,\n appDefaultTemplate: appDefaultMerge.template,\n inheritedTemplate: inheritedMerge ? inheritedMerge.template : null,\n supplyingLevel,\n };\n }\n}\n\n/**\n * Reject a scope the resolver would never read back.\n *\n * `PromptOverride` rows are looked up by the exact `(key, tenantId)` pair —\n * `tenantId: null` for the app scope, a tenant id otherwise. A row written\n * under a scope nothing queries is invisible state: it never takes effect,\n * and the host authorizer cannot catch it, because `scopeType: 'app'` with\n * someone else's tenant id looks like an ordinary app write to an authorizer\n * that only gates the app scope.\n */\n","/**\n * @happyvertical/smrt-prompts\n *\n * Code-first prompts with config overrides, stored app/tenant overrides,\n * and runtime resolution helpers for SMRT applications.\n *\n * @packageDocumentation\n */\n\n// Self-register this package's manifest before any @smrt() decorator fires\n// downstream. Must come first so the side effect runs ahead of the class\n// module loads below. See __smrt-register__.ts for issue #1132 context.\nimport './__smrt-register__.js';\n\nexport { clearPromptCache, getPromptCacheTtlMs } from './cache.js';\nexport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nexport {\n PromptOverride,\n type PromptOverrideOptions,\n} from './models/PromptOverride.js';\nexport {\n InvalidPromptScopeError,\n PromptOverrideAuthorizationError,\n type PromptOverrideAuthorizer,\n PromptOverrideService,\n type PromptOverrideWriteRequest,\n} from './prompt-override-service.js';\nexport { definePrompt, PromptRegistry } from './prompt-registry.js';\nexport { resolvePrompt } from './prompt-resolver.js';\nexport {\n type ListPromptSettingsOptions,\n PromptFieldNotEditableError,\n type PromptSettingsLevel,\n type PromptSettingsRow,\n PromptSettingsService,\n type PromptSettingsServiceOptions,\n type SetPromptOverrideRequest,\n UnknownPromptKeyError,\n} from './prompt-settings.js';\nexport type {\n NormalizedPromptAI,\n PromptAIInput,\n PromptConfigOverrideInput,\n PromptDefinition,\n PromptDefinitionInput,\n PromptEditableConfig,\n PromptLayer,\n PromptOverrideScopeType,\n PromptPackageConfig,\n PromptParams,\n PromptProfileConfig,\n ResolvedPrompt,\n ResolvedPromptAI,\n ResolvePromptOptions,\n} from './types.js';\nexport { APP_PROMPT_SCOPE_ID } from './types.js';\n\n/** @internal */\nexport const PACKAGE_VERSION_INITIALIZED = true;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/cache.ts","../src/utils.ts","../src/prompt-registry.ts","../src/models/PromptOverride.ts","../src/collections/PromptOverrideCollection.ts","../src/prompt-override-service.ts","../src/prompt-resolver.ts","../src/prompt-settings.ts","../src/index.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"packageVersion\\\":\\\"0.55.6\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-prompts:PromptOverrideCollection\\\":{\\\"name\\\":\\\"promptoverridecollection\\\",\\\"className\\\":\\\"PromptOverrideCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-prompts:PromptOverrideCollection\\\",\\\"collection\\\":\\\"promptoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/prompts/src/collections/PromptOverrideCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getAppOverride\\\":{\\\"name\\\":\\\"getAppOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTenantOverride\\\":{\\\"name\\\":\\\"getTenantOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getResolutionLayers\\\":{\\\"name\\\":\\\"getResolutionLayers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":true,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]},{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\"]}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getOverrideMapForKeys\\\":{\\\"name\\\":\\\"getOverrideMapForKeys\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"keys\\\",\\\"type\\\":\\\"string[]\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<Map<string, PromptOverride>>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"findByScope\\\":{\\\"name\\\":\\\"findByScope\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<PromptOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setTemplateOverride\\\":{\\\"name\\\":\\\"setTemplateOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"template\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":false,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"Promise<PromptOverride>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"removeOverride\\\":{\\\"name\\\":\\\"removeOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeType\\\",\\\"type\\\":\\\"PromptOverrideScopeType\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"scopeId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<boolean>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"PromptOverride\\\",\\\"exportName\\\":\\\"PromptOverrideCollection\\\",\\\"collectionExportName\\\":\\\"PromptOverrideCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_prompt_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT,\\\\n \\\\\\\"profile\\\\\\\" TEXT,\\\\n \\\\\\\"model\\\\\\\" TEXT,\\\\n \\\\\\\"params\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"params\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_prompt_overrides_key_context_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_prompt_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_prompt_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"38f505e7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-prompts\\\"},\\\"@happyvertical/smrt-prompts:PromptOverride\\\":{\\\"name\\\":\\\"promptoverride\\\",\\\"className\\\":\\\"PromptOverride\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-prompts:PromptOverride\\\",\\\"collection\\\":\\\"promptoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/prompts/src/models/PromptOverride.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-prompts\\\",\\\"fields\\\":{\\\"key\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true}},\\\"template\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"profile\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"model\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"params\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"getParams\\\":{\\\"name\\\":\\\"getParams\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"PromptParams\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"setParams\\\":{\\\"name\\\":\\\"setParams\\\",\\\"async\\\":false,\\\"parameters\\\":[{\\\"name\\\":\\\"params\\\",\\\"type\\\":\\\"PromptParams | null\\\",\\\"optional\\\":false,\\\"unionBranches\\\":[{\\\"type\\\":\\\"PromptParams\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"void\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"toPromptLayer\\\":{\\\"name\\\":\\\"toPromptLayer\\\",\\\"async\\\":false,\\\"parameters\\\":[],\\\"returnType\\\":\\\"PromptLayer\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"conflictColumns\\\":[\\\"key\\\",\\\"context\\\"],\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"PromptOverride\\\",\\\"collectionExportName\\\":\\\"PromptOverrideCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"key\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_prompt_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_prompt_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT,\\\\n \\\\\\\"profile\\\\\\\" TEXT,\\\\n \\\\\\\"model\\\\\\\" TEXT,\\\\n \\\\\\\"params\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"profile\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"params\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_prompt_overrides_key_context_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_prompt_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_prompt_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"38f505e7\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-prompts\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"stampsConstructors\\\":true}\"));\n","import type { DatabaseInterface } from '@happyvertical/sql';\nimport type { PromptCacheValue } from './types.js';\n\nconst PROMPT_CACHE_TTL_MS = 30_000;\n\ntype CacheEntry = {\n expiresAt: number;\n value: PromptCacheValue;\n};\n\nconst promptCache = new Map<string, CacheEntry>();\n/** Monotonic per-`(db, key)` invalidation counter; see getPromptCacheGeneration. */\nconst cacheGenerations = new Map<string, number>();\n/**\n * Source of every generation value. Drawing from one counter instead of\n * incrementing each key independently makes a generation unique across every\n * key and every clear, which is what lets `clearedThrough` work as a floor.\n */\nlet nextGeneration = 1;\n/**\n * Floor that `clearPromptCache()` raises for *every* key, including keys with\n * no map entry. A key that has never been invalidated in this process reads as\n * generation 0, so a resolution that captured 0 before a clear would still see\n * 0 after it and write its pre-clear value back — the flush would be silently\n * undone for the rest of the TTL.\n */\nlet clearedThrough = 0;\nconst dbInstanceIds = new WeakMap<object, string>();\nlet nextDbId = 1;\n\nfunction getDbNamespace(db: unknown): string {\n if (!db) {\n return 'no-db';\n }\n\n if (typeof db === 'string') {\n return `db:${db}`;\n }\n\n if (typeof db === 'object') {\n const dbObject = db as Record<string, unknown>;\n if (typeof dbObject.query === 'function') {\n if (!dbInstanceIds.has(dbObject)) {\n dbInstanceIds.set(dbObject, `db-instance:${nextDbId++}`);\n }\n const namespace = dbInstanceIds.get(dbObject);\n if (namespace) {\n return namespace;\n }\n\n return 'db-instance:unknown';\n }\n\n try {\n return `db-config:${JSON.stringify(dbObject)}`;\n } catch {\n return 'db-config:opaque';\n }\n }\n\n return 'db:unknown';\n}\n\nfunction buildCacheKey(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): string {\n return `${getDbNamespace(db)}::${key}::${tenantId ?? 'app'}`;\n}\n\nfunction buildGenerationKey(\n key: string,\n db: DatabaseInterface | unknown,\n): string {\n return `${getDbNamespace(db)}::${key}`;\n}\n\nfunction bumpGeneration(key: string, db: DatabaseInterface | unknown): void {\n cacheGenerations.set(buildGenerationKey(key, db), nextGeneration++);\n}\n\nexport function getPromptCacheTtlMs(): number {\n return PROMPT_CACHE_TTL_MS;\n}\n\nexport function getCachedPromptBase(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): PromptCacheValue | null {\n const cacheKey = buildCacheKey(key, tenantId, db);\n const cached = promptCache.get(cacheKey);\n\n if (!cached) {\n return null;\n }\n\n if (cached.expiresAt <= Date.now()) {\n promptCache.delete(cacheKey);\n return null;\n }\n\n return cached.value;\n}\n\n/**\n * Reads the current invalidation generation for a key.\n *\n * A resolution captures this *before* its asynchronous layer loads and hands\n * it back to {@link setCachedPromptBase}. Any write that lands while those\n * loads are in flight bumps the generation, so the in-flight resolution —\n * which read the pre-write layers — is refused the cache write instead of\n * repopulating the key it just invalidated. Without this, a read that raced a\n * write served the pre-write value for the full TTL, and a raced `delete()`\n * resurrected the deleted override.\n *\n * Tracked per `(db, key)` rather than per `(db, key, tenantId)`: an app-level\n * row is inherited by every tenant, so a write to any scope of a key must\n * invalidate every scope of it. This matches the coarsest fan-out of\n * {@link invalidatePromptCache}.\n *\n * A key with no entry of its own reports the {@link clearPromptCache} floor\n * rather than a bare 0, so a clear refuses in-flight writes for keys that have\n * never been invalidated too.\n */\nexport function getPromptCacheGeneration(\n key: string,\n db: DatabaseInterface | unknown,\n): number {\n const generation = cacheGenerations.get(buildGenerationKey(key, db)) ?? 0;\n return generation > clearedThrough ? generation : clearedThrough;\n}\n\nexport function setCachedPromptBase(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n value: PromptCacheValue,\n loadedAtGeneration: number,\n): void {\n if (getPromptCacheGeneration(key, db) !== loadedAtGeneration) {\n // A write landed while this resolution was loading. Its value is already\n // stale, so drop it rather than poison the key for the whole TTL.\n return;\n }\n\n promptCache.set(buildCacheKey(key, tenantId, db), {\n expiresAt: Date.now() + PROMPT_CACHE_TTL_MS,\n value,\n });\n}\n\n/**\n * Invalidates a cached resolution. An app-level write (tenantId null) clears\n * every tenant's entry for that key, because each tenant inherits from it.\n */\nexport function invalidatePromptCache(\n key: string,\n tenantId: string | null | undefined,\n db: DatabaseInterface | unknown,\n): void {\n const dbNamespace = getDbNamespace(db);\n bumpGeneration(key, db);\n\n if (tenantId !== null && tenantId !== undefined) {\n promptCache.delete(buildCacheKey(key, tenantId, db));\n return;\n }\n\n const keyPrefix = `${dbNamespace}::${key}::`;\n for (const cacheKey of promptCache.keys()) {\n if (cacheKey.startsWith(keyPrefix)) {\n promptCache.delete(cacheKey);\n }\n }\n}\n\nexport function clearPromptCache(): void {\n promptCache.clear();\n // Raise the floor instead of resetting counters: a resolution that started\n // before the clear must be refused its write, and raising a single floor\n // covers keys with no generation entry, which a per-key bump cannot reach.\n // With the floor carrying the refusal, the per-key entries can be dropped.\n clearedThrough = nextGeneration++;\n cacheGenerations.clear();\n}\n","import type {\n NormalizedPromptAI,\n PromptAIInput,\n PromptConfigOverrideInput,\n PromptDefinitionInput,\n PromptEditableConfig,\n PromptLayer,\n PromptPackageConfig,\n PromptParams,\n PromptProfileConfig,\n ResolvedPromptAI,\n} from './types.js';\n\nconst DEFAULT_EDITABLE: PromptEditableConfig = {\n template: false,\n profile: false,\n model: false,\n params: false,\n};\n\nconst TOP_LEVEL_RESERVED_KEYS = new Set([\n 'key',\n 'editable',\n 'template',\n 'ai',\n 'profile',\n 'provider',\n 'model',\n 'params',\n 'temperature',\n 'maxTokens',\n]);\n\nconst AI_RESERVED_KEYS = new Set([\n 'profile',\n 'provider',\n 'model',\n 'params',\n 'temperature',\n 'maxTokens',\n]);\n\nconst AI_ROUTING_PARAM_KEYS = new Set([\n 'profile',\n 'provider',\n 'type',\n 'model',\n 'defaultModel',\n]);\n\nexport function isPlainObject(\n value: unknown,\n): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\nexport function normalizeEditableConfig(\n editable?: Partial<PromptEditableConfig>,\n): PromptEditableConfig {\n return {\n template: editable?.template ?? DEFAULT_EDITABLE.template,\n profile: editable?.profile ?? DEFAULT_EDITABLE.profile,\n model: editable?.model ?? DEFAULT_EDITABLE.model,\n params: editable?.params ?? DEFAULT_EDITABLE.params,\n };\n}\n\nfunction extractPromptParams(\n source: Record<string, unknown>,\n reservedKeys: Set<string>,\n): PromptParams {\n const params: PromptParams = {};\n\n if (isPlainObject(source.params)) {\n Object.assign(params, sanitizePromptParams(source.params));\n }\n\n if ('temperature' in source && source.temperature !== undefined) {\n params.temperature = source.temperature;\n }\n\n if ('maxTokens' in source && source.maxTokens !== undefined) {\n params.maxTokens = source.maxTokens;\n }\n\n for (const [key, value] of Object.entries(source)) {\n if (reservedKeys.has(key) || value === undefined) {\n continue;\n }\n assignPromptParam(params, key, value);\n }\n\n return params;\n}\n\nfunction assignPromptParam(\n params: PromptParams,\n key: string,\n value: unknown,\n): void {\n if (AI_ROUTING_PARAM_KEYS.has(key) || value === undefined) {\n return;\n }\n\n params[key] = value;\n}\n\nexport function sanitizePromptParams(\n params: PromptParams | null | undefined,\n): PromptParams {\n const sanitized: PromptParams = {};\n\n if (!params) {\n return sanitized;\n }\n\n for (const [key, value] of Object.entries(params)) {\n assignPromptParam(sanitized, key, value);\n }\n\n return sanitized;\n}\n\nexport function mergePromptParams(\n ...paramLayers: Array<PromptParams | null | undefined>\n): PromptParams {\n const merged: PromptParams = {};\n\n for (const layer of paramLayers) {\n if (!layer) {\n continue;\n }\n\n for (const [key, value] of Object.entries(layer)) {\n assignPromptParam(merged, key, value);\n }\n }\n\n return merged;\n}\n\nfunction normalizeAIInput(ai?: PromptAIInput | null): NormalizedPromptAI {\n if (!isPlainObject(ai)) {\n return { params: {} };\n }\n\n const profile =\n typeof ai.profile === 'string' || ai.profile === null\n ? ai.profile\n : undefined;\n const model =\n typeof ai.model === 'string' || ai.model === null ? ai.model : undefined;\n\n return {\n profile: profile ?? undefined,\n model: model ?? undefined,\n params: extractPromptParams(ai, AI_RESERVED_KEYS),\n };\n}\n\nexport function normalizePromptDefinitionInput(input: PromptDefinitionInput): {\n key: string;\n template: string;\n description: string;\n ai: NormalizedPromptAI;\n editable: PromptEditableConfig;\n} {\n return {\n key: input.key,\n template: input.template,\n description: input.description ?? '',\n ai: normalizeAIInput(input.ai),\n editable: normalizeEditableConfig(input.editable),\n };\n}\n\nexport function normalizePromptLayer(\n input?: PromptConfigOverrideInput | null,\n): PromptLayer {\n if (!isPlainObject(input)) {\n return {};\n }\n\n const nestedAi = isPlainObject(input.ai)\n ? normalizeAIInput(input.ai)\n : { params: {} };\n const topLevelParams = extractPromptParams(input, TOP_LEVEL_RESERVED_KEYS);\n\n return {\n template:\n input.template === undefined\n ? undefined\n : input.template === null\n ? null\n : String(input.template),\n profile:\n input.profile === undefined\n ? nestedAi.profile\n : input.profile === null\n ? null\n : String(input.profile),\n model:\n input.model === undefined\n ? nestedAi.model\n : input.model === null\n ? null\n : String(input.model),\n params: mergePromptParams(topLevelParams, nestedAi.params),\n };\n}\n\nexport function mergePromptLayers(\n ...layers: Array<PromptLayer | null | undefined>\n): {\n template: string;\n ai: NormalizedPromptAI;\n} {\n let template = '';\n let profile: string | undefined;\n let model: string | undefined;\n let params: PromptParams = {};\n\n for (const layer of layers) {\n if (!layer) {\n continue;\n }\n\n if (layer.template !== undefined && layer.template !== null) {\n template = layer.template;\n }\n\n if (layer.profile !== undefined && layer.profile !== null) {\n profile = layer.profile;\n }\n\n if (layer.model !== undefined && layer.model !== null) {\n model = layer.model;\n }\n\n if (layer.params !== undefined && layer.params !== null) {\n params = mergePromptParams(params, layer.params);\n }\n }\n\n return {\n template,\n ai: {\n profile,\n model,\n params,\n },\n };\n}\n\nexport function normalizeProfileConfig(profile: PromptProfileConfig): {\n provider: string;\n model: string;\n params: PromptParams;\n} {\n const source = isPlainObject(profile) ? profile : {};\n const params = extractPromptParams(source, new Set(['provider', 'model']));\n\n return {\n provider: String(profile.provider),\n model: String(profile.model),\n params,\n };\n}\n\nexport function validateProfileName(\n profileName: string,\n config: PromptPackageConfig,\n): void {\n if (profileName.trim() === '') {\n throw new Error('Prompt profile names cannot be empty');\n }\n\n const allowedProfileNames = config.allowedProfileNames;\n if (\n Array.isArray(allowedProfileNames) &&\n !allowedProfileNames.includes(profileName)\n ) {\n throw new Error(\n `Prompt profile \"${profileName}\" is not in the allowed profile list`,\n );\n }\n\n if (!config.profiles?.[profileName]) {\n throw new Error(`Prompt profile \"${profileName}\" is not configured`);\n }\n}\n\nexport function validateModelName(\n modelName: string,\n config: PromptPackageConfig,\n): void {\n if (modelName.trim() === '') {\n throw new Error('Prompt model overrides cannot be empty');\n }\n\n const allowedModels = config.allowedModels;\n if (Array.isArray(allowedModels) && !allowedModels.includes(modelName)) {\n throw new Error(\n `Prompt model \"${modelName}\" is not in the allowed model list`,\n );\n }\n}\n\nexport function buildResolvedAI(\n ai: NormalizedPromptAI,\n config: PromptPackageConfig,\n): ResolvedPromptAI {\n let provider: string | undefined;\n let model = ai.model;\n let params = ai.params;\n\n if (ai.profile) {\n validateProfileName(ai.profile, config);\n const configuredProfile = config.profiles?.[ai.profile];\n if (!configuredProfile) {\n throw new Error(`Prompt profile \"${ai.profile}\" is not configured`);\n }\n const profileConfig = normalizeProfileConfig(configuredProfile);\n provider = profileConfig.provider;\n model = model ?? profileConfig.model;\n params = mergePromptParams(profileConfig.params, params);\n }\n\n if (ai.model) {\n validateModelName(ai.model, config);\n }\n\n if (ai.model && !ai.profile) {\n throw new Error(\n 'Direct prompt model overrides require an effective prompt profile',\n );\n }\n\n if (model && !ai.model && config.allowedModels) {\n validateModelName(model, config);\n }\n\n const resolved: ResolvedPromptAI = {\n ...params,\n profile: ai.profile,\n provider,\n model,\n ...(config.allowedModels\n ? { allowedModels: [...config.allowedModels] }\n : {}),\n params,\n };\n\n if (typeof params.temperature === 'number') {\n resolved.temperature = params.temperature;\n }\n\n if (typeof params.maxTokens === 'number') {\n resolved.maxTokens = params.maxTokens;\n }\n\n return resolved;\n}\n\nexport function renderPromptTemplate(\n template: string,\n variables?: Record<string, unknown>,\n): string {\n if (!variables || Object.keys(variables).length === 0) {\n return template;\n }\n\n return template.replace(/\\{([^{}]+)\\}/g, (_match, rawKey: string) => {\n const key = rawKey.trim();\n const value = variables[key];\n\n if (value === undefined || value === null) {\n return '';\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (Array.isArray(value) || isPlainObject(value)) {\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n }\n\n return String(value);\n });\n}\n\nexport function parsePromptParams(\n raw: string | null | undefined,\n): PromptParams {\n if (!raw) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(raw);\n return isPlainObject(parsed) ? sanitizePromptParams(parsed) : {};\n } catch {\n return {};\n }\n}\n\nexport function serializePromptParams(\n params: PromptParams | null | undefined,\n): string | null {\n if (params === null || params === undefined) {\n return null;\n }\n\n return JSON.stringify(sanitizePromptParams(params));\n}\n","import type { PromptDefinition, PromptDefinitionInput } from './types.js';\nimport { normalizePromptDefinitionInput } from './utils.js';\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __smrtPromptRegistry: Map<string, PromptDefinition> | undefined;\n}\n\nfunction getRegistry(): Map<string, PromptDefinition> {\n if (!globalThis.__smrtPromptRegistry) {\n globalThis.__smrtPromptRegistry = new Map<string, PromptDefinition>();\n }\n\n return globalThis.__smrtPromptRegistry;\n}\n\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item)).join(',')}]`;\n }\n\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([left], [right]) => left.localeCompare(right),\n );\n return `{${entries\n .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)\n .join(',')}}`;\n }\n\n return JSON.stringify(value);\n}\n\nexport const PromptRegistry = {\n register(input: PromptDefinitionInput): PromptDefinition {\n if (!input.key || input.key.trim() === '') {\n throw new Error('Prompt definitions require a non-empty key');\n }\n\n const definition = normalizePromptDefinitionInput(input);\n const registry = getRegistry();\n const existing = registry.get(definition.key);\n\n if (existing) {\n const existingSignature = stableStringify(existing);\n const incomingSignature = stableStringify(definition);\n\n if (existingSignature !== incomingSignature) {\n throw new Error(\n `Prompt \"${definition.key}\" is already registered with a different definition`,\n );\n }\n\n return existing;\n }\n\n registry.set(definition.key, definition);\n return definition;\n },\n\n get(key: string): PromptDefinition | undefined {\n return getRegistry().get(key);\n },\n\n has(key: string): boolean {\n return getRegistry().has(key);\n },\n\n getAll(): PromptDefinition[] {\n return Array.from(getRegistry().values());\n },\n\n clear(): void {\n getRegistry().clear();\n },\n};\n\nexport function definePrompt(input: PromptDefinitionInput): PromptDefinition {\n return PromptRegistry.register(input);\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport {\n field,\n SmrtObject,\n type SmrtObjectOptions,\n smrt,\n} from '@happyvertical/smrt-core';\nimport type { DatabaseInterface } from '@happyvertical/sql';\nimport { invalidatePromptCache } from '../cache.js';\nimport { PromptRegistry } from '../prompt-registry.js';\nimport {\n APP_PROMPT_SCOPE_ID,\n type PromptLayer,\n type PromptPackageConfig,\n type PromptParams,\n} from '../types.js';\nimport {\n mergePromptLayers,\n normalizePromptLayer,\n parsePromptParams,\n serializePromptParams,\n validateModelName,\n validateProfileName,\n} from '../utils.js';\n\nexport interface PromptOverrideOptions extends SmrtObjectOptions {\n key?: string;\n tenantId?: string | null;\n template?: string | null;\n profile?: string | null;\n model?: string | null;\n params?: string | PromptParams | null;\n}\n\ntype PromptOverrideIdentity = {\n key: string;\n tenantId: string | null;\n};\n\ntype PromptTransactionHandle = DatabaseInterface & {\n commit: () => Promise<void>;\n rollback: () => Promise<void>;\n};\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\n// Override rows are authorization state: any scope (app-wide, or another\n// tenant) can be written, and the object is not tenant-scoped by the request\n// context — `tenantId` is an ordinary settable field. Generated REST routes\n// and MCP tools only check authentication, so they are closed (#3013, mirrored\n// from `@happyvertical/smrt-features`). Hosts write overrides server-side\n// through `PromptOverrideService`, which requires an explicit authorizer for\n// every write (or `PromptOverrideCollection.setTemplateOverride()` /\n// `removeOverride()` after their own authorization decision). The CLI is\n// closed too: generated CLI commands dispatch through the generated API.\n@smrt({\n tableName: '_smrt_prompt_overrides',\n conflictColumns: ['key', 'context'],\n api: false,\n cli: false,\n mcp: false,\n})\nexport class PromptOverride extends SmrtObject { static __smrtPackage__ = \"@happyvertical/smrt-prompts\";\n @field({ required: true })\n key: string = '';\n\n // Not tenant-scoped (any scope is writable), but the value is a tenant id:\n // uuid on Postgres, so it compares with every other tenant_id column.\n @field({ sqlType: 'UUID', nullable: true })\n tenantId: string | null = null;\n\n @field({ type: 'text', nullable: true })\n template: string | null = null;\n\n @field({ type: 'text', nullable: true })\n profile: string | null = null;\n\n @field({ type: 'text', nullable: true })\n model: string | null = null;\n\n @field({ type: 'text', nullable: true })\n params: string | null = null;\n\n constructor(options: PromptOverrideOptions = {}) {\n super(options);\n\n if (options.key !== undefined) this.key = options.key;\n if (options.tenantId !== undefined) this.tenantId = options.tenantId;\n if (options.template !== undefined) this.template = options.template;\n if (options.profile !== undefined) this.profile = options.profile;\n if (options.model !== undefined) this.model = options.model;\n if (options.params !== undefined) {\n if (typeof options.params === 'string' || options.params === null) {\n this.params = options.params;\n } else {\n this.params = serializePromptParams(options.params);\n }\n }\n }\n\n getParams(): PromptParams {\n return parsePromptParams(this.params);\n }\n\n setParams(params: PromptParams | null): void {\n this.params = serializePromptParams(params);\n }\n\n toPromptLayer(): PromptLayer {\n return {\n template: this.template,\n profile: this.profile,\n model: this.model,\n params: this.params === null ? null : this.getParams(),\n };\n }\n\n override async save(): Promise<this> {\n const previousIdentity = await this.getPersistedIdentity();\n this.normalizeParamsForPersistence();\n await this.validatePromptOverride();\n // Use context as the uniqueness scope so app-level rows remain unique even\n // though tenantId is nullable and would otherwise allow multiple NULL rows.\n this.context = this.tenantId ?? APP_PROMPT_SCOPE_ID;\n const identityChanged =\n previousIdentity &&\n (previousIdentity.key !== this.key ||\n previousIdentity.tenantId !== this.tenantId);\n\n const result =\n identityChanged && previousIdentity\n ? await this.saveAfterIdentityChange()\n : await super.save();\n\n if (identityChanged && previousIdentity) {\n invalidatePromptCache(\n previousIdentity.key,\n previousIdentity.tenantId,\n this.db,\n );\n }\n invalidatePromptCache(this.key, this.tenantId, this.db);\n return result;\n }\n\n private async saveAfterIdentityChange(): Promise<this> {\n if (typeof this.db.beginTransaction === 'function') {\n return this.saveAfterIdentityChangeInTransaction();\n }\n\n return this.saveAfterIdentityChangeWithDeferredDelete();\n }\n\n private async saveAfterIdentityChangeInTransaction(): Promise<this> {\n const originalDb = this._db;\n const originalOptionsDb = this.options.db;\n const tx = (await this.db.beginTransaction?.()) as\n | PromptTransactionHandle\n | undefined;\n\n if (!tx) {\n return this.saveAfterIdentityChangeWithDeferredDelete();\n }\n\n try {\n this._db = tx;\n this.options.db = tx;\n await super.delete();\n const result = await super.save();\n await tx.commit();\n return result;\n } catch (error) {\n try {\n await tx.rollback();\n } catch {\n // Preserve the original save error; rollback failures are secondary.\n }\n throw error;\n } finally {\n this._db = originalDb;\n this.options.db = originalOptionsDb;\n }\n }\n\n private async saveAfterIdentityChangeWithDeferredDelete(): Promise<this> {\n const previousId = this.id;\n if (!previousId) {\n return super.save();\n }\n\n const replacementId = crypto.randomUUID();\n let replacementSaved = false;\n this.id = replacementId;\n\n try {\n const result = await super.save();\n replacementSaved = true;\n await this.db.delete(this.tableName, { id: previousId });\n return result;\n } catch (error) {\n if (replacementSaved) {\n try {\n await this.db.delete(this.tableName, { id: replacementId });\n } catch {\n // Best effort cleanup keeps the original row as the source of truth.\n }\n }\n\n this.id = previousId;\n throw error;\n }\n }\n\n override async delete(): Promise<void> {\n const key = this.key;\n const tenantId = this.tenantId;\n await super.delete();\n invalidatePromptCache(key, tenantId, this.db);\n }\n\n private async validatePromptOverride(): Promise<void> {\n if (!this.key || this.key.trim() === '') {\n throw new Error('PromptOverride.key is required');\n }\n\n const definition = PromptRegistry.get(this.key);\n if (!definition) {\n throw new Error(`Unknown prompt key \"${this.key}\"`);\n }\n\n const config = getPromptConfig();\n const editable = definition.editable;\n\n if (this.template !== null && !editable.template) {\n throw new Error(`Prompt \"${this.key}\" does not allow template overrides`);\n }\n\n if (this.profile !== null && !editable.profile) {\n throw new Error(`Prompt \"${this.key}\" does not allow profile overrides`);\n }\n\n if (this.model !== null && !editable.model) {\n throw new Error(`Prompt \"${this.key}\" does not allow model overrides`);\n }\n\n if (this.params !== null && !editable.params) {\n throw new Error(`Prompt \"${this.key}\" does not allow params overrides`);\n }\n\n if (this.params !== null) {\n try {\n const parsed = JSON.parse(this.params);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('Prompt params must be a JSON object');\n }\n } catch (error) {\n throw new Error(\n `Prompt \"${this.key}\" has invalid params JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n }\n\n if (this.profile !== null) {\n validateProfileName(this.profile, config);\n }\n\n if (this.model !== null) {\n validateModelName(this.model, config);\n }\n\n const lowerLayers = await this.getLowerPrecedenceLayers();\n const currentLayer = this.toPromptLayer();\n const merged = mergePromptLayers(...lowerLayers, currentLayer);\n\n if (currentLayer.model && !merged.ai.profile) {\n throw new Error(\n `Prompt \"${this.key}\" model overrides require an effective prompt profile`,\n );\n }\n }\n\n private async getLowerPrecedenceLayers(): Promise<PromptLayer[]> {\n const definition = PromptRegistry.get(this.key);\n const config = getPromptConfig();\n const layers: PromptLayer[] = [];\n\n if (definition) {\n layers.push({\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n });\n }\n\n layers.push(normalizePromptLayer(config.prompts?.[this.key]));\n\n const { PromptOverrideCollection } = await import(\n '../collections/PromptOverrideCollection.js'\n );\n const collection = await PromptOverrideCollection.create({\n db: this.options.db ?? this.options.persistence,\n });\n\n if (this.tenantId) {\n const appOverride = await collection.getAppOverride(this.key, {\n excludeId: this.id ?? undefined,\n });\n if (appOverride) {\n layers.push(appOverride.toPromptLayer());\n }\n }\n\n return layers;\n }\n\n private normalizeParamsForPersistence(): void {\n const rawParams = this.params as unknown;\n\n if (rawParams === null || rawParams === undefined) {\n this.params = null;\n return;\n }\n\n if (typeof rawParams === 'string') {\n this.params = rawParams;\n return;\n }\n\n if (typeof rawParams === 'object' && !Array.isArray(rawParams)) {\n this.params = serializePromptParams(rawParams as PromptParams);\n return;\n }\n\n throw new Error(\n `Prompt \"${this.key}\" params must be a JSON object or JSON string`,\n );\n }\n\n private async getPersistedIdentity(): Promise<PromptOverrideIdentity | null> {\n if (!this.id) {\n return null;\n }\n\n const existing = await this.db.get(this.tableName, { id: this.id });\n if (!existing) {\n return null;\n }\n\n return {\n key: String((existing as Record<string, unknown>).key ?? this.key),\n tenantId:\n (existing as Record<string, unknown>).tenantId !== undefined\n ? ((existing as Record<string, unknown>).tenantId as string | null)\n : (((existing as Record<string, unknown>).tenant_id as\n | string\n | null\n | undefined) ?? null),\n };\n }\n}\n","import { SmrtCollection } from '@happyvertical/smrt-core';\nimport { PromptOverride } from '../models/PromptOverride.js';\nimport type { PromptOverrideScopeType } from '../types.js';\n\nexport class PromptOverrideCollection extends SmrtCollection<PromptOverride> {\n static readonly _itemClass = PromptOverride;\n\n private excludeOverrideId(\n items: PromptOverride[],\n excludeId?: string,\n ): PromptOverride[] {\n return items.filter((item) => (excludeId ? item.id !== excludeId : true));\n }\n\n async getAppOverride(\n key: string,\n options: { excludeId?: string } = {},\n ): Promise<PromptOverride | null> {\n const items = await this.list({ where: { key, tenantId: null } });\n return this.excludeOverrideId(items, options.excludeId)[0] ?? null;\n }\n\n async getTenantOverride(\n key: string,\n tenantId: string,\n options: { excludeId?: string } = {},\n ): Promise<PromptOverride | null> {\n const items = await this.list({ where: { key, tenantId } });\n return this.excludeOverrideId(items, options.excludeId)[0] ?? null;\n }\n\n async getResolutionLayers(\n key: string,\n tenantId?: string | null,\n options: { excludeId?: string } = {},\n ): Promise<{ app: PromptOverride | null; tenant: PromptOverride | null }> {\n const [app, tenant] = await Promise.all([\n this.getAppOverride(key, options),\n tenantId != null\n ? this.getTenantOverride(key, tenantId, options)\n : Promise.resolve(null),\n ]);\n\n return {\n app,\n tenant,\n };\n }\n\n /**\n * The override row for every key in `keys` at one scope, in a single query.\n *\n * Used by `PromptSettingsService.listPromptSettings()` to enumerate the\n * whole registry's override state without one round trip per key. Because\n * this is an enumeration read — a host-configured\n * `defaultListLimit`/`maxListLimit` on the collection's options would\n * silently drop keys past the cap, changing which prompts a management\n * screen reports as overridden, with no error (the #3056 hazard class in\n * `@happyvertical/smrt-features`'s `getOverrideMap`) — callers that need the\n * full map construct this collection through\n * `PromptSettingsService.create()`, which strips those bounds.\n */\n async getOverrideMapForKeys(\n keys: string[],\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<Map<string, PromptOverride>> {\n const result = new Map<string, PromptOverride>();\n if (keys.length === 0) {\n return result;\n }\n\n const tenantId = scopeType === 'app' ? null : scopeId;\n const rows = await this.list({ where: { key: keys, tenantId } });\n for (const row of rows) {\n result.set(row.key, row);\n }\n\n return result;\n }\n\n /** The override row for a scope request, in the vocabulary used at the write boundary. */\n async findByScope(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<PromptOverride | null> {\n return scopeType === 'app'\n ? this.getAppOverride(key)\n : this.getTenantOverride(key, scopeId);\n }\n\n /**\n * Set (or clear, with `template: null`) the `template` field of the override\n * row for one scope, creating the row if it did not exist. Other fields\n * (`profile`, `model`, `params`) on an existing row are left untouched, per\n * this package's field-by-field inheritance model.\n */\n async setTemplateOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n const existing = await this.findByScope(key, scopeType, scopeId);\n\n if (existing) {\n existing.template = template;\n await existing.save();\n return existing;\n }\n\n const created = await this.create({\n key,\n tenantId: scopeType === 'app' ? null : scopeId,\n template,\n });\n await created.save();\n return created;\n }\n\n /** Remove the override row for one scope entirely, if one exists. */\n async removeOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<boolean> {\n const existing = await this.findByScope(key, scopeType, scopeId);\n if (!existing) {\n return false;\n }\n\n await existing.delete();\n return true;\n }\n}\n","import type { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport type { PromptOverride } from './models/PromptOverride.js';\nimport { APP_PROMPT_SCOPE_ID, type PromptOverrideScopeType } from './types.js';\n\n/** One override write the host must authorize before it runs (mirrors #3013). */\nexport interface PromptOverrideWriteRequest {\n operation: 'set' | 'remove';\n key: string;\n scopeType: PromptOverrideScopeType;\n scopeId: string;\n /** Present for `set`. `null` clears the template field. */\n template?: string | null;\n}\n\n/**\n * The host's explicit authorization decision for one override write. Return\n * `true` only when the current caller may write that exact scope; anything\n * else denies.\n */\nexport type PromptOverrideAuthorizer = (\n request: PromptOverrideWriteRequest,\n) => boolean | Promise<boolean>;\n\n/** Thrown when the authorizer does not return `true`. Nothing is written. */\nexport class PromptOverrideAuthorizationError extends Error {\n readonly status = 403;\n constructor(readonly request: PromptOverrideWriteRequest) {\n super(\n `Prompt override ${request.operation} denied for ${request.scopeType} scope`,\n );\n this.name = 'PromptOverrideAuthorizationError';\n }\n}\n\n/**\n * Thrown when a write names a scope the resolver never reads: an unknown scope\n * type, an app scope other than {@link APP_PROMPT_SCOPE_ID}, or a blank /\n * untrimmed / non-string tenant id. Checked before the authorizer runs, so a\n * malformed tenant scope can never resolve to the app-wide row. Nothing is\n * written.\n */\nexport class InvalidPromptScopeError extends Error {\n readonly status = 400;\n constructor(\n readonly scopeType: string,\n readonly scopeId: string,\n reason: string,\n ) {\n super(`Invalid prompt override scope (${scopeType}): ${reason}`);\n this.name = 'InvalidPromptScopeError';\n }\n}\n\n/** Reject any scope the resolver does not read (see {@link InvalidPromptScopeError}). */\nexport function assertValidPromptScope(\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n): void {\n if (scopeType !== 'app' && scopeType !== 'tenant') {\n throw new InvalidPromptScopeError(\n String(scopeType),\n String(scopeId),\n 'scope type must be \"app\" or \"tenant\"',\n );\n }\n if (typeof scopeId !== 'string') {\n throw new InvalidPromptScopeError(\n scopeType,\n String(scopeId),\n 'scope id must be a string',\n );\n }\n if (scopeType === 'app' && scopeId !== APP_PROMPT_SCOPE_ID) {\n throw new InvalidPromptScopeError(\n scopeType,\n scopeId,\n `the app scope is only ever \"${APP_PROMPT_SCOPE_ID}\"`,\n );\n }\n if (\n scopeType === 'tenant' &&\n (!scopeId.trim() ||\n scopeId !== scopeId.trim() ||\n scopeId === APP_PROMPT_SCOPE_ID)\n ) {\n throw new InvalidPromptScopeError(\n scopeType,\n scopeId,\n 'a tenant scope id must be non-blank, already trimmed, and not the app scope id',\n );\n }\n}\n\n/**\n * Authorized write path for prompt overrides (mirrors `FeatureOverrideService`,\n * #3013). Override rows are authorization state for every scope and\n * `PromptOverride` is not tenant-scoped by the request context, so generated\n * surfaces are closed. Hosts that let callers change prompt text construct\n * this service with an authorizer bound to the current caller and write\n * through it; every write asks the authorizer first and fails closed.\n */\nexport class PromptOverrideService {\n constructor(\n private readonly overrides: PromptOverrideCollection,\n private readonly authorize: PromptOverrideAuthorizer,\n ) {}\n\n async setTemplateOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n await this.require({ operation: 'set', key, scopeType, scopeId, template });\n return this.overrides.setTemplateOverride(\n key,\n scopeType,\n scopeId,\n template,\n );\n }\n\n async removeOverride(\n key: string,\n scopeType: PromptOverrideScopeType,\n scopeId: string,\n ): Promise<boolean> {\n await this.require({ operation: 'remove', key, scopeType, scopeId });\n return this.overrides.removeOverride(key, scopeType, scopeId);\n }\n\n private async require(request: PromptOverrideWriteRequest): Promise<void> {\n assertValidPromptScope(request.scopeType, request.scopeId);\n let allowed = false;\n try {\n allowed = (await this.authorize(request)) === true;\n } catch {\n allowed = false;\n }\n if (!allowed) throw new PromptOverrideAuthorizationError(request);\n }\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n getCachedPromptBase,\n getPromptCacheGeneration,\n setCachedPromptBase,\n} from './cache.js';\nimport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport { PromptRegistry } from './prompt-registry.js';\nimport type {\n PromptCacheValue,\n PromptPackageConfig,\n ResolvedPrompt,\n ResolvePromptOptions,\n} from './types.js';\nimport {\n buildResolvedAI,\n mergePromptLayers,\n normalizePromptLayer,\n renderPromptTemplate,\n} from './utils.js';\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\nasync function loadPromptBase(\n key: string,\n options: ResolvePromptOptions,\n): Promise<PromptCacheValue> {\n const definition = PromptRegistry.get(key);\n if (!definition) {\n throw new Error(`Unknown prompt key \"${key}\"`);\n }\n\n const tenantId =\n options.tenantId !== undefined ? options.tenantId : (getTenantId() ?? null);\n\n let collection: PromptOverrideCollection | null = null;\n let cacheDb: ResolvePromptOptions['db'] | undefined = options.db;\n if (options.db) {\n const initializedCollection = await PromptOverrideCollection.create({\n db: options.db,\n });\n collection = initializedCollection;\n cacheDb = initializedCollection.db as ResolvePromptOptions['db'];\n }\n\n const cached = getCachedPromptBase(key, tenantId, cacheDb);\n if (cached) {\n return cached;\n }\n\n // Capture the invalidation generation before the asynchronous layer loads. A\n // write that lands while they are in flight bumps it, and the cache write\n // below is then refused rather than repopulating the key the write just\n // invalidated with the pre-write value.\n const loadedAtGeneration = getPromptCacheGeneration(key, cacheDb);\n\n const config = getPromptConfig();\n const layers = [\n {\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n },\n normalizePromptLayer(config.prompts?.[key]),\n ];\n\n if (collection) {\n const stored = await collection.getResolutionLayers(key, tenantId);\n\n if (stored.app) {\n layers.push(stored.app.toPromptLayer());\n }\n\n if (stored.tenant) {\n layers.push(stored.tenant.toPromptLayer());\n }\n }\n\n const merged = mergePromptLayers(...layers);\n const value: PromptCacheValue = {\n key,\n template: merged.template,\n ai: merged.ai,\n };\n\n setCachedPromptBase(key, tenantId, cacheDb, value, loadedAtGeneration);\n return value;\n}\n\nexport async function resolvePrompt(\n key: string,\n options: ResolvePromptOptions = {},\n): Promise<ResolvedPrompt> {\n const config = getPromptConfig();\n const base = await loadPromptBase(key, options);\n const runtimeOverride = normalizePromptLayer(options.override);\n const merged = mergePromptLayers(\n {\n template: base.template,\n profile: base.ai.profile ?? null,\n model: base.ai.model ?? null,\n params: base.ai.params,\n },\n runtimeOverride,\n );\n\n return {\n key,\n template: merged.template,\n text: renderPromptTemplate(merged.template, options.variables),\n ai: buildResolvedAI(merged.ai, config),\n };\n}\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport type {\n SmrtClassOptions,\n SmrtCollectionOptions,\n} from '@happyvertical/smrt-core';\nimport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nimport type { PromptOverride } from './models/PromptOverride.js';\nimport {\n assertValidPromptScope,\n type PromptOverrideAuthorizer,\n PromptOverrideService,\n} from './prompt-override-service.js';\nimport { PromptRegistry } from './prompt-registry.js';\nimport {\n APP_PROMPT_SCOPE_ID,\n type PromptDefinition,\n type PromptEditableConfig,\n type PromptLayer,\n type PromptOverrideScopeType,\n type PromptPackageConfig,\n} from './types.js';\nimport { mergePromptLayers, normalizePromptLayer } from './utils.js';\n\nfunction getPromptConfig(): PromptPackageConfig {\n return getPackageConfig<PromptPackageConfig>('prompts', {\n profiles: {},\n prompts: {},\n });\n}\n\n/**\n * The caller's options with its list bounds removed.\n *\n * `SmrtCollection.create()` forwards `defaultListLimit`/`maxListLimit` from\n * any options bag it is handed (#2367), so a host that sets those\n * application-wide would silently cap the bulk override-enumeration read\n * {@link PromptSettingsService.listPromptSettings} runs\n * (`getOverrideMapForKeys`) — a management screen showing every prompt, not a\n * user-facing page of results. A dropped row here is an override an operator\n * cannot see, and the prompt then reports as unoverridden, silently (the\n * `#3056` hazard class in `@happyvertical/smrt-features`'s `getOverrideMap`,\n * applied here proactively rather than left for a follow-up). Only the list\n * bounds are stripped; the database and every other option still apply.\n */\nfunction withoutListBounds(\n options: SmrtClassOptions | SmrtCollectionOptions,\n): SmrtCollectionOptions {\n return { ...options, defaultListLimit: undefined, maxListLimit: undefined };\n}\n\n/** The level that supplied a prompt's effective template. */\nexport type PromptSettingsLevel = 'default' | 'config' | 'app' | 'tenant';\n\n/**\n * One prompt, rendered for a management screen: the code-owned definition,\n * the text actually in effect for the requested tenant, and the raw override\n * state at each scope so the UI can show *why* it is in effect and what\n * reverting a scope produces.\n */\nexport interface PromptSettingsRow {\n /**\n * The persisted identifier. Renaming it orphans every existing override —\n * see the warning on {@link PromptSettingsService}.\n */\n key: string;\n /** Human description from the definition; may be empty. */\n description: string;\n /** Which fields a stored override may change, from the definition. */\n editable: PromptEditableConfig;\n /** The code-registered template, before the config layer or any override. */\n defaultTemplate: string;\n /**\n * What {@link resolvePrompt} resolves the template to for the requested\n * context — the text the application actually uses (unrendered: no\n * `{variable}` substitution).\n */\n effectiveTemplate: string;\n /** The app-level override row's `template` field, or `null` when there is none. */\n appTemplate: string | null;\n /**\n * The tenant-level override row's `template` field, or `null` when there is\n * none (or when no `tenantId` was requested).\n */\n tenantTemplate: string | null;\n /**\n * What the **app** scope's \"revert to default\" produces: the code default\n * merged with the config-file layer. Always knowable — nothing sits above\n * the app scope — unlike {@link inheritedTemplate}.\n */\n appDefaultTemplate: string;\n /**\n * What the **tenant** scope's \"revert to default\" produces: the code\n * default, the config-file layer, and the app-level override, merged with\n * no tenant override of its own. `null` when no `tenantId` was requested.\n *\n * This is the value a \"revert to default\" control for the tenant scope must\n * show or apply — never {@link defaultTemplate}, which ignores the config\n * layer and any app-level override and would silently discard them.\n */\n inheritedTemplate: string | null;\n /** Which level supplied {@link effectiveTemplate}. */\n supplyingLevel: PromptSettingsLevel;\n}\n\n/** Selection for {@link PromptSettingsService.listPromptSettings}. */\nexport interface ListPromptSettingsOptions {\n /**\n * Tenant whose overrides and effective template to report. Omit for an\n * app-only view.\n */\n tenantId?: string | null;\n /**\n * Restrict to an explicit allowlist of keys. Keys with no definition are\n * simply absent from the result — this filters, it does not validate.\n */\n keys?: string[];\n}\n\n/** One override write requested through {@link PromptSettingsService}. */\nexport interface SetPromptOverrideRequest {\n key: string;\n scopeType: PromptOverrideScopeType;\n scopeId: string;\n /** `null` clears the override, returning the scope to whatever it inherits. */\n template: string | null;\n}\n\n/**\n * Thrown when a write names a `key` that has no registered {@link PromptDefinition}.\n * Nothing is written.\n *\n * This is the generalized form of the per-app \"is this one of my keys?\" guard\n * every consumer would otherwise hand-roll to keep a form post from creating an\n * override for an arbitrary string.\n */\nexport class UnknownPromptKeyError extends Error {\n readonly status = 400;\n constructor(readonly key: string) {\n super(`Unknown prompt key: ${key}`);\n this.name = 'UnknownPromptKeyError';\n }\n}\n\n/**\n * Thrown when a write would set a field the definition's `editable` config\n * does not allow overriding. Nothing is written.\n */\nexport class PromptFieldNotEditableError extends Error {\n readonly status = 400;\n constructor(\n readonly key: string,\n readonly field: string,\n ) {\n super(`Prompt \"${key}\" does not allow ${field} overrides`);\n this.name = 'PromptFieldNotEditableError';\n }\n}\n\n/** Options for {@link PromptSettingsService.create}. */\nexport interface PromptSettingsServiceOptions {\n /**\n * The host's authorization decision for each override write, bound to the\n * current caller. **Omitting it makes the service read-only**: every write\n * then fails closed with `PromptOverrideAuthorizationError`. This package\n * never decides who may write.\n */\n authorize?: PromptOverrideAuthorizer;\n}\n\n/**\n * Read and write side of a prompt management screen, so consumers do not\n * re-derive the row shape or the unknown-key guard.\n *\n * **Authorization stays with the consumer.** This service makes no\n * authorization decision of its own: reads are unfiltered, and every write is\n * delegated to {@link PromptOverrideService}, which asks the host-supplied\n * {@link PromptOverrideAuthorizer} first and fails closed. Call it only from\n * server code that has already established who the caller is. See\n * `packages/prompts/README.md` for the consumer recipe.\n *\n * **Prompt keys are persisted identifiers.** Overrides are stored keyed by the\n * exact `key` string and resolved by that string at runtime. Renaming a key\n * orphans every existing override, silently reverting all tenants to the\n * registry default. Treat a key as immutable once shipped; a rename needs a\n * data migration, not an edit.\n */\nexport class PromptSettingsService {\n private readonly writes: PromptOverrideService;\n\n constructor(\n private readonly overrides: PromptOverrideCollection,\n authorize?: PromptOverrideAuthorizer,\n ) {\n this.writes = new PromptOverrideService(\n overrides,\n authorize ?? (() => false),\n );\n }\n\n /**\n * Build a service over the given database options.\n *\n * The internal bulk override-enumeration read {@link listPromptSettings}\n * runs is always issued without the caller's\n * `defaultListLimit`/`maxListLimit` — see {@link withoutListBounds}. Only\n * that read is affected; a `db` option is still honored.\n *\n * @param options - SMRT database options, as passed to any collection.\n * @param serviceOptions - Host authorizer. Omit for a read-only (load-function) service.\n */\n static async create(\n options: SmrtClassOptions = {},\n serviceOptions: PromptSettingsServiceOptions = {},\n ): Promise<PromptSettingsService> {\n const overrides = await PromptOverrideCollection.create(\n withoutListBounds(options),\n );\n return new PromptSettingsService(\n overrides as PromptOverrideCollection,\n serviceOptions.authorize,\n );\n }\n\n /**\n * One {@link PromptSettingsRow} per matching registered prompt, ordered by\n * key, so a rendered list is stable across loads.\n *\n * Makes no authorization decision — the caller has already decided that this\n * principal may see this tenant's prompts.\n */\n async listPromptSettings(\n options: ListPromptSettingsOptions = {},\n ): Promise<PromptSettingsRow[]> {\n const definitions = this.loadDefinitions(options);\n const keys = definitions.map((definition) => definition.key);\n const tenantId = options.tenantId;\n\n // Two bulk reads instead of up to 2N: see getOverrideMapForKeys for why\n // these must run through a bounds-stripped collection (#3056 class).\n const [appOverrides, tenantOverrides] = await Promise.all([\n this.overrides.getOverrideMapForKeys(keys, 'app', APP_PROMPT_SCOPE_ID),\n tenantId\n ? this.overrides.getOverrideMapForKeys(keys, 'tenant', tenantId)\n : Promise.resolve(new Map<string, PromptOverride>()),\n ]);\n\n return definitions.map((definition) =>\n this.toRow(\n definition,\n tenantId,\n appOverrides.get(definition.key) ?? null,\n tenantOverrides.get(definition.key) ?? null,\n ),\n );\n }\n\n /** The single row for one key, or `null` when no definition owns that key. */\n async getPromptSetting(\n key: string,\n tenantId?: string | null,\n ): Promise<PromptSettingsRow | null> {\n const definition = PromptRegistry.get(key);\n if (!definition) {\n return null;\n }\n\n const [appOverride, tenantOverride] = await Promise.all([\n this.overrides.getAppOverride(key),\n tenantId\n ? this.overrides.getTenantOverride(key, tenantId)\n : Promise.resolve(null),\n ]);\n\n return this.toRow(definition, tenantId, appOverride, tenantOverride);\n }\n\n /**\n * Apply one override change to the `template` field.\n *\n * Refuses any `key` without a registered {@link PromptDefinition}, any scope\n * the resolver would never read back, and a non-`null` template when the\n * definition's `editable.template` is `false`, then delegates to\n * {@link PromptOverrideService} so the host authorizer decides whether this\n * caller may write this scope. `template: null` clears the override.\n *\n * @throws {UnknownPromptKeyError} when the key has no definition.\n * @throws {InvalidPromptScopeError} when the scope is not one the resolver reads.\n * @throws {PromptFieldNotEditableError} when the definition disallows template overrides.\n * @throws `PromptOverrideAuthorizationError` when the authorizer declines.\n */\n async setPromptOverride(\n request: SetPromptOverrideRequest,\n ): Promise<PromptOverride> {\n const { key, scopeType, scopeId, template } = request;\n\n assertValidPromptScope(scopeType, scopeId);\n const definition = this.assertKnownPromptKey(key);\n\n if (template !== null && !definition.editable.template) {\n throw new PromptFieldNotEditableError(key, 'template');\n }\n\n return this.writes.setTemplateOverride(key, scopeType, scopeId, template);\n }\n\n /** {@link setPromptOverride} for the app-wide scope. */\n async setAppPromptOverride(\n key: string,\n template: string | null,\n ): Promise<PromptOverride> {\n return this.setPromptOverride({\n key,\n scopeType: 'app',\n scopeId: APP_PROMPT_SCOPE_ID,\n template,\n });\n }\n\n /** {@link setPromptOverride} for one tenant. */\n async setTenantPromptOverride(\n key: string,\n tenantId: string,\n template: string | null,\n ): Promise<PromptOverride> {\n return this.setPromptOverride({\n key,\n scopeType: 'tenant',\n scopeId: tenantId,\n template,\n });\n }\n\n private assertKnownPromptKey(key: string): PromptDefinition {\n const trimmed = typeof key === 'string' ? key.trim() : '';\n if (!trimmed || trimmed !== key) {\n throw new UnknownPromptKeyError(String(key));\n }\n const definition = PromptRegistry.get(trimmed);\n if (!definition) {\n throw new UnknownPromptKeyError(trimmed);\n }\n return definition;\n }\n\n private loadDefinitions(\n options: ListPromptSettingsOptions,\n ): PromptDefinition[] {\n const all = PromptRegistry.getAll();\n const allowed = options.keys ? new Set(options.keys) : null;\n const selected = allowed\n ? all.filter((definition) => allowed.has(definition.key))\n : all;\n\n return [...selected].sort((a, b) => a.key.localeCompare(b.key));\n }\n\n private toRow(\n definition: PromptDefinition,\n tenantId: string | null | undefined,\n appOverride: PromptOverride | null,\n tenantOverride: PromptOverride | null,\n ): PromptSettingsRow {\n const { key } = definition;\n const config = getPromptConfig();\n\n const registryLayer: PromptLayer = {\n template: definition.template,\n profile: definition.ai.profile ?? null,\n model: definition.ai.model ?? null,\n params: definition.ai.params,\n };\n const configLayer = normalizePromptLayer(config.prompts?.[key]);\n\n const appLayer = appOverride ? appOverride.toPromptLayer() : null;\n const tenantLayer = tenantOverride ? tenantOverride.toPromptLayer() : null;\n\n // What the \"app\" scope's own revert-to-default produces: registry + config\n // only. This intentionally excludes the app override itself, so it must\n // NOT be reused as the app-only effective value below (that bug shipped\n // and broke both `effectiveTemplate` when no tenant is requested and every\n // tenant's inherited fallback until caught by this package's own tests).\n const appDefaultMerge = mergePromptLayers(registryLayer, configLayer);\n const inheritedMerge = tenantId\n ? mergePromptLayers(registryLayer, configLayer, appLayer)\n : null;\n // The effective template always includes the app override when present;\n // only the tenant layer is conditional on a requested tenantId.\n const effectiveMerge = mergePromptLayers(\n registryLayer,\n configLayer,\n appLayer,\n tenantId ? tenantLayer : null,\n );\n\n const appTemplate = appOverride?.template ?? null;\n const tenantTemplate = tenantId ? (tenantOverride?.template ?? null) : null;\n\n let supplyingLevel: PromptSettingsLevel = 'default';\n if (tenantId && tenantTemplate != null) {\n supplyingLevel = 'tenant';\n } else if (appTemplate != null) {\n supplyingLevel = 'app';\n } else if (configLayer.template != null) {\n supplyingLevel = 'config';\n }\n\n return {\n key,\n description: definition.description,\n editable: definition.editable,\n defaultTemplate: definition.template,\n effectiveTemplate: effectiveMerge.template,\n appTemplate,\n tenantTemplate,\n appDefaultTemplate: appDefaultMerge.template,\n inheritedTemplate: inheritedMerge ? inheritedMerge.template : null,\n supplyingLevel,\n };\n }\n}\n\n/**\n * Reject a scope the resolver would never read back.\n *\n * `PromptOverride` rows are looked up by the exact `(key, tenantId)` pair —\n * `tenantId: null` for the app scope, a tenant id otherwise. A row written\n * under a scope nothing queries is invisible state: it never takes effect,\n * and the host authorizer cannot catch it, because `scopeType: 'app'` with\n * someone else's tenant id looks like an ordinary app write to an authorizer\n * that only gates the app scope.\n */\n","/**\n * @happyvertical/smrt-prompts\n *\n * Code-first prompts with config overrides, stored app/tenant overrides,\n * and runtime resolution helpers for SMRT applications.\n *\n * @packageDocumentation\n */\n\n// Self-register this package's manifest before any @smrt() decorator fires\n// downstream. Must come first so the side effect runs ahead of the class\n// module loads below. See __smrt-register__.ts for issue #1132 context.\nimport './__smrt-register__.js';\n\nexport { clearPromptCache, getPromptCacheTtlMs } from './cache.js';\nexport { PromptOverrideCollection } from './collections/PromptOverrideCollection.js';\nexport {\n PromptOverride,\n type PromptOverrideOptions,\n} from './models/PromptOverride.js';\nexport {\n InvalidPromptScopeError,\n PromptOverrideAuthorizationError,\n type PromptOverrideAuthorizer,\n PromptOverrideService,\n type PromptOverrideWriteRequest,\n} from './prompt-override-service.js';\nexport { definePrompt, PromptRegistry } from './prompt-registry.js';\nexport { resolvePrompt } from './prompt-resolver.js';\nexport {\n type ListPromptSettingsOptions,\n PromptFieldNotEditableError,\n type PromptSettingsLevel,\n type PromptSettingsRow,\n PromptSettingsService,\n type PromptSettingsServiceOptions,\n type SetPromptOverrideRequest,\n UnknownPromptKeyError,\n} from './prompt-settings.js';\nexport type {\n NormalizedPromptAI,\n PromptAIInput,\n PromptConfigOverrideInput,\n PromptDefinition,\n PromptDefinitionInput,\n PromptEditableConfig,\n PromptLayer,\n PromptOverrideScopeType,\n PromptPackageConfig,\n PromptParams,\n PromptProfileConfig,\n ResolvedPrompt,\n ResolvedPromptAI,\n ResolvePromptOptions,\n} from './types.js';\nexport { APP_PROMPT_SCOPE_ID } from './types.js';\n\n/** @internal */\nexport const PACKAGE_VERSION_INITIALIZED = true;\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-prompts",
5
- "packageVersion": "0.55.5",
5
+ "packageVersion": "0.55.6",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-prompts:PromptOverrideCollection": {
8
8
  "name": "promptoverridecollection",
@@ -3,12 +3,12 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-prompts",
6
- "packageVersion": "0.55.5",
6
+ "packageVersion": "0.55.6",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "37f96638cbe857c3832a1870fa6adb5f8c1350adcbf3bce89fd267ac8712befe",
11
- "packageJson": "cab2a1eaa5df9cf27166d8bbcd46b5b09384157246305f7dfc7bb6754a23d9b7",
10
+ "manifest": "9850c7f1c6e567ee20d536121335e0af60c470ba631d1ab3a0f8a14b5520591f",
11
+ "packageJson": "52b5a217bca738ccab5c168b9d574c1d2f43f63a974c27519f270a3ea89c26bc",
12
12
  "agents": "45d48bbf65b540f94cd3a9c261f21c883d3f5fef0681931d5438842cf1727a66"
13
13
  },
14
14
  "exports": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-prompts",
3
- "version": "0.55.5",
3
+ "version": "0.55.6",
4
4
  "description": "Typed prompt registry, override resolution, and tenant-aware prompt settings for SMRT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,14 +24,14 @@
24
24
  "./manifest.json": "./dist/manifest.json"
25
25
  },
26
26
  "dependencies": {
27
- "@happyvertical/smrt-config": "0.55.5",
28
- "@happyvertical/smrt-core": "0.55.5",
29
- "@happyvertical/smrt-tenancy": "0.55.5",
30
- "@happyvertical/smrt-ui": "0.55.5",
27
+ "@happyvertical/smrt-config": "0.55.6",
28
+ "@happyvertical/smrt-core": "0.55.6",
29
+ "@happyvertical/smrt-tenancy": "0.55.6",
30
+ "@happyvertical/smrt-ui": "0.55.6",
31
31
  "@happyvertical/sql": "^0.102.4"
32
32
  },
33
33
  "devDependencies": {
34
- "@happyvertical/smrt-vitest": "0.55.5",
34
+ "@happyvertical/smrt-vitest": "0.55.6",
35
35
  "@sveltejs/package": "^2.5.8",
36
36
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
37
37
  "@types/node": "24.13.6",