promptopskit 0.8.1 → 0.9.0
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 +10 -4
- package/dist/{chunk-ZVCKP4EM.js → chunk-AAQNCAVA.js} +3 -3
- package/dist/{chunk-5XH2GROP.js → chunk-E2AIIPQC.js} +2 -2
- package/dist/{chunk-UQLAWU67.js → chunk-FJ3D76IV.js} +2 -2
- package/dist/{chunk-RVAFVWR2.js → chunk-NS6OTKY2.js} +115 -34
- package/dist/chunk-NS6OTKY2.js.map +1 -0
- package/dist/{chunk-Z3DPPJNU.js → chunk-Q67E2GGD.js} +2 -2
- package/dist/{chunk-PDVUVZAU.js → chunk-SVNQNMMV.js} +2 -2
- package/dist/{chunk-E4GEKWVP.js → chunk-VOXMOGU5.js} +5 -2
- package/dist/chunk-VOXMOGU5.js.map +1 -0
- package/dist/{chunk-DI7Q4T7A.js → chunk-W6XHGSPJ.js} +3 -3
- package/dist/cli/index.js +49 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +158 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +49 -8
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +117 -33
- 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 +117 -33
- 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/llmasaservice.cjs +117 -33
- package/dist/providers/llmasaservice.cjs.map +1 -1
- package/dist/providers/llmasaservice.d.cts +2 -2
- package/dist/providers/llmasaservice.d.ts +2 -2
- package/dist/providers/llmasaservice.js +4 -4
- package/dist/providers/openai-responses.cjs +117 -33
- package/dist/providers/openai-responses.cjs.map +1 -1
- package/dist/providers/openai-responses.d.cts +2 -2
- package/dist/providers/openai-responses.d.ts +2 -2
- package/dist/providers/openai-responses.js +3 -3
- package/dist/providers/openai.cjs +117 -33
- 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 +117 -33
- 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-BgVLZ2u5.d.cts → schema-BkOMklgI.d.cts} +129 -0
- package/dist/{schema-BgVLZ2u5.d.ts → schema-BkOMklgI.d.ts} +129 -0
- 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-2hnZmCkH.d.cts → types-B4TWRzUY.d.cts} +1 -1
- package/dist/{types-DgAT4jSR.d.ts → types-D6VJJo1x.d.ts} +1 -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-E4GEKWVP.js.map +0 -1
- package/dist/chunk-RVAFVWR2.js.map +0 -1
- /package/dist/{chunk-ZVCKP4EM.js.map → chunk-AAQNCAVA.js.map} +0 -0
- /package/dist/{chunk-5XH2GROP.js.map → chunk-E2AIIPQC.js.map} +0 -0
- /package/dist/{chunk-UQLAWU67.js.map → chunk-FJ3D76IV.js.map} +0 -0
- /package/dist/{chunk-Z3DPPJNU.js.map → chunk-Q67E2GGD.js.map} +0 -0
- /package/dist/{chunk-PDVUVZAU.js.map → chunk-SVNQNMMV.js.map} +0 -0
- /package/dist/{chunk-DI7Q4T7A.js.map → chunk-W6XHGSPJ.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -153,7 +153,10 @@ function normalizeContextInputCompression(value) {
|
|
|
153
153
|
target_reduction: value.heuristic.target_reduction,
|
|
154
154
|
query: value.heuristic.query,
|
|
155
155
|
query_variable: value.heuristic.query_variable,
|
|
156
|
-
json_to_toon: value.heuristic.json_to_toon
|
|
156
|
+
json_to_toon: value.heuristic.json_to_toon,
|
|
157
|
+
mode: value.heuristic.mode,
|
|
158
|
+
preserve_neighbors: value.heuristic.preserve_neighbors,
|
|
159
|
+
fail_on_low_confidence: value.heuristic.fail_on_low_confidence
|
|
157
160
|
}
|
|
158
161
|
};
|
|
159
162
|
const code = normalizeCodeCompression(value.code);
|
|
@@ -658,7 +661,10 @@ function line(depth, content, indent) {
|
|
|
658
661
|
var TOKEN_REGEX = /[\p{L}\p{N}]+|[^\s]/gu;
|
|
659
662
|
var TOKEN_NORMALIZE_REGEX = /[^\p{L}\p{N}]/gu;
|
|
660
663
|
var DEDUPE_NORMALIZE_REGEX = /[^\p{L}\p{N}\s]/gu;
|
|
661
|
-
var BOILERPLATE_REGEX = /copyright|all rights reserved|disclaimer
|
|
664
|
+
var BOILERPLATE_REGEX = /copyright|all rights reserved|disclaimer/i;
|
|
665
|
+
var STRUCTURED_BLOCK_REGEX = /(^|\n)\s*```|(^|\n)\s*\|.+\|\s*(\n|$)/;
|
|
666
|
+
var PROTECTED_SIGNAL_REGEX = /\b(?:must|shall|should|required|requires|requirement|never|do not|don't|only|except|unless|however|but|constraint|constraints|safety|security|deadline|sla)\b|output\s+format/i;
|
|
667
|
+
var EVIDENCE_SIGNAL_REGEX = /https?:\/\/|\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b|[$€£]\s?\d|\b\d+(?:[.,:/-]\d+)*%?\b|\b[A-Z]{2,}[-_A-Z0-9]*\b|\b[A-Z]\d\b/i;
|
|
662
668
|
var MAX_SEGMENT_TOKENS = 120;
|
|
663
669
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
664
670
|
"a",
|
|
@@ -692,7 +698,8 @@ var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
|
692
698
|
var DEFAULT_OPTIONS = {
|
|
693
699
|
min_tokens: 80,
|
|
694
700
|
max_sentences: 10,
|
|
695
|
-
target_reduction: 0.45
|
|
701
|
+
target_reduction: 0.45,
|
|
702
|
+
mode: "conservative"
|
|
696
703
|
};
|
|
697
704
|
function tokenizeForHeuristicCompression(text) {
|
|
698
705
|
if (!text) {
|
|
@@ -726,25 +733,46 @@ function compressHeuristicText(input, options = {}) {
|
|
|
726
733
|
warnings: ["JSON-to-TOON skipped because the input is not a complete valid JSON object or array."]
|
|
727
734
|
};
|
|
728
735
|
}
|
|
729
|
-
const analysis = preprocessContext(inputText);
|
|
730
736
|
if (inputTokens === 0) {
|
|
731
737
|
return toCompressionOutput(inputText, inputTokens);
|
|
732
738
|
}
|
|
739
|
+
const mode = options.mode ?? DEFAULT_OPTIONS.mode;
|
|
740
|
+
const isConservative = mode === "conservative";
|
|
741
|
+
const failOnLowConfidence = options.fail_on_low_confidence ?? isConservative;
|
|
742
|
+
const preserveNeighbors = options.preserve_neighbors ?? isConservative;
|
|
733
743
|
const minTokens = options.min_tokens ?? DEFAULT_OPTIONS.min_tokens;
|
|
734
744
|
if (inputTokens <= minTokens) {
|
|
735
745
|
return toCompressionOutput(inputText, inputTokens);
|
|
736
746
|
}
|
|
747
|
+
if (isConservative && looksStructured(inputText)) {
|
|
748
|
+
return toCompressionOutput(inputText, inputTokens, [
|
|
749
|
+
"Heuristic compression skipped because the input appears to contain structured blocks; use TOON or code compaction for structured content."
|
|
750
|
+
]);
|
|
751
|
+
}
|
|
752
|
+
const analysis = preprocessContext(inputText);
|
|
737
753
|
const targetReduction = options.target_reduction ?? DEFAULT_OPTIONS.target_reduction;
|
|
738
754
|
const targetTokens = Math.max(1, Math.max(minTokens, Math.floor(inputTokens * (1 - targetReduction))));
|
|
739
755
|
const maxSentences = options.max_sentences ?? DEFAULT_OPTIONS.max_sentences;
|
|
740
756
|
const query = options.query ?? "";
|
|
741
757
|
const terms = queryTerms(query);
|
|
758
|
+
if (failOnLowConfidence && terms.size === 0) {
|
|
759
|
+
return toCompressionOutput(inputText, inputTokens, [
|
|
760
|
+
"Heuristic compression skipped because no usable relevance query terms were available."
|
|
761
|
+
]);
|
|
762
|
+
}
|
|
742
763
|
const scoredSentences = analysis.candidates.map((candidate) => ({
|
|
743
764
|
sentence: candidate.sentence,
|
|
744
765
|
index: candidate.index,
|
|
745
766
|
...scoreSentenceCandidate(candidate, terms),
|
|
746
|
-
tokens: candidate.tokenCount
|
|
767
|
+
tokens: candidate.tokenCount,
|
|
768
|
+
isProtected: candidate.isProtected,
|
|
769
|
+
hasEvidence: candidate.hasEvidence
|
|
747
770
|
}));
|
|
771
|
+
if (failOnLowConfidence && terms.size > 0 && !scoredSentences.some((candidate) => candidate.overlapCount > 0)) {
|
|
772
|
+
return toCompressionOutput(inputText, inputTokens, [
|
|
773
|
+
"Heuristic compression skipped because no sentence matched the relevance query."
|
|
774
|
+
]);
|
|
775
|
+
}
|
|
748
776
|
const selected = [];
|
|
749
777
|
const selectedIndices = /* @__PURE__ */ new Set();
|
|
750
778
|
const coveredTerms = /* @__PURE__ */ new Set();
|
|
@@ -784,19 +812,15 @@ function compressHeuristicText(input, options = {}) {
|
|
|
784
812
|
coveredTerms.add(term);
|
|
785
813
|
}
|
|
786
814
|
}
|
|
787
|
-
selected
|
|
788
|
-
|
|
815
|
+
const finalSelection = preserveNeighbors ? expandSelectionWithNeighbors(selected, scoredSentences, maxSentences) : selected;
|
|
816
|
+
finalSelection.sort((left, right) => left.index - right.index);
|
|
817
|
+
let output = finalSelection.map((item) => item.sentence).join(" ");
|
|
789
818
|
if (!output) {
|
|
790
|
-
output =
|
|
791
|
-
} else {
|
|
792
|
-
const outputTokens = tokenizeForHeuristicCompression(output);
|
|
793
|
-
if (outputTokens.length > targetTokens) {
|
|
794
|
-
output = outputTokens.slice(0, targetTokens).join(" ");
|
|
795
|
-
}
|
|
819
|
+
output = takeWholeCandidatesWithinBudget(analysis.candidates, targetTokens) || inputText;
|
|
796
820
|
}
|
|
797
821
|
return toCompressionOutput(output, inputTokens);
|
|
798
822
|
}
|
|
799
|
-
function toCompressionOutput(output, inputTokens) {
|
|
823
|
+
function toCompressionOutput(output, inputTokens, warnings = []) {
|
|
800
824
|
const outputTokens = estimateHeuristicTokens(output);
|
|
801
825
|
const tokensSaved = Math.max(0, inputTokens - outputTokens);
|
|
802
826
|
return {
|
|
@@ -804,7 +828,8 @@ function toCompressionOutput(output, inputTokens) {
|
|
|
804
828
|
inputTokens,
|
|
805
829
|
outputTokens,
|
|
806
830
|
tokensSaved,
|
|
807
|
-
compressionRatio: outputTokens === 0 ? 0 : inputTokens / outputTokens
|
|
831
|
+
compressionRatio: outputTokens === 0 ? 0 : inputTokens / outputTokens,
|
|
832
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
808
833
|
};
|
|
809
834
|
}
|
|
810
835
|
function isBetterTieBreak(candidate, bestCandidate) {
|
|
@@ -822,13 +847,6 @@ function normalizeForDeduping(sentence) {
|
|
|
822
847
|
function splitIntoSentences(text) {
|
|
823
848
|
return text.split(/(?<=[.!?])\s+|\n+/g).map((sentence) => sentence.trim()).filter(Boolean);
|
|
824
849
|
}
|
|
825
|
-
function chunkTokens(tokens, chunkSize) {
|
|
826
|
-
const chunks = [];
|
|
827
|
-
for (let index = 0; index < tokens.length; index += chunkSize) {
|
|
828
|
-
chunks.push(tokens.slice(index, index + chunkSize));
|
|
829
|
-
}
|
|
830
|
-
return chunks;
|
|
831
|
-
}
|
|
832
850
|
function splitOversizedSentence(sentence, maxTokens = MAX_SEGMENT_TOKENS) {
|
|
833
851
|
const rawTokens = tokenizeForHeuristicCompression(sentence);
|
|
834
852
|
if (rawTokens.length <= maxTokens) {
|
|
@@ -840,10 +858,10 @@ function splitOversizedSentence(sentence, maxTokens = MAX_SEGMENT_TOKENS) {
|
|
|
840
858
|
if (estimateHeuristicTokens(segment) <= maxTokens) {
|
|
841
859
|
return [segment];
|
|
842
860
|
}
|
|
843
|
-
return
|
|
861
|
+
return [segment];
|
|
844
862
|
});
|
|
845
863
|
}
|
|
846
|
-
return
|
|
864
|
+
return [sentence];
|
|
847
865
|
}
|
|
848
866
|
function normalizeToken(token) {
|
|
849
867
|
return token.replace(TOKEN_NORMALIZE_REGEX, "").trim();
|
|
@@ -852,19 +870,24 @@ function tokenizeNormalized(text) {
|
|
|
852
870
|
return tokenizeForHeuristicCompression(text.toLowerCase()).map(normalizeToken).filter(Boolean);
|
|
853
871
|
}
|
|
854
872
|
function queryTerms(query) {
|
|
855
|
-
return new Set(tokenizeNormalized(query).filter((term) =>
|
|
873
|
+
return new Set(tokenizeNormalized(query).filter((term) => {
|
|
874
|
+
if (STOP_WORDS.has(term)) {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
return term.length >= 3 || /^(?:[a-z]\d|\d+[a-z]?|[a-z]{2})$/i.test(term);
|
|
878
|
+
}));
|
|
856
879
|
}
|
|
857
880
|
function preprocessContext(context) {
|
|
858
881
|
const originalTokens = estimateHeuristicTokens(context);
|
|
859
|
-
const dedupeSet = /* @__PURE__ */ new Set();
|
|
860
882
|
const candidates = [];
|
|
883
|
+
let previousNormalized = "";
|
|
861
884
|
for (const sentence of splitIntoSentences(context)) {
|
|
862
885
|
for (const segment of splitOversizedSentence(sentence)) {
|
|
863
886
|
const normalized = normalizeForDeduping(segment);
|
|
864
|
-
if (!normalized ||
|
|
887
|
+
if (!normalized || normalized === previousNormalized) {
|
|
865
888
|
continue;
|
|
866
889
|
}
|
|
867
|
-
|
|
890
|
+
previousNormalized = normalized;
|
|
868
891
|
const rawTokens = tokenizeForHeuristicCompression(segment);
|
|
869
892
|
const normalizedTerms = rawTokens.map((token) => normalizeToken(token.toLowerCase())).filter(Boolean);
|
|
870
893
|
const lowered = segment.toLowerCase();
|
|
@@ -873,7 +896,9 @@ function preprocessContext(context) {
|
|
|
873
896
|
index: candidates.length,
|
|
874
897
|
tokenCount: rawTokens.length,
|
|
875
898
|
uniqueTerms: new Set(normalizedTerms),
|
|
876
|
-
isBoilerplate: BOILERPLATE_REGEX.test(lowered)
|
|
899
|
+
isBoilerplate: BOILERPLATE_REGEX.test(lowered),
|
|
900
|
+
isProtected: PROTECTED_SIGNAL_REGEX.test(segment),
|
|
901
|
+
hasEvidence: EVIDENCE_SIGNAL_REGEX.test(segment)
|
|
877
902
|
});
|
|
878
903
|
}
|
|
879
904
|
}
|
|
@@ -899,12 +924,62 @@ function scoreSentenceCandidate(candidate, terms) {
|
|
|
899
924
|
const densityScore = terms.size > 0 ? overlap / terms.size : 0;
|
|
900
925
|
const lengthScore = Math.min(candidate.tokenCount, 40) / 40;
|
|
901
926
|
const boilerplatePenalty = candidate.isBoilerplate ? 0.5 : 0;
|
|
927
|
+
const protectedScore = candidate.isProtected ? 0.9 : 0;
|
|
928
|
+
const evidenceScore = candidate.hasEvidence ? 0.4 : 0;
|
|
902
929
|
return {
|
|
903
|
-
score: overlapScore + densityScore + lengthScore - boilerplatePenalty,
|
|
930
|
+
score: overlapScore + densityScore + lengthScore + protectedScore + evidenceScore - boilerplatePenalty,
|
|
904
931
|
overlapCount: overlap,
|
|
905
932
|
overlapTerms
|
|
906
933
|
};
|
|
907
934
|
}
|
|
935
|
+
function looksStructured(text) {
|
|
936
|
+
if (STRUCTURED_BLOCK_REGEX.test(text)) {
|
|
937
|
+
return true;
|
|
938
|
+
}
|
|
939
|
+
const lines = text.split(/\r?\n/).map((line2) => line2.trim()).filter(Boolean);
|
|
940
|
+
if (lines.length < 3) {
|
|
941
|
+
return false;
|
|
942
|
+
}
|
|
943
|
+
const listLikeLines = lines.filter((line2) => /^[-*+] |\d+[.)] /.test(line2)).length;
|
|
944
|
+
return listLikeLines >= 3 && listLikeLines / lines.length >= 0.6;
|
|
945
|
+
}
|
|
946
|
+
function expandSelectionWithNeighbors(selected, scoredSentences, maxSentences) {
|
|
947
|
+
if (selected.length === 0 || selected.length >= maxSentences) {
|
|
948
|
+
return selected;
|
|
949
|
+
}
|
|
950
|
+
const byIndex = new Map(scoredSentences.map((candidate) => [candidate.index, candidate]));
|
|
951
|
+
const expanded = new Map(selected.map((candidate) => [candidate.index, candidate]));
|
|
952
|
+
for (const candidate of selected) {
|
|
953
|
+
if (expanded.size >= maxSentences) {
|
|
954
|
+
break;
|
|
955
|
+
}
|
|
956
|
+
if (candidate.overlapCount === 0 && !candidate.isProtected && !candidate.hasEvidence) {
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
for (const neighborIndex of [candidate.index - 1, candidate.index + 1]) {
|
|
960
|
+
if (expanded.size >= maxSentences) {
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
963
|
+
const neighbor = byIndex.get(neighborIndex);
|
|
964
|
+
if (neighbor && !expanded.has(neighbor.index)) {
|
|
965
|
+
expanded.set(neighbor.index, neighbor);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return [...expanded.values()];
|
|
970
|
+
}
|
|
971
|
+
function takeWholeCandidatesWithinBudget(candidates, targetTokens) {
|
|
972
|
+
const selected = [];
|
|
973
|
+
let tokens = 0;
|
|
974
|
+
for (const candidate of candidates) {
|
|
975
|
+
if (tokens + candidate.tokenCount > targetTokens) {
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
selected.push(candidate.sentence);
|
|
979
|
+
tokens += candidate.tokenCount;
|
|
980
|
+
}
|
|
981
|
+
return selected.join(" ");
|
|
982
|
+
}
|
|
908
983
|
|
|
909
984
|
// src/code-compaction.ts
|
|
910
985
|
function compactCode(input, options = {}) {
|
|
@@ -1070,7 +1145,10 @@ function renderSections(asset, options = {}) {
|
|
|
1070
1145
|
max_sentences: configuredHeuristic?.max_sentences,
|
|
1071
1146
|
target_reduction: configuredHeuristic?.target_reduction,
|
|
1072
1147
|
query,
|
|
1073
|
-
json_to_toon: configuredHeuristic?.json_to_toon
|
|
1148
|
+
json_to_toon: configuredHeuristic?.json_to_toon,
|
|
1149
|
+
mode: configuredHeuristic?.mode,
|
|
1150
|
+
preserve_neighbors: configuredHeuristic?.preserve_neighbors,
|
|
1151
|
+
fail_on_low_confidence: configuredHeuristic?.fail_on_low_confidence
|
|
1074
1152
|
};
|
|
1075
1153
|
const cacheKey = JSON.stringify([name, value, compressionOptions]);
|
|
1076
1154
|
const cached = compressionCache.get(cacheKey);
|
|
@@ -1436,7 +1514,10 @@ var HeuristicCompressionSchema = import_zod.z.object({
|
|
|
1436
1514
|
target_reduction: import_zod.z.number().min(0).max(1).optional(),
|
|
1437
1515
|
query: import_zod.z.string().optional(),
|
|
1438
1516
|
query_variable: import_zod.z.string().min(1).optional(),
|
|
1439
|
-
json_to_toon: import_zod.z.boolean().optional()
|
|
1517
|
+
json_to_toon: import_zod.z.boolean().optional(),
|
|
1518
|
+
mode: import_zod.z.enum(["conservative", "balanced"]).optional(),
|
|
1519
|
+
preserve_neighbors: import_zod.z.boolean().optional(),
|
|
1520
|
+
fail_on_low_confidence: import_zod.z.boolean().optional()
|
|
1440
1521
|
});
|
|
1441
1522
|
var CodeCompactionSchema = import_zod.z.object({
|
|
1442
1523
|
enabled: import_zod.z.boolean().optional(),
|
|
@@ -2421,7 +2502,10 @@ async function applyPromptCompressionForRender(asset, runtime) {
|
|
|
2421
2502
|
max_sentences: heuristicConfig?.max_sentences,
|
|
2422
2503
|
target_reduction: heuristicConfig?.target_reduction,
|
|
2423
2504
|
query: resolveHeuristicPromptQuery(heuristicConfig, runtime.variables, sections.system_instructions),
|
|
2424
|
-
json_to_toon: heuristicConfig?.json_to_toon
|
|
2505
|
+
json_to_toon: heuristicConfig?.json_to_toon,
|
|
2506
|
+
mode: heuristicConfig?.mode,
|
|
2507
|
+
preserve_neighbors: heuristicConfig?.preserve_neighbors,
|
|
2508
|
+
fail_on_low_confidence: heuristicConfig?.fail_on_low_confidence
|
|
2425
2509
|
});
|
|
2426
2510
|
promptTemplate = result.output;
|
|
2427
2511
|
reportHeuristicCompressionWarnings2(warnings, result.warnings, "prompt template");
|
|
@@ -3327,6 +3411,7 @@ var RISKY_UNBOUNDED_INPUT_NAMES = [
|
|
|
3327
3411
|
"body",
|
|
3328
3412
|
"context"
|
|
3329
3413
|
];
|
|
3414
|
+
var COMPRESS_MODIFIER_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\|\s*compress\s*\}\}/g;
|
|
3330
3415
|
function validateAsset(asset, frontMatterKeys, filePath) {
|
|
3331
3416
|
const errors = [];
|
|
3332
3417
|
const warnings = [];
|
|
@@ -3408,6 +3493,26 @@ function validateAsset(asset, frontMatterKeys, filePath) {
|
|
|
3408
3493
|
suggestion: "Declare context.inputs to enable input policy validation."
|
|
3409
3494
|
});
|
|
3410
3495
|
}
|
|
3496
|
+
if (asset.compression?.heuristic?.enabled === true && asset.compression.heuristic.json_to_toon !== true) {
|
|
3497
|
+
warnings.push({
|
|
3498
|
+
code: "POK055",
|
|
3499
|
+
message: "Prompt-level heuristic compression is enabled for the full prompt template.",
|
|
3500
|
+
filePath,
|
|
3501
|
+
suggestion: "Prefer per-placeholder compression for bulky context values so instructions, output constraints, and safety conditions are not sentence-selected away."
|
|
3502
|
+
});
|
|
3503
|
+
}
|
|
3504
|
+
const systemHeuristicCompressionVariables = findSystemHeuristicCompressionVariables(
|
|
3505
|
+
asset.sections?.system_instructions,
|
|
3506
|
+
declaredInputsByName
|
|
3507
|
+
);
|
|
3508
|
+
if (systemHeuristicCompressionVariables.length > 0) {
|
|
3509
|
+
warnings.push({
|
|
3510
|
+
code: "POK056",
|
|
3511
|
+
message: `System instructions use heuristic compression for ${formatQuotedList(systemHeuristicCompressionVariables)}.`,
|
|
3512
|
+
filePath,
|
|
3513
|
+
suggestion: "Avoid compressing values inside system instructions; move lossy compression to prompt-template context placeholders when possible."
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
3411
3516
|
for (const input of contextInputs) {
|
|
3412
3517
|
const lowerName = input.name.toLowerCase();
|
|
3413
3518
|
const inputWarningsEnabled = areContextInputWarningsEnabled(input);
|
|
@@ -3599,6 +3704,26 @@ function findClosestMatch(input, candidates) {
|
|
|
3599
3704
|
}
|
|
3600
3705
|
return best;
|
|
3601
3706
|
}
|
|
3707
|
+
function findSystemHeuristicCompressionVariables(systemInstructions, declaredInputsByName) {
|
|
3708
|
+
if (!systemInstructions) {
|
|
3709
|
+
return [];
|
|
3710
|
+
}
|
|
3711
|
+
const variables = /* @__PURE__ */ new Set();
|
|
3712
|
+
for (const match of systemInstructions.matchAll(COMPRESS_MODIFIER_RE)) {
|
|
3713
|
+
variables.add(match[1]);
|
|
3714
|
+
}
|
|
3715
|
+
for (const variable of extractVariables(systemInstructions)) {
|
|
3716
|
+
const input = declaredInputsByName.get(variable);
|
|
3717
|
+
const heuristic = input?.compression?.heuristic;
|
|
3718
|
+
if (heuristic?.enabled === true && heuristic.json_to_toon !== true) {
|
|
3719
|
+
variables.add(variable);
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
return [...variables].sort();
|
|
3723
|
+
}
|
|
3724
|
+
function formatQuotedList(values) {
|
|
3725
|
+
return values.map((value) => `"${value}"`).join(", ");
|
|
3726
|
+
}
|
|
3602
3727
|
function isRecord2(value) {
|
|
3603
3728
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3604
3729
|
}
|