promptopskit 0.3.8 → 0.4.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 +97 -10
- package/SKILL.md +69 -6
- package/dist/chunk-F6UJ73Y6.js +113 -0
- package/dist/chunk-F6UJ73Y6.js.map +1 -0
- package/dist/chunk-HLNVKKMS.js +145 -0
- package/dist/chunk-HLNVKKMS.js.map +1 -0
- package/dist/{chunk-5OYWNRNC.js → chunk-JBLUPKY4.js} +191 -5
- package/dist/chunk-JBLUPKY4.js.map +1 -0
- package/dist/{chunk-UJU5XERR.js → chunk-L2V7LDKD.js} +25 -4
- package/dist/chunk-L2V7LDKD.js.map +1 -0
- package/dist/{chunk-E6NPZOJL.js → chunk-RY5DVTLV.js} +29 -4
- package/dist/chunk-RY5DVTLV.js.map +1 -0
- package/dist/chunk-UPTCSWK3.js +60 -0
- package/dist/chunk-UPTCSWK3.js.map +1 -0
- package/dist/{chunk-X73VG645.js → chunk-XNNDGDPI.js} +64 -3
- package/dist/chunk-XNNDGDPI.js.map +1 -0
- package/dist/cli/index.js +423 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +655 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +172 -11
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +306 -10
- 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 +274 -6
- package/dist/providers/gemini.cjs.map +1 -1
- package/dist/providers/gemini.d.cts +2 -2
- package/dist/providers/gemini.d.ts +2 -2
- package/dist/providers/gemini.js +3 -3
- package/dist/providers/openai-responses.cjs +1245 -0
- package/dist/providers/openai-responses.cjs.map +1 -0
- package/dist/providers/openai-responses.d.cts +11 -0
- package/dist/providers/openai-responses.d.ts +11 -0
- package/dist/providers/openai-responses.js +9 -0
- package/dist/providers/openai-responses.js.map +1 -0
- package/dist/providers/openai.cjs +270 -6
- 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 +305 -9
- 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-B9A1zLRk.d.cts +2403 -0
- package/dist/schema-B9A1zLRk.d.ts +2403 -0
- package/dist/testing.cjs +264 -6
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +59 -2
- package/dist/testing.d.ts +59 -2
- package/dist/testing.js +70 -2
- package/dist/testing.js.map +1 -1
- package/dist/{types-fBvo_d4k.d.ts → types-DjGAwJxC.d.ts} +13 -1
- package/dist/{types-C6RG0Si0.d.cts → types-DpbzzZO2.d.cts} +13 -1
- package/dist/usagetap/index.d.cts +2 -2
- package/dist/usagetap/index.d.ts +2 -2
- package/package.json +12 -2
- package/dist/chunk-5OYWNRNC.js.map +0 -1
- package/dist/chunk-BBVVA27J.js +0 -92
- package/dist/chunk-BBVVA27J.js.map +0 -1
- package/dist/chunk-E2NXJLS6.js +0 -26
- package/dist/chunk-E2NXJLS6.js.map +0 -1
- package/dist/chunk-E6NPZOJL.js.map +0 -1
- package/dist/chunk-UJU5XERR.js.map +0 -1
- package/dist/chunk-X73VG645.js.map +0 -1
- package/dist/schema-DwzYbZba.d.cts +0 -859
- package/dist/schema-DwzYbZba.d.ts +0 -859
package/dist/index.cjs
CHANGED
|
@@ -51,6 +51,7 @@ __export(src_exports, {
|
|
|
51
51
|
interpolate: () => interpolate,
|
|
52
52
|
loadPromptFile: () => loadPromptFile,
|
|
53
53
|
openaiAdapter: () => openaiAdapter,
|
|
54
|
+
openaiResponsesAdapter: () => openaiResponsesAdapter,
|
|
54
55
|
openrouterAdapter: () => openrouterAdapter,
|
|
55
56
|
parsePrompt: () => parsePrompt,
|
|
56
57
|
renderPrompt: () => renderPrompt,
|
|
@@ -144,8 +145,53 @@ function mergeOverride(base, override) {
|
|
|
144
145
|
if (override.response !== void 0) {
|
|
145
146
|
result.response = { ...result.response, ...override.response };
|
|
146
147
|
}
|
|
148
|
+
if (override.cache !== void 0) {
|
|
149
|
+
result.cache = {
|
|
150
|
+
...result.cache,
|
|
151
|
+
...override.cache,
|
|
152
|
+
openai: mergeRecordBlock(result.cache?.openai, override.cache.openai),
|
|
153
|
+
anthropic: mergeRecordBlock(result.cache?.anthropic, override.cache.anthropic),
|
|
154
|
+
gemini: mergeRecordBlock(result.cache?.gemini, override.cache.gemini),
|
|
155
|
+
google: mergeRecordBlock(result.cache?.google, override.cache.google)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (override.raw !== void 0) {
|
|
159
|
+
result.raw = {
|
|
160
|
+
...result.raw,
|
|
161
|
+
...override.raw,
|
|
162
|
+
openai: mergeRecordBlock(result.raw?.openai, override.raw.openai),
|
|
163
|
+
"openai-responses": mergeRecordBlock(result.raw?.["openai-responses"], override.raw["openai-responses"]),
|
|
164
|
+
openai_responses: mergeRecordBlock(result.raw?.openai_responses, override.raw.openai_responses),
|
|
165
|
+
anthropic: mergeRecordBlock(result.raw?.anthropic, override.raw.anthropic),
|
|
166
|
+
gemini: mergeRecordBlock(result.raw?.gemini, override.raw.gemini),
|
|
167
|
+
google: mergeRecordBlock(result.raw?.google, override.raw.google),
|
|
168
|
+
openrouter: mergeRecordBlock(result.raw?.openrouter, override.raw.openrouter)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (override.provider_options !== void 0) {
|
|
172
|
+
result.provider_options = {
|
|
173
|
+
...result.provider_options,
|
|
174
|
+
...override.provider_options,
|
|
175
|
+
anthropic: {
|
|
176
|
+
...result.provider_options?.anthropic,
|
|
177
|
+
...override.provider_options.anthropic
|
|
178
|
+
},
|
|
179
|
+
gemini: {
|
|
180
|
+
...result.provider_options?.gemini,
|
|
181
|
+
...override.provider_options.gemini
|
|
182
|
+
},
|
|
183
|
+
openrouter: {
|
|
184
|
+
...result.provider_options?.openrouter,
|
|
185
|
+
...override.provider_options.openrouter
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
147
189
|
return result;
|
|
148
190
|
}
|
|
191
|
+
function mergeRecordBlock(base, override) {
|
|
192
|
+
if (override === void 0) return base;
|
|
193
|
+
return { ...base, ...override };
|
|
194
|
+
}
|
|
149
195
|
|
|
150
196
|
// src/providers/resolve-asset.ts
|
|
151
197
|
function resolveAssetForProvider(asset, runtime = {}) {
|
|
@@ -246,7 +292,66 @@ var SamplingSchema = import_zod.z.object({
|
|
|
246
292
|
});
|
|
247
293
|
var ResponseSchema = import_zod.z.object({
|
|
248
294
|
format: import_zod.z.enum(["text", "json", "markdown"]).optional(),
|
|
249
|
-
stream: import_zod.z.boolean().optional()
|
|
295
|
+
stream: import_zod.z.boolean().optional(),
|
|
296
|
+
schema: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
297
|
+
schema_name: import_zod.z.string().optional(),
|
|
298
|
+
schema_description: import_zod.z.string().optional(),
|
|
299
|
+
schema_strict: import_zod.z.boolean().optional()
|
|
300
|
+
});
|
|
301
|
+
var AnthropicProviderOptionsSchema = import_zod.z.object({
|
|
302
|
+
top_k: import_zod.z.number().int().min(0).optional(),
|
|
303
|
+
tool_choice: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
304
|
+
output_config: import_zod.z.record(import_zod.z.unknown()).optional()
|
|
305
|
+
});
|
|
306
|
+
var GeminiProviderOptionsSchema = import_zod.z.object({
|
|
307
|
+
candidate_count: import_zod.z.number().int().positive().optional(),
|
|
308
|
+
top_k: import_zod.z.number().int().min(0).optional(),
|
|
309
|
+
seed: import_zod.z.number().int().optional(),
|
|
310
|
+
response_schema: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
311
|
+
response_json_schema: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
312
|
+
response_modalities: import_zod.z.array(import_zod.z.string()).optional(),
|
|
313
|
+
thinking_budget_tokens: import_zod.z.number().int().positive().optional()
|
|
314
|
+
});
|
|
315
|
+
var OpenRouterProviderOptionsSchema = import_zod.z.object({
|
|
316
|
+
provider: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
317
|
+
transforms: import_zod.z.array(import_zod.z.string()).optional(),
|
|
318
|
+
plugins: import_zod.z.array(import_zod.z.record(import_zod.z.unknown())).optional(),
|
|
319
|
+
models: import_zod.z.array(import_zod.z.string()).optional()
|
|
320
|
+
});
|
|
321
|
+
var ProviderOptionsSchema = import_zod.z.object({
|
|
322
|
+
anthropic: AnthropicProviderOptionsSchema.optional(),
|
|
323
|
+
gemini: GeminiProviderOptionsSchema.optional(),
|
|
324
|
+
openrouter: OpenRouterProviderOptionsSchema.optional()
|
|
325
|
+
});
|
|
326
|
+
var RawProviderBodySchema = import_zod.z.object({
|
|
327
|
+
openai: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
328
|
+
"openai-responses": import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
329
|
+
openai_responses: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
330
|
+
anthropic: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
331
|
+
gemini: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
332
|
+
google: import_zod.z.record(import_zod.z.unknown()).optional(),
|
|
333
|
+
openrouter: import_zod.z.record(import_zod.z.unknown()).optional()
|
|
334
|
+
});
|
|
335
|
+
var OpenAICacheSchema = import_zod.z.object({
|
|
336
|
+
prompt_cache_key: import_zod.z.string().min(1).optional(),
|
|
337
|
+
retention: import_zod.z.enum(["in_memory", "24h"]).optional()
|
|
338
|
+
});
|
|
339
|
+
var AnthropicCacheSchema = import_zod.z.object({
|
|
340
|
+
mode: import_zod.z.enum(["automatic", "explicit"]).optional(),
|
|
341
|
+
type: import_zod.z.literal("ephemeral").optional(),
|
|
342
|
+
ttl: import_zod.z.enum(["5m", "1h"]).optional(),
|
|
343
|
+
cache_system_instructions: import_zod.z.boolean().optional(),
|
|
344
|
+
cache_tools: import_zod.z.boolean().optional(),
|
|
345
|
+
cache_prompt_template: import_zod.z.boolean().optional()
|
|
346
|
+
});
|
|
347
|
+
var GeminiCacheSchema = import_zod.z.object({
|
|
348
|
+
cached_content: import_zod.z.string().min(1).optional()
|
|
349
|
+
});
|
|
350
|
+
var CacheSchema = import_zod.z.object({
|
|
351
|
+
openai: OpenAICacheSchema.optional(),
|
|
352
|
+
anthropic: AnthropicCacheSchema.optional(),
|
|
353
|
+
gemini: GeminiCacheSchema.optional(),
|
|
354
|
+
google: GeminiCacheSchema.optional()
|
|
250
355
|
});
|
|
251
356
|
var HistorySchema = import_zod.z.object({
|
|
252
357
|
max_items: import_zod.z.number().int().positive().optional()
|
|
@@ -297,7 +402,10 @@ var PromptAssetOverridesSchema = import_zod.z.object({
|
|
|
297
402
|
reasoning: ReasoningSchema.optional(),
|
|
298
403
|
sampling: SamplingSchema.optional(),
|
|
299
404
|
response: ResponseSchema.optional(),
|
|
300
|
-
|
|
405
|
+
cache: CacheSchema.optional(),
|
|
406
|
+
raw: RawProviderBodySchema.optional(),
|
|
407
|
+
tools: import_zod.z.array(ToolRefSchema).optional(),
|
|
408
|
+
provider_options: ProviderOptionsSchema.optional()
|
|
301
409
|
});
|
|
302
410
|
var SourceSchema = import_zod.z.object({
|
|
303
411
|
file_path: import_zod.z.string().optional(),
|
|
@@ -309,8 +417,9 @@ var SectionsSchema = import_zod.z.object({
|
|
|
309
417
|
notes: import_zod.z.string().optional()
|
|
310
418
|
});
|
|
311
419
|
var PromptDefaultsSchema = import_zod.z.object({
|
|
312
|
-
provider: import_zod.z.enum(["openai", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
|
|
420
|
+
provider: import_zod.z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
|
|
313
421
|
model: import_zod.z.string().optional(),
|
|
422
|
+
cache: CacheSchema.optional(),
|
|
314
423
|
metadata: MetadataSchema.optional(),
|
|
315
424
|
sections: import_zod.z.object({
|
|
316
425
|
system_instructions: import_zod.z.string().optional()
|
|
@@ -320,13 +429,16 @@ var PromptAssetSchema = import_zod.z.object({
|
|
|
320
429
|
id: import_zod.z.string(),
|
|
321
430
|
schema_version: import_zod.z.number().int().positive().default(1),
|
|
322
431
|
description: import_zod.z.string().optional(),
|
|
323
|
-
provider: import_zod.z.enum(["openai", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
|
|
432
|
+
provider: import_zod.z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
|
|
324
433
|
model: import_zod.z.string().optional(),
|
|
325
434
|
fallback_models: import_zod.z.array(import_zod.z.string()).optional(),
|
|
326
435
|
reasoning: ReasoningSchema.optional(),
|
|
327
436
|
sampling: SamplingSchema.optional(),
|
|
328
437
|
response: ResponseSchema.optional(),
|
|
438
|
+
cache: CacheSchema.optional(),
|
|
439
|
+
raw: RawProviderBodySchema.optional(),
|
|
329
440
|
tools: import_zod.z.array(ToolRefSchema).optional(),
|
|
441
|
+
provider_options: ProviderOptionsSchema.optional(),
|
|
330
442
|
mcp: MCPSchema.optional(),
|
|
331
443
|
context: ContextSchema.optional(),
|
|
332
444
|
includes: import_zod.z.array(import_zod.z.string()).optional(),
|
|
@@ -338,6 +450,123 @@ var PromptAssetSchema = import_zod.z.object({
|
|
|
338
450
|
source: SourceSchema.optional()
|
|
339
451
|
});
|
|
340
452
|
|
|
453
|
+
// src/parser/frontmatter-guard.ts
|
|
454
|
+
var FRONT_MATTER_DELIMITER = /^---[ \t]*$/;
|
|
455
|
+
var REGEX_FIELD = /^(?<indent>\s*)(?<field>allow_regex|deny_regex)\s*:\s*(?<value>.*)$/;
|
|
456
|
+
var PATTERN_FIELD = /^(?<indent>\s*)pattern\s*:\s*(?<value>.*)$/;
|
|
457
|
+
var INLINE_PATTERN_FIELD = /(?:^|[{,]\s*)pattern\s*:\s*(?<value>"(?:\\.|[^"\\])*")/;
|
|
458
|
+
function assertRegexFrontMatterQuoting(content, filePath) {
|
|
459
|
+
const frontMatter = extractFrontMatter(content);
|
|
460
|
+
if (!frontMatter) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
let pendingRegex;
|
|
464
|
+
for (const [index, line] of frontMatter.lines.entries()) {
|
|
465
|
+
const lineNumber = frontMatter.startLine + index;
|
|
466
|
+
const regexMatch = line.match(REGEX_FIELD);
|
|
467
|
+
if (regexMatch?.groups) {
|
|
468
|
+
const field = regexMatch.groups.field;
|
|
469
|
+
const indent2 = regexMatch.groups.indent.length;
|
|
470
|
+
const value = regexMatch.groups.value.trim();
|
|
471
|
+
pendingRegex = value === "" ? { field, indent: indent2 } : void 0;
|
|
472
|
+
assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber);
|
|
473
|
+
assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber);
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
if (!pendingRegex) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (line.trim() === "" || line.trimStart().startsWith("#")) {
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
const indent = line.match(/^\s*/)?.[0].length ?? 0;
|
|
483
|
+
if (indent <= pendingRegex.indent) {
|
|
484
|
+
pendingRegex = void 0;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const patternMatch = line.match(PATTERN_FIELD);
|
|
488
|
+
if (!patternMatch?.groups) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
assertNoUnescapedBackslashInDoubleQuotedRegex(
|
|
492
|
+
patternMatch.groups.value.trim(),
|
|
493
|
+
`${pendingRegex.field}.pattern`,
|
|
494
|
+
filePath,
|
|
495
|
+
lineNumber
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function assertNoUnescapedBackslashInInlinePattern(value, field, filePath, lineNumber) {
|
|
500
|
+
const match = value.match(INLINE_PATTERN_FIELD);
|
|
501
|
+
const pattern = match?.groups?.value;
|
|
502
|
+
if (!pattern) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
assertNoUnescapedBackslashInDoubleQuotedRegex(pattern, `${field}.pattern`, filePath, lineNumber);
|
|
506
|
+
}
|
|
507
|
+
function extractFrontMatter(content) {
|
|
508
|
+
const lines = content.split(/\r?\n/);
|
|
509
|
+
if (!FRONT_MATTER_DELIMITER.test(lines[0] ?? "")) {
|
|
510
|
+
return void 0;
|
|
511
|
+
}
|
|
512
|
+
for (let index = 1; index < lines.length; index += 1) {
|
|
513
|
+
if (FRONT_MATTER_DELIMITER.test(lines[index] ?? "")) {
|
|
514
|
+
return {
|
|
515
|
+
lines: lines.slice(1, index),
|
|
516
|
+
startLine: 2
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return void 0;
|
|
521
|
+
}
|
|
522
|
+
function assertNoUnescapedBackslashInDoubleQuotedRegex(value, field, filePath, lineNumber) {
|
|
523
|
+
if (!value.startsWith('"')) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const quoted = readDoubleQuotedScalar(value);
|
|
527
|
+
if (!quoted) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
if (!hasUnescapedBackslash(quoted)) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const location = filePath ? `${filePath}:${lineNumber}` : `line ${lineNumber}`;
|
|
534
|
+
throw new Error(
|
|
535
|
+
`POK013: Invalid context regex YAML at ${location}, field "${field}": double-quoted regex strings treat backslashes as YAML escapes. Use unquoted /pattern/i literal form, single quotes, or double each backslash.`
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
function readDoubleQuotedScalar(value) {
|
|
539
|
+
let result = "";
|
|
540
|
+
for (let index = 1; index < value.length; index += 1) {
|
|
541
|
+
const char = value[index];
|
|
542
|
+
if (char === '"') {
|
|
543
|
+
return result;
|
|
544
|
+
}
|
|
545
|
+
result += char;
|
|
546
|
+
if (char === "\\" && index + 1 < value.length) {
|
|
547
|
+
index += 1;
|
|
548
|
+
result += value[index];
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return void 0;
|
|
552
|
+
}
|
|
553
|
+
function hasUnescapedBackslash(value) {
|
|
554
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
555
|
+
if (value[index] !== "\\") {
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
let count = 1;
|
|
559
|
+
while (value[index + count] === "\\") {
|
|
560
|
+
count += 1;
|
|
561
|
+
}
|
|
562
|
+
if (count % 2 === 1) {
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
index += count - 1;
|
|
566
|
+
}
|
|
567
|
+
return false;
|
|
568
|
+
}
|
|
569
|
+
|
|
341
570
|
// src/parser/sections.ts
|
|
342
571
|
var SECTION_MAP = {
|
|
343
572
|
"system instructions": "system_instructions",
|
|
@@ -378,6 +607,7 @@ function extractSections(body) {
|
|
|
378
607
|
|
|
379
608
|
// src/parser/parser.ts
|
|
380
609
|
function parsePrompt(content, filePath) {
|
|
610
|
+
assertRegexFrontMatterQuoting(content, filePath);
|
|
381
611
|
const { data: frontMatter, content: body } = (0, import_gray_matter.default)(content);
|
|
382
612
|
const sections = extractSections(body);
|
|
383
613
|
const raw = {
|
|
@@ -958,6 +1188,21 @@ function withPromptInputSupport(adapter) {
|
|
|
958
1188
|
};
|
|
959
1189
|
}
|
|
960
1190
|
|
|
1191
|
+
// src/providers/raw.ts
|
|
1192
|
+
function applyRawProviderBody(body, asset, provider) {
|
|
1193
|
+
const raw = getRawProviderBody(asset, provider);
|
|
1194
|
+
return raw ? { ...body, ...raw } : body;
|
|
1195
|
+
}
|
|
1196
|
+
function getRawProviderBody(asset, provider) {
|
|
1197
|
+
if (provider === "openai-responses") {
|
|
1198
|
+
return asset.raw?.["openai-responses"] ?? asset.raw?.openai_responses;
|
|
1199
|
+
}
|
|
1200
|
+
if (provider === "gemini") {
|
|
1201
|
+
return asset.raw?.gemini ?? asset.raw?.google;
|
|
1202
|
+
}
|
|
1203
|
+
return asset.raw?.[provider];
|
|
1204
|
+
}
|
|
1205
|
+
|
|
961
1206
|
// src/providers/openai.ts
|
|
962
1207
|
var openaiAdapter = withPromptInputSupport({
|
|
963
1208
|
name: "openai",
|
|
@@ -971,6 +1216,9 @@ var openaiAdapter = withPromptInputSupport({
|
|
|
971
1216
|
if (resolvedAsset.reasoning?.budget_tokens !== void 0) {
|
|
972
1217
|
warnings.push("OpenAI uses reasoning_effort, not budget_tokens. budget_tokens will be ignored.");
|
|
973
1218
|
}
|
|
1219
|
+
if (resolvedAsset.response?.schema !== void 0 && resolvedAsset.response?.format !== "json") {
|
|
1220
|
+
warnings.push("OpenAI response.schema requires response.format: json. schema will still be applied as JSON schema output.");
|
|
1221
|
+
}
|
|
974
1222
|
return { valid: errors.length === 0, errors, warnings };
|
|
975
1223
|
},
|
|
976
1224
|
render(asset, runtime) {
|
|
@@ -995,6 +1243,7 @@ var openaiAdapter = withPromptInputSupport({
|
|
|
995
1243
|
model: resolvedAsset.model,
|
|
996
1244
|
messages
|
|
997
1245
|
};
|
|
1246
|
+
const openaiCacheConfig = resolvedAsset.cache?.openai;
|
|
998
1247
|
if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
|
|
999
1248
|
if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
|
|
1000
1249
|
if (resolvedAsset.sampling?.frequency_penalty !== void 0) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;
|
|
@@ -1004,12 +1253,28 @@ var openaiAdapter = withPromptInputSupport({
|
|
|
1004
1253
|
if (resolvedAsset.reasoning?.effort) {
|
|
1005
1254
|
body.reasoning_effort = resolvedAsset.reasoning.effort;
|
|
1006
1255
|
}
|
|
1007
|
-
if (resolvedAsset.response?.
|
|
1256
|
+
if (resolvedAsset.response?.schema) {
|
|
1257
|
+
body.response_format = {
|
|
1258
|
+
type: "json_schema",
|
|
1259
|
+
json_schema: {
|
|
1260
|
+
name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,
|
|
1261
|
+
...resolvedAsset.response.schema_description ? { description: resolvedAsset.response.schema_description } : {},
|
|
1262
|
+
schema: resolvedAsset.response.schema,
|
|
1263
|
+
strict: resolvedAsset.response.schema_strict ?? true
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
} else if (resolvedAsset.response?.format === "json") {
|
|
1008
1267
|
body.response_format = { type: "json_object" };
|
|
1009
1268
|
}
|
|
1010
1269
|
if (resolvedAsset.response?.stream !== void 0) {
|
|
1011
1270
|
body.stream = resolvedAsset.response.stream;
|
|
1012
1271
|
}
|
|
1272
|
+
if (openaiCacheConfig?.prompt_cache_key) {
|
|
1273
|
+
body.prompt_cache_key = openaiCacheConfig.prompt_cache_key;
|
|
1274
|
+
}
|
|
1275
|
+
if (openaiCacheConfig?.retention) {
|
|
1276
|
+
body.prompt_cache_retention = openaiCacheConfig.retention;
|
|
1277
|
+
}
|
|
1013
1278
|
if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
|
|
1014
1279
|
body.tools = resolvedAsset.tools.map((tool) => {
|
|
1015
1280
|
if (typeof tool === "string") {
|
|
@@ -1028,13 +1293,115 @@ var openaiAdapter = withPromptInputSupport({
|
|
|
1028
1293
|
});
|
|
1029
1294
|
}
|
|
1030
1295
|
return {
|
|
1031
|
-
body,
|
|
1296
|
+
body: applyRawProviderBody(body, resolvedAsset, "openai"),
|
|
1032
1297
|
provider: "openai",
|
|
1033
1298
|
model: resolvedAsset.model ?? "unknown"
|
|
1034
1299
|
};
|
|
1035
1300
|
}
|
|
1036
1301
|
});
|
|
1037
1302
|
|
|
1303
|
+
// src/providers/openai-responses.ts
|
|
1304
|
+
var openaiResponsesAdapter = withPromptInputSupport({
|
|
1305
|
+
name: "openai-responses",
|
|
1306
|
+
validate(asset, runtime) {
|
|
1307
|
+
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
1308
|
+
const errors = [];
|
|
1309
|
+
const warnings = [];
|
|
1310
|
+
if (!resolvedAsset.model) {
|
|
1311
|
+
errors.push("OpenAI Responses adapter requires a model to be specified.");
|
|
1312
|
+
}
|
|
1313
|
+
if (resolvedAsset.reasoning?.budget_tokens !== void 0) {
|
|
1314
|
+
warnings.push("OpenAI Responses uses reasoning.effort, not budget_tokens. budget_tokens will be ignored.");
|
|
1315
|
+
}
|
|
1316
|
+
if (resolvedAsset.response?.schema !== void 0 && resolvedAsset.response?.format !== "json") {
|
|
1317
|
+
warnings.push("OpenAI Responses response.schema requires response.format: json. schema will still be applied as JSON schema output.");
|
|
1318
|
+
}
|
|
1319
|
+
if (runtime?.openaiResponses?.conversation !== void 0 && runtime?.openaiResponses?.previous_response_id !== void 0) {
|
|
1320
|
+
errors.push('OpenAI Responses options "conversation" and "previous_response_id" cannot both be set.');
|
|
1321
|
+
}
|
|
1322
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
1323
|
+
},
|
|
1324
|
+
render(asset, runtime) {
|
|
1325
|
+
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
1326
|
+
const sections = renderSections(resolvedAsset, {
|
|
1327
|
+
variables: runtime.variables,
|
|
1328
|
+
strict: runtime.strict
|
|
1329
|
+
});
|
|
1330
|
+
const responseOptions = runtime.openaiResponses;
|
|
1331
|
+
const input = [];
|
|
1332
|
+
if (runtime.history) {
|
|
1333
|
+
for (const msg of runtime.history) {
|
|
1334
|
+
input.push({ role: msg.role, content: msg.content });
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
if (sections.prompt_template) {
|
|
1338
|
+
input.push({ role: "user", content: sections.prompt_template });
|
|
1339
|
+
}
|
|
1340
|
+
const body = {
|
|
1341
|
+
model: resolvedAsset.model,
|
|
1342
|
+
input
|
|
1343
|
+
};
|
|
1344
|
+
if (responseOptions?.instructions !== void 0) {
|
|
1345
|
+
body.instructions = responseOptions.instructions;
|
|
1346
|
+
} else if (sections.system_instructions) {
|
|
1347
|
+
body.instructions = sections.system_instructions;
|
|
1348
|
+
}
|
|
1349
|
+
if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
|
|
1350
|
+
if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
|
|
1351
|
+
if (resolvedAsset.sampling?.frequency_penalty !== void 0) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;
|
|
1352
|
+
if (resolvedAsset.sampling?.presence_penalty !== void 0) body.presence_penalty = resolvedAsset.sampling.presence_penalty;
|
|
1353
|
+
if (resolvedAsset.sampling?.stop !== void 0) body.stop = resolvedAsset.sampling.stop;
|
|
1354
|
+
if (resolvedAsset.sampling?.max_output_tokens !== void 0) body.max_output_tokens = resolvedAsset.sampling.max_output_tokens;
|
|
1355
|
+
if (resolvedAsset.reasoning?.effort) {
|
|
1356
|
+
body.reasoning = { effort: resolvedAsset.reasoning.effort };
|
|
1357
|
+
}
|
|
1358
|
+
if (resolvedAsset.response?.schema) {
|
|
1359
|
+
body.text = {
|
|
1360
|
+
format: {
|
|
1361
|
+
type: "json_schema",
|
|
1362
|
+
name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,
|
|
1363
|
+
...resolvedAsset.response.schema_description ? { description: resolvedAsset.response.schema_description } : {},
|
|
1364
|
+
schema: resolvedAsset.response.schema,
|
|
1365
|
+
strict: resolvedAsset.response.schema_strict ?? true
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
} else if (resolvedAsset.response?.format === "json") {
|
|
1369
|
+
body.text = { format: { type: "json_object" } };
|
|
1370
|
+
}
|
|
1371
|
+
if (resolvedAsset.response?.stream !== void 0) {
|
|
1372
|
+
body.stream = resolvedAsset.response.stream;
|
|
1373
|
+
}
|
|
1374
|
+
if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
|
|
1375
|
+
body.tools = resolvedAsset.tools.map((tool) => {
|
|
1376
|
+
if (typeof tool === "string") {
|
|
1377
|
+
const def = runtime.toolRegistry?.[tool];
|
|
1378
|
+
if (def) return def;
|
|
1379
|
+
return { type: "function", name: tool };
|
|
1380
|
+
}
|
|
1381
|
+
return {
|
|
1382
|
+
type: "function",
|
|
1383
|
+
name: tool.name,
|
|
1384
|
+
description: tool.description,
|
|
1385
|
+
parameters: tool.input_schema
|
|
1386
|
+
};
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
if (responseOptions?.previous_response_id !== void 0) body.previous_response_id = responseOptions.previous_response_id;
|
|
1390
|
+
if (responseOptions?.conversation !== void 0) body.conversation = responseOptions.conversation;
|
|
1391
|
+
if (responseOptions?.parallel_tool_calls !== void 0) body.parallel_tool_calls = responseOptions.parallel_tool_calls;
|
|
1392
|
+
if (responseOptions?.max_tool_calls !== void 0) body.max_tool_calls = responseOptions.max_tool_calls;
|
|
1393
|
+
if (responseOptions?.store !== void 0) body.store = responseOptions.store;
|
|
1394
|
+
if (responseOptions?.metadata !== void 0) body.metadata = responseOptions.metadata;
|
|
1395
|
+
if (responseOptions?.include !== void 0) body.include = responseOptions.include;
|
|
1396
|
+
if (responseOptions?.background !== void 0) body.background = responseOptions.background;
|
|
1397
|
+
return {
|
|
1398
|
+
body: applyRawProviderBody(body, resolvedAsset, "openai-responses"),
|
|
1399
|
+
provider: "openai-responses",
|
|
1400
|
+
model: resolvedAsset.model ?? "unknown"
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
|
|
1038
1405
|
// src/providers/anthropic.ts
|
|
1039
1406
|
var anthropicAdapter = withPromptInputSupport({
|
|
1040
1407
|
name: "anthropic",
|
|
@@ -1054,6 +1421,12 @@ var anthropicAdapter = withPromptInputSupport({
|
|
|
1054
1421
|
if (resolvedAsset.reasoning?.effort !== void 0) {
|
|
1055
1422
|
warnings.push("Anthropic uses budget_tokens for thinking, not effort. effort will be mapped approximately.");
|
|
1056
1423
|
}
|
|
1424
|
+
if (resolvedAsset.response?.schema !== void 0 && resolvedAsset.response?.format !== "json") {
|
|
1425
|
+
warnings.push("Anthropic response.schema is mapped to output_config.format and should usually be paired with response.format: json.");
|
|
1426
|
+
}
|
|
1427
|
+
if (resolvedAsset.provider_options?.anthropic?.top_k !== void 0 && resolvedAsset.provider_options.anthropic.top_k < 0) {
|
|
1428
|
+
errors.push("Anthropic provider_options.top_k must be >= 0.");
|
|
1429
|
+
}
|
|
1057
1430
|
return { valid: errors.length === 0, errors, warnings };
|
|
1058
1431
|
},
|
|
1059
1432
|
render(asset, runtime) {
|
|
@@ -1063,20 +1436,38 @@ var anthropicAdapter = withPromptInputSupport({
|
|
|
1063
1436
|
strict: runtime.strict
|
|
1064
1437
|
});
|
|
1065
1438
|
const messages = [];
|
|
1439
|
+
const anthropicCacheConfig = resolvedAsset.cache?.anthropic;
|
|
1440
|
+
const cacheType = anthropicCacheConfig?.type ?? "ephemeral";
|
|
1441
|
+
const cacheControl = anthropicCacheConfig ? {
|
|
1442
|
+
type: cacheType,
|
|
1443
|
+
...anthropicCacheConfig.ttl ? { ttl: anthropicCacheConfig.ttl } : {}
|
|
1444
|
+
} : void 0;
|
|
1445
|
+
const cacheMode = anthropicCacheConfig?.mode ?? "automatic";
|
|
1066
1446
|
if (runtime.history) {
|
|
1067
1447
|
for (const msg of runtime.history) {
|
|
1068
1448
|
messages.push({ role: msg.role, content: msg.content });
|
|
1069
1449
|
}
|
|
1070
1450
|
}
|
|
1071
1451
|
if (sections.prompt_template) {
|
|
1072
|
-
|
|
1452
|
+
if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_prompt_template) {
|
|
1453
|
+
messages.push({
|
|
1454
|
+
role: "user",
|
|
1455
|
+
content: [{ type: "text", text: sections.prompt_template, cache_control: cacheControl }]
|
|
1456
|
+
});
|
|
1457
|
+
} else {
|
|
1458
|
+
messages.push({ role: "user", content: sections.prompt_template });
|
|
1459
|
+
}
|
|
1073
1460
|
}
|
|
1074
1461
|
const body = {
|
|
1075
1462
|
model: resolvedAsset.model,
|
|
1076
1463
|
messages
|
|
1077
1464
|
};
|
|
1078
1465
|
if (sections.system_instructions) {
|
|
1079
|
-
|
|
1466
|
+
if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_system_instructions !== false) {
|
|
1467
|
+
body.system = [{ type: "text", text: sections.system_instructions, cache_control: cacheControl }];
|
|
1468
|
+
} else {
|
|
1469
|
+
body.system = sections.system_instructions;
|
|
1470
|
+
}
|
|
1080
1471
|
}
|
|
1081
1472
|
if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
|
|
1082
1473
|
if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
|
|
@@ -1092,25 +1483,53 @@ var anthropicAdapter = withPromptInputSupport({
|
|
|
1092
1483
|
budget_tokens: resolvedAsset.reasoning.budget_tokens
|
|
1093
1484
|
};
|
|
1094
1485
|
}
|
|
1486
|
+
if (resolvedAsset.provider_options?.anthropic?.top_k !== void 0) {
|
|
1487
|
+
body.top_k = resolvedAsset.provider_options.anthropic.top_k;
|
|
1488
|
+
}
|
|
1489
|
+
if (resolvedAsset.provider_options?.anthropic?.output_config !== void 0) {
|
|
1490
|
+
body.output_config = resolvedAsset.provider_options.anthropic.output_config;
|
|
1491
|
+
} else if (resolvedAsset.response?.schema !== void 0) {
|
|
1492
|
+
body.output_config = {
|
|
1493
|
+
format: {
|
|
1494
|
+
type: "json_schema",
|
|
1495
|
+
schema: resolvedAsset.response.schema
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1095
1499
|
if (resolvedAsset.response?.stream !== void 0) {
|
|
1096
1500
|
body.stream = resolvedAsset.response.stream;
|
|
1097
1501
|
}
|
|
1502
|
+
if (cacheControl && cacheMode === "automatic") {
|
|
1503
|
+
body.cache_control = cacheControl;
|
|
1504
|
+
}
|
|
1098
1505
|
if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
|
|
1099
1506
|
body.tools = resolvedAsset.tools.map((tool) => {
|
|
1100
1507
|
if (typeof tool === "string") {
|
|
1101
1508
|
const def = runtime.toolRegistry?.[tool];
|
|
1102
|
-
if (def)
|
|
1103
|
-
|
|
1509
|
+
if (def) {
|
|
1510
|
+
if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools) {
|
|
1511
|
+
return { ...def, cache_control: cacheControl };
|
|
1512
|
+
}
|
|
1513
|
+
return def;
|
|
1514
|
+
}
|
|
1515
|
+
return {
|
|
1516
|
+
name: tool,
|
|
1517
|
+
...cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools ? { cache_control: cacheControl } : {}
|
|
1518
|
+
};
|
|
1104
1519
|
}
|
|
1105
1520
|
return {
|
|
1106
1521
|
name: tool.name,
|
|
1107
1522
|
description: tool.description,
|
|
1108
|
-
input_schema: tool.input_schema ?? { type: "object", properties: {} }
|
|
1523
|
+
input_schema: tool.input_schema ?? { type: "object", properties: {} },
|
|
1524
|
+
...cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools ? { cache_control: cacheControl } : {}
|
|
1109
1525
|
};
|
|
1110
1526
|
});
|
|
1111
1527
|
}
|
|
1528
|
+
if (resolvedAsset.provider_options?.anthropic?.tool_choice !== void 0) {
|
|
1529
|
+
body.tool_choice = resolvedAsset.provider_options.anthropic.tool_choice;
|
|
1530
|
+
}
|
|
1112
1531
|
return {
|
|
1113
|
-
body,
|
|
1532
|
+
body: applyRawProviderBody(body, resolvedAsset, "anthropic"),
|
|
1114
1533
|
provider: "anthropic",
|
|
1115
1534
|
model: resolvedAsset.model ?? "unknown"
|
|
1116
1535
|
};
|
|
@@ -1124,6 +1543,8 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1124
1543
|
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
1125
1544
|
const errors = [];
|
|
1126
1545
|
const warnings = [];
|
|
1546
|
+
const geminiCache = resolvedAsset.cache?.gemini?.cached_content;
|
|
1547
|
+
const googleCache = resolvedAsset.cache?.google?.cached_content;
|
|
1127
1548
|
if (!resolvedAsset.model) {
|
|
1128
1549
|
errors.push("Gemini adapter requires a model to be specified.");
|
|
1129
1550
|
}
|
|
@@ -1133,6 +1554,12 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1133
1554
|
if (resolvedAsset.sampling?.presence_penalty !== void 0) {
|
|
1134
1555
|
warnings.push("Gemini does not support presence_penalty. It will be ignored.");
|
|
1135
1556
|
}
|
|
1557
|
+
if (geminiCache && googleCache && geminiCache !== googleCache) {
|
|
1558
|
+
warnings.push("Both cache.gemini.cached_content and cache.google.cached_content are set. Gemini uses cache.gemini.cached_content.");
|
|
1559
|
+
}
|
|
1560
|
+
if (resolvedAsset.response?.stream !== void 0) {
|
|
1561
|
+
warnings.push("Gemini streaming is endpoint-based (streamGenerateContent), not body-based. response.stream will be ignored.");
|
|
1562
|
+
}
|
|
1136
1563
|
return { valid: errors.length === 0, errors, warnings };
|
|
1137
1564
|
},
|
|
1138
1565
|
render(asset, runtime) {
|
|
@@ -1159,20 +1586,33 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1159
1586
|
const body = {
|
|
1160
1587
|
contents
|
|
1161
1588
|
};
|
|
1589
|
+
const geminiCacheConfig = resolvedAsset.cache?.gemini ?? resolvedAsset.cache?.google;
|
|
1162
1590
|
if (sections.system_instructions) {
|
|
1163
1591
|
body.systemInstruction = {
|
|
1164
1592
|
parts: [{ text: sections.system_instructions }]
|
|
1165
1593
|
};
|
|
1166
1594
|
}
|
|
1167
1595
|
const generationConfig = {};
|
|
1596
|
+
const geminiOptions = resolvedAsset.provider_options?.gemini;
|
|
1168
1597
|
if (resolvedAsset.sampling?.temperature !== void 0) generationConfig.temperature = resolvedAsset.sampling.temperature;
|
|
1169
1598
|
if (resolvedAsset.sampling?.top_p !== void 0) generationConfig.topP = resolvedAsset.sampling.top_p;
|
|
1170
1599
|
if (resolvedAsset.sampling?.max_output_tokens !== void 0) generationConfig.maxOutputTokens = resolvedAsset.sampling.max_output_tokens;
|
|
1171
1600
|
if (resolvedAsset.sampling?.stop !== void 0) generationConfig.stopSequences = resolvedAsset.sampling.stop;
|
|
1601
|
+
if (geminiOptions?.candidate_count !== void 0) generationConfig.candidateCount = geminiOptions.candidate_count;
|
|
1602
|
+
if (geminiOptions?.top_k !== void 0) generationConfig.topK = geminiOptions.top_k;
|
|
1603
|
+
if (geminiOptions?.seed !== void 0) generationConfig.seed = geminiOptions.seed;
|
|
1604
|
+
if (geminiOptions?.response_modalities !== void 0) generationConfig.responseModalities = geminiOptions.response_modalities;
|
|
1605
|
+
if (resolvedAsset.response?.schema !== void 0) generationConfig.responseJsonSchema = resolvedAsset.response.schema;
|
|
1606
|
+
if (geminiOptions?.response_schema !== void 0) generationConfig.responseSchema = geminiOptions.response_schema;
|
|
1607
|
+
if (geminiOptions?.response_json_schema !== void 0) generationConfig.responseJsonSchema = geminiOptions.response_json_schema;
|
|
1172
1608
|
if (resolvedAsset.response?.format === "json") {
|
|
1173
1609
|
generationConfig.responseMimeType = "application/json";
|
|
1174
1610
|
}
|
|
1175
|
-
if (
|
|
1611
|
+
if (geminiOptions?.thinking_budget_tokens !== void 0) {
|
|
1612
|
+
body.thinkingConfig = {
|
|
1613
|
+
thinkingBudget: geminiOptions.thinking_budget_tokens
|
|
1614
|
+
};
|
|
1615
|
+
} else if (resolvedAsset.reasoning?.effort) {
|
|
1176
1616
|
body.thinkingConfig = {
|
|
1177
1617
|
thinkingBudget: resolvedAsset.reasoning.effort === "high" ? 8192 : resolvedAsset.reasoning.effort === "medium" ? 4096 : 1024
|
|
1178
1618
|
};
|
|
@@ -1180,6 +1620,9 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1180
1620
|
if (Object.keys(generationConfig).length > 0) {
|
|
1181
1621
|
body.generationConfig = generationConfig;
|
|
1182
1622
|
}
|
|
1623
|
+
if (geminiCacheConfig?.cached_content) {
|
|
1624
|
+
body.cachedContent = geminiCacheConfig.cached_content;
|
|
1625
|
+
}
|
|
1183
1626
|
if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
|
|
1184
1627
|
const functionDeclarations = resolvedAsset.tools.map((tool) => {
|
|
1185
1628
|
if (typeof tool === "string") {
|
|
@@ -1196,7 +1639,7 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1196
1639
|
body.tools = [{ functionDeclarations }];
|
|
1197
1640
|
}
|
|
1198
1641
|
return {
|
|
1199
|
-
body,
|
|
1642
|
+
body: applyRawProviderBody(body, resolvedAsset, "gemini"),
|
|
1200
1643
|
provider: "gemini",
|
|
1201
1644
|
model: resolvedAsset.model ?? "unknown"
|
|
1202
1645
|
};
|
|
@@ -1207,13 +1650,45 @@ var geminiAdapter = withPromptInputSupport({
|
|
|
1207
1650
|
var openrouterAdapter = withPromptInputSupport({
|
|
1208
1651
|
name: "openrouter",
|
|
1209
1652
|
validate(asset, runtime) {
|
|
1210
|
-
|
|
1653
|
+
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
1654
|
+
const validation = openaiAdapter.validate(asset, runtime);
|
|
1655
|
+
const hasOpenRouterModels = (resolvedAsset.provider_options?.openrouter?.models?.length ?? 0) > 0;
|
|
1656
|
+
if (!hasOpenRouterModels) {
|
|
1657
|
+
return validation;
|
|
1658
|
+
}
|
|
1659
|
+
const modelRequiredError = "OpenAI adapter requires a model to be specified.";
|
|
1660
|
+
const errors = validation.errors.filter((error) => error !== modelRequiredError);
|
|
1661
|
+
const warnings = validation.warnings.filter((warning) => warning !== modelRequiredError);
|
|
1662
|
+
return {
|
|
1663
|
+
valid: errors.length === 0,
|
|
1664
|
+
errors,
|
|
1665
|
+
warnings
|
|
1666
|
+
};
|
|
1211
1667
|
},
|
|
1212
1668
|
render(asset, runtime) {
|
|
1213
|
-
const
|
|
1669
|
+
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
1670
|
+
const result = openaiAdapter.render(
|
|
1671
|
+
{ ...resolvedAsset, raw: void 0 },
|
|
1672
|
+
{
|
|
1673
|
+
variables: runtime.variables,
|
|
1674
|
+
history: runtime.history,
|
|
1675
|
+
toolRegistry: runtime.toolRegistry,
|
|
1676
|
+
strict: runtime.strict
|
|
1677
|
+
}
|
|
1678
|
+
);
|
|
1679
|
+
const openrouterOptions = resolvedAsset.provider_options?.openrouter;
|
|
1680
|
+
let body = { ...result.body };
|
|
1681
|
+
if (openrouterOptions?.provider !== void 0) body.provider = openrouterOptions.provider;
|
|
1682
|
+
if (openrouterOptions?.transforms !== void 0) body.transforms = openrouterOptions.transforms;
|
|
1683
|
+
if (openrouterOptions?.plugins !== void 0) body.plugins = openrouterOptions.plugins;
|
|
1684
|
+
if (openrouterOptions?.models !== void 0) body.models = openrouterOptions.models;
|
|
1685
|
+
if (body.model === void 0) delete body.model;
|
|
1686
|
+
body = applyRawProviderBody(body, resolvedAsset, "openrouter");
|
|
1214
1687
|
return {
|
|
1215
1688
|
...result,
|
|
1216
|
-
|
|
1689
|
+
body,
|
|
1690
|
+
provider: "openrouter",
|
|
1691
|
+
model: resolvedAsset.model ?? openrouterOptions?.models?.[0] ?? "unknown"
|
|
1217
1692
|
};
|
|
1218
1693
|
}
|
|
1219
1694
|
});
|
|
@@ -1221,6 +1696,7 @@ var openrouterAdapter = withPromptInputSupport({
|
|
|
1221
1696
|
// src/providers/index.ts
|
|
1222
1697
|
var adapters = {
|
|
1223
1698
|
openai: openaiAdapter,
|
|
1699
|
+
"openai-responses": openaiResponsesAdapter,
|
|
1224
1700
|
anthropic: anthropicAdapter,
|
|
1225
1701
|
google: geminiAdapter,
|
|
1226
1702
|
gemini: geminiAdapter,
|
|
@@ -1275,8 +1751,22 @@ var KNOWN_FRONT_MATTER_KEYS = /* @__PURE__ */ new Set([
|
|
|
1275
1751
|
"includes",
|
|
1276
1752
|
"environments",
|
|
1277
1753
|
"tiers",
|
|
1278
|
-
"metadata"
|
|
1754
|
+
"metadata",
|
|
1755
|
+
"cache",
|
|
1756
|
+
"provider_options",
|
|
1757
|
+
"raw"
|
|
1279
1758
|
]);
|
|
1759
|
+
var RISKY_UNBOUNDED_INPUT_NAMES = [
|
|
1760
|
+
"message",
|
|
1761
|
+
"prompt",
|
|
1762
|
+
"history",
|
|
1763
|
+
"transcript",
|
|
1764
|
+
"document",
|
|
1765
|
+
"content",
|
|
1766
|
+
"input",
|
|
1767
|
+
"body",
|
|
1768
|
+
"context"
|
|
1769
|
+
];
|
|
1280
1770
|
function validateAsset(asset, frontMatterKeys, filePath) {
|
|
1281
1771
|
const errors = [];
|
|
1282
1772
|
const warnings = [];
|
|
@@ -1347,7 +1837,32 @@ function validateAsset(asset, frontMatterKeys, filePath) {
|
|
|
1347
1837
|
});
|
|
1348
1838
|
}
|
|
1349
1839
|
}
|
|
1840
|
+
if (usedVars.size > 0 && (!asset.context?.inputs || asset.context.inputs.length === 0)) {
|
|
1841
|
+
warnings.push({
|
|
1842
|
+
code: "POK046",
|
|
1843
|
+
message: `Template uses ${usedVars.size === 1 ? "a variable" : "variables"} but context.inputs is not declared.`,
|
|
1844
|
+
filePath,
|
|
1845
|
+
suggestion: "Declare context.inputs to enable input policy validation."
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1350
1848
|
for (const input of getContextInputs(asset)) {
|
|
1849
|
+
const lowerName = input.name.toLowerCase();
|
|
1850
|
+
if (input.max_size === void 0 && RISKY_UNBOUNDED_INPUT_NAMES.some((needle) => lowerName.includes(needle))) {
|
|
1851
|
+
warnings.push({
|
|
1852
|
+
code: "POK040",
|
|
1853
|
+
message: `Context input "${input.name}" has no max_size and appears unbounded.`,
|
|
1854
|
+
filePath,
|
|
1855
|
+
suggestion: "Add max_size to constrain prompt payload growth."
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
if (input.allow_regex === void 0 && input.deny_regex === void 0 && input.non_empty === void 0 && input.reject_secrets === void 0) {
|
|
1859
|
+
warnings.push({
|
|
1860
|
+
code: "POK041",
|
|
1861
|
+
message: `Context input "${input.name}" has no input hardening validators.`,
|
|
1862
|
+
filePath,
|
|
1863
|
+
suggestion: "Consider non_empty/reject_secrets and allow/deny regex validators."
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1351
1866
|
if (input.trim !== void 0 && input.trim !== false && input.max_size === void 0) {
|
|
1352
1867
|
warnings.push({
|
|
1353
1868
|
code: "POK014",
|
|
@@ -1375,6 +1890,91 @@ function validateAsset(asset, frontMatterKeys, filePath) {
|
|
|
1375
1890
|
}
|
|
1376
1891
|
}
|
|
1377
1892
|
}
|
|
1893
|
+
if (asset.provider) {
|
|
1894
|
+
let providerCache;
|
|
1895
|
+
let cacheSuggestionField;
|
|
1896
|
+
switch (asset.provider) {
|
|
1897
|
+
case "openai":
|
|
1898
|
+
providerCache = asset.cache?.openai;
|
|
1899
|
+
cacheSuggestionField = "cache.openai";
|
|
1900
|
+
break;
|
|
1901
|
+
case "anthropic":
|
|
1902
|
+
providerCache = asset.cache?.anthropic;
|
|
1903
|
+
cacheSuggestionField = "cache.anthropic";
|
|
1904
|
+
break;
|
|
1905
|
+
case "gemini":
|
|
1906
|
+
case "google":
|
|
1907
|
+
providerCache = asset.cache?.gemini ?? asset.cache?.google;
|
|
1908
|
+
cacheSuggestionField = "cache.gemini";
|
|
1909
|
+
break;
|
|
1910
|
+
default:
|
|
1911
|
+
break;
|
|
1912
|
+
}
|
|
1913
|
+
if (cacheSuggestionField && providerCache === void 0) {
|
|
1914
|
+
warnings.push({
|
|
1915
|
+
code: "POK042",
|
|
1916
|
+
message: `Provider "${asset.provider}" has no provider-specific cache settings.`,
|
|
1917
|
+
filePath,
|
|
1918
|
+
suggestion: `Consider configuring ${cacheSuggestionField} for better cache-hit behavior.`
|
|
1919
|
+
});
|
|
1920
|
+
}
|
|
1921
|
+
if (!asset.model) {
|
|
1922
|
+
warnings.push({
|
|
1923
|
+
code: "POK044",
|
|
1924
|
+
message: `Provider "${asset.provider}" is configured without a model.`,
|
|
1925
|
+
filePath,
|
|
1926
|
+
suggestion: "Set model in prompt or defaults to avoid adapter-time errors."
|
|
1927
|
+
});
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
if (asset.cache?.gemini?.cached_content && asset.cache.google?.cached_content && asset.cache.gemini.cached_content !== asset.cache.google.cached_content) {
|
|
1931
|
+
warnings.push({
|
|
1932
|
+
code: "POK043",
|
|
1933
|
+
message: "cache.gemini.cached_content and cache.google.cached_content are both set to different values.",
|
|
1934
|
+
filePath,
|
|
1935
|
+
suggestion: "Use one canonical value; Gemini prefers cache.gemini.cached_content."
|
|
1936
|
+
});
|
|
1937
|
+
}
|
|
1938
|
+
for (const [envName, overrides] of Object.entries(asset.environments ?? {})) {
|
|
1939
|
+
if (asset.cache && (!isRecord(overrides) || !overrides.cache)) {
|
|
1940
|
+
warnings.push({
|
|
1941
|
+
code: "POK045",
|
|
1942
|
+
message: `Environment "${envName}" does not override cache while prompt-level cache is defined.`,
|
|
1943
|
+
filePath,
|
|
1944
|
+
suggestion: "Confirm cache strategy is intentionally shared across environments."
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
for (const [tierName, overrides] of Object.entries(asset.tiers ?? {})) {
|
|
1949
|
+
if (asset.cache && (!isRecord(overrides) || !overrides.cache)) {
|
|
1950
|
+
warnings.push({
|
|
1951
|
+
code: "POK045",
|
|
1952
|
+
message: `Tier "${tierName}" does not override cache while prompt-level cache is defined.`,
|
|
1953
|
+
filePath,
|
|
1954
|
+
suggestion: "Confirm cache strategy is intentionally shared across tiers."
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
for (const tool of asset.tools ?? []) {
|
|
1959
|
+
if (isRecord(tool)) {
|
|
1960
|
+
if (!tool.description) {
|
|
1961
|
+
warnings.push({
|
|
1962
|
+
code: "POK047",
|
|
1963
|
+
message: `Inline tool "${tool.name}" is missing a description.`,
|
|
1964
|
+
filePath,
|
|
1965
|
+
suggestion: "Add description to improve model tool-selection quality."
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1968
|
+
if (!tool.input_schema) {
|
|
1969
|
+
warnings.push({
|
|
1970
|
+
code: "POK047",
|
|
1971
|
+
message: `Inline tool "${tool.name}" is missing input_schema.`,
|
|
1972
|
+
filePath,
|
|
1973
|
+
suggestion: "Add input_schema so tool inputs are strongly typed."
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1378
1978
|
return {
|
|
1379
1979
|
valid: errors.length === 0,
|
|
1380
1980
|
errors,
|
|
@@ -1411,6 +2011,9 @@ function findClosestMatch(input, candidates) {
|
|
|
1411
2011
|
}
|
|
1412
2012
|
return best;
|
|
1413
2013
|
}
|
|
2014
|
+
function isRecord(value) {
|
|
2015
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2016
|
+
}
|
|
1414
2017
|
|
|
1415
2018
|
// src/usagetap/client.ts
|
|
1416
2019
|
var DEFAULT_BASE_URL = "https://api.usagetap.com";
|
|
@@ -1849,7 +2452,9 @@ var PromptOpsKit = class {
|
|
|
1849
2452
|
throw new Error('Either "path" or "source" must be provided to renderPrompt()');
|
|
1850
2453
|
}
|
|
1851
2454
|
const adapter = getAdapter(options.provider);
|
|
1852
|
-
const validation = adapter.validate(resolved
|
|
2455
|
+
const validation = adapter.validate(resolved, {
|
|
2456
|
+
openaiResponses: options.openaiResponses
|
|
2457
|
+
});
|
|
1853
2458
|
if (!validation.valid) {
|
|
1854
2459
|
throw new Error(
|
|
1855
2460
|
`Provider validation failed for "${options.provider}":
|
|
@@ -1879,7 +2484,8 @@ var PromptOpsKit = class {
|
|
|
1879
2484
|
variables: sanitization.variables,
|
|
1880
2485
|
history: options.history,
|
|
1881
2486
|
toolRegistry: options.toolRegistry,
|
|
1882
|
-
strict: options.strict
|
|
2487
|
+
strict: options.strict,
|
|
2488
|
+
openaiResponses: options.openaiResponses
|
|
1883
2489
|
});
|
|
1884
2490
|
return {
|
|
1885
2491
|
resolved,
|
|
@@ -1891,9 +2497,21 @@ var PromptOpsKit = class {
|
|
|
1891
2497
|
* Validate a prompt file.
|
|
1892
2498
|
*/
|
|
1893
2499
|
async validatePrompt(promptPath) {
|
|
1894
|
-
const asset = await this.loadPrompt(promptPath);
|
|
1895
2500
|
const sourceFile = (0, import_node_path4.resolve)(this.config.sourceDir, promptPath + ".md");
|
|
1896
|
-
|
|
2501
|
+
try {
|
|
2502
|
+
const asset = await this.loadPrompt(promptPath);
|
|
2503
|
+
return validateAssetWithIncludes(asset, sourceFile);
|
|
2504
|
+
} catch (error) {
|
|
2505
|
+
const validationError = toPromptValidationError(error, sourceFile);
|
|
2506
|
+
if (validationError) {
|
|
2507
|
+
return {
|
|
2508
|
+
valid: false,
|
|
2509
|
+
errors: [validationError],
|
|
2510
|
+
warnings: []
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
throw error;
|
|
2514
|
+
}
|
|
1897
2515
|
}
|
|
1898
2516
|
/**
|
|
1899
2517
|
* Clear the internal cache.
|
|
@@ -1905,6 +2523,20 @@ var PromptOpsKit = class {
|
|
|
1905
2523
|
function createPromptOpsKit(config = {}) {
|
|
1906
2524
|
return new PromptOpsKit(config);
|
|
1907
2525
|
}
|
|
2526
|
+
function toPromptValidationError(error, filePath) {
|
|
2527
|
+
if (!(error instanceof Error)) {
|
|
2528
|
+
return void 0;
|
|
2529
|
+
}
|
|
2530
|
+
const match = error.message.match(/^(POK\d+):\s*(.*)$/);
|
|
2531
|
+
if (!match) {
|
|
2532
|
+
return void 0;
|
|
2533
|
+
}
|
|
2534
|
+
return {
|
|
2535
|
+
code: match[1],
|
|
2536
|
+
message: match[2],
|
|
2537
|
+
filePath
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
1908
2540
|
async function renderPrompt(options) {
|
|
1909
2541
|
const kit = createPromptOpsKit({
|
|
1910
2542
|
sourceDir: options.sourceDir ?? DEFAULT_PROMPTS_DIR,
|
|
@@ -1936,6 +2568,7 @@ async function renderPrompt(options) {
|
|
|
1936
2568
|
interpolate,
|
|
1937
2569
|
loadPromptFile,
|
|
1938
2570
|
openaiAdapter,
|
|
2571
|
+
openaiResponsesAdapter,
|
|
1939
2572
|
openrouterAdapter,
|
|
1940
2573
|
parsePrompt,
|
|
1941
2574
|
renderPrompt,
|