promptopskit 0.3.7 → 0.3.9

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.
Files changed (69) hide show
  1. package/README.md +37 -11
  2. package/SKILL.md +26 -3
  3. package/dist/{chunk-IXPIBZXT.js → chunk-4LEPCCSA.js} +60 -8
  4. package/dist/chunk-4LEPCCSA.js.map +1 -0
  5. package/dist/{chunk-5TLHYSP7.js → chunk-AN3OR7YC.js} +26 -3
  6. package/dist/chunk-AN3OR7YC.js.map +1 -0
  7. package/dist/{chunk-QPOHKVY5.js → chunk-LMURMZUA.js} +22 -3
  8. package/dist/chunk-LMURMZUA.js.map +1 -0
  9. package/dist/{chunk-KFSP5KN4.js → chunk-O6RQZYS4.js} +49 -7
  10. package/dist/chunk-O6RQZYS4.js.map +1 -0
  11. package/dist/{chunk-6XKV4YVK.js → chunk-V7QY7MRM.js} +85 -8
  12. package/dist/chunk-V7QY7MRM.js.map +1 -0
  13. package/dist/{chunk-DGLLQ3FR.js → chunk-YAD6COQX.js} +3 -3
  14. package/dist/chunk-YNIAA4ZJ.js +111 -0
  15. package/dist/chunk-YNIAA4ZJ.js.map +1 -0
  16. package/dist/cli/index.js +95 -11
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/index.cjs +354 -26
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +9 -5
  21. package/dist/index.d.ts +9 -5
  22. package/dist/index.js +28 -12
  23. package/dist/index.js.map +1 -1
  24. package/dist/providers/anthropic.cjs +189 -18
  25. package/dist/providers/anthropic.cjs.map +1 -1
  26. package/dist/providers/anthropic.d.cts +2 -2
  27. package/dist/providers/anthropic.d.ts +2 -2
  28. package/dist/providers/anthropic.js +3 -3
  29. package/dist/providers/gemini.cjs +166 -14
  30. package/dist/providers/gemini.cjs.map +1 -1
  31. package/dist/providers/gemini.d.cts +2 -2
  32. package/dist/providers/gemini.d.ts +2 -2
  33. package/dist/providers/gemini.js +3 -3
  34. package/dist/providers/openai-responses.cjs +1059 -0
  35. package/dist/providers/openai-responses.cjs.map +1 -0
  36. package/dist/providers/openai-responses.d.cts +11 -0
  37. package/dist/providers/openai-responses.d.ts +11 -0
  38. package/dist/providers/openai-responses.js +9 -0
  39. package/dist/providers/openai-responses.js.map +1 -0
  40. package/dist/providers/openai.cjs +162 -14
  41. package/dist/providers/openai.cjs.map +1 -1
  42. package/dist/providers/openai.d.cts +2 -2
  43. package/dist/providers/openai.d.ts +2 -2
  44. package/dist/providers/openai.js +3 -3
  45. package/dist/providers/openrouter.cjs +162 -14
  46. package/dist/providers/openrouter.cjs.map +1 -1
  47. package/dist/providers/openrouter.d.cts +2 -2
  48. package/dist/providers/openrouter.d.ts +2 -2
  49. package/dist/providers/openrouter.js +4 -4
  50. package/dist/schema-BKkg93rL.d.cts +1923 -0
  51. package/dist/schema-BKkg93rL.d.ts +1923 -0
  52. package/dist/testing.cjs +59 -7
  53. package/dist/testing.cjs.map +1 -1
  54. package/dist/testing.d.cts +1 -1
  55. package/dist/testing.d.ts +1 -1
  56. package/dist/testing.js +1 -1
  57. package/dist/{types-7U58bgVW.d.cts → types-7cC17GWp.d.cts} +24 -5
  58. package/dist/{types-HnZ46u5Q.d.ts → types-CsQ8tON_.d.ts} +24 -5
  59. package/dist/usagetap/index.d.cts +2 -2
  60. package/dist/usagetap/index.d.ts +2 -2
  61. package/package.json +11 -1
  62. package/dist/chunk-5TLHYSP7.js.map +0 -1
  63. package/dist/chunk-6XKV4YVK.js.map +0 -1
  64. package/dist/chunk-IXPIBZXT.js.map +0 -1
  65. package/dist/chunk-KFSP5KN4.js.map +0 -1
  66. package/dist/chunk-QPOHKVY5.js.map +0 -1
  67. package/dist/schema-Bgoff-CN.d.cts +0 -805
  68. package/dist/schema-Bgoff-CN.d.ts +0 -805
  69. /package/dist/{chunk-DGLLQ3FR.js.map → chunk-YAD6COQX.js.map} +0 -0
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,6 +145,20 @@ function mergeOverride(base, override) {
144
145
  if (override.response !== void 0) {
145
146
  result.response = { ...result.response, ...override.response };
146
147
  }
148
+ if (override.provider_options !== void 0) {
149
+ result.provider_options = {
150
+ ...result.provider_options,
151
+ ...override.provider_options,
152
+ anthropic: {
153
+ ...result.provider_options?.anthropic,
154
+ ...override.provider_options.anthropic
155
+ },
156
+ gemini: {
157
+ ...result.provider_options?.gemini,
158
+ ...override.provider_options.gemini
159
+ }
160
+ };
161
+ }
147
162
  return result;
148
163
  }
