@happyvertical/smrt-prompts 0.51.21 → 0.51.29
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/AGENTS.md +34 -1
- package/README.md +148 -2
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/cache.d.ts +33 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/collections/PromptOverrideCollection.d.ts +45 -0
- package/dist/collections/PromptOverrideCollection.d.ts.map +1 -0
- package/dist/index.d.ts +12 -174
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +298 -30
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +117 -28
- package/dist/models/PromptOverride.d.ts +32 -0
- package/dist/models/PromptOverride.d.ts.map +1 -0
- package/dist/prompt-override-service.d.ts +56 -0
- package/dist/prompt-override-service.d.ts.map +1 -0
- package/dist/prompt-registry.d.ts +13 -0
- package/dist/prompt-registry.d.ts.map +1 -0
- package/dist/prompt-resolver.d.ts +3 -0
- package/dist/prompt-resolver.d.ts.map +1 -0
- package/dist/prompt-settings.d.ts +188 -0
- package/dist/prompt-settings.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +108 -248
- package/dist/svelte/components/PromptSettingsPanel.svelte +353 -0
- package/dist/svelte/components/PromptSettingsPanel.svelte.d.ts +52 -0
- package/dist/svelte/components/PromptSettingsPanel.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +14 -0
- package/dist/svelte/types.d.ts +75 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +42 -0
- package/dist/types.d.ts +107 -110
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +29 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +27 -8
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { APP_PROMPT_SCOPE_ID } from "./types.js";
|
|
1
2
|
import { ObjectRegistry, SmrtCollection, SmrtObject, field, smrt } from "@happyvertical/smrt-core";
|
|
2
3
|
import { getPackageConfig } from "@happyvertical/smrt-config";
|
|
3
4
|
import { getTenantId } from "@happyvertical/smrt-tenancy";
|
|
@@ -14,7 +15,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
14
15
|
};
|
|
15
16
|
//#endregion
|
|
16
17
|
//#region src/__smrt-register__.ts
|
|
17
|
-
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-prompts\",\"packageVersion\":\"0.51.
|
|
18
|
+
ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-prompts\",\"packageVersion\":\"0.51.29\",\"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\\\" TEXT,\\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\":\"TEXT\",\"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\":\"6f475427\"},\"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\":{\"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\\\" TEXT,\\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\":\"TEXT\",\"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\":\"6f475427\"},\"importPath\":\"@happyvertical/smrt-prompts\"}},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\",\"@happyvertical/smrt-tenancy\"]}"));
|
|
18
19
|
//#endregion
|
|
19
20
|
//#region src/cache.ts
|
|
20
21
|
var PROMPT_CACHE_TTL_MS = 3e4;
|
|
@@ -180,6 +181,7 @@ function normalizePromptDefinitionInput(input) {
|
|
|
180
181
|
return {
|
|
181
182
|
key: input.key,
|
|
182
183
|
template: input.template,
|
|
184
|
+
description: input.description ?? "",
|
|
183
185
|
ai: normalizeAIInput(input.ai),
|
|
184
186
|
editable: normalizeEditableConfig(input.editable)
|
|
185
187
|
};
|
|
@@ -340,7 +342,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
340
342
|
if (kind && result) __defProp(target, key, result);
|
|
341
343
|
return result;
|
|
342
344
|
};
|
|
343
|
-
function getPromptConfig$
|
|
345
|
+
function getPromptConfig$2() {
|
|
344
346
|
return getPackageConfig("prompts", {
|
|
345
347
|
profiles: {},
|
|
346
348
|
prompts: {}
|
|
@@ -443,7 +445,7 @@ var PromptOverride = class extends SmrtObject {
|
|
|
443
445
|
if (!this.key || this.key.trim() === "") throw new Error("PromptOverride.key is required");
|
|
444
446
|
const definition = PromptRegistry.get(this.key);
|
|
445
447
|
if (!definition) throw new Error(`Unknown prompt key "${this.key}"`);
|
|
446
|
-
const config = getPromptConfig$
|
|
448
|
+
const config = getPromptConfig$2();
|
|
447
449
|
const editable = definition.editable;
|
|
448
450
|
if (this.template !== null && !editable.template) throw new Error(`Prompt "${this.key}" does not allow template overrides`);
|
|
449
451
|
if (this.profile !== null && !editable.profile) throw new Error(`Prompt "${this.key}" does not allow profile overrides`);
|
|
@@ -464,7 +466,7 @@ var PromptOverride = class extends SmrtObject {
|
|
|
464
466
|
}
|
|
465
467
|
async getLowerPrecedenceLayers() {
|
|
466
468
|
const definition = PromptRegistry.get(this.key);
|
|
467
|
-
const config = getPromptConfig$
|
|
469
|
+
const config = getPromptConfig$2();
|
|
468
470
|
const layers = [];
|
|
469
471
|
if (definition) layers.push({
|
|
470
472
|
template: definition.template,
|
|
@@ -531,28 +533,9 @@ __decorateClass([field({
|
|
|
531
533
|
PromptOverride = __decorateClass([smrt({
|
|
532
534
|
tableName: "_smrt_prompt_overrides",
|
|
533
535
|
conflictColumns: ["key", "context"],
|
|
534
|
-
api:
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
"create",
|
|
538
|
-
"update",
|
|
539
|
-
"delete"
|
|
540
|
-
] },
|
|
541
|
-
cli: {
|
|
542
|
-
include: [
|
|
543
|
-
"list",
|
|
544
|
-
"get",
|
|
545
|
-
"create",
|
|
546
|
-
"update",
|
|
547
|
-
"delete"
|
|
548
|
-
],
|
|
549
|
-
exclude: [
|
|
550
|
-
"getParams",
|
|
551
|
-
"setParams",
|
|
552
|
-
"toPromptLayer"
|
|
553
|
-
]
|
|
554
|
-
},
|
|
555
|
-
mcp: { include: [] }
|
|
536
|
+
api: false,
|
|
537
|
+
cli: false,
|
|
538
|
+
mcp: false
|
|
556
539
|
})], PromptOverride);
|
|
557
540
|
//#endregion
|
|
558
541
|
//#region src/collections/PromptOverrideCollection.ts
|
|
@@ -583,10 +566,131 @@ var PromptOverrideCollection = class extends SmrtCollection {
|
|
|
583
566
|
tenant
|
|
584
567
|
};
|
|
585
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* The override row for every key in `keys` at one scope, in a single query.
|
|
571
|
+
*
|
|
572
|
+
* Used by `PromptSettingsService.listPromptSettings()` to enumerate the
|
|
573
|
+
* whole registry's override state without one round trip per key. Because
|
|
574
|
+
* this is an enumeration read — a host-configured
|
|
575
|
+
* `defaultListLimit`/`maxListLimit` on the collection's options would
|
|
576
|
+
* silently drop keys past the cap, changing which prompts a management
|
|
577
|
+
* screen reports as overridden, with no error (the #3056 hazard class in
|
|
578
|
+
* `@happyvertical/smrt-features`'s `getOverrideMap`) — callers that need the
|
|
579
|
+
* full map construct this collection through
|
|
580
|
+
* `PromptSettingsService.create()`, which strips those bounds.
|
|
581
|
+
*/
|
|
582
|
+
async getOverrideMapForKeys(keys, scopeType, scopeId) {
|
|
583
|
+
const result = /* @__PURE__ */ new Map();
|
|
584
|
+
if (keys.length === 0) return result;
|
|
585
|
+
const tenantId = scopeType === "app" ? null : scopeId;
|
|
586
|
+
const rows = await this.list({ where: {
|
|
587
|
+
key: keys,
|
|
588
|
+
tenantId
|
|
589
|
+
} });
|
|
590
|
+
for (const row of rows) result.set(row.key, row);
|
|
591
|
+
return result;
|
|
592
|
+
}
|
|
593
|
+
/** The override row for a scope request, in the vocabulary used at the write boundary. */
|
|
594
|
+
async findByScope(key, scopeType, scopeId) {
|
|
595
|
+
return scopeType === "app" ? this.getAppOverride(key) : this.getTenantOverride(key, scopeId);
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Set (or clear, with `template: null`) the `template` field of the override
|
|
599
|
+
* row for one scope, creating the row if it did not exist. Other fields
|
|
600
|
+
* (`profile`, `model`, `params`) on an existing row are left untouched, per
|
|
601
|
+
* this package's field-by-field inheritance model.
|
|
602
|
+
*/
|
|
603
|
+
async setTemplateOverride(key, scopeType, scopeId, template) {
|
|
604
|
+
const existing = await this.findByScope(key, scopeType, scopeId);
|
|
605
|
+
if (existing) {
|
|
606
|
+
existing.template = template;
|
|
607
|
+
await existing.save();
|
|
608
|
+
return existing;
|
|
609
|
+
}
|
|
610
|
+
const created = await this.create({
|
|
611
|
+
key,
|
|
612
|
+
tenantId: scopeType === "app" ? null : scopeId,
|
|
613
|
+
template
|
|
614
|
+
});
|
|
615
|
+
await created.save();
|
|
616
|
+
return created;
|
|
617
|
+
}
|
|
618
|
+
/** Remove the override row for one scope entirely, if one exists. */
|
|
619
|
+
async removeOverride(key, scopeType, scopeId) {
|
|
620
|
+
const existing = await this.findByScope(key, scopeType, scopeId);
|
|
621
|
+
if (!existing) return false;
|
|
622
|
+
await existing.delete();
|
|
623
|
+
return true;
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
//#endregion
|
|
627
|
+
//#region src/prompt-override-service.ts
|
|
628
|
+
var PromptOverrideAuthorizationError = class extends Error {
|
|
629
|
+
constructor(request) {
|
|
630
|
+
super(`Prompt override ${request.operation} denied for ${request.scopeType} scope`);
|
|
631
|
+
this.request = request;
|
|
632
|
+
this.name = "PromptOverrideAuthorizationError";
|
|
633
|
+
}
|
|
634
|
+
request;
|
|
635
|
+
status = 403;
|
|
636
|
+
};
|
|
637
|
+
var InvalidPromptScopeError = class extends Error {
|
|
638
|
+
constructor(scopeType, scopeId, reason) {
|
|
639
|
+
super(`Invalid prompt override scope (${scopeType}): ${reason}`);
|
|
640
|
+
this.scopeType = scopeType;
|
|
641
|
+
this.scopeId = scopeId;
|
|
642
|
+
this.name = "InvalidPromptScopeError";
|
|
643
|
+
}
|
|
644
|
+
scopeType;
|
|
645
|
+
scopeId;
|
|
646
|
+
status = 400;
|
|
647
|
+
};
|
|
648
|
+
function assertValidPromptScope(scopeType, scopeId) {
|
|
649
|
+
if (scopeType !== "app" && scopeType !== "tenant") throw new InvalidPromptScopeError(String(scopeType), String(scopeId), "scope type must be \"app\" or \"tenant\"");
|
|
650
|
+
if (typeof scopeId !== "string") throw new InvalidPromptScopeError(scopeType, String(scopeId), "scope id must be a string");
|
|
651
|
+
if (scopeType === "app" && scopeId !== "__app__") throw new InvalidPromptScopeError(scopeType, scopeId, `the app scope is only ever "${APP_PROMPT_SCOPE_ID}"`);
|
|
652
|
+
if (scopeType === "tenant" && (!scopeId.trim() || scopeId !== scopeId.trim() || scopeId === "__app__")) throw new InvalidPromptScopeError(scopeType, scopeId, "a tenant scope id must be non-blank, already trimmed, and not the app scope id");
|
|
653
|
+
}
|
|
654
|
+
var PromptOverrideService = class {
|
|
655
|
+
constructor(overrides, authorize) {
|
|
656
|
+
this.overrides = overrides;
|
|
657
|
+
this.authorize = authorize;
|
|
658
|
+
}
|
|
659
|
+
overrides;
|
|
660
|
+
authorize;
|
|
661
|
+
async setTemplateOverride(key, scopeType, scopeId, template) {
|
|
662
|
+
await this.require({
|
|
663
|
+
operation: "set",
|
|
664
|
+
key,
|
|
665
|
+
scopeType,
|
|
666
|
+
scopeId,
|
|
667
|
+
template
|
|
668
|
+
});
|
|
669
|
+
return this.overrides.setTemplateOverride(key, scopeType, scopeId, template);
|
|
670
|
+
}
|
|
671
|
+
async removeOverride(key, scopeType, scopeId) {
|
|
672
|
+
await this.require({
|
|
673
|
+
operation: "remove",
|
|
674
|
+
key,
|
|
675
|
+
scopeType,
|
|
676
|
+
scopeId
|
|
677
|
+
});
|
|
678
|
+
return this.overrides.removeOverride(key, scopeType, scopeId);
|
|
679
|
+
}
|
|
680
|
+
async require(request) {
|
|
681
|
+
assertValidPromptScope(request.scopeType, request.scopeId);
|
|
682
|
+
let allowed = false;
|
|
683
|
+
try {
|
|
684
|
+
allowed = await this.authorize(request) === true;
|
|
685
|
+
} catch {
|
|
686
|
+
allowed = false;
|
|
687
|
+
}
|
|
688
|
+
if (!allowed) throw new PromptOverrideAuthorizationError(request);
|
|
689
|
+
}
|
|
586
690
|
};
|
|
587
691
|
//#endregion
|
|
588
692
|
//#region src/prompt-resolver.ts
|
|
589
|
-
function getPromptConfig() {
|
|
693
|
+
function getPromptConfig$1() {
|
|
590
694
|
return getPackageConfig("prompts", {
|
|
591
695
|
profiles: {},
|
|
592
696
|
prompts: {}
|
|
@@ -606,7 +710,7 @@ async function loadPromptBase(key, options) {
|
|
|
606
710
|
const cached = getCachedPromptBase(key, tenantId, cacheDb);
|
|
607
711
|
if (cached) return cached;
|
|
608
712
|
const loadedAtGeneration = getPromptCacheGeneration(key, cacheDb);
|
|
609
|
-
const config = getPromptConfig();
|
|
713
|
+
const config = getPromptConfig$1();
|
|
610
714
|
const layers = [{
|
|
611
715
|
template: definition.template,
|
|
612
716
|
profile: definition.ai.profile ?? null,
|
|
@@ -628,7 +732,7 @@ async function loadPromptBase(key, options) {
|
|
|
628
732
|
return value;
|
|
629
733
|
}
|
|
630
734
|
async function resolvePrompt(key, options = {}) {
|
|
631
|
-
const config = getPromptConfig();
|
|
735
|
+
const config = getPromptConfig$1();
|
|
632
736
|
const base = await loadPromptBase(key, options);
|
|
633
737
|
const runtimeOverride = normalizePromptLayer(options.override);
|
|
634
738
|
const merged = mergePromptLayers({
|
|
@@ -645,9 +749,173 @@ async function resolvePrompt(key, options = {}) {
|
|
|
645
749
|
};
|
|
646
750
|
}
|
|
647
751
|
//#endregion
|
|
752
|
+
//#region src/prompt-settings.ts
|
|
753
|
+
function getPromptConfig() {
|
|
754
|
+
return getPackageConfig("prompts", {
|
|
755
|
+
profiles: {},
|
|
756
|
+
prompts: {}
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
function withoutListBounds(options) {
|
|
760
|
+
return {
|
|
761
|
+
...options,
|
|
762
|
+
defaultListLimit: void 0,
|
|
763
|
+
maxListLimit: void 0
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
var UnknownPromptKeyError = class extends Error {
|
|
767
|
+
constructor(key) {
|
|
768
|
+
super(`Unknown prompt key: ${key}`);
|
|
769
|
+
this.key = key;
|
|
770
|
+
this.name = "UnknownPromptKeyError";
|
|
771
|
+
}
|
|
772
|
+
key;
|
|
773
|
+
status = 400;
|
|
774
|
+
};
|
|
775
|
+
var PromptFieldNotEditableError = class extends Error {
|
|
776
|
+
constructor(key, field) {
|
|
777
|
+
super(`Prompt "${key}" does not allow ${field} overrides`);
|
|
778
|
+
this.key = key;
|
|
779
|
+
this.field = field;
|
|
780
|
+
this.name = "PromptFieldNotEditableError";
|
|
781
|
+
}
|
|
782
|
+
key;
|
|
783
|
+
field;
|
|
784
|
+
status = 400;
|
|
785
|
+
};
|
|
786
|
+
var PromptSettingsService = class PromptSettingsService {
|
|
787
|
+
constructor(overrides, authorize) {
|
|
788
|
+
this.overrides = overrides;
|
|
789
|
+
this.writes = new PromptOverrideService(overrides, authorize ?? (() => false));
|
|
790
|
+
}
|
|
791
|
+
overrides;
|
|
792
|
+
writes;
|
|
793
|
+
/**
|
|
794
|
+
* Build a service over the given database options.
|
|
795
|
+
*
|
|
796
|
+
* The internal bulk override-enumeration read {@link listPromptSettings}
|
|
797
|
+
* runs is always issued without the caller's
|
|
798
|
+
* `defaultListLimit`/`maxListLimit` — see {@link withoutListBounds}. Only
|
|
799
|
+
* that read is affected; a `db` option is still honored.
|
|
800
|
+
*
|
|
801
|
+
* @param options - SMRT database options, as passed to any collection.
|
|
802
|
+
* @param serviceOptions - Host authorizer. Omit for a read-only (load-function) service.
|
|
803
|
+
*/
|
|
804
|
+
static async create(options = {}, serviceOptions = {}) {
|
|
805
|
+
const overrides = await PromptOverrideCollection.create(withoutListBounds(options));
|
|
806
|
+
return new PromptSettingsService(overrides, serviceOptions.authorize);
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* One {@link PromptSettingsRow} per matching registered prompt, ordered by
|
|
810
|
+
* key, so a rendered list is stable across loads.
|
|
811
|
+
*
|
|
812
|
+
* Makes no authorization decision — the caller has already decided that this
|
|
813
|
+
* principal may see this tenant's prompts.
|
|
814
|
+
*/
|
|
815
|
+
async listPromptSettings(options = {}) {
|
|
816
|
+
const definitions = this.loadDefinitions(options);
|
|
817
|
+
const keys = definitions.map((definition) => definition.key);
|
|
818
|
+
const tenantId = options.tenantId;
|
|
819
|
+
const [appOverrides, tenantOverrides] = await Promise.all([this.overrides.getOverrideMapForKeys(keys, "app", APP_PROMPT_SCOPE_ID), tenantId ? this.overrides.getOverrideMapForKeys(keys, "tenant", tenantId) : Promise.resolve(/* @__PURE__ */ new Map())]);
|
|
820
|
+
return definitions.map((definition) => this.toRow(definition, tenantId, appOverrides.get(definition.key) ?? null, tenantOverrides.get(definition.key) ?? null));
|
|
821
|
+
}
|
|
822
|
+
/** The single row for one key, or `null` when no definition owns that key. */
|
|
823
|
+
async getPromptSetting(key, tenantId) {
|
|
824
|
+
const definition = PromptRegistry.get(key);
|
|
825
|
+
if (!definition) return null;
|
|
826
|
+
const [appOverride, tenantOverride] = await Promise.all([this.overrides.getAppOverride(key), tenantId ? this.overrides.getTenantOverride(key, tenantId) : Promise.resolve(null)]);
|
|
827
|
+
return this.toRow(definition, tenantId, appOverride, tenantOverride);
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Apply one override change to the `template` field.
|
|
831
|
+
*
|
|
832
|
+
* Refuses any `key` without a registered {@link PromptDefinition}, any scope
|
|
833
|
+
* the resolver would never read back, and a non-`null` template when the
|
|
834
|
+
* definition's `editable.template` is `false`, then delegates to
|
|
835
|
+
* {@link PromptOverrideService} so the host authorizer decides whether this
|
|
836
|
+
* caller may write this scope. `template: null` clears the override.
|
|
837
|
+
*
|
|
838
|
+
* @throws {UnknownPromptKeyError} when the key has no definition.
|
|
839
|
+
* @throws {InvalidPromptScopeError} when the scope is not one the resolver reads.
|
|
840
|
+
* @throws {PromptFieldNotEditableError} when the definition disallows template overrides.
|
|
841
|
+
* @throws `PromptOverrideAuthorizationError` when the authorizer declines.
|
|
842
|
+
*/
|
|
843
|
+
async setPromptOverride(request) {
|
|
844
|
+
const { key, scopeType, scopeId, template } = request;
|
|
845
|
+
assertValidPromptScope(scopeType, scopeId);
|
|
846
|
+
const definition = this.assertKnownPromptKey(key);
|
|
847
|
+
if (template !== null && !definition.editable.template) throw new PromptFieldNotEditableError(key, "template");
|
|
848
|
+
return this.writes.setTemplateOverride(key, scopeType, scopeId, template);
|
|
849
|
+
}
|
|
850
|
+
/** {@link setPromptOverride} for the app-wide scope. */
|
|
851
|
+
async setAppPromptOverride(key, template) {
|
|
852
|
+
return this.setPromptOverride({
|
|
853
|
+
key,
|
|
854
|
+
scopeType: "app",
|
|
855
|
+
scopeId: APP_PROMPT_SCOPE_ID,
|
|
856
|
+
template
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
/** {@link setPromptOverride} for one tenant. */
|
|
860
|
+
async setTenantPromptOverride(key, tenantId, template) {
|
|
861
|
+
return this.setPromptOverride({
|
|
862
|
+
key,
|
|
863
|
+
scopeType: "tenant",
|
|
864
|
+
scopeId: tenantId,
|
|
865
|
+
template
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
assertKnownPromptKey(key) {
|
|
869
|
+
const trimmed = typeof key === "string" ? key.trim() : "";
|
|
870
|
+
if (!trimmed || trimmed !== key) throw new UnknownPromptKeyError(String(key));
|
|
871
|
+
const definition = PromptRegistry.get(trimmed);
|
|
872
|
+
if (!definition) throw new UnknownPromptKeyError(trimmed);
|
|
873
|
+
return definition;
|
|
874
|
+
}
|
|
875
|
+
loadDefinitions(options) {
|
|
876
|
+
const all = PromptRegistry.getAll();
|
|
877
|
+
const allowed = options.keys ? new Set(options.keys) : null;
|
|
878
|
+
return [...allowed ? all.filter((definition) => allowed.has(definition.key)) : all].sort((a, b) => a.key.localeCompare(b.key));
|
|
879
|
+
}
|
|
880
|
+
toRow(definition, tenantId, appOverride, tenantOverride) {
|
|
881
|
+
const { key } = definition;
|
|
882
|
+
const config = getPromptConfig();
|
|
883
|
+
const registryLayer = {
|
|
884
|
+
template: definition.template,
|
|
885
|
+
profile: definition.ai.profile ?? null,
|
|
886
|
+
model: definition.ai.model ?? null,
|
|
887
|
+
params: definition.ai.params
|
|
888
|
+
};
|
|
889
|
+
const configLayer = normalizePromptLayer(config.prompts?.[key]);
|
|
890
|
+
const appLayer = appOverride ? appOverride.toPromptLayer() : null;
|
|
891
|
+
const tenantLayer = tenantOverride ? tenantOverride.toPromptLayer() : null;
|
|
892
|
+
const appDefaultMerge = mergePromptLayers(registryLayer, configLayer);
|
|
893
|
+
const inheritedMerge = tenantId ? mergePromptLayers(registryLayer, configLayer, appLayer) : null;
|
|
894
|
+
const effectiveMerge = mergePromptLayers(registryLayer, configLayer, appLayer, tenantId ? tenantLayer : null);
|
|
895
|
+
const appTemplate = appOverride?.template ?? null;
|
|
896
|
+
const tenantTemplate = tenantId ? tenantOverride?.template ?? null : null;
|
|
897
|
+
let supplyingLevel = "default";
|
|
898
|
+
if (tenantId && tenantTemplate != null) supplyingLevel = "tenant";
|
|
899
|
+
else if (appTemplate != null) supplyingLevel = "app";
|
|
900
|
+
else if (configLayer.template != null) supplyingLevel = "config";
|
|
901
|
+
return {
|
|
902
|
+
key,
|
|
903
|
+
description: definition.description,
|
|
904
|
+
editable: definition.editable,
|
|
905
|
+
defaultTemplate: definition.template,
|
|
906
|
+
effectiveTemplate: effectiveMerge.template,
|
|
907
|
+
appTemplate,
|
|
908
|
+
tenantTemplate,
|
|
909
|
+
appDefaultTemplate: appDefaultMerge.template,
|
|
910
|
+
inheritedTemplate: inheritedMerge ? inheritedMerge.template : null,
|
|
911
|
+
supplyingLevel
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
//#endregion
|
|
648
916
|
//#region src/index.ts
|
|
649
917
|
var PACKAGE_VERSION_INITIALIZED = true;
|
|
650
918
|
//#endregion
|
|
651
|
-
export { PACKAGE_VERSION_INITIALIZED, PromptOverride, PromptOverrideCollection, PromptRegistry, clearPromptCache, definePrompt, getPromptCacheTtlMs, resolvePrompt };
|
|
919
|
+
export { APP_PROMPT_SCOPE_ID, InvalidPromptScopeError, PACKAGE_VERSION_INITIALIZED, PromptFieldNotEditableError, PromptOverride, PromptOverrideAuthorizationError, PromptOverrideCollection, PromptOverrideService, PromptRegistry, PromptSettingsService, UnknownPromptKeyError, clearPromptCache, definePrompt, getPromptCacheTtlMs, resolvePrompt };
|
|
652
920
|
|
|
653
921
|
//# sourceMappingURL=index.js.map
|