promptopskit 0.7.1 → 0.8.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 +39 -4
- package/dist/{chunk-OWMP5NMV.js → chunk-5XH2GROP.js} +2 -2
- package/dist/{chunk-FICB2ZSK.js → chunk-DI7Q4T7A.js} +3 -3
- package/dist/{chunk-ULVY473P.js → chunk-E4GEKWVP.js} +31 -3
- package/dist/chunk-E4GEKWVP.js.map +1 -0
- package/dist/{chunk-3G3EAV7H.js → chunk-PDVUVZAU.js} +2 -2
- package/dist/chunk-RVAFVWR2.js +1760 -0
- package/dist/chunk-RVAFVWR2.js.map +1 -0
- package/dist/{chunk-35NN5F6O.js → chunk-UQLAWU67.js} +2 -2
- package/dist/{chunk-6NOUETAC.js → chunk-Z3DPPJNU.js} +2 -2
- package/dist/{chunk-R65RAHAG.js → chunk-ZVCKP4EM.js} +3 -3
- package/dist/cli/index.js +86 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +964 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -5
- package/dist/index.d.ts +45 -5
- package/dist/index.js +18 -10
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +954 -42
- 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 +954 -42
- 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 +954 -42
- 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 +954 -42
- 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 +954 -42
- 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 +954 -42
- 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-DBcSns_b.d.cts → schema-BgVLZ2u5.d.cts} +641 -0
- package/dist/{schema-DBcSns_b.d.ts → schema-BgVLZ2u5.d.ts} +641 -0
- package/dist/testing.cjs +27 -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-BlLXT5Qb.d.ts → types-2hnZmCkH.d.cts} +16 -3
- package/dist/{types-8T2D5KB5.d.cts → types-DgAT4jSR.d.ts} +16 -3
- package/dist/usagetap/index.d.cts +2 -2
- package/dist/usagetap/index.d.ts +2 -2
- package/package.json +1 -1
- package/dist/chunk-F552OBUV.js +0 -875
- package/dist/chunk-F552OBUV.js.map +0 -1
- package/dist/chunk-ULVY473P.js.map +0 -1
- /package/dist/{chunk-OWMP5NMV.js.map → chunk-5XH2GROP.js.map} +0 -0
- /package/dist/{chunk-FICB2ZSK.js.map → chunk-DI7Q4T7A.js.map} +0 -0
- /package/dist/{chunk-3G3EAV7H.js.map → chunk-PDVUVZAU.js.map} +0 -0
- /package/dist/{chunk-35NN5F6O.js.map → chunk-UQLAWU67.js.map} +0 -0
- /package/dist/{chunk-6NOUETAC.js.map → chunk-Z3DPPJNU.js.map} +0 -0
- /package/dist/{chunk-R65RAHAG.js.map → chunk-ZVCKP4EM.js.map} +0 -0
|
@@ -0,0 +1,1760 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadPromptFile,
|
|
3
|
+
parsePrompt
|
|
4
|
+
} from "./chunk-E4GEKWVP.js";
|
|
5
|
+
|
|
6
|
+
// src/renderer/interpolate.ts
|
|
7
|
+
var VARIABLE_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)(?:\s*\|\s*(compress|toon|compact|code))?\s*\}\}/g;
|
|
8
|
+
var ESCAPED_OPEN = /\\\{\\\{/g;
|
|
9
|
+
var ESCAPE_PLACEHOLDER = "\0ESCAPED_OPEN\0";
|
|
10
|
+
function interpolate(template, variables, options = {}) {
|
|
11
|
+
const { strict = false } = options;
|
|
12
|
+
const optionalVariables = new Set(options.optionalVariables ?? []);
|
|
13
|
+
let result = template.replace(ESCAPED_OPEN, ESCAPE_PLACEHOLDER);
|
|
14
|
+
result = result.replace(VARIABLE_RE, (match, name, modifier) => {
|
|
15
|
+
if (name in variables) {
|
|
16
|
+
const value = variables[name];
|
|
17
|
+
return options.transformVariable ? options.transformVariable({ name, value, modifier, match }) : value;
|
|
18
|
+
}
|
|
19
|
+
if (strict && !optionalVariables.has(name)) {
|
|
20
|
+
throw new Error(`Missing required variable: "${name}"`);
|
|
21
|
+
}
|
|
22
|
+
return match;
|
|
23
|
+
});
|
|
24
|
+
result = result.replaceAll(ESCAPE_PLACEHOLDER, "{{");
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
function extractVariables(template) {
|
|
28
|
+
const vars = /* @__PURE__ */ new Set();
|
|
29
|
+
let match;
|
|
30
|
+
const re = new RegExp(VARIABLE_RE.source, "g");
|
|
31
|
+
while ((match = re.exec(template)) !== null) {
|
|
32
|
+
vars.add(match[1]);
|
|
33
|
+
}
|
|
34
|
+
return [...vars];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/context.ts
|
|
38
|
+
var textEncoder = new TextEncoder();
|
|
39
|
+
var REJECT_SECRETS_PATTERN = "(secret|api[_-]?key|password)";
|
|
40
|
+
var REJECT_SECRETS_FLAGS = "i";
|
|
41
|
+
function getContextInputs(asset) {
|
|
42
|
+
return (asset.context?.inputs ?? []).map(normalizeContextInput);
|
|
43
|
+
}
|
|
44
|
+
function normalizeContextInput(input) {
|
|
45
|
+
if (typeof input === "string") {
|
|
46
|
+
return { name: input };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
name: input.name,
|
|
50
|
+
optional: input.optional,
|
|
51
|
+
warnings: input.warnings,
|
|
52
|
+
max_size: input.max_size,
|
|
53
|
+
trim: input.trim,
|
|
54
|
+
compression: normalizeContextInputCompression(input.compression),
|
|
55
|
+
allow_regex: normalizeContextRegex(input.allow_regex),
|
|
56
|
+
deny_regex: normalizeContextRegex(input.deny_regex),
|
|
57
|
+
non_empty: normalizeBuiltInValidator(input.non_empty),
|
|
58
|
+
reject_secrets: normalizeBuiltInValidator(input.reject_secrets)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function normalizeContextInputCompression(value) {
|
|
62
|
+
if (value === void 0) {
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
if (value === "heuristic") {
|
|
66
|
+
return { heuristic: { enabled: true } };
|
|
67
|
+
}
|
|
68
|
+
if (value === "code") {
|
|
69
|
+
return { code: { enabled: true } };
|
|
70
|
+
}
|
|
71
|
+
if (value.heuristic === void 0) {
|
|
72
|
+
return normalizeCodeCompression(value.code);
|
|
73
|
+
}
|
|
74
|
+
const normalized = {
|
|
75
|
+
heuristic: {
|
|
76
|
+
enabled: value.heuristic.enabled ?? true,
|
|
77
|
+
min_tokens: value.heuristic.min_tokens,
|
|
78
|
+
max_sentences: value.heuristic.max_sentences,
|
|
79
|
+
target_reduction: value.heuristic.target_reduction,
|
|
80
|
+
query: value.heuristic.query,
|
|
81
|
+
query_variable: value.heuristic.query_variable,
|
|
82
|
+
json_to_toon: value.heuristic.json_to_toon
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const code = normalizeCodeCompression(value.code);
|
|
86
|
+
if (code?.code) {
|
|
87
|
+
normalized.code = code.code;
|
|
88
|
+
}
|
|
89
|
+
return normalized;
|
|
90
|
+
}
|
|
91
|
+
function normalizeCodeCompression(value) {
|
|
92
|
+
if (value === void 0) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
code: {
|
|
97
|
+
enabled: value.enabled ?? true,
|
|
98
|
+
remove_comments: value.remove_comments,
|
|
99
|
+
trim_indentation: value.trim_indentation,
|
|
100
|
+
collapse_blank_lines: value.collapse_blank_lines
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function areContextInputWarningsEnabled(input) {
|
|
105
|
+
return input.warnings !== false;
|
|
106
|
+
}
|
|
107
|
+
function normalizeContextRegex(value) {
|
|
108
|
+
if (value === void 0) {
|
|
109
|
+
return void 0;
|
|
110
|
+
}
|
|
111
|
+
if (typeof value === "string") {
|
|
112
|
+
const literal = parseRegexLiteral(value);
|
|
113
|
+
if (value.startsWith("/") && !literal) {
|
|
114
|
+
return {
|
|
115
|
+
pattern: value,
|
|
116
|
+
flags: "",
|
|
117
|
+
raw: value,
|
|
118
|
+
invalidLiteral: true
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
pattern: literal?.pattern ?? value,
|
|
123
|
+
flags: literal?.flags ?? "",
|
|
124
|
+
raw: value
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
pattern: value.pattern,
|
|
129
|
+
flags: value.flags ?? "",
|
|
130
|
+
raw: JSON.stringify(value),
|
|
131
|
+
returnMessage: value.return_message
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function normalizeBuiltInValidator(value) {
|
|
135
|
+
if (value === void 0 || value === false) {
|
|
136
|
+
return void 0;
|
|
137
|
+
}
|
|
138
|
+
if (value === true) {
|
|
139
|
+
return {};
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
returnMessage: value.return_message
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function parseRegexLiteral(value) {
|
|
146
|
+
if (!value.startsWith("/")) {
|
|
147
|
+
return void 0;
|
|
148
|
+
}
|
|
149
|
+
for (let index = value.length - 1; index > 0; index -= 1) {
|
|
150
|
+
if (value[index] !== "/") {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
let backslashCount = 0;
|
|
154
|
+
for (let cursor = index - 1; cursor >= 0 && value[cursor] === "\\"; cursor -= 1) {
|
|
155
|
+
backslashCount += 1;
|
|
156
|
+
}
|
|
157
|
+
if (backslashCount % 2 === 1) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
pattern: value.slice(1, index),
|
|
162
|
+
flags: value.slice(index + 1)
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return void 0;
|
|
166
|
+
}
|
|
167
|
+
function formatInvalidContextRegexMessage(details) {
|
|
168
|
+
return [
|
|
169
|
+
`Invalid context regex for prompt "${details.promptId}"`,
|
|
170
|
+
`variable "${details.variable}"`,
|
|
171
|
+
`field "${details.field}"`,
|
|
172
|
+
`value ${JSON.stringify(details.raw)}: ${details.reason}`
|
|
173
|
+
].join(", ");
|
|
174
|
+
}
|
|
175
|
+
function compileContextRegex(regex, details) {
|
|
176
|
+
if (regex.invalidLiteral) {
|
|
177
|
+
throw new Error(
|
|
178
|
+
`POK013: ${formatInvalidContextRegexMessage({
|
|
179
|
+
...details,
|
|
180
|
+
raw: regex.raw,
|
|
181
|
+
reason: "Malformed regex literal. Use /pattern/flags or { pattern, flags }."
|
|
182
|
+
})}`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
return new RegExp(regex.pattern, regex.flags);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
189
|
+
throw new Error(`POK013: ${formatInvalidContextRegexMessage({ ...details, raw: regex.raw, reason })}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function getRejectSecretsRegex() {
|
|
193
|
+
return {
|
|
194
|
+
pattern: REJECT_SECRETS_PATTERN,
|
|
195
|
+
flags: REJECT_SECRETS_FLAGS,
|
|
196
|
+
raw: JSON.stringify({ pattern: REJECT_SECRETS_PATTERN, flags: REJECT_SECRETS_FLAGS })
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function isTrimEnabled(mode) {
|
|
200
|
+
return mode === true || mode === "start" || mode === "end" || mode === "both";
|
|
201
|
+
}
|
|
202
|
+
function normalizeTrimMode(mode) {
|
|
203
|
+
if (mode === "start") {
|
|
204
|
+
return "start";
|
|
205
|
+
}
|
|
206
|
+
return "end";
|
|
207
|
+
}
|
|
208
|
+
function trimToMaxSize(value, maxSize, mode) {
|
|
209
|
+
const measured = measureContextValueSize(value);
|
|
210
|
+
if (measured <= maxSize) {
|
|
211
|
+
return value;
|
|
212
|
+
}
|
|
213
|
+
const characters = Array.from(value);
|
|
214
|
+
const normalizedMode = normalizeTrimMode(mode);
|
|
215
|
+
if (normalizedMode === "start") {
|
|
216
|
+
let collected2 = "";
|
|
217
|
+
let size2 = 0;
|
|
218
|
+
for (let i = characters.length - 1; i >= 0; i -= 1) {
|
|
219
|
+
const next = characters[i];
|
|
220
|
+
const charSize = measureContextValueSize(next);
|
|
221
|
+
if (size2 + charSize > maxSize) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
collected2 = next + collected2;
|
|
225
|
+
size2 += charSize;
|
|
226
|
+
}
|
|
227
|
+
return collected2;
|
|
228
|
+
}
|
|
229
|
+
let collected = "";
|
|
230
|
+
let size = 0;
|
|
231
|
+
for (const char of characters) {
|
|
232
|
+
const charSize = measureContextValueSize(char);
|
|
233
|
+
if (size + charSize > maxSize) {
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
collected += char;
|
|
237
|
+
size += charSize;
|
|
238
|
+
}
|
|
239
|
+
return collected;
|
|
240
|
+
}
|
|
241
|
+
function sanitizeContextVariables(asset, variables = {}, options = {}) {
|
|
242
|
+
const { onContextOverflow } = options;
|
|
243
|
+
const sanitized = { ...variables };
|
|
244
|
+
for (const input of getContextInputs(asset)) {
|
|
245
|
+
const value = sanitized[input.name];
|
|
246
|
+
if (value === void 0) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
let candidate = value;
|
|
250
|
+
if (input.max_size !== void 0) {
|
|
251
|
+
const actualSize = measureContextValueSize(candidate);
|
|
252
|
+
if (actualSize > input.max_size && onContextOverflow) {
|
|
253
|
+
candidate = onContextOverflow({
|
|
254
|
+
promptId: asset.id,
|
|
255
|
+
variable: input.name,
|
|
256
|
+
value: candidate,
|
|
257
|
+
maxSize: input.max_size,
|
|
258
|
+
actualSize
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (isTrimEnabled(input.trim) && input.max_size !== void 0) {
|
|
263
|
+
candidate = trimToMaxSize(candidate, input.max_size, input.trim);
|
|
264
|
+
}
|
|
265
|
+
sanitized[input.name] = candidate;
|
|
266
|
+
if (input.allow_regex) {
|
|
267
|
+
const candidate2 = sanitized[input.name];
|
|
268
|
+
const matcher = compileContextRegex(input.allow_regex, {
|
|
269
|
+
promptId: asset.id,
|
|
270
|
+
variable: input.name,
|
|
271
|
+
field: "allow_regex"
|
|
272
|
+
});
|
|
273
|
+
if (!matcher.test(candidate2)) {
|
|
274
|
+
if (input.allow_regex.returnMessage) {
|
|
275
|
+
return {
|
|
276
|
+
variables: sanitized,
|
|
277
|
+
shortCircuit: {
|
|
278
|
+
returnMessage: input.allow_regex.returnMessage,
|
|
279
|
+
code: "POK031",
|
|
280
|
+
variable: input.name,
|
|
281
|
+
field: "allow_regex"
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
throw new Error(
|
|
286
|
+
`POK031: Context variable "${input.name}" failed allow_regex validation for prompt "${asset.id}".`
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (input.deny_regex) {
|
|
291
|
+
const candidate2 = sanitized[input.name];
|
|
292
|
+
const matcher = compileContextRegex(input.deny_regex, {
|
|
293
|
+
promptId: asset.id,
|
|
294
|
+
variable: input.name,
|
|
295
|
+
field: "deny_regex"
|
|
296
|
+
});
|
|
297
|
+
if (matcher.test(candidate2)) {
|
|
298
|
+
if (input.deny_regex.returnMessage) {
|
|
299
|
+
return {
|
|
300
|
+
variables: sanitized,
|
|
301
|
+
shortCircuit: {
|
|
302
|
+
returnMessage: input.deny_regex.returnMessage,
|
|
303
|
+
code: "POK032",
|
|
304
|
+
variable: input.name,
|
|
305
|
+
field: "deny_regex"
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
throw new Error(
|
|
310
|
+
`POK032: Context variable "${input.name}" matched deny_regex for prompt "${asset.id}".`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (input.non_empty && candidate.trim().length === 0) {
|
|
315
|
+
if (input.non_empty.returnMessage) {
|
|
316
|
+
return {
|
|
317
|
+
variables: sanitized,
|
|
318
|
+
shortCircuit: {
|
|
319
|
+
returnMessage: input.non_empty.returnMessage,
|
|
320
|
+
code: "POK033",
|
|
321
|
+
variable: input.name,
|
|
322
|
+
field: "non_empty"
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
throw new Error(
|
|
327
|
+
`POK033: Context variable "${input.name}" failed non_empty validation for prompt "${asset.id}".`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
if (input.reject_secrets) {
|
|
331
|
+
const matcher = compileContextRegex(getRejectSecretsRegex(), {
|
|
332
|
+
promptId: asset.id,
|
|
333
|
+
variable: input.name,
|
|
334
|
+
field: "reject_secrets"
|
|
335
|
+
});
|
|
336
|
+
if (matcher.test(candidate)) {
|
|
337
|
+
if (input.reject_secrets.returnMessage) {
|
|
338
|
+
return {
|
|
339
|
+
variables: sanitized,
|
|
340
|
+
shortCircuit: {
|
|
341
|
+
returnMessage: input.reject_secrets.returnMessage,
|
|
342
|
+
code: "POK034",
|
|
343
|
+
variable: input.name,
|
|
344
|
+
field: "reject_secrets"
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
throw new Error(
|
|
349
|
+
`POK034: Context variable "${input.name}" matched reject_secrets validation for prompt "${asset.id}".`
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return { variables: sanitized };
|
|
355
|
+
}
|
|
356
|
+
function measureContextValueSize(value) {
|
|
357
|
+
return textEncoder.encode(value).length;
|
|
358
|
+
}
|
|
359
|
+
function collectContextSizeWarnings(asset, variables = {}) {
|
|
360
|
+
const warnings = [];
|
|
361
|
+
for (const input of getContextInputs(asset)) {
|
|
362
|
+
if (!areContextInputWarningsEnabled(input)) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (input.max_size === void 0) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
const value = variables[input.name];
|
|
369
|
+
if (value === void 0) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
const actualSize = measureContextValueSize(value);
|
|
373
|
+
if (actualSize > input.max_size) {
|
|
374
|
+
warnings.push({
|
|
375
|
+
variable: input.name,
|
|
376
|
+
maxSize: input.max_size,
|
|
377
|
+
actualSize
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return warnings;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/toon-encoding.ts
|
|
385
|
+
var DEFAULT_INDENT = 2;
|
|
386
|
+
var DEFAULT_DELIMITER = ",";
|
|
387
|
+
function tryJsonToToon(text, options = {}) {
|
|
388
|
+
const trimmed = text.trim();
|
|
389
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
390
|
+
return void 0;
|
|
391
|
+
}
|
|
392
|
+
let parsed;
|
|
393
|
+
try {
|
|
394
|
+
parsed = JSON.parse(trimmed);
|
|
395
|
+
} catch {
|
|
396
|
+
return void 0;
|
|
397
|
+
}
|
|
398
|
+
const value = normalizeJsonValue(parsed);
|
|
399
|
+
if (value === void 0) {
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
output: encodeToon(value, options),
|
|
404
|
+
value
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
function encodeToon(value, options = {}) {
|
|
408
|
+
const resolved = {
|
|
409
|
+
indent: options.indent ?? DEFAULT_INDENT,
|
|
410
|
+
delimiter: options.delimiter ?? DEFAULT_DELIMITER
|
|
411
|
+
};
|
|
412
|
+
return encodeValue(value, void 0, 0, resolved).join("\n");
|
|
413
|
+
}
|
|
414
|
+
function normalizeJsonValue(value) {
|
|
415
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
416
|
+
return value;
|
|
417
|
+
}
|
|
418
|
+
if (typeof value === "number") {
|
|
419
|
+
return Number.isFinite(value) ? value : null;
|
|
420
|
+
}
|
|
421
|
+
if (Array.isArray(value)) {
|
|
422
|
+
return value.map((item) => normalizeJsonValue(item) ?? null);
|
|
423
|
+
}
|
|
424
|
+
if (isPlainObject(value)) {
|
|
425
|
+
const normalized = {};
|
|
426
|
+
for (const [key, child] of Object.entries(value)) {
|
|
427
|
+
normalized[key] = normalizeJsonValue(child) ?? null;
|
|
428
|
+
}
|
|
429
|
+
return normalized;
|
|
430
|
+
}
|
|
431
|
+
return void 0;
|
|
432
|
+
}
|
|
433
|
+
function encodeValue(value, key, depth, options) {
|
|
434
|
+
if (isPrimitive(value)) {
|
|
435
|
+
return [line(depth, key === void 0 ? encodePrimitive(value, options.delimiter) : `${encodeKey(key)}: ${encodePrimitive(value, options.delimiter)}`, options.indent)];
|
|
436
|
+
}
|
|
437
|
+
if (Array.isArray(value)) {
|
|
438
|
+
return encodeArray(value, key, depth, options);
|
|
439
|
+
}
|
|
440
|
+
return encodeObject(value, key, depth, options);
|
|
441
|
+
}
|
|
442
|
+
function encodeObject(value, key, depth, options) {
|
|
443
|
+
const entries = Object.entries(value);
|
|
444
|
+
const lines = [];
|
|
445
|
+
if (key !== void 0) {
|
|
446
|
+
lines.push(line(depth, `${encodeKey(key)}:`, options.indent));
|
|
447
|
+
}
|
|
448
|
+
const childDepth = key === void 0 ? depth : depth + 1;
|
|
449
|
+
for (const [childKey, childValue] of entries) {
|
|
450
|
+
lines.push(...encodeValue(childValue, childKey, childDepth, options));
|
|
451
|
+
}
|
|
452
|
+
return lines;
|
|
453
|
+
}
|
|
454
|
+
function encodeArray(value, key, depth, options) {
|
|
455
|
+
const prefix = key === void 0 ? "" : encodeKey(key);
|
|
456
|
+
if (value.length === 0) {
|
|
457
|
+
return [line(depth, key === void 0 ? "[]" : `${prefix}: []`, options.indent)];
|
|
458
|
+
}
|
|
459
|
+
if (value.every(isPrimitive)) {
|
|
460
|
+
const joined = value.map((item) => encodePrimitive(item, options.delimiter)).join(options.delimiter);
|
|
461
|
+
return [line(depth, `${prefix}[${value.length}]: ${joined}`, options.indent)];
|
|
462
|
+
}
|
|
463
|
+
const tabularFields = getTabularFields(value);
|
|
464
|
+
if (tabularFields) {
|
|
465
|
+
const lines2 = [
|
|
466
|
+
line(depth, `${prefix}[${value.length}]{${tabularFields.map(encodeKey).join(options.delimiter)}}:`, options.indent)
|
|
467
|
+
];
|
|
468
|
+
for (const row of value) {
|
|
469
|
+
lines2.push(line(depth + 1, tabularFields.map((field) => encodePrimitive(row[field], options.delimiter)).join(options.delimiter), options.indent));
|
|
470
|
+
}
|
|
471
|
+
return lines2;
|
|
472
|
+
}
|
|
473
|
+
const lines = [line(depth, `${prefix}[${value.length}]:`, options.indent)];
|
|
474
|
+
for (const item of value) {
|
|
475
|
+
lines.push(...encodeListItem(item, depth + 1, options));
|
|
476
|
+
}
|
|
477
|
+
return lines;
|
|
478
|
+
}
|
|
479
|
+
function encodeListItem(value, depth, options) {
|
|
480
|
+
if (isPrimitive(value)) {
|
|
481
|
+
return [line(depth, `- ${encodePrimitive(value, options.delimiter)}`, options.indent)];
|
|
482
|
+
}
|
|
483
|
+
if (Array.isArray(value)) {
|
|
484
|
+
const encoded = encodeArray(value, void 0, depth, options);
|
|
485
|
+
return encoded.map((item, index) => {
|
|
486
|
+
if (index === 0) {
|
|
487
|
+
return line(depth, `- ${item.trimStart()}`, options.indent);
|
|
488
|
+
}
|
|
489
|
+
return item;
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
const entries = Object.entries(value);
|
|
493
|
+
if (entries.length === 0) {
|
|
494
|
+
return [line(depth, "-", options.indent)];
|
|
495
|
+
}
|
|
496
|
+
const [firstKey, firstValue] = entries[0];
|
|
497
|
+
const rest = Object.fromEntries(entries.slice(1));
|
|
498
|
+
const firstLines = encodeValue(firstValue, firstKey, depth, options);
|
|
499
|
+
const lines = [line(depth, `- ${firstLines[0].trimStart()}`, options.indent)];
|
|
500
|
+
for (const continuation of firstLines.slice(1)) {
|
|
501
|
+
lines.push(continuation);
|
|
502
|
+
}
|
|
503
|
+
if (Object.keys(rest).length > 0) {
|
|
504
|
+
lines.push(...encodeObject(rest, void 0, depth + 1, options));
|
|
505
|
+
}
|
|
506
|
+
return lines;
|
|
507
|
+
}
|
|
508
|
+
function getTabularFields(value) {
|
|
509
|
+
if (value.length === 0 || !value.every(isObjectRecord)) {
|
|
510
|
+
return void 0;
|
|
511
|
+
}
|
|
512
|
+
const first = value[0];
|
|
513
|
+
const fields = Object.keys(first);
|
|
514
|
+
if (fields.length === 0) {
|
|
515
|
+
return void 0;
|
|
516
|
+
}
|
|
517
|
+
for (const row of value) {
|
|
518
|
+
const keys = Object.keys(row);
|
|
519
|
+
if (keys.length !== fields.length) {
|
|
520
|
+
return void 0;
|
|
521
|
+
}
|
|
522
|
+
for (const field of fields) {
|
|
523
|
+
if (!(field in row) || !isPrimitive(row[field])) {
|
|
524
|
+
return void 0;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return fields;
|
|
529
|
+
}
|
|
530
|
+
function encodePrimitive(value, delimiter) {
|
|
531
|
+
if (value === null) {
|
|
532
|
+
return "null";
|
|
533
|
+
}
|
|
534
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
535
|
+
return String(value);
|
|
536
|
+
}
|
|
537
|
+
return encodeString(value, delimiter);
|
|
538
|
+
}
|
|
539
|
+
function encodeString(value, delimiter) {
|
|
540
|
+
if (isSafeUnquotedString(value, delimiter)) {
|
|
541
|
+
return value;
|
|
542
|
+
}
|
|
543
|
+
return JSON.stringify(value);
|
|
544
|
+
}
|
|
545
|
+
function encodeKey(key) {
|
|
546
|
+
if (/^[A-Z_][\w.]*$/i.test(key)) {
|
|
547
|
+
return key;
|
|
548
|
+
}
|
|
549
|
+
return JSON.stringify(key);
|
|
550
|
+
}
|
|
551
|
+
function isSafeUnquotedString(value, delimiter) {
|
|
552
|
+
if (value.length === 0 || value !== value.trim()) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
if (/^(?:true|false|null)$/i.test(value) || /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(value) || /^0\d+$/.test(value)) {
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
if (value.includes(":") || value.includes('"') || value.includes("\\") || value.includes(delimiter)) {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
if (/[[\]{}]|[\u0000-\u001F]/.test(value) || value.startsWith("-")) {
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
function isPrimitive(value) {
|
|
567
|
+
return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
568
|
+
}
|
|
569
|
+
function isObjectRecord(value) {
|
|
570
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
571
|
+
}
|
|
572
|
+
function isPlainObject(value) {
|
|
573
|
+
if (value === null || typeof value !== "object") {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
const prototype = Object.getPrototypeOf(value);
|
|
577
|
+
return prototype === null || prototype === Object.prototype;
|
|
578
|
+
}
|
|
579
|
+
function line(depth, content, indent) {
|
|
580
|
+
return `${" ".repeat(depth * indent)}${content}`;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// src/token-compression.ts
|
|
584
|
+
var TOKEN_REGEX = /[\p{L}\p{N}]+|[^\s]/gu;
|
|
585
|
+
var TOKEN_NORMALIZE_REGEX = /[^\p{L}\p{N}]/gu;
|
|
586
|
+
var DEDUPE_NORMALIZE_REGEX = /[^\p{L}\p{N}\s]/gu;
|
|
587
|
+
var BOILERPLATE_REGEX = /copyright|all rights reserved|disclaimer|confidential/i;
|
|
588
|
+
var MAX_SEGMENT_TOKENS = 120;
|
|
589
|
+
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
590
|
+
"a",
|
|
591
|
+
"an",
|
|
592
|
+
"and",
|
|
593
|
+
"are",
|
|
594
|
+
"as",
|
|
595
|
+
"at",
|
|
596
|
+
"be",
|
|
597
|
+
"by",
|
|
598
|
+
"for",
|
|
599
|
+
"from",
|
|
600
|
+
"how",
|
|
601
|
+
"in",
|
|
602
|
+
"is",
|
|
603
|
+
"it",
|
|
604
|
+
"of",
|
|
605
|
+
"on",
|
|
606
|
+
"or",
|
|
607
|
+
"that",
|
|
608
|
+
"the",
|
|
609
|
+
"this",
|
|
610
|
+
"to",
|
|
611
|
+
"was",
|
|
612
|
+
"we",
|
|
613
|
+
"with",
|
|
614
|
+
"you",
|
|
615
|
+
"your",
|
|
616
|
+
"our"
|
|
617
|
+
]);
|
|
618
|
+
var DEFAULT_OPTIONS = {
|
|
619
|
+
min_tokens: 80,
|
|
620
|
+
max_sentences: 10,
|
|
621
|
+
target_reduction: 0.45
|
|
622
|
+
};
|
|
623
|
+
function tokenizeForHeuristicCompression(text) {
|
|
624
|
+
if (!text) {
|
|
625
|
+
return [];
|
|
626
|
+
}
|
|
627
|
+
return text.match(TOKEN_REGEX) ?? [];
|
|
628
|
+
}
|
|
629
|
+
function estimateHeuristicTokens(text) {
|
|
630
|
+
return tokenizeForHeuristicCompression(text).length;
|
|
631
|
+
}
|
|
632
|
+
function compressHeuristicText(input, options = {}) {
|
|
633
|
+
const inputText = input ?? "";
|
|
634
|
+
const inputTokens = estimateHeuristicTokens(inputText);
|
|
635
|
+
if (options.json_to_toon === true) {
|
|
636
|
+
const toonResult = tryJsonToToon(inputText);
|
|
637
|
+
if (toonResult) {
|
|
638
|
+
const toonOutputTokens = estimateHeuristicTokens(toonResult.output);
|
|
639
|
+
if (toonOutputTokens <= inputTokens) {
|
|
640
|
+
return {
|
|
641
|
+
...toCompressionOutput(toonResult.output, inputTokens),
|
|
642
|
+
outputFormat: "toon"
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
return {
|
|
646
|
+
...toCompressionOutput(inputText, inputTokens),
|
|
647
|
+
warnings: ["JSON-to-TOON skipped because TOON was not smaller than the original JSON."]
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
return {
|
|
651
|
+
...toCompressionOutput(inputText, inputTokens),
|
|
652
|
+
warnings: ["JSON-to-TOON skipped because the input is not a complete valid JSON object or array."]
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
const analysis = preprocessContext(inputText);
|
|
656
|
+
if (inputTokens === 0) {
|
|
657
|
+
return toCompressionOutput(inputText, inputTokens);
|
|
658
|
+
}
|
|
659
|
+
const minTokens = options.min_tokens ?? DEFAULT_OPTIONS.min_tokens;
|
|
660
|
+
if (inputTokens <= minTokens) {
|
|
661
|
+
return toCompressionOutput(inputText, inputTokens);
|
|
662
|
+
}
|
|
663
|
+
const targetReduction = options.target_reduction ?? DEFAULT_OPTIONS.target_reduction;
|
|
664
|
+
const targetTokens = Math.max(1, Math.max(minTokens, Math.floor(inputTokens * (1 - targetReduction))));
|
|
665
|
+
const maxSentences = options.max_sentences ?? DEFAULT_OPTIONS.max_sentences;
|
|
666
|
+
const query = options.query ?? "";
|
|
667
|
+
const terms = queryTerms(query);
|
|
668
|
+
const scoredSentences = analysis.candidates.map((candidate) => ({
|
|
669
|
+
sentence: candidate.sentence,
|
|
670
|
+
index: candidate.index,
|
|
671
|
+
...scoreSentenceCandidate(candidate, terms),
|
|
672
|
+
tokens: candidate.tokenCount
|
|
673
|
+
}));
|
|
674
|
+
const selected = [];
|
|
675
|
+
const selectedIndices = /* @__PURE__ */ new Set();
|
|
676
|
+
const coveredTerms = /* @__PURE__ */ new Set();
|
|
677
|
+
let selectedTokens = 0;
|
|
678
|
+
while (selected.length < maxSentences) {
|
|
679
|
+
let bestCandidate;
|
|
680
|
+
let bestAdjustedScore = Number.NEGATIVE_INFINITY;
|
|
681
|
+
for (const candidate of scoredSentences) {
|
|
682
|
+
if (selectedIndices.has(candidate.index)) {
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
const underBudget = selectedTokens + candidate.tokens <= targetTokens;
|
|
686
|
+
const forceTopCandidate = selected.length === 0;
|
|
687
|
+
const forceRelevantSecond = selected.length === 1 && candidate.overlapCount > 0;
|
|
688
|
+
if (!underBudget && !forceTopCandidate && !forceRelevantSecond) {
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
let uncoveredOverlapCount = 0;
|
|
692
|
+
for (const term of candidate.overlapTerms) {
|
|
693
|
+
if (!coveredTerms.has(term)) {
|
|
694
|
+
uncoveredOverlapCount += 1;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
const adjustedScore = candidate.score + uncoveredOverlapCount * 1.2;
|
|
698
|
+
if (adjustedScore > bestAdjustedScore || adjustedScore === bestAdjustedScore && bestCandidate && isBetterTieBreak(candidate, bestCandidate)) {
|
|
699
|
+
bestAdjustedScore = adjustedScore;
|
|
700
|
+
bestCandidate = candidate;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (!bestCandidate) {
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
706
|
+
selected.push(bestCandidate);
|
|
707
|
+
selectedIndices.add(bestCandidate.index);
|
|
708
|
+
selectedTokens += bestCandidate.tokens;
|
|
709
|
+
for (const term of bestCandidate.overlapTerms) {
|
|
710
|
+
coveredTerms.add(term);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
selected.sort((left, right) => left.index - right.index);
|
|
714
|
+
let output = selected.map((item) => item.sentence).join(" ");
|
|
715
|
+
if (!output) {
|
|
716
|
+
output = tokenizeForHeuristicCompression(inputText).slice(0, targetTokens).join(" ");
|
|
717
|
+
} else {
|
|
718
|
+
const outputTokens = tokenizeForHeuristicCompression(output);
|
|
719
|
+
if (outputTokens.length > targetTokens) {
|
|
720
|
+
output = outputTokens.slice(0, targetTokens).join(" ");
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
return toCompressionOutput(output, inputTokens);
|
|
724
|
+
}
|
|
725
|
+
function toCompressionOutput(output, inputTokens) {
|
|
726
|
+
const outputTokens = estimateHeuristicTokens(output);
|
|
727
|
+
const tokensSaved = Math.max(0, inputTokens - outputTokens);
|
|
728
|
+
return {
|
|
729
|
+
output,
|
|
730
|
+
inputTokens,
|
|
731
|
+
outputTokens,
|
|
732
|
+
tokensSaved,
|
|
733
|
+
compressionRatio: outputTokens === 0 ? 0 : inputTokens / outputTokens
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function isBetterTieBreak(candidate, bestCandidate) {
|
|
737
|
+
if (candidate.overlapCount !== bestCandidate.overlapCount) {
|
|
738
|
+
return candidate.overlapCount > bestCandidate.overlapCount;
|
|
739
|
+
}
|
|
740
|
+
if (candidate.tokens !== bestCandidate.tokens) {
|
|
741
|
+
return candidate.tokens < bestCandidate.tokens;
|
|
742
|
+
}
|
|
743
|
+
return candidate.index < bestCandidate.index;
|
|
744
|
+
}
|
|
745
|
+
function normalizeForDeduping(sentence) {
|
|
746
|
+
return sentence.toLowerCase().replace(DEDUPE_NORMALIZE_REGEX, " ").replace(/\s+/g, " ").trim();
|
|
747
|
+
}
|
|
748
|
+
function splitIntoSentences(text) {
|
|
749
|
+
return text.split(/(?<=[.!?])\s+|\n+/g).map((sentence) => sentence.trim()).filter(Boolean);
|
|
750
|
+
}
|
|
751
|
+
function chunkTokens(tokens, chunkSize) {
|
|
752
|
+
const chunks = [];
|
|
753
|
+
for (let index = 0; index < tokens.length; index += chunkSize) {
|
|
754
|
+
chunks.push(tokens.slice(index, index + chunkSize));
|
|
755
|
+
}
|
|
756
|
+
return chunks;
|
|
757
|
+
}
|
|
758
|
+
function splitOversizedSentence(sentence, maxTokens = MAX_SEGMENT_TOKENS) {
|
|
759
|
+
const rawTokens = tokenizeForHeuristicCompression(sentence);
|
|
760
|
+
if (rawTokens.length <= maxTokens) {
|
|
761
|
+
return [sentence];
|
|
762
|
+
}
|
|
763
|
+
const commaSplit = sentence.split(/(?<=[,;:])\s+|\s+-\s+/g).map((segment) => segment.trim()).filter(Boolean);
|
|
764
|
+
if (commaSplit.length > 1) {
|
|
765
|
+
return commaSplit.flatMap((segment) => {
|
|
766
|
+
if (estimateHeuristicTokens(segment) <= maxTokens) {
|
|
767
|
+
return [segment];
|
|
768
|
+
}
|
|
769
|
+
return chunkTokens(tokenizeForHeuristicCompression(segment), maxTokens).map((chunk) => chunk.join(" "));
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
return chunkTokens(rawTokens, maxTokens).map((chunk) => chunk.join(" "));
|
|
773
|
+
}
|
|
774
|
+
function normalizeToken(token) {
|
|
775
|
+
return token.replace(TOKEN_NORMALIZE_REGEX, "").trim();
|
|
776
|
+
}
|
|
777
|
+
function tokenizeNormalized(text) {
|
|
778
|
+
return tokenizeForHeuristicCompression(text.toLowerCase()).map(normalizeToken).filter(Boolean);
|
|
779
|
+
}
|
|
780
|
+
function queryTerms(query) {
|
|
781
|
+
return new Set(tokenizeNormalized(query).filter((term) => term.length >= 3 && !STOP_WORDS.has(term)));
|
|
782
|
+
}
|
|
783
|
+
function preprocessContext(context) {
|
|
784
|
+
const originalTokens = estimateHeuristicTokens(context);
|
|
785
|
+
const dedupeSet = /* @__PURE__ */ new Set();
|
|
786
|
+
const candidates = [];
|
|
787
|
+
for (const sentence of splitIntoSentences(context)) {
|
|
788
|
+
for (const segment of splitOversizedSentence(sentence)) {
|
|
789
|
+
const normalized = normalizeForDeduping(segment);
|
|
790
|
+
if (!normalized || dedupeSet.has(normalized)) {
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
dedupeSet.add(normalized);
|
|
794
|
+
const rawTokens = tokenizeForHeuristicCompression(segment);
|
|
795
|
+
const normalizedTerms = rawTokens.map((token) => normalizeToken(token.toLowerCase())).filter(Boolean);
|
|
796
|
+
const lowered = segment.toLowerCase();
|
|
797
|
+
candidates.push({
|
|
798
|
+
sentence: segment,
|
|
799
|
+
index: candidates.length,
|
|
800
|
+
tokenCount: rawTokens.length,
|
|
801
|
+
uniqueTerms: new Set(normalizedTerms),
|
|
802
|
+
isBoilerplate: BOILERPLATE_REGEX.test(lowered)
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return { originalTokens, candidates };
|
|
807
|
+
}
|
|
808
|
+
function scoreSentenceCandidate(candidate, terms) {
|
|
809
|
+
if (candidate.tokenCount === 0) {
|
|
810
|
+
return {
|
|
811
|
+
score: 0,
|
|
812
|
+
overlapCount: 0,
|
|
813
|
+
overlapTerms: []
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
const overlapTerms = [];
|
|
817
|
+
let overlap = 0;
|
|
818
|
+
for (const term of terms) {
|
|
819
|
+
if (candidate.uniqueTerms.has(term)) {
|
|
820
|
+
overlap += 1;
|
|
821
|
+
overlapTerms.push(term);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
const overlapScore = overlap * 2;
|
|
825
|
+
const densityScore = terms.size > 0 ? overlap / terms.size : 0;
|
|
826
|
+
const lengthScore = Math.min(candidate.tokenCount, 40) / 40;
|
|
827
|
+
const boilerplatePenalty = candidate.isBoilerplate ? 0.5 : 0;
|
|
828
|
+
return {
|
|
829
|
+
score: overlapScore + densityScore + lengthScore - boilerplatePenalty,
|
|
830
|
+
overlapCount: overlap,
|
|
831
|
+
overlapTerms
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// src/code-compaction.ts
|
|
836
|
+
function compactCode(input, options = {}) {
|
|
837
|
+
const inputText = input ?? "";
|
|
838
|
+
const removeComments = options.remove_comments ?? true;
|
|
839
|
+
const trimIndentation = options.trim_indentation ?? true;
|
|
840
|
+
const collapseBlankLines = options.collapse_blank_lines ?? true;
|
|
841
|
+
let output = inputText.replace(/\r\n?/g, "\n");
|
|
842
|
+
if (removeComments) {
|
|
843
|
+
output = stripCodeComments(output);
|
|
844
|
+
}
|
|
845
|
+
output = output.split("\n").map((line2) => line2.replace(/[ \t]+$/g, "")).join("\n");
|
|
846
|
+
if (trimIndentation) {
|
|
847
|
+
output = stripCommonIndent(output);
|
|
848
|
+
}
|
|
849
|
+
if (collapseBlankLines) {
|
|
850
|
+
output = output.split("\n").filter((line2) => line2.trim().length > 0).join("\n");
|
|
851
|
+
}
|
|
852
|
+
output = output.trim();
|
|
853
|
+
const inputTokens = estimateHeuristicTokens(inputText);
|
|
854
|
+
const outputTokens = estimateHeuristicTokens(output);
|
|
855
|
+
return {
|
|
856
|
+
output,
|
|
857
|
+
inputTokens,
|
|
858
|
+
outputTokens,
|
|
859
|
+
tokensSaved: Math.max(0, inputTokens - outputTokens),
|
|
860
|
+
compressionRatio: outputTokens === 0 ? 0 : inputTokens / outputTokens
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
function stripCommonIndent(input) {
|
|
864
|
+
const lines = input.split("\n");
|
|
865
|
+
const nonEmptyLines = lines.filter((line2) => line2.trim().length > 0);
|
|
866
|
+
if (nonEmptyLines.length === 0) {
|
|
867
|
+
return "";
|
|
868
|
+
}
|
|
869
|
+
const commonIndent = Math.min(
|
|
870
|
+
...nonEmptyLines.map((line2) => {
|
|
871
|
+
const match = line2.match(/^[ \t]*/);
|
|
872
|
+
return match?.[0].length ?? 0;
|
|
873
|
+
})
|
|
874
|
+
);
|
|
875
|
+
if (commonIndent === 0) {
|
|
876
|
+
return input;
|
|
877
|
+
}
|
|
878
|
+
return lines.map((line2) => line2.slice(commonIndent)).join("\n");
|
|
879
|
+
}
|
|
880
|
+
function stripCodeComments(input) {
|
|
881
|
+
let output = "";
|
|
882
|
+
let index = 0;
|
|
883
|
+
let quote;
|
|
884
|
+
let escaped = false;
|
|
885
|
+
let atLineStart = true;
|
|
886
|
+
while (index < input.length) {
|
|
887
|
+
const char = input[index];
|
|
888
|
+
const next = input[index + 1];
|
|
889
|
+
if (quote) {
|
|
890
|
+
output += char;
|
|
891
|
+
if (escaped) {
|
|
892
|
+
escaped = false;
|
|
893
|
+
} else if (char === "\\") {
|
|
894
|
+
escaped = true;
|
|
895
|
+
} else if (char === quote) {
|
|
896
|
+
quote = void 0;
|
|
897
|
+
}
|
|
898
|
+
atLineStart = char === "\n";
|
|
899
|
+
index += 1;
|
|
900
|
+
continue;
|
|
901
|
+
}
|
|
902
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
903
|
+
quote = char;
|
|
904
|
+
output += char;
|
|
905
|
+
atLineStart = false;
|
|
906
|
+
index += 1;
|
|
907
|
+
continue;
|
|
908
|
+
}
|
|
909
|
+
if (atLineStart && char === "#" && next === "!") {
|
|
910
|
+
while (index < input.length && input[index] !== "\n") {
|
|
911
|
+
output += input[index];
|
|
912
|
+
index += 1;
|
|
913
|
+
}
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
if (char === "/" && next === "/") {
|
|
917
|
+
index += 2;
|
|
918
|
+
while (index < input.length && input[index] !== "\n") {
|
|
919
|
+
index += 1;
|
|
920
|
+
}
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
if (char === "/" && next === "*") {
|
|
924
|
+
index += 2;
|
|
925
|
+
while (index < input.length && !(input[index] === "*" && input[index + 1] === "/")) {
|
|
926
|
+
if (input[index] === "\n") {
|
|
927
|
+
output += "\n";
|
|
928
|
+
}
|
|
929
|
+
index += 1;
|
|
930
|
+
}
|
|
931
|
+
index += input[index] === "*" ? 2 : 0;
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
if (char === "#" && (next === " " || next === " ")) {
|
|
935
|
+
index += 1;
|
|
936
|
+
while (index < input.length && input[index] !== "\n") {
|
|
937
|
+
index += 1;
|
|
938
|
+
}
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
output += char;
|
|
942
|
+
atLineStart = char === "\n" || atLineStart && (char === " " || char === " ");
|
|
943
|
+
index += 1;
|
|
944
|
+
}
|
|
945
|
+
return output;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// src/renderer/renderer.ts
|
|
949
|
+
function renderSections(asset, options = {}) {
|
|
950
|
+
const { variables = {}, strict = false } = options;
|
|
951
|
+
const contextInputs = getContextInputs(asset);
|
|
952
|
+
const optionalVariables = contextInputs.filter((input) => input.optional === true).map((input) => input.name);
|
|
953
|
+
const contextInputsByName = new Map(contextInputs.map((input) => [input.name, input]));
|
|
954
|
+
const compressionCache = /* @__PURE__ */ new Map();
|
|
955
|
+
const createTransformVariable = (template) => {
|
|
956
|
+
return ({ name, value, modifier, match }) => {
|
|
957
|
+
const input = contextInputsByName.get(name);
|
|
958
|
+
const configuredHeuristic = input?.compression?.heuristic;
|
|
959
|
+
const configuredCode = input?.compression?.code;
|
|
960
|
+
const shouldCompactCode = modifier === "compact" || modifier === "code" || configuredCode?.enabled === true;
|
|
961
|
+
const shouldCompress = modifier === "compress" || configuredHeuristic?.enabled === true;
|
|
962
|
+
if (modifier === "toon") {
|
|
963
|
+
const result3 = toToonPlaceholder(value);
|
|
964
|
+
if (!result3) {
|
|
965
|
+
options.compression?.onCompressionWarning?.(
|
|
966
|
+
`POK031: JSON-to-TOON skipped for placeholder "${name}" because the value is not a complete valid JSON object or array.`
|
|
967
|
+
);
|
|
968
|
+
return value;
|
|
969
|
+
}
|
|
970
|
+
if (result3.tokensSaved > 0 || result3.output !== value) {
|
|
971
|
+
options.compression?.onHeuristicCompression?.({
|
|
972
|
+
scope: "placeholder",
|
|
973
|
+
variable: name,
|
|
974
|
+
...result3
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
return result3.output;
|
|
978
|
+
}
|
|
979
|
+
if (shouldCompactCode) {
|
|
980
|
+
const result3 = compactCode(value, toCodeCompactionOptions(configuredCode));
|
|
981
|
+
if (result3.tokensSaved > 0 || result3.output !== value) {
|
|
982
|
+
options.compression?.onCodeCompaction?.({
|
|
983
|
+
scope: "placeholder",
|
|
984
|
+
variable: name,
|
|
985
|
+
...result3
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
return result3.output;
|
|
989
|
+
}
|
|
990
|
+
if (!shouldCompress) {
|
|
991
|
+
return value;
|
|
992
|
+
}
|
|
993
|
+
const query = resolveHeuristicQuery(configuredHeuristic, variables, template, match);
|
|
994
|
+
const compressionOptions = {
|
|
995
|
+
min_tokens: configuredHeuristic?.min_tokens,
|
|
996
|
+
max_sentences: configuredHeuristic?.max_sentences,
|
|
997
|
+
target_reduction: configuredHeuristic?.target_reduction,
|
|
998
|
+
query,
|
|
999
|
+
json_to_toon: configuredHeuristic?.json_to_toon
|
|
1000
|
+
};
|
|
1001
|
+
const cacheKey = JSON.stringify([name, value, compressionOptions]);
|
|
1002
|
+
const cached = compressionCache.get(cacheKey);
|
|
1003
|
+
if (cached !== void 0) {
|
|
1004
|
+
return cached;
|
|
1005
|
+
}
|
|
1006
|
+
const result2 = compressHeuristicText(value, compressionOptions);
|
|
1007
|
+
compressionCache.set(cacheKey, result2.output);
|
|
1008
|
+
reportHeuristicCompressionWarnings(options, result2, `placeholder "${name}"`);
|
|
1009
|
+
if (result2.tokensSaved > 0 || result2.output !== value) {
|
|
1010
|
+
options.compression?.onHeuristicCompression?.({
|
|
1011
|
+
scope: "placeholder",
|
|
1012
|
+
variable: name,
|
|
1013
|
+
...result2
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
return result2.output;
|
|
1017
|
+
};
|
|
1018
|
+
};
|
|
1019
|
+
const result = {};
|
|
1020
|
+
if (asset.sections.system_instructions) {
|
|
1021
|
+
result.system_instructions = interpolate(
|
|
1022
|
+
asset.sections.system_instructions,
|
|
1023
|
+
variables,
|
|
1024
|
+
{
|
|
1025
|
+
strict,
|
|
1026
|
+
optionalVariables,
|
|
1027
|
+
transformVariable: createTransformVariable(asset.sections.system_instructions)
|
|
1028
|
+
}
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
if (asset.sections.prompt_template) {
|
|
1032
|
+
result.prompt_template = interpolate(
|
|
1033
|
+
asset.sections.prompt_template,
|
|
1034
|
+
variables,
|
|
1035
|
+
{
|
|
1036
|
+
strict,
|
|
1037
|
+
optionalVariables,
|
|
1038
|
+
transformVariable: createTransformVariable(asset.sections.prompt_template)
|
|
1039
|
+
}
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
return result;
|
|
1043
|
+
}
|
|
1044
|
+
function resolveHeuristicQuery(options, variables, template, match) {
|
|
1045
|
+
if (options?.query !== void 0) {
|
|
1046
|
+
return options.query;
|
|
1047
|
+
}
|
|
1048
|
+
if (options?.query_variable && variables[options.query_variable] !== void 0) {
|
|
1049
|
+
return variables[options.query_variable];
|
|
1050
|
+
}
|
|
1051
|
+
return template.replace(match, " ");
|
|
1052
|
+
}
|
|
1053
|
+
function toToonPlaceholder(value) {
|
|
1054
|
+
const toon = tryJsonToToon(value);
|
|
1055
|
+
if (!toon) {
|
|
1056
|
+
return void 0;
|
|
1057
|
+
}
|
|
1058
|
+
const inputTokens = estimateHeuristicTokens(value);
|
|
1059
|
+
const outputTokens = estimateHeuristicTokens(toon.output);
|
|
1060
|
+
return {
|
|
1061
|
+
output: toon.output,
|
|
1062
|
+
inputTokens,
|
|
1063
|
+
outputTokens,
|
|
1064
|
+
tokensSaved: Math.max(0, inputTokens - outputTokens),
|
|
1065
|
+
compressionRatio: outputTokens === 0 ? 0 : inputTokens / outputTokens,
|
|
1066
|
+
outputFormat: "toon"
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
function toCodeCompactionOptions(options) {
|
|
1070
|
+
return {
|
|
1071
|
+
remove_comments: options?.remove_comments,
|
|
1072
|
+
trim_indentation: options?.trim_indentation,
|
|
1073
|
+
collapse_blank_lines: options?.collapse_blank_lines
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
function reportHeuristicCompressionWarnings(options, result, scope) {
|
|
1077
|
+
for (const warning of result.warnings ?? []) {
|
|
1078
|
+
options.compression?.onCompressionWarning?.(`POK031: ${warning} Scope: ${scope}.`);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
// src/overrides/apply-overrides.ts
|
|
1083
|
+
function applyOverrides(asset, options = {}) {
|
|
1084
|
+
let result = { ...asset };
|
|
1085
|
+
if (options.environment && result.environments?.[options.environment]) {
|
|
1086
|
+
result = mergeOverride(result, result.environments[options.environment]);
|
|
1087
|
+
}
|
|
1088
|
+
if (options.tier && result.tiers?.[options.tier]) {
|
|
1089
|
+
result = mergeOverride(result, result.tiers[options.tier]);
|
|
1090
|
+
}
|
|
1091
|
+
if (options.runtime) {
|
|
1092
|
+
result = mergeOverride(result, options.runtime);
|
|
1093
|
+
}
|
|
1094
|
+
return result;
|
|
1095
|
+
}
|
|
1096
|
+
function mergeOverride(base, override) {
|
|
1097
|
+
const result = { ...base };
|
|
1098
|
+
if (override.model !== void 0) result.model = override.model;
|
|
1099
|
+
if (override.fallback_models !== void 0) result.fallback_models = override.fallback_models;
|
|
1100
|
+
if (override.tools !== void 0) result.tools = override.tools;
|
|
1101
|
+
if (override.reasoning !== void 0) {
|
|
1102
|
+
result.reasoning = { ...result.reasoning, ...override.reasoning };
|
|
1103
|
+
}
|
|
1104
|
+
if (override.sampling !== void 0) {
|
|
1105
|
+
result.sampling = { ...result.sampling, ...override.sampling };
|
|
1106
|
+
}
|
|
1107
|
+
if (override.response !== void 0) {
|
|
1108
|
+
result.response = { ...result.response, ...override.response };
|
|
1109
|
+
}
|
|
1110
|
+
if (override.compression !== void 0) {
|
|
1111
|
+
result.compression = {
|
|
1112
|
+
...result.compression,
|
|
1113
|
+
...override.compression,
|
|
1114
|
+
thetokencompany: mergeRecordBlock(
|
|
1115
|
+
result.compression?.thetokencompany,
|
|
1116
|
+
override.compression.thetokencompany
|
|
1117
|
+
),
|
|
1118
|
+
heuristic: mergeRecordBlock(
|
|
1119
|
+
result.compression?.heuristic,
|
|
1120
|
+
override.compression.heuristic
|
|
1121
|
+
),
|
|
1122
|
+
code: mergeRecordBlock(
|
|
1123
|
+
result.compression?.code,
|
|
1124
|
+
override.compression.code
|
|
1125
|
+
)
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
if (override.cache !== void 0) {
|
|
1129
|
+
result.cache = {
|
|
1130
|
+
...result.cache,
|
|
1131
|
+
...override.cache,
|
|
1132
|
+
openai: mergeRecordBlock(result.cache?.openai, override.cache.openai),
|
|
1133
|
+
anthropic: mergeRecordBlock(result.cache?.anthropic, override.cache.anthropic),
|
|
1134
|
+
gemini: mergeRecordBlock(result.cache?.gemini, override.cache.gemini),
|
|
1135
|
+
google: mergeRecordBlock(result.cache?.google, override.cache.google)
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
if (override.raw !== void 0) {
|
|
1139
|
+
result.raw = {
|
|
1140
|
+
...result.raw,
|
|
1141
|
+
...override.raw,
|
|
1142
|
+
openai: mergeRecordBlock(result.raw?.openai, override.raw.openai),
|
|
1143
|
+
"openai-responses": mergeRecordBlock(result.raw?.["openai-responses"], override.raw["openai-responses"]),
|
|
1144
|
+
openai_responses: mergeRecordBlock(result.raw?.openai_responses, override.raw.openai_responses),
|
|
1145
|
+
anthropic: mergeRecordBlock(result.raw?.anthropic, override.raw.anthropic),
|
|
1146
|
+
gemini: mergeRecordBlock(result.raw?.gemini, override.raw.gemini),
|
|
1147
|
+
google: mergeRecordBlock(result.raw?.google, override.raw.google),
|
|
1148
|
+
openrouter: mergeRecordBlock(result.raw?.openrouter, override.raw.openrouter),
|
|
1149
|
+
llmasaservice: mergeRecordBlock(result.raw?.llmasaservice, override.raw.llmasaservice)
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
if (override.provider_options !== void 0) {
|
|
1153
|
+
result.provider_options = {
|
|
1154
|
+
...result.provider_options,
|
|
1155
|
+
...override.provider_options,
|
|
1156
|
+
anthropic: {
|
|
1157
|
+
...result.provider_options?.anthropic,
|
|
1158
|
+
...override.provider_options.anthropic
|
|
1159
|
+
},
|
|
1160
|
+
gemini: {
|
|
1161
|
+
...result.provider_options?.gemini,
|
|
1162
|
+
...override.provider_options.gemini
|
|
1163
|
+
},
|
|
1164
|
+
openrouter: {
|
|
1165
|
+
...result.provider_options?.openrouter,
|
|
1166
|
+
...override.provider_options.openrouter
|
|
1167
|
+
},
|
|
1168
|
+
llmasaservice: {
|
|
1169
|
+
...result.provider_options?.llmasaservice,
|
|
1170
|
+
...override.provider_options.llmasaservice
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
return result;
|
|
1175
|
+
}
|
|
1176
|
+
function mergeRecordBlock(base, override) {
|
|
1177
|
+
if (override === void 0) return base;
|
|
1178
|
+
return { ...base, ...override };
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// src/providers/resolve-asset.ts
|
|
1182
|
+
function resolveAssetForProvider(asset, runtime = {}) {
|
|
1183
|
+
if (!runtime.environment && !runtime.tier && !runtime.runtime) {
|
|
1184
|
+
return asset;
|
|
1185
|
+
}
|
|
1186
|
+
return applyOverrides(asset, {
|
|
1187
|
+
environment: runtime.environment,
|
|
1188
|
+
tier: runtime.tier,
|
|
1189
|
+
runtime: runtime.runtime
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// src/cache.ts
|
|
1194
|
+
import { statSync } from "fs";
|
|
1195
|
+
var PromptCache = class {
|
|
1196
|
+
cache = /* @__PURE__ */ new Map();
|
|
1197
|
+
maxSize;
|
|
1198
|
+
constructor(maxSize = 100) {
|
|
1199
|
+
this.maxSize = maxSize;
|
|
1200
|
+
}
|
|
1201
|
+
get(filePath) {
|
|
1202
|
+
const entry = this.cache.get(filePath);
|
|
1203
|
+
if (!entry) return void 0;
|
|
1204
|
+
try {
|
|
1205
|
+
const stat = statSync(filePath);
|
|
1206
|
+
if (stat.mtimeMs !== entry.mtime) {
|
|
1207
|
+
this.cache.delete(filePath);
|
|
1208
|
+
return void 0;
|
|
1209
|
+
}
|
|
1210
|
+
} catch {
|
|
1211
|
+
this.cache.delete(filePath);
|
|
1212
|
+
return void 0;
|
|
1213
|
+
}
|
|
1214
|
+
this.cache.delete(filePath);
|
|
1215
|
+
this.cache.set(filePath, entry);
|
|
1216
|
+
return entry.value;
|
|
1217
|
+
}
|
|
1218
|
+
set(filePath, value) {
|
|
1219
|
+
try {
|
|
1220
|
+
const stat = statSync(filePath);
|
|
1221
|
+
if (this.cache.has(filePath)) {
|
|
1222
|
+
this.cache.delete(filePath);
|
|
1223
|
+
} else if (this.cache.size >= this.maxSize) {
|
|
1224
|
+
const oldest = this.cache.keys().next().value;
|
|
1225
|
+
if (oldest) this.cache.delete(oldest);
|
|
1226
|
+
}
|
|
1227
|
+
this.cache.set(filePath, { value, mtime: stat.mtimeMs });
|
|
1228
|
+
} catch {
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
clear() {
|
|
1232
|
+
this.cache.clear();
|
|
1233
|
+
}
|
|
1234
|
+
get size() {
|
|
1235
|
+
return this.cache.size;
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
// src/composition/resolve-includes.ts
|
|
1240
|
+
import { readFile } from "fs/promises";
|
|
1241
|
+
import { resolve, dirname } from "path";
|
|
1242
|
+
async function resolveIncludes(asset, basePath, visited = /* @__PURE__ */ new Set()) {
|
|
1243
|
+
if (!asset.includes || asset.includes.length === 0) {
|
|
1244
|
+
return asset;
|
|
1245
|
+
}
|
|
1246
|
+
const baseDir = dirname(basePath);
|
|
1247
|
+
const resolvedPath = resolve(basePath);
|
|
1248
|
+
if (visited.has(resolvedPath)) {
|
|
1249
|
+
throw new Error(`Circular include detected: ${resolvedPath}`);
|
|
1250
|
+
}
|
|
1251
|
+
visited.add(resolvedPath);
|
|
1252
|
+
let mergedSystemInstructions = "";
|
|
1253
|
+
for (const includePath of asset.includes) {
|
|
1254
|
+
const fullPath = resolve(baseDir, includePath);
|
|
1255
|
+
if (visited.has(fullPath)) {
|
|
1256
|
+
throw new Error(`Circular include detected: ${fullPath} (included from ${basePath})`);
|
|
1257
|
+
}
|
|
1258
|
+
const content = await readFile(fullPath, "utf-8");
|
|
1259
|
+
const { asset: includedAsset } = parsePrompt(content, fullPath);
|
|
1260
|
+
const resolved = await resolveIncludes(includedAsset, fullPath, new Set(visited));
|
|
1261
|
+
if (resolved.sections?.system_instructions) {
|
|
1262
|
+
mergedSystemInstructions += resolved.sections.system_instructions + "\n\n";
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
const localSystem = asset.sections?.system_instructions ?? "";
|
|
1266
|
+
const combinedSystem = (mergedSystemInstructions + localSystem).trim() || void 0;
|
|
1267
|
+
return {
|
|
1268
|
+
...asset,
|
|
1269
|
+
sections: {
|
|
1270
|
+
...asset.sections,
|
|
1271
|
+
system_instructions: combinedSystem
|
|
1272
|
+
},
|
|
1273
|
+
// Drop includes from the resolved asset — they've been inlined
|
|
1274
|
+
includes: void 0
|
|
1275
|
+
};
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// src/prompt-resolution.ts
|
|
1279
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1280
|
+
import { existsSync, statSync as statSync2 } from "fs";
|
|
1281
|
+
import { resolve as resolve2 } from "path";
|
|
1282
|
+
var DEFAULT_PROMPTS_DIR = "./prompts";
|
|
1283
|
+
var DEFAULT_COMPILED_JSON_DIR = "./.generated-prompts/json";
|
|
1284
|
+
function withPromptResolutionDefaults(config) {
|
|
1285
|
+
return {
|
|
1286
|
+
...config,
|
|
1287
|
+
sourceDir: config.sourceDir ?? DEFAULT_PROMPTS_DIR,
|
|
1288
|
+
compiledDir: config.compiledDir ?? DEFAULT_COMPILED_JSON_DIR
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
var sharedPromptCache = new PromptCache();
|
|
1292
|
+
async function loadPromptAsset(promptPath, config, promptCache = sharedPromptCache) {
|
|
1293
|
+
const resolvedConfig = withPromptResolutionDefaults(config);
|
|
1294
|
+
const mode = resolvedConfig.mode ?? "auto";
|
|
1295
|
+
if (mode !== "source-only" && resolvedConfig.compiledDir) {
|
|
1296
|
+
const compiledFile = resolve2(resolvedConfig.compiledDir, promptPath + ".json");
|
|
1297
|
+
if (existsSync(compiledFile)) {
|
|
1298
|
+
if (mode === "auto") {
|
|
1299
|
+
const sourceFile = resolve2(resolvedConfig.sourceDir, promptPath + ".md");
|
|
1300
|
+
if (existsSync(sourceFile)) {
|
|
1301
|
+
const compiledMtime = statSync2(compiledFile).mtimeMs;
|
|
1302
|
+
const sourceMtime = statSync2(sourceFile).mtimeMs;
|
|
1303
|
+
if (sourceMtime > compiledMtime) {
|
|
1304
|
+
console.warn(
|
|
1305
|
+
`[promptopskit] Warning: compiled artifact for "${promptPath}" is older than source .md file.
|
|
1306
|
+
Run "promptopskit compile" or switch to source-only mode.`
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
const content = await readFile2(compiledFile, "utf-8");
|
|
1312
|
+
return JSON.parse(content);
|
|
1313
|
+
}
|
|
1314
|
+
if (mode === "compiled-only") {
|
|
1315
|
+
throw new Error(
|
|
1316
|
+
`Compiled artifact not found: ${compiledFile}
|
|
1317
|
+
Run "promptopskit compile" to generate it.`
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
if (mode !== "compiled-only") {
|
|
1322
|
+
const sourceFile = resolve2(resolvedConfig.sourceDir, promptPath + ".md");
|
|
1323
|
+
if (resolvedConfig.cache !== false) {
|
|
1324
|
+
const cached = promptCache.get(sourceFile);
|
|
1325
|
+
if (cached) {
|
|
1326
|
+
return cached;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
if (!existsSync(sourceFile)) {
|
|
1330
|
+
const paths = [sourceFile];
|
|
1331
|
+
if (resolvedConfig.compiledDir) {
|
|
1332
|
+
paths.unshift(resolve2(resolvedConfig.compiledDir, promptPath + ".json"));
|
|
1333
|
+
}
|
|
1334
|
+
throw new Error(
|
|
1335
|
+
`Prompt not found: "${promptPath}"
|
|
1336
|
+
Searched:
|
|
1337
|
+
${paths.map((candidate) => ` - ${candidate}`).join("\n")}`
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
const { asset } = await loadPromptFile(sourceFile, { defaultsRoot: resolvedConfig.sourceDir });
|
|
1341
|
+
if (resolvedConfig.cache !== false) {
|
|
1342
|
+
promptCache.set(sourceFile, asset);
|
|
1343
|
+
}
|
|
1344
|
+
return asset;
|
|
1345
|
+
}
|
|
1346
|
+
throw new Error(`Prompt not found: "${promptPath}"`);
|
|
1347
|
+
}
|
|
1348
|
+
async function resolvePromptAsset(promptPath, config, options = {}, promptCache = sharedPromptCache) {
|
|
1349
|
+
const resolvedConfig = withPromptResolutionDefaults(config);
|
|
1350
|
+
let asset = await loadPromptAsset(promptPath, resolvedConfig, promptCache);
|
|
1351
|
+
const sourceFile = resolve2(resolvedConfig.sourceDir, promptPath + ".md");
|
|
1352
|
+
if (asset.includes && asset.includes.length > 0 && existsSync(sourceFile)) {
|
|
1353
|
+
asset = await resolveIncludes(asset, sourceFile);
|
|
1354
|
+
}
|
|
1355
|
+
asset = applyOverrides(asset, {
|
|
1356
|
+
environment: options.environment,
|
|
1357
|
+
tier: options.tier,
|
|
1358
|
+
runtime: options.runtime
|
|
1359
|
+
});
|
|
1360
|
+
return asset;
|
|
1361
|
+
}
|
|
1362
|
+
function resolveInlinePromptSource(source, options = {}) {
|
|
1363
|
+
const { asset } = parsePrompt(source);
|
|
1364
|
+
return applyOverrides(asset, {
|
|
1365
|
+
environment: options.environment,
|
|
1366
|
+
tier: options.tier,
|
|
1367
|
+
runtime: options.runtime
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
// src/history.ts
|
|
1372
|
+
function defaultCompactHistory(info) {
|
|
1373
|
+
const content = info.overflow.map((message) => `${message.role}: ${message.content}`).join("\n\n");
|
|
1374
|
+
return {
|
|
1375
|
+
role: "user",
|
|
1376
|
+
content: `Earlier conversation compacted to preserve history:
|
|
1377
|
+
|
|
1378
|
+
${content}`
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
function normalizeCompactionResult(result) {
|
|
1382
|
+
if (typeof result === "string") {
|
|
1383
|
+
return {
|
|
1384
|
+
role: "user",
|
|
1385
|
+
content: result
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
return result;
|
|
1389
|
+
}
|
|
1390
|
+
function compactHistoryForPrompt(asset, runtime) {
|
|
1391
|
+
const history = runtime.history;
|
|
1392
|
+
const maxItems = asset.context?.history?.max_items;
|
|
1393
|
+
if (!history || maxItems === void 0 || history.length <= maxItems) {
|
|
1394
|
+
return history;
|
|
1395
|
+
}
|
|
1396
|
+
if (maxItems === 1) {
|
|
1397
|
+
const info2 = {
|
|
1398
|
+
promptId: asset.id,
|
|
1399
|
+
maxItems,
|
|
1400
|
+
overflow: history,
|
|
1401
|
+
preserved: [],
|
|
1402
|
+
history
|
|
1403
|
+
};
|
|
1404
|
+
const compacted2 = runtime.onHistoryCompaction ? normalizeCompactionResult(runtime.onHistoryCompaction(info2)) : defaultCompactHistory(info2);
|
|
1405
|
+
return [compacted2];
|
|
1406
|
+
}
|
|
1407
|
+
const preservedCount = maxItems - 1;
|
|
1408
|
+
const overflow = history.slice(0, history.length - preservedCount);
|
|
1409
|
+
const preserved = history.slice(-preservedCount);
|
|
1410
|
+
const info = {
|
|
1411
|
+
promptId: asset.id,
|
|
1412
|
+
maxItems,
|
|
1413
|
+
overflow,
|
|
1414
|
+
preserved,
|
|
1415
|
+
history
|
|
1416
|
+
};
|
|
1417
|
+
const compacted = runtime.onHistoryCompaction ? normalizeCompactionResult(runtime.onHistoryCompaction(info)) : defaultCompactHistory(info);
|
|
1418
|
+
return [compacted, ...preserved];
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// src/compression.ts
|
|
1422
|
+
var THETOKENCOMPANY_DEFAULT_MODEL = "bear-2";
|
|
1423
|
+
var THETOKENCOMPANY_DEFAULT_BASE_URL = "https://api.thetokencompany.com";
|
|
1424
|
+
var HEURISTIC_COMPRESSION_MODEL = "local-heuristic-v1";
|
|
1425
|
+
var CODE_COMPACTION_MODEL = "local-code-compactor-v1";
|
|
1426
|
+
function summarizePromptCompression(compression = []) {
|
|
1427
|
+
const totals = compression.reduce(
|
|
1428
|
+
(accumulator, result) => {
|
|
1429
|
+
accumulator.inputTokens += result.inputTokens;
|
|
1430
|
+
accumulator.outputTokens += result.outputTokens;
|
|
1431
|
+
accumulator.tokensSaved += result.tokensSaved;
|
|
1432
|
+
return accumulator;
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
inputTokens: 0,
|
|
1436
|
+
outputTokens: 0,
|
|
1437
|
+
tokensSaved: 0
|
|
1438
|
+
}
|
|
1439
|
+
);
|
|
1440
|
+
return {
|
|
1441
|
+
steps: compression.length,
|
|
1442
|
+
inputTokens: totals.inputTokens,
|
|
1443
|
+
outputTokens: totals.outputTokens,
|
|
1444
|
+
tokensSaved: totals.tokensSaved,
|
|
1445
|
+
reductionRatio: totals.inputTokens === 0 ? 0 : totals.tokensSaved / totals.inputTokens
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
async function applyPromptCompressionForRender(asset, runtime) {
|
|
1449
|
+
const theTokenCompanyConfig = asset.compression?.thetokencompany;
|
|
1450
|
+
const heuristicConfig = asset.compression?.heuristic;
|
|
1451
|
+
const codeConfig = asset.compression?.code;
|
|
1452
|
+
const hasTheTokenCompanyCompression = theTokenCompanyConfig?.enabled === true && Boolean(asset.sections.prompt_template);
|
|
1453
|
+
const hasHeuristicPromptCompression = heuristicConfig?.enabled === true && Boolean(asset.sections.prompt_template);
|
|
1454
|
+
const hasCodePromptCompaction = codeConfig?.enabled === true && Boolean(asset.sections.prompt_template);
|
|
1455
|
+
const hasPlaceholderCompression = usesPlaceholderCompression(asset);
|
|
1456
|
+
if (!hasTheTokenCompanyCompression && !hasHeuristicPromptCompression && !hasCodePromptCompaction && !hasPlaceholderCompression) {
|
|
1457
|
+
return { asset, runtime, compression: [], warnings: [] };
|
|
1458
|
+
}
|
|
1459
|
+
const compression = [];
|
|
1460
|
+
const warnings = [];
|
|
1461
|
+
const sections = renderSections(asset, {
|
|
1462
|
+
variables: runtime.variables,
|
|
1463
|
+
strict: runtime.strict,
|
|
1464
|
+
compression: {
|
|
1465
|
+
onHeuristicCompression: (event) => {
|
|
1466
|
+
compression.push({
|
|
1467
|
+
provider: "heuristic",
|
|
1468
|
+
model: HEURISTIC_COMPRESSION_MODEL,
|
|
1469
|
+
inputTokens: event.inputTokens,
|
|
1470
|
+
outputTokens: event.outputTokens,
|
|
1471
|
+
tokensSaved: event.tokensSaved,
|
|
1472
|
+
compressionRatio: event.compressionRatio,
|
|
1473
|
+
scope: event.scope,
|
|
1474
|
+
variable: event.variable,
|
|
1475
|
+
outputFormat: event.outputFormat
|
|
1476
|
+
});
|
|
1477
|
+
},
|
|
1478
|
+
onCodeCompaction: (event) => {
|
|
1479
|
+
compression.push({
|
|
1480
|
+
provider: "code",
|
|
1481
|
+
model: CODE_COMPACTION_MODEL,
|
|
1482
|
+
inputTokens: event.inputTokens,
|
|
1483
|
+
outputTokens: event.outputTokens,
|
|
1484
|
+
tokensSaved: event.tokensSaved,
|
|
1485
|
+
compressionRatio: event.compressionRatio,
|
|
1486
|
+
scope: event.scope,
|
|
1487
|
+
variable: event.variable,
|
|
1488
|
+
outputFormat: "code"
|
|
1489
|
+
});
|
|
1490
|
+
},
|
|
1491
|
+
onCompressionWarning: (warning) => {
|
|
1492
|
+
warnings.push(warning);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
});
|
|
1496
|
+
let promptTemplate = sections.prompt_template;
|
|
1497
|
+
if (hasCodePromptCompaction && promptTemplate) {
|
|
1498
|
+
if (hasHeuristicPromptCompression) {
|
|
1499
|
+
warnings.push(
|
|
1500
|
+
"POK032: Local heuristic prompt compression skipped because compression.code is enabled for the prompt template."
|
|
1501
|
+
);
|
|
1502
|
+
}
|
|
1503
|
+
const result = compactCode(promptTemplate, toCodeCompactionOptions2(codeConfig));
|
|
1504
|
+
promptTemplate = result.output;
|
|
1505
|
+
if (result.tokensSaved > 0 || result.output !== sections.prompt_template) {
|
|
1506
|
+
compression.push({
|
|
1507
|
+
provider: "code",
|
|
1508
|
+
model: CODE_COMPACTION_MODEL,
|
|
1509
|
+
inputTokens: result.inputTokens,
|
|
1510
|
+
outputTokens: result.outputTokens,
|
|
1511
|
+
tokensSaved: result.tokensSaved,
|
|
1512
|
+
compressionRatio: result.compressionRatio,
|
|
1513
|
+
scope: "prompt_template",
|
|
1514
|
+
outputFormat: "code"
|
|
1515
|
+
});
|
|
1516
|
+
}
|
|
1517
|
+
} else if (hasHeuristicPromptCompression && promptTemplate) {
|
|
1518
|
+
const result = compressHeuristicText(promptTemplate, {
|
|
1519
|
+
min_tokens: heuristicConfig?.min_tokens,
|
|
1520
|
+
max_sentences: heuristicConfig?.max_sentences,
|
|
1521
|
+
target_reduction: heuristicConfig?.target_reduction,
|
|
1522
|
+
query: resolveHeuristicPromptQuery(heuristicConfig, runtime.variables, sections.system_instructions),
|
|
1523
|
+
json_to_toon: heuristicConfig?.json_to_toon
|
|
1524
|
+
});
|
|
1525
|
+
promptTemplate = result.output;
|
|
1526
|
+
reportHeuristicCompressionWarnings2(warnings, result.warnings, "prompt template");
|
|
1527
|
+
if (result.tokensSaved > 0 || result.output !== sections.prompt_template) {
|
|
1528
|
+
compression.push({
|
|
1529
|
+
provider: "heuristic",
|
|
1530
|
+
model: HEURISTIC_COMPRESSION_MODEL,
|
|
1531
|
+
inputTokens: result.inputTokens,
|
|
1532
|
+
outputTokens: result.outputTokens,
|
|
1533
|
+
tokensSaved: result.tokensSaved,
|
|
1534
|
+
compressionRatio: result.compressionRatio,
|
|
1535
|
+
scope: "prompt_template",
|
|
1536
|
+
outputFormat: result.outputFormat
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
if (hasTheTokenCompanyCompression && hasCodePromptCompaction && promptTemplate) {
|
|
1541
|
+
warnings.push(
|
|
1542
|
+
"POK033: TheTokenCompany compression skipped because compression.code is enabled; code is compacted locally and not text-compressed."
|
|
1543
|
+
);
|
|
1544
|
+
} else if (hasTheTokenCompanyCompression && promptTemplate) {
|
|
1545
|
+
const model = theTokenCompanyConfig?.model ?? THETOKENCOMPANY_DEFAULT_MODEL;
|
|
1546
|
+
const result = await compressWithTheTokenCompany(promptTemplate, {
|
|
1547
|
+
apiKey: runtime.theTokenCompany?.apiKey,
|
|
1548
|
+
baseURL: runtime.theTokenCompany?.baseURL,
|
|
1549
|
+
fetch: runtime.theTokenCompany?.fetch,
|
|
1550
|
+
model,
|
|
1551
|
+
aggressiveness: theTokenCompanyConfig?.aggressiveness
|
|
1552
|
+
});
|
|
1553
|
+
promptTemplate = result.output;
|
|
1554
|
+
compression.push({
|
|
1555
|
+
provider: "thetokencompany",
|
|
1556
|
+
model,
|
|
1557
|
+
inputTokens: result.input_tokens,
|
|
1558
|
+
outputTokens: result.output_tokens,
|
|
1559
|
+
tokensSaved: result.tokens_saved,
|
|
1560
|
+
compressionRatio: result.compression_ratio
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
return {
|
|
1564
|
+
asset: {
|
|
1565
|
+
...asset,
|
|
1566
|
+
sections: {
|
|
1567
|
+
...asset.sections,
|
|
1568
|
+
...sections,
|
|
1569
|
+
...promptTemplate !== void 0 ? { prompt_template: promptTemplate } : {}
|
|
1570
|
+
}
|
|
1571
|
+
},
|
|
1572
|
+
runtime: {
|
|
1573
|
+
...runtime,
|
|
1574
|
+
variables: {},
|
|
1575
|
+
strict: false
|
|
1576
|
+
},
|
|
1577
|
+
compression,
|
|
1578
|
+
warnings
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
function usesPlaceholderCompression(asset) {
|
|
1582
|
+
const hasContextInputCompression = getContextInputs(asset).some(
|
|
1583
|
+
(input) => input.compression?.heuristic?.enabled === true || input.compression?.code?.enabled === true
|
|
1584
|
+
);
|
|
1585
|
+
if (hasContextInputCompression) {
|
|
1586
|
+
return true;
|
|
1587
|
+
}
|
|
1588
|
+
return Boolean(
|
|
1589
|
+
asset.sections.system_instructions && hasCompressionModifier(asset.sections.system_instructions) || asset.sections.prompt_template && hasCompressionModifier(asset.sections.prompt_template)
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
function hasCompressionModifier(template) {
|
|
1593
|
+
return /\{\{\s*[a-zA-Z_][a-zA-Z0-9_]*\s*\|\s*(?:compress|toon|compact|code)\s*\}\}/.test(template);
|
|
1594
|
+
}
|
|
1595
|
+
function resolveHeuristicPromptQuery(options, variables, systemInstructions) {
|
|
1596
|
+
if (options?.query !== void 0) {
|
|
1597
|
+
return options.query;
|
|
1598
|
+
}
|
|
1599
|
+
if (options?.query_variable && variables?.[options.query_variable] !== void 0) {
|
|
1600
|
+
return variables[options.query_variable];
|
|
1601
|
+
}
|
|
1602
|
+
return systemInstructions;
|
|
1603
|
+
}
|
|
1604
|
+
function toCodeCompactionOptions2(options) {
|
|
1605
|
+
return {
|
|
1606
|
+
remove_comments: options?.remove_comments,
|
|
1607
|
+
trim_indentation: options?.trim_indentation,
|
|
1608
|
+
collapse_blank_lines: options?.collapse_blank_lines
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
function reportHeuristicCompressionWarnings2(warnings, compressionWarnings, scope) {
|
|
1612
|
+
for (const warning of compressionWarnings ?? []) {
|
|
1613
|
+
warnings.push(`POK031: ${warning} Scope: ${scope}.`);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
async function compressWithTheTokenCompany(input, options) {
|
|
1617
|
+
const apiKey = options.apiKey ?? getEnv("THETOKENCOMPANY_API_KEY") ?? getEnv("TTC_API_KEY");
|
|
1618
|
+
if (!apiKey) {
|
|
1619
|
+
throw new Error(
|
|
1620
|
+
"TheTokenCompany compression is enabled, but no API key was provided. Pass theTokenCompany.apiKey to renderPrompt() or set THETOKENCOMPANY_API_KEY."
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1624
|
+
if (!fetchImpl) {
|
|
1625
|
+
throw new Error("TheTokenCompany compression requires a runtime with fetch support.");
|
|
1626
|
+
}
|
|
1627
|
+
const baseURL = (options.baseURL ?? THETOKENCOMPANY_DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
1628
|
+
const compressionSettings = options.aggressiveness === void 0 ? void 0 : { aggressiveness: options.aggressiveness };
|
|
1629
|
+
const response = await fetchImpl(`${baseURL}/v1/compress`, {
|
|
1630
|
+
method: "POST",
|
|
1631
|
+
headers: {
|
|
1632
|
+
Authorization: `Bearer ${apiKey}`,
|
|
1633
|
+
"Content-Type": "application/json"
|
|
1634
|
+
},
|
|
1635
|
+
body: JSON.stringify({
|
|
1636
|
+
model: options.model,
|
|
1637
|
+
input,
|
|
1638
|
+
...compressionSettings ? { compression_settings: compressionSettings } : {}
|
|
1639
|
+
})
|
|
1640
|
+
});
|
|
1641
|
+
if (!response.ok) {
|
|
1642
|
+
const body = await response.text().catch(() => "");
|
|
1643
|
+
throw new Error(
|
|
1644
|
+
`TheTokenCompany compression failed with HTTP ${response.status}` + (body ? `: ${body}` : ".")
|
|
1645
|
+
);
|
|
1646
|
+
}
|
|
1647
|
+
const data = await response.json();
|
|
1648
|
+
if (typeof data.output !== "string" || typeof data.output_tokens !== "number" || typeof data.input_tokens !== "number" || typeof data.tokens_saved !== "number" || typeof data.compression_ratio !== "number") {
|
|
1649
|
+
throw new Error("TheTokenCompany compression returned an invalid response payload.");
|
|
1650
|
+
}
|
|
1651
|
+
return data;
|
|
1652
|
+
}
|
|
1653
|
+
function getEnv(name) {
|
|
1654
|
+
if (typeof process === "undefined") {
|
|
1655
|
+
return void 0;
|
|
1656
|
+
}
|
|
1657
|
+
return process.env[name];
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
// src/providers/prompt-input.ts
|
|
1661
|
+
function isPromptLookup(input) {
|
|
1662
|
+
return "path" in input && typeof input.path === "string";
|
|
1663
|
+
}
|
|
1664
|
+
function isInlinePromptSource(input) {
|
|
1665
|
+
return "source" in input && typeof input.source === "string";
|
|
1666
|
+
}
|
|
1667
|
+
async function resolveProviderPromptInput(input, runtime) {
|
|
1668
|
+
if (isPromptLookup(input)) {
|
|
1669
|
+
return resolvePromptAsset(input.path, input, runtime);
|
|
1670
|
+
}
|
|
1671
|
+
if (isInlinePromptSource(input)) {
|
|
1672
|
+
return resolveInlinePromptSource(input.source, runtime);
|
|
1673
|
+
}
|
|
1674
|
+
return input;
|
|
1675
|
+
}
|
|
1676
|
+
function withPromptInputSupport(adapter) {
|
|
1677
|
+
const validatePrompt = async (input, runtime) => {
|
|
1678
|
+
const resolved = await resolveProviderPromptInput(input, runtime);
|
|
1679
|
+
return adapter.validate(resolved, runtime);
|
|
1680
|
+
};
|
|
1681
|
+
const renderPrompt = async (input, runtime) => {
|
|
1682
|
+
const resolved = await resolveProviderPromptInput(input, runtime);
|
|
1683
|
+
const resolvedForRender = resolveAssetForProvider(resolved, runtime);
|
|
1684
|
+
const sanitization = sanitizeContextVariables(resolvedForRender, runtime.variables, {
|
|
1685
|
+
onContextOverflow: runtime.onContextOverflow
|
|
1686
|
+
});
|
|
1687
|
+
if (sanitization.shortCircuit) {
|
|
1688
|
+
return {
|
|
1689
|
+
provider: adapter.name,
|
|
1690
|
+
model: resolvedForRender.model ?? "",
|
|
1691
|
+
returnMessage: sanitization.shortCircuit.returnMessage
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
const prepared = await applyPromptCompressionForRender(resolvedForRender, {
|
|
1695
|
+
...runtime,
|
|
1696
|
+
environment: void 0,
|
|
1697
|
+
tier: void 0,
|
|
1698
|
+
runtime: void 0,
|
|
1699
|
+
variables: sanitization.variables,
|
|
1700
|
+
history: compactHistoryForPrompt(resolvedForRender, runtime)
|
|
1701
|
+
});
|
|
1702
|
+
const request = adapter.render(prepared.asset, prepared.runtime);
|
|
1703
|
+
return prepared.compression.length > 0 || prepared.warnings.length > 0 ? {
|
|
1704
|
+
...request,
|
|
1705
|
+
...prepared.compression.length > 0 ? {
|
|
1706
|
+
compression: prepared.compression,
|
|
1707
|
+
compressionSummary: summarizePromptCompression(prepared.compression)
|
|
1708
|
+
} : {},
|
|
1709
|
+
...prepared.warnings.length > 0 ? { warnings: prepared.warnings } : {}
|
|
1710
|
+
} : request;
|
|
1711
|
+
};
|
|
1712
|
+
return {
|
|
1713
|
+
...adapter,
|
|
1714
|
+
validatePrompt,
|
|
1715
|
+
renderPrompt
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
// src/providers/raw.ts
|
|
1720
|
+
function applyRawProviderBody(body, asset, provider) {
|
|
1721
|
+
const raw = getRawProviderBody(asset, provider);
|
|
1722
|
+
return raw ? { ...body, ...raw } : body;
|
|
1723
|
+
}
|
|
1724
|
+
function getRawProviderBody(asset, provider) {
|
|
1725
|
+
if (provider === "openai-responses") {
|
|
1726
|
+
return asset.raw?.["openai-responses"] ?? asset.raw?.openai_responses;
|
|
1727
|
+
}
|
|
1728
|
+
if (provider === "gemini") {
|
|
1729
|
+
return asset.raw?.gemini ?? asset.raw?.google;
|
|
1730
|
+
}
|
|
1731
|
+
return asset.raw?.[provider];
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
export {
|
|
1735
|
+
interpolate,
|
|
1736
|
+
extractVariables,
|
|
1737
|
+
getContextInputs,
|
|
1738
|
+
areContextInputWarningsEnabled,
|
|
1739
|
+
compileContextRegex,
|
|
1740
|
+
sanitizeContextVariables,
|
|
1741
|
+
collectContextSizeWarnings,
|
|
1742
|
+
renderSections,
|
|
1743
|
+
applyOverrides,
|
|
1744
|
+
resolveAssetForProvider,
|
|
1745
|
+
PromptCache,
|
|
1746
|
+
resolveIncludes,
|
|
1747
|
+
DEFAULT_PROMPTS_DIR,
|
|
1748
|
+
withPromptResolutionDefaults,
|
|
1749
|
+
loadPromptAsset,
|
|
1750
|
+
resolvePromptAsset,
|
|
1751
|
+
resolveInlinePromptSource,
|
|
1752
|
+
compactHistoryForPrompt,
|
|
1753
|
+
THETOKENCOMPANY_DEFAULT_MODEL,
|
|
1754
|
+
THETOKENCOMPANY_DEFAULT_BASE_URL,
|
|
1755
|
+
summarizePromptCompression,
|
|
1756
|
+
applyPromptCompressionForRender,
|
|
1757
|
+
withPromptInputSupport,
|
|
1758
|
+
applyRawProviderBody
|
|
1759
|
+
};
|
|
1760
|
+
//# sourceMappingURL=chunk-RVAFVWR2.js.map
|