149
164
 
@@ -246,7 +261,47 @@ var SamplingSchema = import_zod.z.object({
246
261
  });
247
262
  var ResponseSchema = import_zod.z.object({
248
263
  format: import_zod.z.enum(["text", "json", "markdown"]).optional(),
249
- stream: import_zod.z.boolean().optional()
264
+ stream: import_zod.z.boolean().optional(),
265
+ schema: import_zod.z.record(import_zod.z.unknown()).optional(),
266
+ schema_name: import_zod.z.string().optional(),
267
+ schema_strict: import_zod.z.boolean().optional()
268
+ });
269
+ var AnthropicProviderOptionsSchema = import_zod.z.object({
270
+ top_k: import_zod.z.number().int().min(0).optional(),
271
+ tool_choice: import_zod.z.record(import_zod.z.unknown()).optional()
272
+ });
273
+ var GeminiProviderOptionsSchema = import_zod.z.object({
274
+ candidate_count: import_zod.z.number().int().positive().optional(),
275
+ top_k: import_zod.z.number().int().min(0).optional(),
276
+ seed: import_zod.z.number().int().optional(),
277
+ response_schema: import_zod.z.record(import_zod.z.unknown()).optional(),
278
+ response_modalities: import_zod.z.array(import_zod.z.string()).optional(),
279
+ thinking_budget_tokens: import_zod.z.number().int().positive().optional()
280
+ });
281
+ var ProviderOptionsSchema = import_zod.z.object({
282
+ anthropic: AnthropicProviderOptionsSchema.optional(),
283
+ gemini: GeminiProviderOptionsSchema.optional()
284
+ });
285
+ var OpenAICacheSchema = import_zod.z.object({
286
+ prompt_cache_key: import_zod.z.string().min(1).optional(),
287
+ retention: import_zod.z.enum(["in_memory", "24h"]).optional()
288
+ });
289
+ var AnthropicCacheSchema = import_zod.z.object({
290
+ mode: import_zod.z.enum(["automatic", "explicit"]).optional(),
291
+ type: import_zod.z.literal("ephemeral").optional(),
292
+ ttl: import_zod.z.enum(["5m", "1h"]).optional(),
293
+ cache_system_instructions: import_zod.z.boolean().optional(),
294
+ cache_tools: import_zod.z.boolean().optional(),
295
+ cache_prompt_template: import_zod.z.boolean().optional()
296
+ });
297
+ var GeminiCacheSchema = import_zod.z.object({
298
+ cached_content: import_zod.z.string().min(1).optional()
299
+ });
300
+ var CacheSchema = import_zod.z.object({
301
+ openai: OpenAICacheSchema.optional(),
302
+ anthropic: AnthropicCacheSchema.optional(),
303
+ gemini: GeminiCacheSchema.optional(),
304
+ google: GeminiCacheSchema.optional()
250
305
  });
