promptopskit 0.2.5 → 0.3.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.
Files changed (39) hide show
  1. package/README.md +86 -2
  2. package/SKILL.md +33 -6
  3. package/dist/{chunk-CX6KVBW4.js → chunk-2LK6IILW.js} +10 -2
  4. package/dist/chunk-2LK6IILW.js.map +1 -0
  5. package/dist/chunk-HWEVRBKZ.js +387 -0
  6. package/dist/chunk-HWEVRBKZ.js.map +1 -0
  7. package/dist/cli/index.js +50 -22
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/index.cjs +483 -6
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +9 -4
  12. package/dist/index.d.ts +9 -4
  13. package/dist/index.js +105 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/providers/anthropic.d.cts +2 -2
  16. package/dist/providers/anthropic.d.ts +2 -2
  17. package/dist/providers/gemini.d.cts +2 -2
  18. package/dist/providers/gemini.d.ts +2 -2
  19. package/dist/providers/openai.d.cts +2 -2
  20. package/dist/providers/openai.d.ts +2 -2
  21. package/dist/providers/openrouter.d.cts +2 -2
  22. package/dist/providers/openrouter.d.ts +2 -2
  23. package/dist/{schema-C6smABrt.d.cts → schema-DIOA4OiO.d.cts} +53 -32
  24. package/dist/{schema-C6smABrt.d.ts → schema-DIOA4OiO.d.ts} +53 -32
  25. package/dist/testing.cjs +9 -1
  26. package/dist/testing.cjs.map +1 -1
  27. package/dist/testing.d.cts +1 -1
  28. package/dist/testing.d.ts +1 -1
  29. package/dist/testing.js +1 -1
  30. package/dist/{types-S_c-ZEfK.d.cts → types-1zDDD-Ij.d.cts} +1 -1
  31. package/dist/{types-D7lW5IYT.d.ts → types-CQhlfAnR.d.ts} +1 -1
  32. package/dist/usagetap/index.cjs +425 -0
  33. package/dist/usagetap/index.cjs.map +1 -0
  34. package/dist/usagetap/index.d.cts +147 -0
  35. package/dist/usagetap/index.d.ts +147 -0
  36. package/dist/usagetap/index.js +31 -0
  37. package/dist/usagetap/index.js.map +1 -0
  38. package/package.json +11 -1
  39. package/dist/chunk-CX6KVBW4.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -35,7 +35,15 @@ __export(src_exports, {
35
35
  PromptOpsKit: () => PromptOpsKit,
36
36
  anthropicAdapter: () => anthropicAdapter,
37
37
  applyOverrides: () => applyOverrides,
38
+ applyUsageTapEntitlements: () => applyUsageTapEntitlements,
39
+ beginUsageTapCall: () => beginUsageTapCall,
38
40
  createPromptOpsKit: () => createPromptOpsKit,
41
+ createUsageTapClient: () => createUsageTapClient,
42
+ defaultUsageTapErrorMapper: () => defaultUsageTapErrorMapper,
43
+ endUsageTapCall: () => endUsageTapCall,
44
+ extractAnthropicUsage: () => extractAnthropicUsage,
45
+ extractGeminiUsage: () => extractGeminiUsage,
46
+ extractOpenAIUsage: () => extractOpenAIUsage,
39
47
  extractSections: () => extractSections,
40
48
  extractVariables: () => extractVariables,
41
49
  geminiAdapter: () => geminiAdapter,
@@ -47,8 +55,13 @@ __export(src_exports, {
47
55
  parsePrompt: () => parsePrompt,
48
56
  renderPrompt: () => renderPrompt,
49
57
  resolveIncludes: () => resolveIncludes,
58
+ runAnthropicWithUsageTap: () => runAnthropicWithUsageTap,
59
+ runGeminiWithUsageTap: () => runGeminiWithUsageTap,
60
+ runOpenAIWithUsageTap: () => runOpenAIWithUsageTap,
61
+ runOpenRouterWithUsageTap: () => runOpenRouterWithUsageTap,
50
62
  validateAsset: () => validateAsset,
51
- validateAssetWithIncludes: () => validateAssetWithIncludes
63
+ validateAssetWithIncludes: () => validateAssetWithIncludes,
64
+ withUsageTapCall: () => withUsageTapCall
52
65
  });
53
66
  module.exports = __toCommonJS(src_exports);
54
67
  var import_promises3 = require("fs/promises");
@@ -92,8 +105,16 @@ var ResponseSchema = import_zod.z.object({
92
105
  var HistorySchema = import_zod.z.object({
93
106
  max_items: import_zod.z.number().int().positive().optional()
94
107
  });
108
+ var ContextInputDefinitionObjectSchema = import_zod.z.object({
109
+ name: import_zod.z.string(),
110
+ max_size: import_zod.z.number().int().positive().optional()
111
+ });
112
+ var ContextInputDefinitionSchema = import_zod.z.union([
113
+ import_zod.z.string(),
114
+ ContextInputDefinitionObjectSchema
115
+ ]);
95
116
  var ContextSchema = import_zod.z.object({
96
- inputs: import_zod.z.array(import_zod.z.string()).optional(),
117
+ inputs: import_zod.z.array(ContextInputDefinitionSchema).optional(),
97
118
  history: HistorySchema.optional()
98
119
  });
99
120
  var MetadataSchema = import_zod.z.object({
@@ -694,6 +715,48 @@ function getAdapter(provider) {
694
715
  return adapter;
695
716
  }
696
717
 
718
+ // src/context.ts
719
+ var textEncoder = new TextEncoder();
720
+ function getContextInputs(asset) {
721
+ return (asset.context?.inputs ?? []).map(normalizeContextInput);
722
+ }
723
+ function getContextInputNames(asset) {
724
+ return getContextInputs(asset).map((input) => input.name);
725
+ }
726
+ function normalizeContextInput(input) {
727
+ if (typeof input === "string") {
728
+ return { name: input };
729
+ }
730
+ return {
731
+ name: input.name,
732
+ max_size: input.max_size
733
+ };
734
+ }
735
+ function measureContextValueSize(value) {
736
+ return textEncoder.encode(value).length;
737
+ }
738
+ function collectContextSizeWarnings(asset, variables = {}) {
739
+ const warnings = [];
740
+ for (const input of getContextInputs(asset)) {
741
+ if (input.max_size === void 0) {
742
+ continue;
743
+ }
744
+ const value = variables[input.name];
745
+ if (value === void 0) {
746
+ continue;
747
+ }
748
+ const actualSize = measureContextValueSize(value);
749
+ if (actualSize > input.max_size) {
750
+ warnings.push({
751
+ variable: input.name,
752
+ maxSize: input.max_size,
753
+ actualSize
754
+ });
755
+ }
756
+ }
757
+ return warnings;
758
+ }
759
+
697
760
  // src/validation/levenshtein.ts
698
761
  function levenshtein(a, b) {
699
762
  const m = a.length;
@@ -775,7 +838,7 @@ function validateAsset(asset, frontMatterKeys, filePath) {
775
838
  }
776
839
  }
777
840
  }
778
- const declaredInputs = new Set(asset.context?.inputs ?? []);
841
+ const declaredInputs = new Set(getContextInputNames(asset));
779
842
  const usedVars = /* @__PURE__ */ new Set();
780
843
  if (asset.sections?.system_instructions) {
781
844
  for (const v of extractVariables(asset.sections.system_instructions)) {
@@ -884,7 +947,398 @@ var PromptCache = class {
884
947
  }
885
948
  };
886
949
 
950
+ // src/usagetap/client.ts
951
+ var DEFAULT_BASE_URL = "https://api.usagetap.com";
952
+ var ACCEPT_HEADER = "application/vnd.usagetap.v1+json";
953
+ function createUsageTapHttpError(status, body) {
954
+ const error = new Error(`UsageTap request failed with status ${status}`);
955
+ error.statusCode = status;
956
+ error.body = body;
957
+ return error;
958
+ }
959
+ function createUsageTapClient(config) {
960
+ const fetchImpl = config.fetch ?? globalThis.fetch;
961
+ if (!fetchImpl) {
962
+ throw new Error("Fetch API is not available. Provide config.fetch when creating the UsageTap client.");
963
+ }
964
+ const baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
965
+ async function request(path, body, init = {}) {
966
+ const response = await fetchImpl(`${baseUrl}${path}`, {
967
+ method: "POST",
968
+ headers: {
969
+ Authorization: `Bearer ${config.apiKey}`,
970
+ Accept: ACCEPT_HEADER,
971
+ "Content-Type": "application/json"
972
+ },
973
+ body: JSON.stringify(body),
974
+ signal: init.signal
975
+ });
976
+ const text = await response.text();
977
+ const parsed = text ? JSON.parse(text) : {};
978
+ if (!response.ok) {
979
+ throw createUsageTapHttpError(response.status, parsed);
980
+ }
981
+ return parsed;
982
+ }
983
+ return {
984
+ request,
985
+ beginCall(begin, init) {
986
+ return request("/call_begin", begin, init);
987
+ },
988
+ endCall(end, init) {
989
+ return request("/call_end", end, init);
990
+ }
991
+ };
992
+ }
993
+
994
+ // src/usagetap/lifecycle.ts
995
+ function isObject(value) {
996
+ return typeof value === "object" && value !== null;
997
+ }
998
+ function isInvokeResult(value) {
999
+ return isObject(value) && "result" in value && "usage" in value;
1000
+ }
1001
+ function getErrorStatusCode(error) {
1002
+ if (!isObject(error)) {
1003
+ return void 0;
1004
+ }
1005
+ if (typeof error.statusCode === "number") {
1006
+ return error.statusCode;
1007
+ }
1008
+ if (typeof error.status === "number") {
1009
+ return error.status;
1010
+ }
1011
+ if (isObject(error.response) && typeof error.response.status === "number") {
1012
+ return error.response.status;
1013
+ }
1014
+ return void 0;
1015
+ }
1016
+ function attachEndErrorCause(thrownError, endError) {
1017
+ if (thrownError instanceof Error) {
1018
+ if (thrownError.cause === void 0) {
1019
+ Object.defineProperty(thrownError, "cause", {
1020
+ value: endError,
1021
+ configurable: true,
1022
+ writable: true
1023
+ });
1024
+ }
1025
+ throw thrownError;
1026
+ }
1027
+ throw new AggregateError([thrownError, endError], "Vendor call failed and UsageTap call_end also failed.");
1028
+ }
1029
+ function defaultUsageTapErrorMapper(error) {
1030
+ return {
1031
+ code: "VENDOR_ERROR",
1032
+ message: String(error)
1033
+ };
1034
+ }
1035
+ function beginUsageTapCall(client, begin, init) {
1036
+ return client.beginCall(begin, init);
1037
+ }
1038
+ function endUsageTapCall(client, end, init) {
1039
+ return client.endCall(end, init);
1040
+ }
1041
+ async function withUsageTapCall(client, options) {
1042
+ const begin = await beginUsageTapCall(client, options.begin, { signal: options.signal });
1043
+ const onError = options.onError ?? defaultUsageTapErrorMapper;
1044
+ let result;
1045
+ let usage;
1046
+ let thrownError;
1047
+ const setUsage = (nextUsage) => {
1048
+ usage = { ...usage, ...nextUsage };
1049
+ };
1050
+ try {
1051
+ const invoked = await options.invoke({
1052
+ begin,
1053
+ setUsage,
1054
+ signal: options.signal
1055
+ });
1056
+ if (isInvokeResult(invoked)) {
1057
+ result = invoked.result;
1058
+ setUsage(invoked.usage);
1059
+ } else {
1060
+ result = invoked;
1061
+ }
1062
+ } catch (error) {
1063
+ thrownError = error;
1064
+ }
1065
+ const effectiveUsage = {
1066
+ ...usage
1067
+ };
1068
+ if (thrownError) {
1069
+ effectiveUsage.error = effectiveUsage.error ?? onError(thrownError);
1070
+ effectiveUsage.responseStatusCode = effectiveUsage.responseStatusCode ?? getErrorStatusCode(thrownError);
1071
+ } else {
1072
+ effectiveUsage.responseStatusCode = effectiveUsage.responseStatusCode ?? 200;
1073
+ }
1074
+ let end;
1075
+ try {
1076
+ end = await endUsageTapCall(client, {
1077
+ callId: begin.data.callId,
1078
+ ...effectiveUsage
1079
+ }, { signal: options.signal });
1080
+ } catch (endError) {
1081
+ if (thrownError) {
1082
+ attachEndErrorCause(thrownError, endError);
1083
+ }
1084
+ throw endError;
1085
+ }
1086
+ if (thrownError) {
1087
+ throw thrownError;
1088
+ }
1089
+ return {
1090
+ result,
1091
+ begin,
1092
+ end,
1093
+ effectiveUsage
1094
+ };
1095
+ }
1096
+
1097
+ // src/usagetap/providers.ts
1098
+ function cloneRequest(request) {
1099
+ return structuredClone(request);
1100
+ }
1101
+ function isObject2(value) {
1102
+ return typeof value === "object" && value !== null;
1103
+ }
1104
+ function isRecordArray(value) {
1105
+ return Array.isArray(value) && value.every((item) => isObject2(item));
1106
+ }
1107
+ function isInvokeResult2(value) {
1108
+ return isObject2(value) && "result" in value && "usage" in value;
1109
+ }
1110
+ function capabilityAllowed(allowed, capability) {
1111
+ return allowed[capability] !== false;
1112
+ }
1113
+ function reasoningLevelOrder(level) {
1114
+ switch (level) {
1115
+ case "HIGH":
1116
+ return 3;
1117
+ case "MEDIUM":
1118
+ return 2;
1119
+ case "LOW":
1120
+ return 1;
1121
+ default:
1122
+ return 0;
1123
+ }
1124
+ }
1125
+ function capOpenAIReasoning(body, allowed) {
1126
+ if (typeof body.reasoning_effort !== "string") {
1127
+ return;
1128
+ }
1129
+ const current = String(body.reasoning_effort).toUpperCase();
1130
+ const allowedLevel = allowed.reasoningLevel ?? "HIGH";
1131
+ if (allowedLevel === "NONE") {
1132
+ delete body.reasoning_effort;
1133
+ return;
1134
+ }
1135
+ if (reasoningLevelOrder(current) > reasoningLevelOrder(allowedLevel)) {
1136
+ body.reasoning_effort = allowedLevel.toLowerCase();
1137
+ }
1138
+ }
1139
+ function capGeminiReasoning(body, allowed) {
1140
+ if (allowed.reasoningLevel === "NONE") {
1141
+ delete body.thinkingConfig;
1142
+ return;
1143
+ }
1144
+ const budgets = {
1145
+ LOW: 1024,
1146
+ MEDIUM: 4096,
1147
+ HIGH: 8192
1148
+ };
1149
+ const allowedBudget = allowed.reasoningLevel ? budgets[allowed.reasoningLevel] : void 0;
1150
+ if (allowedBudget === void 0) {
1151
+ return;
1152
+ }
1153
+ if (!isObject2(body.thinkingConfig)) {
1154
+ body.thinkingConfig = { thinkingBudget: allowedBudget };
1155
+ return;
1156
+ }
1157
+ const thinkingConfig = body.thinkingConfig;
1158
+ if (typeof thinkingConfig.thinkingBudget === "number") {
1159
+ thinkingConfig.thinkingBudget = Math.min(thinkingConfig.thinkingBudget, allowedBudget);
1160
+ return;
1161
+ }
1162
+ thinkingConfig.thinkingBudget = allowedBudget;
1163
+ }
1164
+ function applyModelTier(request, allowed, options) {
1165
+ const nextModel = allowed.premium && options.modelTiers?.premium ? options.modelTiers.premium : allowed.standard && options.modelTiers?.standard ? options.modelTiers.standard : void 0;
1166
+ if (!nextModel) {
1167
+ return;
1168
+ }
1169
+ request.model = nextModel;
1170
+ if (isObject2(request.body) && "model" in request.body) {
1171
+ request.body.model = nextModel;
1172
+ }
1173
+ }
1174
+ function filterOpenAITools(tools, allowed, options) {
1175
+ return tools.filter((tool) => {
1176
+ if (tool.type === "web_search" && allowed.search === false) {
1177
+ return false;
1178
+ }
1179
+ const functionDef = isObject2(tool.function) ? tool.function : void 0;
1180
+ const name = typeof functionDef?.name === "string" ? functionDef.name : typeof tool.name === "string" ? tool.name : typeof tool.type === "string" ? tool.type : void 0;
1181
+ if (!name) {
1182
+ return true;
1183
+ }
1184
+ const capability = options.toolEntitlements?.[name];
1185
+ return capability ? capabilityAllowed(allowed, capability) : true;
1186
+ });
1187
+ }
1188
+ function filterAnthropicTools(tools, allowed, options) {
1189
+ return tools.filter((tool) => {
1190
+ const name = typeof tool.name === "string" ? tool.name : void 0;
1191
+ if (!name) {
1192
+ return true;
1193
+ }
1194
+ const capability = options.toolEntitlements?.[name];
1195
+ return capability ? capabilityAllowed(allowed, capability) : true;
1196
+ });
1197
+ }
1198
+ function filterGeminiTools(tools, allowed, options) {
1199
+ return tools.map((tool) => {
1200
+ const declarations = Array.isArray(tool.functionDeclarations) ? tool.functionDeclarations.filter((declaration) => {
1201
+ if (!isObject2(declaration) || typeof declaration.name !== "string") {
1202
+ return true;
1203
+ }
1204
+ const capability = options.toolEntitlements?.[declaration.name];
1205
+ return capability ? capabilityAllowed(allowed, capability) : true;
1206
+ }) : tool.functionDeclarations;
1207
+ return {
1208
+ ...tool,
1209
+ functionDeclarations: declarations
1210
+ };
1211
+ }).filter((tool) => {
1212
+ if (!Array.isArray(tool.functionDeclarations)) {
1213
+ return true;
1214
+ }
1215
+ return tool.functionDeclarations.length > 0;
1216
+ });
1217
+ }
1218
+ function applyUsageTapEntitlements(request, begin, options = {}) {
1219
+ const nextRequest = cloneRequest(request);
1220
+ const allowed = begin.data.allowed ?? {};
1221
+ applyModelTier(nextRequest, allowed, options);
1222
+ if (!isObject2(nextRequest.body)) {
1223
+ return nextRequest;
1224
+ }
1225
+ if (nextRequest.provider === "openai" || nextRequest.provider === "openrouter") {
1226
+ capOpenAIReasoning(nextRequest.body, allowed);
1227
+ if (isRecordArray(nextRequest.body.tools)) {
1228
+ nextRequest.body.tools = filterOpenAITools(nextRequest.body.tools, allowed, options);
1229
+ }
1230
+ return nextRequest;
1231
+ }
1232
+ if (nextRequest.provider === "gemini") {
1233
+ capGeminiReasoning(nextRequest.body, allowed);
1234
+ if (isRecordArray(nextRequest.body.tools)) {
1235
+ nextRequest.body.tools = filterGeminiTools(nextRequest.body.tools, allowed, options);
1236
+ }
1237
+ return nextRequest;
1238
+ }
1239
+ if (nextRequest.provider === "anthropic" && isRecordArray(nextRequest.body.tools)) {
1240
+ nextRequest.body.tools = filterAnthropicTools(nextRequest.body.tools, allowed, options);
1241
+ }
1242
+ return nextRequest;
1243
+ }
1244
+ function extractOpenAIUsage(response, meta = {}) {
1245
+ const usage = isObject2(response) && isObject2(response.usage) ? response.usage : {};
1246
+ const promptDetails = isObject2(usage.prompt_tokens_details) ? usage.prompt_tokens_details : {};
1247
+ const completionDetails = isObject2(usage.completion_tokens_details) ? usage.completion_tokens_details : {};
1248
+ return {
1249
+ modelUsed: meta.modelUsed,
1250
+ inputTokens: typeof usage.prompt_tokens === "number" ? usage.prompt_tokens : 0,
1251
+ responseTokens: typeof usage.completion_tokens === "number" ? usage.completion_tokens : 0,
1252
+ cachedInputTokens: typeof promptDetails.cached_tokens === "number" ? promptDetails.cached_tokens : void 0,
1253
+ reasoningTokens: typeof completionDetails.reasoning_tokens === "number" ? completionDetails.reasoning_tokens : void 0,
1254
+ responseStatusCode: meta.responseStatusCode ?? 200
1255
+ };
1256
+ }
1257
+ function extractAnthropicUsage(response, meta = {}) {
1258
+ const usage = isObject2(response) && isObject2(response.usage) ? response.usage : {};
1259
+ return {
1260
+ modelUsed: meta.modelUsed,
1261
+ inputTokens: typeof usage.input_tokens === "number" ? usage.input_tokens : 0,
1262
+ responseTokens: typeof usage.output_tokens === "number" ? usage.output_tokens : 0,
1263
+ cachedInputTokens: typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : void 0,
1264
+ responseStatusCode: meta.responseStatusCode ?? 200
1265
+ };
1266
+ }
1267
+ function extractGeminiUsage(response, meta = {}) {
1268
+ const usage = isObject2(response) && isObject2(response.usageMetadata) ? response.usageMetadata : {};
1269
+ return {
1270
+ modelUsed: meta.modelUsed,
1271
+ inputTokens: typeof usage.promptTokenCount === "number" ? usage.promptTokenCount : 0,
1272
+ responseTokens: typeof usage.candidatesTokenCount === "number" ? usage.candidatesTokenCount : 0,
1273
+ cachedInputTokens: typeof usage.cachedContentTokenCount === "number" ? usage.cachedContentTokenCount : void 0,
1274
+ reasoningTokens: typeof usage.thoughtsTokenCount === "number" ? usage.thoughtsTokenCount : void 0,
1275
+ responseStatusCode: meta.responseStatusCode ?? 200
1276
+ };
1277
+ }
1278
+ async function runProviderWithUsageTap(client, options, defaultExtractor) {
1279
+ let requestUsed = cloneRequest(options.request);
1280
+ const lifecycle = await withUsageTapCall(client, {
1281
+ begin: options.begin,
1282
+ signal: options.signal,
1283
+ onError: options.onError ?? defaultUsageTapErrorMapper,
1284
+ invoke: async ({ begin, setUsage }) => {
1285
+ requestUsed = options.entitlementMode === "apply" ? applyUsageTapEntitlements(options.request, begin, options) : cloneRequest(options.request);
1286
+ const invoked = await options.invoke(requestUsed);
1287
+ if (isInvokeResult2(invoked)) {
1288
+ return invoked;
1289
+ }
1290
+ const response = invoked;
1291
+ const usage = (options.extractUsage ?? defaultExtractor)(response, {
1292
+ modelUsed: requestUsed.model,
1293
+ responseStatusCode: 200
1294
+ });
1295
+ setUsage(usage);
1296
+ return response;
1297
+ }
1298
+ });
1299
+ return {
1300
+ response: lifecycle.result,
1301
+ begin: lifecycle.begin,
1302
+ end: lifecycle.end,
1303
+ requestUsed,
1304
+ effectiveUsage: lifecycle.effectiveUsage,
1305
+ allowed: lifecycle.begin.data.allowed ?? {}
1306
+ };
1307
+ }
1308
+ function runOpenAIWithUsageTap(client, options) {
1309
+ return runProviderWithUsageTap(client, options, extractOpenAIUsage);
1310
+ }
1311
+ function runOpenRouterWithUsageTap(client, options) {
1312
+ return runProviderWithUsageTap(client, options, extractOpenAIUsage);
1313
+ }
1314
+ function runAnthropicWithUsageTap(client, options) {
1315
+ return runProviderWithUsageTap(client, options, extractAnthropicUsage);
1316
+ }
1317
+ function runGeminiWithUsageTap(client, options) {
1318
+ return runProviderWithUsageTap(client, options, extractGeminiUsage);
1319
+ }
1320
+
887
1321
  // src/index.ts
1322
+ function shouldIncludeContextWarningsInResult(policy) {
1323
+ return policy === void 0 || policy === "auto" || policy === "result-only" || policy === "console-and-result";
1324
+ }
1325
+ function shouldLogContextWarnings(policy, options, mode) {
1326
+ if (policy === "off" || policy === "result-only") {
1327
+ return false;
1328
+ }
1329
+ if (policy === "console" || policy === "console-and-result") {
1330
+ return true;
1331
+ }
1332
+ return Boolean(options.source || mode !== "compiled-only");
1333
+ }
1334
+ function formatContextSizeWarning(asset, warning) {
1335
+ return [
1336
+ "POK030:",
1337
+ `Context variable "${warning.variable}" exceeded max_size`,
1338
+ `for prompt "${asset.id}"`,
1339
+ `(${warning.actualSize} bytes > ${warning.maxSize} bytes).`
1340
+ ].join(" ");
1341
+ }
888
1342
  var PromptOpsKit = class {
889
1343
  config;
890
1344
  promptCache;
@@ -995,6 +1449,15 @@ ${paths.map((p) => ` - ${p}`).join("\n")}`
995
1449
  ` + validation.errors.map((e) => ` - ${e}`).join("\n")
996
1450
  );
997
1451
  }
1452
+ const contextSizeWarnings = collectContextSizeWarnings(resolved, options.variables).map(
1453
+ (warning) => formatContextSizeWarning(resolved, warning)
1454
+ );
1455
+ const contextWarningPolicy = this.config.warnings?.contextSize;
1456
+ if (contextSizeWarnings.length > 0 && shouldLogContextWarnings(contextWarningPolicy, options, this.config.mode)) {
1457
+ for (const warning of contextSizeWarnings) {
1458
+ console.warn(`[promptopskit] Warning: ${warning}`);
1459
+ }
1460
+ }
998
1461
  const request = adapter.render(resolved, {
999
1462
  variables: options.variables,
1000
1463
  history: options.history,
@@ -1004,7 +1467,7 @@ ${paths.map((p) => ` - ${p}`).join("\n")}`
1004
1467
  return {
1005
1468
  resolved,
1006
1469
  request,
1007
- warnings: validation.warnings
1470
+ warnings: shouldIncludeContextWarningsInResult(contextWarningPolicy) ? [...validation.warnings, ...contextSizeWarnings] : validation.warnings
1008
1471
  };
1009
1472
  }
1010
1473
  /**
@@ -1027,7 +1490,8 @@ function createPromptOpsKit(config) {
1027
1490
  async function renderPrompt(options) {
1028
1491
  const kit = createPromptOpsKit({
1029
1492
  sourceDir: options.sourceDir ?? ".",
1030
- cache: false
1493
+ cache: false,
1494
+ warnings: options.warnings
1031
1495
  });
1032
1496
  return kit.renderPrompt(options);
1033
1497
  }
@@ -1038,7 +1502,15 @@ async function renderPrompt(options) {
1038
1502
  PromptOpsKit,
1039
1503
  anthropicAdapter,
1040
1504
  applyOverrides,
1505
+ applyUsageTapEntitlements,
1506
+ beginUsageTapCall,
1041
1507
  createPromptOpsKit,
1508
+ createUsageTapClient,
1509
+ defaultUsageTapErrorMapper,
1510
+ endUsageTapCall,
1511
+ extractAnthropicUsage,
1512
+ extractGeminiUsage,
1513
+ extractOpenAIUsage,
1042
1514
  extractSections,
1043
1515
  extractVariables,
1044
1516
  geminiAdapter,
@@ -1050,7 +1522,12 @@ async function renderPrompt(options) {
1050
1522
  parsePrompt,
1051
1523
  renderPrompt,
1052
1524
  resolveIncludes,
1525
+ runAnthropicWithUsageTap,
1526
+ runGeminiWithUsageTap,
1527
+ runOpenAIWithUsageTap,
1528
+ runOpenRouterWithUsageTap,
1053
1529
  validateAsset,
1054
- validateAssetWithIncludes
1530
+ validateAssetWithIncludes,
1531
+ withUsageTapCall
1055
1532
  });
1056
1533
  //# sourceMappingURL=index.cjs.map