promptopskit 0.3.5 → 0.3.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/README.md +2 -1
- package/SKILL.md +4 -1
- package/dist/{chunk-2LK6IILW.js → chunk-6FLNJVE7.js} +5 -2
- package/dist/chunk-6FLNJVE7.js.map +1 -0
- package/dist/{chunk-7RWTFGMS.js → chunk-J32I6DSG.js} +2 -2
- package/dist/{chunk-2X5HFPSD.js → chunk-MN3RQ7DZ.js} +2 -2
- package/dist/{chunk-4QW4BSGE.js → chunk-MYXDJMWV.js} +2 -2
- package/dist/{chunk-M5VKRDIY.js → chunk-SHYKSLVR.js} +146 -3
- package/dist/chunk-SHYKSLVR.js.map +1 -0
- package/dist/{chunk-ROBYCHAW.js → chunk-SOY2CEJM.js} +3 -3
- package/dist/cli/index.js +32 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +173 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +39 -50
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +120 -2
- package/dist/providers/anthropic.cjs.map +1 -1
- package/dist/providers/anthropic.d.cts +2 -2
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +3 -3
- package/dist/providers/gemini.cjs +120 -2
- package/dist/providers/gemini.cjs.map +1 -1
- package/dist/providers/gemini.d.cts +2 -2
- package/dist/providers/gemini.d.ts +2 -2
- package/dist/providers/gemini.js +3 -3
- package/dist/providers/openai.cjs +120 -2
- package/dist/providers/openai.cjs.map +1 -1
- package/dist/providers/openai.d.cts +2 -2
- package/dist/providers/openai.d.ts +2 -2
- package/dist/providers/openai.js +3 -3
- package/dist/providers/openrouter.cjs +120 -2
- package/dist/providers/openrouter.cjs.map +1 -1
- package/dist/providers/openrouter.d.cts +2 -2
- package/dist/providers/openrouter.d.ts +2 -2
- package/dist/providers/openrouter.js +4 -4
- package/dist/{schema-Dq0jKest.d.cts → schema-D145q3Dw.d.cts} +63 -42
- package/dist/{schema-Dq0jKest.d.ts → schema-D145q3Dw.d.ts} +63 -42
- package/dist/testing.cjs +4 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-ClXTFaX-.d.cts → types-B3sWHzIo.d.cts} +8 -1
- package/dist/{types-lLD7m02V.d.ts → types-CXlVWckk.d.ts} +8 -1
- package/dist/usagetap/index.d.cts +2 -2
- package/dist/usagetap/index.d.ts +2 -2
- package/package.json +1 -1
- package/dist/chunk-2LK6IILW.js.map +0 -1
- package/dist/chunk-M5VKRDIY.js.map +0 -1
- /package/dist/{chunk-7RWTFGMS.js.map → chunk-J32I6DSG.js.map} +0 -0
- /package/dist/{chunk-2X5HFPSD.js.map → chunk-MN3RQ7DZ.js.map} +0 -0
- /package/dist/{chunk-4QW4BSGE.js.map → chunk-MYXDJMWV.js.map} +0 -0
- /package/dist/{chunk-ROBYCHAW.js.map → chunk-SOY2CEJM.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -253,7 +253,10 @@ var HistorySchema = import_zod.z.object({
|
|
|
253
253
|
});
|
|
254
254
|
var ContextInputDefinitionObjectSchema = import_zod.z.object({
|
|
255
255
|
name: import_zod.z.string(),
|
|
256
|
-
max_size: import_zod.z.number().int().positive().optional()
|
|
256
|
+
max_size: import_zod.z.number().int().positive().optional(),
|
|
257
|
+
trim: import_zod.z.union([import_zod.z.boolean(), import_zod.z.enum(["start", "end", "both"])]).optional(),
|
|
258
|
+
allow_regex: import_zod.z.string().optional(),
|
|
259
|
+
deny_regex: import_zod.z.string().optional()
|
|
257
260
|
});
|
|
258
261
|
var ContextInputDefinitionSchema = import_zod.z.union([
|
|
259
262
|
import_zod.z.string(),
|
|
@@ -596,6 +599,139 @@ function resolveInlinePromptSource(source, options = {}) {
|
|
|
596
599
|
});
|
|
597
600
|
}
|
|
598
601
|
|
|
602
|
+
// src/context.ts
|
|
603
|
+
var textEncoder = new TextEncoder();
|
|
604
|
+
function getContextInputs(asset) {
|
|
605
|
+
return (asset.context?.inputs ?? []).map(normalizeContextInput);
|
|
606
|
+
}
|
|
607
|
+
function getContextInputNames(asset) {
|
|
608
|
+
return getContextInputs(asset).map((input) => input.name);
|
|
609
|
+
}
|
|
610
|
+
function normalizeContextInput(input) {
|
|
611
|
+
if (typeof input === "string") {
|
|
612
|
+
return { name: input };
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
name: input.name,
|
|
616
|
+
max_size: input.max_size,
|
|
617
|
+
trim: input.trim,
|
|
618
|
+
allow_regex: input.allow_regex,
|
|
619
|
+
deny_regex: input.deny_regex
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
function isTrimEnabled(mode) {
|
|
623
|
+
return mode === true || mode === "start" || mode === "end" || mode === "both";
|
|
624
|
+
}
|
|
625
|
+
function normalizeTrimMode(mode) {
|
|
626
|
+
if (mode === "start") {
|
|
627
|
+
return "start";
|
|
628
|
+
}
|
|
629
|
+
return "end";
|
|
630
|
+
}
|
|
631
|
+
function trimToMaxSize(value, maxSize, mode) {
|
|
632
|
+
const measured = measureContextValueSize(value);
|
|
633
|
+
if (measured <= maxSize) {
|
|
634
|
+
return value;
|
|
635
|
+
}
|
|
636
|
+
const characters = Array.from(value);
|
|
637
|
+
const normalizedMode = normalizeTrimMode(mode);
|
|
638
|
+
if (normalizedMode === "start") {
|
|
639
|
+
let collected2 = "";
|
|
640
|
+
let size2 = 0;
|
|
641
|
+
for (let i = characters.length - 1; i >= 0; i -= 1) {
|
|
642
|
+
const next = characters[i];
|
|
643
|
+
const charSize = measureContextValueSize(next);
|
|
644
|
+
if (size2 + charSize > maxSize) {
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
collected2 = next + collected2;
|
|
648
|
+
size2 += charSize;
|
|
649
|
+
}
|
|
650
|
+
return collected2;
|
|
651
|
+
}
|
|
652
|
+
let collected = "";
|
|
653
|
+
let size = 0;
|
|
654
|
+
for (const char of characters) {
|
|
655
|
+
const charSize = measureContextValueSize(char);
|
|
656
|
+
if (size + charSize > maxSize) {
|
|
657
|
+
break;
|
|
658
|
+
}
|
|
659
|
+
collected += char;
|
|
660
|
+
size += charSize;
|
|
661
|
+
}
|
|
662
|
+
return collected;
|
|
663
|
+
}
|
|
664
|
+
function sanitizeContextVariables(asset, variables = {}, options = {}) {
|
|
665
|
+
const { onContextOverflow } = options;
|
|
666
|
+
const sanitized = { ...variables };
|
|
667
|
+
for (const input of getContextInputs(asset)) {
|
|
668
|
+
const value = sanitized[input.name];
|
|
669
|
+
if (value === void 0) {
|
|
670
|
+
continue;
|
|
671
|
+
}
|
|
672
|
+
let candidate = value;
|
|
673
|
+
if (input.max_size !== void 0) {
|
|
674
|
+
const actualSize = measureContextValueSize(candidate);
|
|
675
|
+
if (actualSize > input.max_size && onContextOverflow) {
|
|
676
|
+
candidate = onContextOverflow({
|
|
677
|
+
promptId: asset.id,
|
|
678
|
+
variable: input.name,
|
|
679
|
+
value: candidate,
|
|
680
|
+
maxSize: input.max_size,
|
|
681
|
+
actualSize
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
if (isTrimEnabled(input.trim) && input.max_size !== void 0) {
|
|
686
|
+
candidate = trimToMaxSize(candidate, input.max_size, input.trim);
|
|
687
|
+
}
|
|
688
|
+
sanitized[input.name] = candidate;
|
|
689
|
+
if (input.allow_regex) {
|
|
690
|
+
const candidate2 = sanitized[input.name];
|
|
691
|
+
const matcher = new RegExp(input.allow_regex);
|
|
692
|
+
if (!matcher.test(candidate2)) {
|
|
693
|
+
throw new Error(
|
|
694
|
+
`POK031: Context variable "${input.name}" failed allow_regex validation for prompt "${asset.id}".`
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
if (input.deny_regex) {
|
|
699
|
+
const candidate2 = sanitized[input.name];
|
|
700
|
+
const matcher = new RegExp(input.deny_regex);
|
|
701
|
+
if (matcher.test(candidate2)) {
|
|
702
|
+
throw new Error(
|
|
703
|
+
`POK032: Context variable "${input.name}" matched deny_regex for prompt "${asset.id}".`
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
return sanitized;
|
|
709
|
+
}
|
|
710
|
+
function measureContextValueSize(value) {
|
|
711
|
+
return textEncoder.encode(value).length;
|
|
712
|
+
}
|
|
713
|
+
function collectContextSizeWarnings(asset, variables = {}) {
|
|
714
|
+
const warnings = [];
|
|
715
|
+
for (const input of getContextInputs(asset)) {
|
|
716
|
+
if (input.max_size === void 0) {
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
const value = variables[input.name];
|
|
720
|
+
if (value === void 0) {
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
const actualSize = measureContextValueSize(value);
|
|
724
|
+
if (actualSize > input.max_size) {
|
|
725
|
+
warnings.push({
|
|
726
|
+
variable: input.name,
|
|
727
|
+
maxSize: input.max_size,
|
|
728
|
+
actualSize
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return warnings;
|
|
733
|
+
}
|
|
734
|
+
|
|
599
735
|
// src/providers/prompt-input.ts
|
|
600
736
|
function isPromptLookup(input) {
|
|
601
737
|
return "path" in input && typeof input.path === "string";
|
|
@@ -619,7 +755,13 @@ function withPromptInputSupport(adapter) {
|
|
|
619
755
|
};
|
|
620
756
|
const renderPrompt2 = async (input, runtime) => {
|
|
621
757
|
const resolved = await resolveProviderPromptInput(input, runtime);
|
|
622
|
-
|
|
758
|
+
const variables = sanitizeContextVariables(resolved, runtime.variables, {
|
|
759
|
+
onContextOverflow: runtime.onContextOverflow
|
|
760
|
+
});
|
|
761
|
+
return adapter.render(resolved, {
|
|
762
|
+
...runtime,
|
|
763
|
+
variables
|
|
764
|
+
});
|
|
623
765
|
};
|
|
624
766
|
return {
|
|
625
767
|
...adapter,
|
|
@@ -906,48 +1048,6 @@ function getAdapter(provider) {
|
|
|
906
1048
|
return adapter;
|
|
907
1049
|
}
|
|
908
1050
|
|
|
909
|
-
// src/context.ts
|
|
910
|
-
var textEncoder = new TextEncoder();
|
|
911
|
-
function getContextInputs(asset) {
|
|
912
|
-
return (asset.context?.inputs ?? []).map(normalizeContextInput);
|
|
913
|
-
}
|
|
914
|
-
function getContextInputNames(asset) {
|
|
915
|
-
return getContextInputs(asset).map((input) => input.name);
|
|
916
|
-
}
|
|
917
|
-
function normalizeContextInput(input) {
|
|
918
|
-
if (typeof input === "string") {
|
|
919
|
-
return { name: input };
|
|
920
|
-
}
|
|
921
|
-
return {
|
|
922
|
-
name: input.name,
|
|
923
|
-
max_size: input.max_size
|
|
924
|
-
};
|
|
925
|
-
}
|
|
926
|
-
function measureContextValueSize(value) {
|
|
927
|
-
return textEncoder.encode(value).length;
|
|
928
|
-
}
|
|
929
|
-
function collectContextSizeWarnings(asset, variables = {}) {
|
|
930
|
-
const warnings = [];
|
|
931
|
-
for (const input of getContextInputs(asset)) {
|
|
932
|
-
if (input.max_size === void 0) {
|
|
933
|
-
continue;
|
|
934
|
-
}
|
|
935
|
-
const value = variables[input.name];
|
|
936
|
-
if (value === void 0) {
|
|
937
|
-
continue;
|
|
938
|
-
}
|
|
939
|
-
const actualSize = measureContextValueSize(value);
|
|
940
|
-
if (actualSize > input.max_size) {
|
|
941
|
-
warnings.push({
|
|
942
|
-
variable: input.name,
|
|
943
|
-
maxSize: input.max_size,
|
|
944
|
-
actualSize
|
|
945
|
-
});
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
return warnings;
|
|
949
|
-
}
|
|
950
|
-
|
|
951
1051
|
// src/validation/levenshtein.ts
|
|
952
1052
|
function levenshtein(a, b) {
|
|
953
1053
|
const m = a.length;
|
|
@@ -1059,6 +1159,30 @@ function validateAsset(asset, frontMatterKeys, filePath) {
|
|
|
1059
1159
|
});
|
|
1060
1160
|
}
|
|
1061
1161
|
}
|
|
1162
|
+
for (const input of getContextInputs(asset)) {
|
|
1163
|
+
if (input.trim !== void 0 && input.trim !== false && input.max_size === void 0) {
|
|
1164
|
+
warnings.push({
|
|
1165
|
+
code: "POK014",
|
|
1166
|
+
message: `Context input "${input.name}" sets trim but has no max_size; trim-to-budget will be skipped.`,
|
|
1167
|
+
filePath
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
const checks = [];
|
|
1171
|
+
if (input.allow_regex) checks.push({ pattern: input.allow_regex, kind: "allow_regex" });
|
|
1172
|
+
if (input.deny_regex) checks.push({ pattern: input.deny_regex, kind: "deny_regex" });
|
|
1173
|
+
for (const check of checks) {
|
|
1174
|
+
try {
|
|
1175
|
+
new RegExp(check.pattern);
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1178
|
+
errors.push({
|
|
1179
|
+
code: "POK013",
|
|
1180
|
+
message: `Invalid context ${check.kind} for "${input.name}": ${reason}`,
|
|
1181
|
+
filePath
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1062
1186
|
return {
|
|
1063
1187
|
valid: errors.length === 0,
|
|
1064
1188
|
errors,
|
|
@@ -1540,7 +1664,10 @@ var PromptOpsKit = class {
|
|
|
1540
1664
|
` + validation.errors.map((e) => ` - ${e}`).join("\n")
|
|
1541
1665
|
);
|
|
1542
1666
|
}
|
|
1543
|
-
const
|
|
1667
|
+
const sanitizedVariables = sanitizeContextVariables(resolved, options.variables, {
|
|
1668
|
+
onContextOverflow: options.onContextOverflow
|
|
1669
|
+
});
|
|
1670
|
+
const contextSizeWarnings = collectContextSizeWarnings(resolved, sanitizedVariables).map(
|
|
1544
1671
|
(warning) => formatContextSizeWarning(resolved, warning)
|
|
1545
1672
|
);
|
|
1546
1673
|
const contextWarningPolicy = this.config.warnings?.contextSize;
|
|
@@ -1550,7 +1677,7 @@ var PromptOpsKit = class {
|
|
|
1550
1677
|
}
|
|
1551
1678
|
}
|
|
1552
1679
|
const request = adapter.render(resolved, {
|
|
1553
|
-
variables:
|
|
1680
|
+
variables: sanitizedVariables,
|
|
1554
1681
|
history: options.history,
|
|
1555
1682
|
toolRegistry: options.toolRegistry,
|
|
1556
1683
|
strict: options.strict
|