251
306
  var HistorySchema = import_zod.z.object({
252
307
  max_items: import_zod.z.number().int().positive().optional()
@@ -255,7 +310,14 @@ var ContextRegexSchema = import_zod.z.union([
255
310
  import_zod.z.string(),
256
311
  import_zod.z.object({
257
312
  pattern: import_zod.z.string(),
258
- flags: import_zod.z.string().optional()
313
+ flags: import_zod.z.string().optional(),
314
+ return_message: import_zod.z.string().optional()
315
+ })
316
+ ]);
317
+ var ContextBuiltInValidatorSchema = import_zod.z.union([
318
+ import_zod.z.boolean(),
319
+ import_zod.z.object({
320
+ return_message: import_zod.z.string().optional()
259
321
  })
260
322
  ]);
261
323
  var ContextInputDefinitionObjectSchema = import_zod.z.object({
@@ -264,8 +326,8 @@ var ContextInputDefinitionObjectSchema = import_zod.z.object({
264
326
  trim: import_zod.z.union([import_zod.z.boolean(), import_zod.z.enum(["start", "end", "both"])]).optional(),
265
327
  allow_regex: ContextRegexSchema.optional(),
266
328
  deny_regex: ContextRegexSchema.optional(),
267
- non_empty: import_zod.z.boolean().optional(),
268
- reject_secrets: import_zod.z.boolean().optional()
329
+ non_empty: ContextBuiltInValidatorSchema.optional(),
330
+ reject_secrets: ContextBuiltInValidatorSchema.optional()
269
331
  });
270
332
  var ContextInputDefinitionSchema = import_zod.z.union([
271
333
  import_zod.z.string(),
@@ -290,7 +352,9 @@ var PromptAssetOverridesSchema = import_zod.z.object({
290
352
  reasoning: ReasoningSchema.optional(),
291
353
  sampling: SamplingSchema.optional(),
292
354
  response: ResponseSchema.optional(),
293
- tools: import_zod.z.array(ToolRefSchema).optional()
355
+ cache: CacheSchema.optional(),
356
+ tools: import_zod.z.array(ToolRefSchema).optional(),
357
+ provider_options: ProviderOptionsSchema.optional()
294
358
  });
295
359
  var SourceSchema = import_zod.z.object({
296
360
  file_path: import_zod.z.string().optional(),
@@ -302,8 +366,9 @@ var SectionsSchema = import_zod.z.object({
302
366
  notes: import_zod.z.string().optional()
303
367
  });
304
368
  var PromptDefaultsSchema = import_zod.z.object({
305
- provider: import_zod.z.enum(["openai", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
369
+ provider: import_zod.z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
306
370
  model: import_zod.z.string().optional(),
371
+ cache: CacheSchema.optional(),
307
372
  metadata: MetadataSchema.optional(),
308
373
  sections: import_zod.z.object({
309
374
  system_instructions: import_zod.z.string().optional()
@@ -313,13 +378,15 @@ var PromptAssetSchema = import_zod.z.object({
313
378
  id: import_zod.z.string(),
314
379
  schema_version: import_zod.z.number().int().positive().default(1),
315
380
  description: import_zod.z.string().optional(),
316
- provider: import_zod.z.enum(["openai", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
381
+ provider: import_zod.z.enum(["openai", "openai-responses", "anthropic", "google", "gemini", "openrouter", "any"]).optional(),
317
382
  model: import_zod.z.string().optional(),
318
383
  fallback_models: import_zod.z.array(import_zod.z.string()).optional(),
319
384
  reasoning: ReasoningSchema.optional(),
320
385
  sampling: SamplingSchema.optional(),
321
386
  response: ResponseSchema.optional(),
387
+ cache: CacheSchema.optional(),
322
388
  tools: import_zod.z.array(ToolRefSchema).optional(),
389
+ provider_options: ProviderOptionsSchema.optional(),
323
390
  mcp: MCPSchema.optional(),
324
391
  context: ContextSchema.optional(),
325
392
  includes: import_zod.z.array(import_zod.z.string()).optional(),
@@ -628,8 +695,8 @@ function normalizeContextInput(input) {
628
695
  trim: input.trim,
629
696
  allow_regex: normalizeContextRegex(input.allow_regex),
630
697
  deny_regex: normalizeContextRegex(input.deny_regex),
631
- non_empty: input.non_empty,
632
- reject_secrets: input.reject_secrets
698
+ non_empty: normalizeBuiltInValidator(input.non_empty),
699
+ reject_secrets: normalizeBuiltInValidator(input.reject_secrets)
633
700
  };
634
701
  }
635
702
  function normalizeContextRegex(value) {
@@ -655,7 +722,19 @@ function normalizeContextRegex(value) {
655
722
  return {
656
723
  pattern: value.pattern,
657
724
  flags: value.flags ?? "",
658
- raw: JSON.stringify(value)
725
+ raw: JSON.stringify(value),
726
+ returnMessage: value.return_message
727
+ };
728
+ }
729
+ function normalizeBuiltInValidator(value) {
730
+ if (value === void 0 || value === false) {
731
+ return void 0;
732
+ }
733
+ if (value === true) {
734
+ return {};
735
+ }
736
+ return {
737
+ returnMessage: value.return_message
659
738
  };
660
739
  }
661
740
  function parseRegexLiteral(value) {
@@ -787,6 +866,17 @@ function sanitizeContextVariables(asset, variables = {}, options = {}) {
787
866
  field: "allow_regex"
788
867
  });
789
868
  if (!matcher.test(candidate2)) {
869
+ if (input.allow_regex.returnMessage) {
870
+ return {
871
+ variables: sanitized,
872
+ shortCircuit: {
873
+ returnMessage: input.allow_regex.returnMessage,
874
+ code: "POK031",
875
+ variable: input.name,
876
+ field: "allow_regex"
877
+ }
878
+ };
879
+ }
790
880
  throw new Error(
791
881
  `POK031: Context variable "${input.name}" failed allow_regex validation for prompt "${asset.id}".`
792
882
  );
@@ -800,12 +890,34 @@ function sanitizeContextVariables(asset, variables = {}, options = {}) {
800
890
  field: "deny_regex"
801
891
  });
802
892
  if (matcher.test(candidate2)) {
893
+ if (input.deny_regex.returnMessage) {
894
+ return {
895
+ variables: sanitized,
896
+ shortCircuit: {
897
+ returnMessage: input.deny_regex.returnMessage,
898
+ code: "POK032",
899
+ variable: input.name,
900
+ field: "deny_regex"
901
+ }
902
+ };
903
+ }
803
904
  throw new Error(
804
905
  `POK032: Context variable "${input.name}" matched deny_regex for prompt "${asset.id}".`
805
906
  );
806
907
  }
807
908
  }
808
909
  if (input.non_empty && candidate.trim().length === 0) {
910
+ if (input.non_empty.returnMessage) {
911
+ return {
912
+ variables: sanitized,
913
+ shortCircuit: {
914
+ returnMessage: input.non_empty.returnMessage,
915
+ code: "POK033",
916
+ variable: input.name,
917
+ field: "non_empty"
918
+ }
919
+ };
920
+ }
809
921
  throw new Error(
810
922
  `POK033: Context variable "${input.name}" failed non_empty validation for prompt "${asset.id}".`
811
923
  );
@@ -817,13 +929,24 @@ function sanitizeContextVariables(asset, variables = {}, options = {}) {
817
929
  field: "reject_secrets"
818
930
  });
819
931
  if (matcher.test(candidate)) {
932
+ if (input.reject_secrets.returnMessage) {
933
+ return {
934
+ variables: sanitized,
935
+ shortCircuit: {
936
+ returnMessage: input.reject_secrets.returnMessage,
937
+ code: "POK034",
938
+ variable: input.name,
939
+ field: "reject_secrets"
940
+ }
941
+ };
942
+ }
820
943
  throw new Error(
821
944
  `POK034: Context variable "${input.name}" matched reject_secrets validation for prompt "${asset.id}".`
822
945
  );
823
946
  }
824
947
  }
825
948
  }
826
- return sanitized;
949
+ return { variables: sanitized };
827
950
  }
828
951
  function measureContextValueSize(value) {
829
952
  return textEncoder.encode(value).length;
@@ -873,12 +996,19 @@ function withPromptInputSupport(adapter) {
873
996
  };
874
997
  const renderPrompt2 = async (input, runtime) => {
875
998
  const resolved = await resolveProviderPromptInput(input, runtime);
876
- const variables = sanitizeContextVariables(resolved, runtime.variables, {
999
+ const sanitization = sanitizeContextVariables(resolved, runtime.variables, {
877
1000
  onContextOverflow: runtime.onContextOverflow
878
1001
  });
1002
+ if (sanitization.shortCircuit) {
1003
+ return {
1004
+ provider: adapter.name,
1005
+ model: resolved.model ?? "",
1006
+ returnMessage: sanitization.shortCircuit.returnMessage
1007
+ };
1008
+ }
879
1009
  return adapter.render(resolved, {
880
1010
  ...runtime,
881
- variables
1011
+ variables: sanitization.variables
882
1012
  });
883
1013
  };
884
1014
  return {
@@ -901,6 +1031,9 @@ var openaiAdapter = withPromptInputSupport({
901
1031
  if (resolvedAsset.reasoning?.budget_tokens !== void 0) {
902
1032
  warnings.push("OpenAI uses reasoning_effort, not budget_tokens. budget_tokens will be ignored.");
903
1033
  }
1034
+ if (resolvedAsset.response?.schema !== void 0 && resolvedAsset.response?.format !== "json") {
1035
+ warnings.push("OpenAI response.schema requires response.format: json. schema will still be applied as JSON schema output.");
1036
+ }
904
1037
  return { valid: errors.length === 0, errors, warnings };
905
1038
  },
906
1039
  render(asset, runtime) {
@@ -925,6 +1058,7 @@ var openaiAdapter = withPromptInputSupport({
925
1058
  model: resolvedAsset.model,
926
1059
  messages
927
1060
  };
1061
+ const openaiCacheConfig = resolvedAsset.cache?.openai;
928
1062
  if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
929
1063
  if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
930
1064
  if (resolvedAsset.sampling?.frequency_penalty !== void 0) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;
@@ -934,12 +1068,27 @@ var openaiAdapter = withPromptInputSupport({
934
1068
  if (resolvedAsset.reasoning?.effort) {
935
1069
  body.reasoning_effort = resolvedAsset.reasoning.effort;
936
1070
  }
937
- if (resolvedAsset.response?.format === "json") {
1071
+ if (resolvedAsset.response?.schema) {
1072
+ body.response_format = {
1073
+ type: "json_schema",
1074
+ json_schema: {
1075
+ name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,
1076
+ schema: resolvedAsset.response.schema,
1077
+ strict: resolvedAsset.response.schema_strict ?? true
1078
+ }
1079
+ };
1080
+ } else if (resolvedAsset.response?.format === "json") {
938
1081
  body.response_format = { type: "json_object" };
939
1082
  }
940
1083
  if (resolvedAsset.response?.stream !== void 0) {
941
1084
  body.stream = resolvedAsset.response.stream;
942
1085
  }
1086
+ if (openaiCacheConfig?.prompt_cache_key) {
1087
+ body.prompt_cache_key = openaiCacheConfig.prompt_cache_key;
1088
+ }
1089
+ if (openaiCacheConfig?.retention) {
1090
+ body.prompt_cache_retention = openaiCacheConfig.retention;
1091
+ }
943
1092
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
944
1093
  body.tools = resolvedAsset.tools.map((tool) => {
945
1094
  if (typeof tool === "string") {
@@ -965,6 +1114,107 @@ var openaiAdapter = withPromptInputSupport({
965
1114
  }
966
1115
  });
967
1116
 
1117
+ // src/providers/openai-responses.ts
1118
+ var openaiResponsesAdapter = withPromptInputSupport({
1119
+ name: "openai-responses",
1120
+ validate(asset, runtime) {
1121
+ const resolvedAsset = resolveAssetForProvider(asset, runtime);
1122
+ const errors = [];
1123
+ const warnings = [];
1124
+ if (!resolvedAsset.model) {
1125
+ errors.push("OpenAI Responses adapter requires a model to be specified.");
1126
+ }
1127
+ if (resolvedAsset.reasoning?.budget_tokens !== void 0) {
1128
+ warnings.push("OpenAI Responses uses reasoning.effort, not budget_tokens. budget_tokens will be ignored.");
1129
+ }
1130
+ if (resolvedAsset.response?.schema !== void 0 && resolvedAsset.response?.format !== "json") {
1131
+ warnings.push("OpenAI Responses response.schema requires response.format: json. schema will still be applied as JSON schema output.");
1132
+ }
1133
+ if (runtime?.openaiResponses?.conversation !== void 0 && runtime?.openaiResponses?.previous_response_id !== void 0) {
1134
+ errors.push('OpenAI Responses options "conversation" and "previous_response_id" cannot both be set.');
1135
+ }
1136
+ return { valid: errors.length === 0, errors, warnings };
1137
+ },
1138
+ render(asset, runtime) {
1139
+ const resolvedAsset = resolveAssetForProvider(asset, runtime);
1140
+ const sections = renderSections(resolvedAsset, {
1141
+ variables: runtime.variables,
1142
+ strict: runtime.strict
1143
+ });
1144
+ const responseOptions = runtime.openaiResponses;
1145
+ const input = [];
1146
+ if (runtime.history) {
1147
+ for (const msg of runtime.history) {
1148
+ input.push({ role: msg.role, content: msg.content });
1149
+ }
1150
+ }
1151
+ if (sections.prompt_template) {
1152
+ input.push({ role: "user", content: sections.prompt_template });
1153
+ }
1154
+ const body = {
1155
+ model: resolvedAsset.model,
1156
+ input
1157
+ };
1158
+ if (responseOptions?.instructions !== void 0) {
1159
+ body.instructions = responseOptions.instructions;
1160
+ } else if (sections.system_instructions) {
1161
+ body.instructions = sections.system_instructions;
1162
+ }
1163
+ if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
1164
+ if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
1165
+ if (resolvedAsset.sampling?.frequency_penalty !== void 0) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;
1166
+ if (resolvedAsset.sampling?.presence_penalty !== void 0) body.presence_penalty = resolvedAsset.sampling.presence_penalty;
1167
+ if (resolvedAsset.sampling?.stop !== void 0) body.stop = resolvedAsset.sampling.stop;
1168
+ if (resolvedAsset.sampling?.max_output_tokens !== void 0) body.max_output_tokens = resolvedAsset.sampling.max_output_tokens;
1169
+ if (resolvedAsset.reasoning?.effort) {
1170
+ body.reasoning = { effort: resolvedAsset.reasoning.effort };
1171
+ }
1172
+ if (resolvedAsset.response?.schema) {
1173
+ body.text = {
1174
+ format: {
1175
+ type: "json_schema",
1176
+ name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,
1177
+ schema: resolvedAsset.response.schema,
1178
+ strict: resolvedAsset.response.schema_strict ?? true
1179
+ }
1180
+ };
1181
+ } else if (resolvedAsset.response?.format === "json") {
1182
+ body.text = { format: { type: "json_object" } };
1183
+ }
1184
+ if (resolvedAsset.response?.stream !== void 0) {
1185
+ body.stream = resolvedAsset.response.stream;
1186
+ }
1187
+ if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1188
+ body.tools = resolvedAsset.tools.map((tool) => {
1189
+ if (typeof tool === "string") {
1190
+ const def = runtime.toolRegistry?.[tool];
1191
+ if (def) return def;
1192
+ return { type: "function", name: tool };
1193
+ }
1194
+ return {
1195
+ type: "function",
1196
+ name: tool.name,
1197
+ description: tool.description,
1198
+ parameters: tool.input_schema
1199
+ };
1200
+ });
1201
+ }
1202
+ if (responseOptions?.previous_response_id !== void 0) body.previous_response_id = responseOptions.previous_response_id;
1203
+ if (responseOptions?.conversation !== void 0) body.conversation = responseOptions.conversation;
1204
+ if (responseOptions?.parallel_tool_calls !== void 0) body.parallel_tool_calls = responseOptions.parallel_tool_calls;
1205
+ if (responseOptions?.max_tool_calls !== void 0) body.max_tool_calls = responseOptions.max_tool_calls;
1206
+ if (responseOptions?.store !== void 0) body.store = responseOptions.store;
1207
+ if (responseOptions?.metadata !== void 0) body.metadata = responseOptions.metadata;
1208
+ if (responseOptions?.include !== void 0) body.include = responseOptions.include;
1209
+ if (responseOptions?.background !== void 0) body.background = responseOptions.background;
1210
+ return {
1211
+ body,
1212
+ provider: "openai-responses",
1213
+ model: resolvedAsset.model ?? "unknown"
1214
+ };
1215
+ }
1216
+ });
1217
+
968
1218
  // src/providers/anthropic.ts
969
1219
  var anthropicAdapter = withPromptInputSupport({
970
1220
  name: "anthropic",
@@ -984,6 +1234,12 @@ var anthropicAdapter = withPromptInputSupport({
984
1234
  if (resolvedAsset.reasoning?.effort !== void 0) {
985
1235
  warnings.push("Anthropic uses budget_tokens for thinking, not effort. effort will be mapped approximately.");
986
1236
  }
1237
+ if (resolvedAsset.response?.schema !== void 0) {
1238
+ warnings.push("Anthropic does not support response.schema structured output in this adapter. It will be ignored.");
1239
+ }
1240
+ if (resolvedAsset.provider_options?.anthropic?.top_k !== void 0 && resolvedAsset.provider_options.anthropic.top_k < 0) {
1241
+ errors.push("Anthropic provider_options.top_k must be >= 0.");
1242
+ }
987
1243
  return { valid: errors.length === 0, errors, warnings };
988
1244
  },
989
1245
  render(asset, runtime) {
@@ -993,20 +1249,38 @@ var anthropicAdapter = withPromptInputSupport({
993
1249
  strict: runtime.strict
994
1250
  });
995
1251
  const messages = [];
1252
+ const anthropicCacheConfig = resolvedAsset.cache?.anthropic;
1253
+ const cacheType = anthropicCacheConfig?.type ?? "ephemeral";
1254
+ const cacheControl = anthropicCacheConfig ? {
1255
+ type: cacheType,
1256
+ ...anthropicCacheConfig.ttl ? { ttl: anthropicCacheConfig.ttl } : {}
1257
+ } : void 0;
1258
+ const cacheMode = anthropicCacheConfig?.mode ?? "automatic";
996
1259
  if (runtime.history) {
997
1260
  for (const msg of runtime.history) {
998
1261
  messages.push({ role: msg.role, content: msg.content });
999
1262
  }
1000
1263
  }
1001
1264
  if (sections.prompt_template) {
1002
- messages.push({ role: "user", content: sections.prompt_template });
1265
+ if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_prompt_template) {
1266
+ messages.push({
1267
+ role: "user",
1268
+ content: [{ type: "text", text: sections.prompt_template, cache_control: cacheControl }]
1269
+ });
1270
+ } else {
1271
+ messages.push({ role: "user", content: sections.prompt_template });
1272
+ }
1003
1273
  }
1004
1274
  const body = {
1005
1275
  model: resolvedAsset.model,
1006
1276
  messages
1007
1277
  };
1008
1278
  if (sections.system_instructions) {
1009
- body.system = sections.system_instructions;
1279
+ if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_system_instructions !== false) {
1280
+ body.system = [{ type: "text", text: sections.system_instructions, cache_control: cacheControl }];
1281
+ } else {
1282
+ body.system = sections.system_instructions;
1283
+ }
1010
1284
  }
1011
1285
  if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
1012
1286
  if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
@@ -1022,23 +1296,41 @@ var anthropicAdapter = withPromptInputSupport({
1022
1296
  budget_tokens: resolvedAsset.reasoning.budget_tokens
1023
1297
  };
1024
1298
  }
1299
+ if (resolvedAsset.provider_options?.anthropic?.top_k !== void 0) {
1300
+ body.top_k = resolvedAsset.provider_options.anthropic.top_k;
1301
+ }
1025
1302
  if (resolvedAsset.response?.stream !== void 0) {
1026
1303
  body.stream = resolvedAsset.response.stream;
1027
1304
  }
1305
+ if (cacheControl && cacheMode === "automatic") {
1306
+ body.cache_control = cacheControl;
1307
+ }
1028
1308
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1029
1309
  body.tools = resolvedAsset.tools.map((tool) => {
1030
1310
  if (typeof tool === "string") {
1031
1311
  const def = runtime.toolRegistry?.[tool];
1032
- if (def) return def;
1033
- return { name: tool };
1312
+ if (def) {
1313
+ if (cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools) {
1314
+ return { ...def, cache_control: cacheControl };
1315
+ }
1316
+ return def;
1317
+ }
1318
+ return {
1319
+ name: tool,
1320
+ ...cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools ? { cache_control: cacheControl } : {}
1321
+ };
1034
1322
  }
1035
1323
  return {
1036
1324
  name: tool.name,
1037
1325
  description: tool.description,
1038
- input_schema: tool.input_schema ?? { type: "object", properties: {} }
1326
+ input_schema: tool.input_schema ?? { type: "object", properties: {} },
1327
+ ...cacheControl && cacheMode === "explicit" && anthropicCacheConfig?.cache_tools ? { cache_control: cacheControl } : {}
1039
1328
  };
1040
1329
  });
1041
1330
  }
1331
+ if (resolvedAsset.provider_options?.anthropic?.tool_choice !== void 0) {
1332
+ body.tool_choice = resolvedAsset.provider_options.anthropic.tool_choice;
1333
+ }
1042
1334
  return {
1043
1335
  body,
1044
1336
  provider: "anthropic",
@@ -1054,6 +1346,8 @@ var geminiAdapter = withPromptInputSupport({
1054
1346
  const resolvedAsset = resolveAssetForProvider(asset, runtime);
1055
1347
  const errors = [];
1056
1348
  const warnings = [];
1349
+ const geminiCache = resolvedAsset.cache?.gemini?.cached_content;
1350
+ const googleCache = resolvedAsset.cache?.google?.cached_content;
1057
1351
  if (!resolvedAsset.model) {
1058
1352
  errors.push("Gemini adapter requires a model to be specified.");
1059
1353
  }
@@ -1063,6 +1357,12 @@ var geminiAdapter = withPromptInputSupport({
1063
1357
  if (resolvedAsset.sampling?.presence_penalty !== void 0) {
1064
1358
  warnings.push("Gemini does not support presence_penalty. It will be ignored.");
1065
1359
  }
1360
+ if (geminiCache && googleCache && geminiCache !== googleCache) {
1361
+ warnings.push("Both cache.gemini.cached_content and cache.google.cached_content are set. Gemini uses cache.gemini.cached_content.");
1362
+ }
1363
+ if (resolvedAsset.response?.stream !== void 0) {
1364
+ warnings.push("Gemini streaming is endpoint-based (streamGenerateContent), not body-based. response.stream will be ignored.");
1365
+ }
1066
1366
  return { valid: errors.length === 0, errors, warnings };
1067
1367
  },
1068
1368
  render(asset, runtime) {
@@ -1089,20 +1389,32 @@ var geminiAdapter = withPromptInputSupport({
1089
1389
  const body = {
1090
1390
  contents
1091
1391
  };
1392
+ const geminiCacheConfig = resolvedAsset.cache?.gemini ?? resolvedAsset.cache?.google;
1092
1393
  if (sections.system_instructions) {
1093
1394
  body.systemInstruction = {
1094
1395
  parts: [{ text: sections.system_instructions }]
1095
1396
  };
1096
1397
  }
1097
1398
  const generationConfig = {};
1399
+ const geminiOptions = resolvedAsset.provider_options?.gemini;
1098
1400
  if (resolvedAsset.sampling?.temperature !== void 0) generationConfig.temperature = resolvedAsset.sampling.temperature;
1099
1401
  if (resolvedAsset.sampling?.top_p !== void 0) generationConfig.topP = resolvedAsset.sampling.top_p;
1100
1402
  if (resolvedAsset.sampling?.max_output_tokens !== void 0) generationConfig.maxOutputTokens = resolvedAsset.sampling.max_output_tokens;
1101
1403
  if (resolvedAsset.sampling?.stop !== void 0) generationConfig.stopSequences = resolvedAsset.sampling.stop;
1404
+ if (geminiOptions?.candidate_count !== void 0) generationConfig.candidateCount = geminiOptions.candidate_count;
1405
+ if (geminiOptions?.top_k !== void 0) generationConfig.topK = geminiOptions.top_k;
1406
+ if (geminiOptions?.seed !== void 0) generationConfig.seed = geminiOptions.seed;
1407
+ if (geminiOptions?.response_schema !== void 0) generationConfig.responseSchema = geminiOptions.response_schema;
1408
+ if (geminiOptions?.response_modalities !== void 0) generationConfig.responseModalities = geminiOptions.response_modalities;
1409
+ if (resolvedAsset.response?.schema !== void 0) generationConfig.responseSchema = resolvedAsset.response.schema;
1102
1410
  if (resolvedAsset.response?.format === "json") {
1103
1411
  generationConfig.responseMimeType = "application/json";
1104
1412
  }
1105
- if (resolvedAsset.reasoning?.effort) {
1413
+ if (geminiOptions?.thinking_budget_tokens !== void 0) {
1414
+ body.thinkingConfig = {
1415
+ thinkingBudget: geminiOptions.thinking_budget_tokens
1416
+ };
1417
+ } else if (resolvedAsset.reasoning?.effort) {
1106
1418
  body.thinkingConfig = {
1107
1419
  thinkingBudget: resolvedAsset.reasoning.effort === "high" ? 8192 : resolvedAsset.reasoning.effort === "medium" ? 4096 : 1024
1108
1420
  };
@@ -1110,6 +1422,9 @@ var geminiAdapter = withPromptInputSupport({
1110
1422
  if (Object.keys(generationConfig).length > 0) {
1111
1423
  body.generationConfig = generationConfig;
1112
1424
  }
1425
+ if (geminiCacheConfig?.cached_content) {
1426
+ body.cachedContent = geminiCacheConfig.cached_content;
1427
+ }
1113
1428
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1114
1429
  const functionDeclarations = resolvedAsset.tools.map((tool) => {
1115
1430
  if (typeof tool === "string") {
@@ -1151,6 +1466,7 @@ var openrouterAdapter = withPromptInputSupport({
1151
1466
  // src/providers/index.ts
1152
1467
  var adapters = {
1153
1468
  openai: openaiAdapter,
1469
+ "openai-responses": openaiResponsesAdapter,
1154
1470
  anthropic: anthropicAdapter,
1155
1471
  google: geminiAdapter,
1156
1472
  gemini: geminiAdapter,
@@ -1205,7 +1521,8 @@ var KNOWN_FRONT_MATTER_KEYS = /* @__PURE__ */ new Set([
1205
1521
  "includes",
1206
1522
  "environments",
1207
1523
  "tiers",
1208
- "metadata"
1524
+ "metadata",
1525
+ "cache"
1209
1526
  ]);
1210
1527
  function validateAsset(asset, frontMatterKeys, filePath) {
1211
1528
  const errors = [];
@@ -1779,17 +2096,26 @@ var PromptOpsKit = class {
1779
2096
  throw new Error('Either "path" or "source" must be provided to renderPrompt()');
1780
2097
  }
1781
2098
  const adapter = getAdapter(options.provider);
1782
- const validation = adapter.validate(resolved);
2099
+ const validation = adapter.validate(resolved, {
2100
+ openaiResponses: options.openaiResponses
2101
+ });
1783
2102
  if (!validation.valid) {
1784
2103
  throw new Error(
1785
2104
  `Provider validation failed for "${options.provider}":
1786
2105
  ` + validation.errors.map((e) => ` - ${e}`).join("\n")
1787
2106
  );
1788
2107
  }
1789
- const sanitizedVariables = sanitizeContextVariables(resolved, options.variables, {
2108
+ const sanitization = sanitizeContextVariables(resolved, options.variables, {
1790
2109
  onContextOverflow: options.onContextOverflow
1791
2110
  });
1792
- const contextSizeWarnings = collectContextSizeWarnings(resolved, sanitizedVariables).map(
2111
+ if (sanitization.shortCircuit) {
2112
+ return {
2113
+ resolved,
2114
+ returnMessage: sanitization.shortCircuit.returnMessage,
2115
+ warnings: validation.warnings
2116
+ };
2117
+ }
2118
+ const contextSizeWarnings = collectContextSizeWarnings(resolved, sanitization.variables).map(
1793
2119
  (warning) => formatContextSizeWarning(resolved, warning)
1794
2120
  );
1795
2121
  const contextWarningPolicy = this.config.warnings?.contextSize;
@@ -1799,10 +2125,11 @@ var PromptOpsKit = class {
1799
2125
  }
1800
2126
  }
1801
2127
  const request = adapter.render(resolved, {
1802
- variables: sanitizedVariables,
2128
+ variables: sanitization.variables,
1803
2129
  history: options.history,
1804
2130
  toolRegistry: options.toolRegistry,
1805
- strict: options.strict
2131
+ strict: options.strict,
2132
+ openaiResponses: options.openaiResponses
1806
2133
  });
1807
2134
  return {
1808
2135
  resolved,
@@ -1859,6 +2186,7 @@ async function renderPrompt(options) {
1859
2186
  interpolate,
1860
2187
  loadPromptFile,
1861
2188
  openaiAdapter,
2189
+ openaiResponsesAdapter,
1862
2190
  openrouterAdapter,
1863
2191
  parsePrompt,
1864
2192
  renderPrompt,