promptopskit 0.3.8 → 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 (68) hide show
  1. package/README.md +6 -3
  2. package/dist/{chunk-5OYWNRNC.js → chunk-4LEPCCSA.js} +50 -5
  3. package/dist/chunk-4LEPCCSA.js.map +1 -0
  4. package/dist/{chunk-E6NPZOJL.js → chunk-AN3OR7YC.js} +26 -3
  5. package/dist/chunk-AN3OR7YC.js.map +1 -0
  6. package/dist/{chunk-UJU5XERR.js → chunk-LMURMZUA.js} +22 -3
  7. package/dist/chunk-LMURMZUA.js.map +1 -0
  8. package/dist/{chunk-BBVVA27J.js → chunk-O6RQZYS4.js} +49 -7
  9. package/dist/chunk-O6RQZYS4.js.map +1 -0
  10. package/dist/{chunk-X73VG645.js → chunk-V7QY7MRM.js} +16 -2
  11. package/dist/chunk-V7QY7MRM.js.map +1 -0
  12. package/dist/{chunk-E2NXJLS6.js → chunk-YAD6COQX.js} +3 -3
  13. package/dist/chunk-YNIAA4ZJ.js +111 -0
  14. package/dist/chunk-YNIAA4ZJ.js.map +1 -0
  15. package/dist/cli/index.js +70 -5
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/index.cjs +265 -14
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +7 -4
  20. package/dist/index.d.ts +7 -4
  21. package/dist/index.js +18 -9
  22. package/dist/index.js.map +1 -1
  23. package/dist/providers/anthropic.cjs +110 -9
  24. package/dist/providers/anthropic.cjs.map +1 -1
  25. package/dist/providers/anthropic.d.cts +2 -2
  26. package/dist/providers/anthropic.d.ts +2 -2
  27. package/dist/providers/anthropic.js +3 -3
  28. package/dist/providers/gemini.cjs +87 -5
  29. package/dist/providers/gemini.cjs.map +1 -1
  30. package/dist/providers/gemini.d.cts +2 -2
  31. package/dist/providers/gemini.d.ts +2 -2
  32. package/dist/providers/gemini.js +3 -3
  33. package/dist/providers/openai-responses.cjs +1059 -0
  34. package/dist/providers/openai-responses.cjs.map +1 -0
  35. package/dist/providers/openai-responses.d.cts +11 -0
  36. package/dist/providers/openai-responses.d.ts +11 -0
  37. package/dist/providers/openai-responses.js +9 -0
  38. package/dist/providers/openai-responses.js.map +1 -0
  39. package/dist/providers/openai.cjs +83 -5
  40. package/dist/providers/openai.cjs.map +1 -1
  41. package/dist/providers/openai.d.cts +2 -2
  42. package/dist/providers/openai.d.ts +2 -2
  43. package/dist/providers/openai.js +3 -3
  44. package/dist/providers/openrouter.cjs +83 -5
  45. package/dist/providers/openrouter.cjs.map +1 -1
  46. package/dist/providers/openrouter.d.cts +2 -2
  47. package/dist/providers/openrouter.d.ts +2 -2
  48. package/dist/providers/openrouter.js +4 -4
  49. package/dist/schema-BKkg93rL.d.cts +1923 -0
  50. package/dist/schema-BKkg93rL.d.ts +1923 -0
  51. package/dist/testing.cjs +49 -4
  52. package/dist/testing.cjs.map +1 -1
  53. package/dist/testing.d.cts +1 -1
  54. package/dist/testing.d.ts +1 -1
  55. package/dist/testing.js +1 -1
  56. package/dist/{types-C6RG0Si0.d.cts → types-7cC17GWp.d.cts} +13 -1
  57. package/dist/{types-fBvo_d4k.d.ts → types-CsQ8tON_.d.ts} +13 -1
  58. package/dist/usagetap/index.d.cts +2 -2
  59. package/dist/usagetap/index.d.ts +2 -2
  60. package/package.json +11 -1
  61. package/dist/chunk-5OYWNRNC.js.map +0 -1
  62. package/dist/chunk-BBVVA27J.js.map +0 -1
  63. package/dist/chunk-E6NPZOJL.js.map +0 -1
  64. package/dist/chunk-UJU5XERR.js.map +0 -1
  65. package/dist/chunk-X73VG645.js.map +0 -1
  66. package/dist/schema-DwzYbZba.d.cts +0 -859
  67. package/dist/schema-DwzYbZba.d.ts +0 -859
  68. /package/dist/{chunk-E2NXJLS6.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()
@@ -297,7 +352,9 @@ var PromptAssetOverridesSchema = import_zod.z.object({
297
352
  reasoning: ReasoningSchema.optional(),
298
353
  sampling: SamplingSchema.optional(),
299
354
  response: ResponseSchema.optional(),
300
- tools: import_zod.z.array(ToolRefSchema).optional()
355
+ cache: CacheSchema.optional(),
356
+ tools: import_zod.z.array(ToolRefSchema).optional(),
357
+ provider_options: ProviderOptionsSchema.optional()
301
358
  });
302
359
  var SourceSchema = import_zod.z.object({
303
360
  file_path: import_zod.z.string().optional(),
@@ -309,8 +366,9 @@ var SectionsSchema = import_zod.z.object({
309
366
  notes: import_zod.z.string().optional()
310
367
  });
311
368
  var PromptDefaultsSchema = import_zod.z.object({
312
- 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(),
313
370
  model: import_zod.z.string().optional(),
371
+ cache: CacheSchema.optional(),
314
372
  metadata: MetadataSchema.optional(),
315
373
  sections: import_zod.z.object({
316
374
  system_instructions: import_zod.z.string().optional()
@@ -320,13 +378,15 @@ var PromptAssetSchema = import_zod.z.object({
320
378
  id: import_zod.z.string(),
321
379
  schema_version: import_zod.z.number().int().positive().default(1),
322
380
  description: import_zod.z.string().optional(),
323
- 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(),
324
382
  model: import_zod.z.string().optional(),
325
383
  fallback_models: import_zod.z.array(import_zod.z.string()).optional(),
326
384
  reasoning: ReasoningSchema.optional(),
327
385
  sampling: SamplingSchema.optional(),
328
386
  response: ResponseSchema.optional(),
387
+ cache: CacheSchema.optional(),
329
388
  tools: import_zod.z.array(ToolRefSchema).optional(),
389
+ provider_options: ProviderOptionsSchema.optional(),
330
390
  mcp: MCPSchema.optional(),
331
391
  context: ContextSchema.optional(),
332
392
  includes: import_zod.z.array(import_zod.z.string()).optional(),
@@ -971,6 +1031,9 @@ var openaiAdapter = withPromptInputSupport({
971
1031
  if (resolvedAsset.reasoning?.budget_tokens !== void 0) {
972
1032
  warnings.push("OpenAI uses reasoning_effort, not budget_tokens. budget_tokens will be ignored.");
973
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
+ }
974
1037
  return { valid: errors.length === 0, errors, warnings };
975
1038
  },
976
1039
  render(asset, runtime) {
@@ -995,6 +1058,7 @@ var openaiAdapter = withPromptInputSupport({
995
1058
  model: resolvedAsset.model,
996
1059
  messages
997
1060
  };
1061
+ const openaiCacheConfig = resolvedAsset.cache?.openai;
998
1062
  if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
999
1063
  if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
1000
1064
  if (resolvedAsset.sampling?.frequency_penalty !== void 0) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;
@@ -1004,12 +1068,27 @@ var openaiAdapter = withPromptInputSupport({
1004
1068
  if (resolvedAsset.reasoning?.effort) {
1005
1069
  body.reasoning_effort = resolvedAsset.reasoning.effort;
1006
1070
  }
1007
- 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") {
1008
1081
  body.response_format = { type: "json_object" };
1009
1082
  }
1010
1083
  if (resolvedAsset.response?.stream !== void 0) {
1011
1084
  body.stream = resolvedAsset.response.stream;
1012
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
+ }
1013
1092
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1014
1093
  body.tools = resolvedAsset.tools.map((tool) => {
1015
1094
  if (typeof tool === "string") {
@@ -1035,6 +1114,107 @@ var openaiAdapter = withPromptInputSupport({
1035
1114
  }
1036
1115
  });
1037
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
+
1038
1218
  // src/providers/anthropic.ts
1039
1219
  var anthropicAdapter = withPromptInputSupport({
1040
1220
  name: "anthropic",
@@ -1054,6 +1234,12 @@ var anthropicAdapter = withPromptInputSupport({
1054
1234
  if (resolvedAsset.reasoning?.effort !== void 0) {
1055
1235
  warnings.push("Anthropic uses budget_tokens for thinking, not effort. effort will be mapped approximately.");
1056
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
+ }
1057
1243
  return { valid: errors.length === 0, errors, warnings };
1058
1244
  },
1059
1245
  render(asset, runtime) {
@@ -1063,20 +1249,38 @@ var anthropicAdapter = withPromptInputSupport({
1063
1249
  strict: runtime.strict
1064
1250
  });
1065
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";
1066
1259
  if (runtime.history) {
1067
1260
  for (const msg of runtime.history) {
1068
1261
  messages.push({ role: msg.role, content: msg.content });
1069
1262
  }
1070
1263
  }
1071
1264
  if (sections.prompt_template) {
1072
- 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
+ }
1073
1273
  }
1074
1274
  const body = {
1075
1275
  model: resolvedAsset.model,
1076
1276
  messages
1077
1277
  };
1078
1278
  if (sections.system_instructions) {
1079
- 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
+ }
1080
1284
  }
1081
1285
  if (resolvedAsset.sampling?.temperature !== void 0) body.temperature = resolvedAsset.sampling.temperature;
1082
1286
  if (resolvedAsset.sampling?.top_p !== void 0) body.top_p = resolvedAsset.sampling.top_p;
@@ -1092,23 +1296,41 @@ var anthropicAdapter = withPromptInputSupport({
1092
1296
  budget_tokens: resolvedAsset.reasoning.budget_tokens
1093
1297
  };
1094
1298
  }
1299
+ if (resolvedAsset.provider_options?.anthropic?.top_k !== void 0) {
1300
+ body.top_k = resolvedAsset.provider_options.anthropic.top_k;
1301
+ }
1095
1302
  if (resolvedAsset.response?.stream !== void 0) {
1096
1303
  body.stream = resolvedAsset.response.stream;
1097
1304
  }
1305
+ if (cacheControl && cacheMode === "automatic") {
1306
+ body.cache_control = cacheControl;
1307
+ }
1098
1308
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1099
1309
  body.tools = resolvedAsset.tools.map((tool) => {
1100
1310
  if (typeof tool === "string") {
1101
1311
  const def = runtime.toolRegistry?.[tool];
1102
- if (def) return def;
1103
- 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
+ };
1104
1322
  }
1105
1323
  return {
1106
1324
  name: tool.name,
1107
1325
  description: tool.description,
1108
- 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 } : {}
1109
1328
  };
1110
1329
  });
1111
1330
  }
1331
+ if (resolvedAsset.provider_options?.anthropic?.tool_choice !== void 0) {
1332
+ body.tool_choice = resolvedAsset.provider_options.anthropic.tool_choice;
1333
+ }
1112
1334
  return {
1113
1335
  body,
1114
1336
  provider: "anthropic",
@@ -1124,6 +1346,8 @@ var geminiAdapter = withPromptInputSupport({
1124
1346
  const resolvedAsset = resolveAssetForProvider(asset, runtime);
1125
1347
  const errors = [];
1126
1348
  const warnings = [];
1349
+ const geminiCache = resolvedAsset.cache?.gemini?.cached_content;
1350
+ const googleCache = resolvedAsset.cache?.google?.cached_content;
1127
1351
  if (!resolvedAsset.model) {
1128
1352
  errors.push("Gemini adapter requires a model to be specified.");
1129
1353
  }
@@ -1133,6 +1357,12 @@ var geminiAdapter = withPromptInputSupport({
1133
1357
  if (resolvedAsset.sampling?.presence_penalty !== void 0) {
1134
1358
  warnings.push("Gemini does not support presence_penalty. It will be ignored.");
1135
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
+ }
1136
1366
  return { valid: errors.length === 0, errors, warnings };
1137
1367
  },
1138
1368
  render(asset, runtime) {
@@ -1159,20 +1389,32 @@ var geminiAdapter = withPromptInputSupport({
1159
1389
  const body = {
1160
1390
  contents
1161
1391
  };
1392
+ const geminiCacheConfig = resolvedAsset.cache?.gemini ?? resolvedAsset.cache?.google;
1162
1393
  if (sections.system_instructions) {
1163
1394
  body.systemInstruction = {
1164
1395
  parts: [{ text: sections.system_instructions }]
1165
1396
  };
1166
1397
  }
1167
1398
  const generationConfig = {};
1399
+ const geminiOptions = resolvedAsset.provider_options?.gemini;
1168
1400
  if (resolvedAsset.sampling?.temperature !== void 0) generationConfig.temperature = resolvedAsset.sampling.temperature;
1169
1401
  if (resolvedAsset.sampling?.top_p !== void 0) generationConfig.topP = resolvedAsset.sampling.top_p;
1170
1402
  if (resolvedAsset.sampling?.max_output_tokens !== void 0) generationConfig.maxOutputTokens = resolvedAsset.sampling.max_output_tokens;
1171
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;
1172
1410
  if (resolvedAsset.response?.format === "json") {
1173
1411
  generationConfig.responseMimeType = "application/json";
1174
1412
  }
1175
- 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) {
1176
1418
  body.thinkingConfig = {
1177
1419
  thinkingBudget: resolvedAsset.reasoning.effort === "high" ? 8192 : resolvedAsset.reasoning.effort === "medium" ? 4096 : 1024
1178
1420
  };
@@ -1180,6 +1422,9 @@ var geminiAdapter = withPromptInputSupport({
1180
1422
  if (Object.keys(generationConfig).length > 0) {
1181
1423
  body.generationConfig = generationConfig;
1182
1424
  }
1425
+ if (geminiCacheConfig?.cached_content) {
1426
+ body.cachedContent = geminiCacheConfig.cached_content;
1427
+ }
1183
1428
  if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {
1184
1429
  const functionDeclarations = resolvedAsset.tools.map((tool) => {
1185
1430
  if (typeof tool === "string") {
@@ -1221,6 +1466,7 @@ var openrouterAdapter = withPromptInputSupport({
1221
1466
  // src/providers/index.ts
1222
1467
  var adapters = {
1223
1468
  openai: openaiAdapter,
1469
+ "openai-responses": openaiResponsesAdapter,
1224
1470
  anthropic: anthropicAdapter,
1225
1471
  google: geminiAdapter,
1226
1472
  gemini: geminiAdapter,
@@ -1275,7 +1521,8 @@ var KNOWN_FRONT_MATTER_KEYS = /* @__PURE__ */ new Set([
1275
1521
  "includes",
1276
1522
  "environments",
1277
1523
  "tiers",
1278
- "metadata"
1524
+ "metadata",
1525
+ "cache"
1279
1526
  ]);
1280
1527
  function validateAsset(asset, frontMatterKeys, filePath) {
1281
1528
  const errors = [];
@@ -1849,7 +2096,9 @@ var PromptOpsKit = class {
1849
2096
  throw new Error('Either "path" or "source" must be provided to renderPrompt()');
1850
2097
  }
1851
2098
  const adapter = getAdapter(options.provider);
1852
- const validation = adapter.validate(resolved);
2099
+ const validation = adapter.validate(resolved, {
2100
+ openaiResponses: options.openaiResponses
2101
+ });
1853
2102
  if (!validation.valid) {
1854
2103
  throw new Error(
1855
2104
  `Provider validation failed for "${options.provider}":
@@ -1879,7 +2128,8 @@ var PromptOpsKit = class {
1879
2128
  variables: sanitization.variables,
1880
2129
  history: options.history,
1881
2130
  toolRegistry: options.toolRegistry,
1882
- strict: options.strict
2131
+ strict: options.strict,
2132
+ openaiResponses: options.openaiResponses
1883
2133
  });
1884
2134
  return {
1885
2135
  resolved,
@@ -1936,6 +2186,7 @@ async function renderPrompt(options) {
1936
2186
  interpolate,
1937
2187
  loadPromptFile,
1938
2188
  openaiAdapter,
2189
+ openaiResponsesAdapter,
1939
2190
  openrouterAdapter,
1940
2191
  parsePrompt,
1941
2192
  renderPrompt,