promptopskit 0.9.1 → 0.10.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 (66) hide show
  1. package/README.md +9 -7
  2. package/SKILL.md +5 -4
  3. package/dist/{chunk-QZHR2YMK.js → chunk-46Z64RVO.js} +61 -21
  4. package/dist/{chunk-QZHR2YMK.js.map → chunk-46Z64RVO.js.map} +1 -1
  5. package/dist/{chunk-EDHPVR2F.js → chunk-7XLJOH2K.js} +3 -3
  6. package/dist/{chunk-VOXMOGU5.js → chunk-ALBSFXYR.js} +2 -1
  7. package/dist/chunk-ALBSFXYR.js.map +1 -0
  8. package/dist/{chunk-C5HHTLZX.js → chunk-IGLKVT74.js} +2 -2
  9. package/dist/{chunk-7GMCNHXJ.js → chunk-PSQWMBKX.js} +21 -21
  10. package/dist/chunk-PSQWMBKX.js.map +1 -0
  11. package/dist/{chunk-O3SRIDTH.js → chunk-QVJTND5A.js} +2 -2
  12. package/dist/{chunk-QHAIOVQ3.js → chunk-UULXO5I6.js} +2 -2
  13. package/dist/{chunk-D23T3X4V.js → chunk-VUQEB5ML.js} +2 -2
  14. package/dist/cli/index.js +1 -0
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/index.cjs +81 -39
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +5 -3
  19. package/dist/index.d.ts +5 -3
  20. package/dist/index.js +11 -11
  21. package/dist/index.js.map +1 -1
  22. package/dist/providers/anthropic.cjs +60 -19
  23. package/dist/providers/anthropic.cjs.map +1 -1
  24. package/dist/providers/anthropic.d.cts +1 -1
  25. package/dist/providers/anthropic.d.ts +1 -1
  26. package/dist/providers/anthropic.js +3 -3
  27. package/dist/providers/gemini.cjs +60 -19
  28. package/dist/providers/gemini.cjs.map +1 -1
  29. package/dist/providers/gemini.d.cts +1 -1
  30. package/dist/providers/gemini.d.ts +1 -1
  31. package/dist/providers/gemini.js +3 -3
  32. package/dist/providers/llmasaservice.cjs +78 -38
  33. package/dist/providers/llmasaservice.cjs.map +1 -1
  34. package/dist/providers/llmasaservice.d.cts +6 -5
  35. package/dist/providers/llmasaservice.d.ts +6 -5
  36. package/dist/providers/llmasaservice.js +4 -6
  37. package/dist/providers/openai-responses.cjs +60 -19
  38. package/dist/providers/openai-responses.cjs.map +1 -1
  39. package/dist/providers/openai-responses.d.cts +1 -1
  40. package/dist/providers/openai-responses.d.ts +1 -1
  41. package/dist/providers/openai-responses.js +3 -3
  42. package/dist/providers/openai.cjs +60 -19
  43. package/dist/providers/openai.cjs.map +1 -1
  44. package/dist/providers/openai.d.cts +1 -1
  45. package/dist/providers/openai.d.ts +1 -1
  46. package/dist/providers/openai.js +3 -3
  47. package/dist/providers/openrouter.cjs +60 -19
  48. package/dist/providers/openrouter.cjs.map +1 -1
  49. package/dist/providers/openrouter.d.cts +1 -1
  50. package/dist/providers/openrouter.d.ts +1 -1
  51. package/dist/providers/openrouter.js +4 -4
  52. package/dist/testing.cjs +1 -0
  53. package/dist/testing.cjs.map +1 -1
  54. package/dist/testing.js +1 -1
  55. package/dist/{types-D6VJJo1x.d.ts → types-9Jv8eHhM.d.ts} +8 -1
  56. package/dist/{types-B4TWRzUY.d.cts → types-D3MemVmM.d.cts} +8 -1
  57. package/dist/usagetap/index.d.cts +1 -1
  58. package/dist/usagetap/index.d.ts +1 -1
  59. package/package.json +1 -1
  60. package/dist/chunk-7GMCNHXJ.js.map +0 -1
  61. package/dist/chunk-VOXMOGU5.js.map +0 -1
  62. /package/dist/{chunk-EDHPVR2F.js.map → chunk-7XLJOH2K.js.map} +0 -0
  63. /package/dist/{chunk-C5HHTLZX.js.map → chunk-IGLKVT74.js.map} +0 -0
  64. /package/dist/{chunk-O3SRIDTH.js.map → chunk-QVJTND5A.js.map} +0 -0
  65. /package/dist/{chunk-QHAIOVQ3.js.map → chunk-UULXO5I6.js.map} +0 -0
  66. /package/dist/{chunk-D23T3X4V.js.map → chunk-VUQEB5ML.js.map} +0 -0
package/README.md CHANGED
@@ -219,14 +219,16 @@ result = await kit.renderPrompt({
219
219
  });
220
220
  if (!result.request) throw new Error(result.returnMessage ?? 'Prompt rendering failed.');
221
221
 
222
- // LLMAsAService — OpenAI-compatible gateway with project and customer metadata
222
+ // LLMAsAService — OpenAI-compatible gateway with bearer auth and customer metadata
223
223
  result = await kit.renderPrompt({
224
224
  path: 'hello',
225
225
  provider: 'llmasaservice',
226
+ llmasaservice: {
227
+ apiKey: process.env.LLM_GATEWAY_API_KEY!,
228
+ },
226
229
  runtime: {
227
230
  provider_options: {
228
231
  llmasaservice: {
229
- project_id: process.env.LLM_GATEWAY_PROJECT_ID,
230
232
  customer: { customer_id: 'cust_123', customer_name: 'Acme' },
231
233
  },
232
234
  },
@@ -235,7 +237,7 @@ result = await kit.renderPrompt({
235
237
  });
236
238
  if (!result.request) throw new Error(result.returnMessage ?? 'Prompt rendering failed.');
237
239
  // result.request.body → { model, messages, customer, ... }
238
- // result.request.headers → { 'x-project-id': '...' }
240
+ // result.request.headers → { Authorization: 'Bearer ...' }
239
241
  ```
240
242
 
241
243
  Provider adapters are also available as direct imports:
@@ -292,7 +294,7 @@ cache:
292
294
  retention: 24h
293
295
  ```
294
296
 
295
- At render time, pass the caller-owned API key. PromptOpsKit calls `POST https://api.thetokencompany.com/v1/compress` directly with `fetch`; no TheTokenCompany SDK is required.
297
+ At render time, pass the caller-owned API key. PromptOpsKit calls `POST https://api.thetokencompany.com/v1/compress` directly with `fetch`; no TheTokenCompany SDK is required. If credentials are unavailable or the backend call fails, PromptOpsKit preserves the original prompt text, returns a `POK057` warning in `warnings`, and reports zero token savings with matching input/output token counts. Library rendering does not log this fallback to the console.
296
298
 
297
299
  ```typescript
298
300
  const result = await kit.renderPrompt({
@@ -341,7 +343,7 @@ TOON preprocessing uses a local encode-only implementation inspired by the MIT-l
341
343
 
342
344
  See [Compression and Compaction](./docs/compression.md) for complete examples and token-savings reporting.
343
345
 
344
- Use `provider_options` when PromptOpsKit has a known provider-specific mapping, such as Anthropic `top_k`, Gemini's native `response_schema`, OpenRouter routing fields, or LLMAsAService gateway routing/customer metadata.
346
+ Use `provider_options` when PromptOpsKit has a known provider-specific mapping, such as Anthropic `top_k`, Gemini's native `response_schema`, OpenRouter routing fields, or LLMAsAService customer/conversation metadata.
345
347
 
346
348
  ```yaml
347
349
  response:
@@ -359,14 +361,13 @@ provider_options:
359
361
  order: ["anthropic", "openai"]
360
362
  transforms: ["middle-out"]
361
363
  llmasaservice:
362
- project_id: "llm-project-id"
363
364
  # Optional default; usually pass the real customer at render time.
364
365
  customer:
365
366
  customer_id: "cust_123"
366
367
  customer_name: "Acme"
367
368
  ```
368
369
 
369
- For LLMAsAService, `provider_options.llmasaservice.customer` is intended to be render-time attribution for the current account/user. A prompt can keep a default, but production calls should normally override it through `runtime.provider_options.llmasaservice.customer`.
370
+ For LLMAsAService, pass the gateway credential through the render-time `llmasaservice.apiKey` option; the adapter emits it as an `Authorization: Bearer ...` header. `provider_options.llmasaservice.customer` is intended to be render-time attribution for the current account/user. A prompt can keep a default, but production calls should normally override it through `runtime.provider_options.llmasaservice.customer`. A project id is no longer required.
370
371
 
371
372
  When a provider adds a body field PromptOpsKit does not model yet, use `raw`:
372
373
 
@@ -689,6 +690,7 @@ Renders a prompt for a specific provider. Returns `{ resolved, request?, returnM
689
690
  | `toolRegistry` | `Record<string, unknown>` | Tool definitions for resolving string tool references |
690
691
  | `strict` | `boolean` | Fail on missing variables except object-form inputs marked `optional: true` |
691
692
  | `openaiResponses` | `object` | Optional Responses API extras (`previous_response_id`, `conversation`, `instructions`, `parallel_tool_calls`, `max_tool_calls`, `store`, `metadata`, `include`, `background`) |
693
+ | `llmasaservice` | `object` | Required LLMAsAService gateway credentials (`apiKey`) when using that provider |
692
694
  | `theTokenCompany` | `object` | Optional compression settings (`apiKey`, `baseURL`, `fetch`) used when `compression.thetokencompany.enabled: true` |
693
695
 
694
696
  Use `compressionSummary.tokensSaved` for a lightweight operation-level aggregate across compression and compaction steps. Use `compression` for the detailed per-step breakdown.
package/SKILL.md CHANGED
@@ -269,8 +269,8 @@ import {
269
269
  } from 'promptopskit/llmasaservice';
270
270
 
271
271
  const client = new OpenAI(createLLMAsAServiceOpenAIConfig({
272
+ apiKey: process.env.LLM_GATEWAY_API_KEY!,
272
273
  baseURL: process.env.LLM_GATEWAY_BASE_URL,
273
- projectId: process.env.LLM_GATEWAY_PROJECT_ID,
274
274
  }));
275
275
 
276
276
  const result = await llmasaserviceAdapter.renderPrompt(
@@ -278,10 +278,12 @@ const result = await llmasaserviceAdapter.renderPrompt(
278
278
  path: 'support/triage-summary',
279
279
  },
280
280
  {
281
+ llmasaservice: {
282
+ apiKey: process.env.LLM_GATEWAY_API_KEY!,
283
+ },
281
284
  runtime: {
282
285
  provider_options: {
283
286
  llmasaservice: {
284
- project_id: process.env.LLM_GATEWAY_PROJECT_ID,
285
287
  customer: {
286
288
  customer_id: customer.id,
287
289
  customer_name: customer.name,
@@ -772,14 +774,13 @@ provider_options:
772
774
  order: ["anthropic", "openai"]
773
775
  transforms: ["middle-out"]
774
776
  llmasaservice:
775
- project_id: llm-project-id
776
777
  # Optional default; usually pass the real customer at render time.
777
778
  customer:
778
779
  customer_id: cust_123
779
780
  customer_name: Acme
780
781
  ```
781
782
 
782
- For LLMAsAService, prefer putting the current customer/account/user attribution in `runtime.provider_options.llmasaservice.customer` during rendering. Static prompt metadata may include a default, but runtime values should override it for real requests.
783
+ For LLMAsAService, pass the server-owned gateway credential through `llmasaservice.apiKey`; the adapter emits `Authorization: Bearer <api-key>`. Prefer putting the current customer/account/user attribution in `runtime.provider_options.llmasaservice.customer` during rendering. Static prompt metadata may include a default, but runtime values should override it for real requests. Do not require or generate a project id.
783
784
 
784
785
  Use `raw` only when a vendor request-body field is important and PromptOpsKit does not model it yet:
785
786
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadPromptFile,
3
3
  parsePrompt
4
- } from "./chunk-VOXMOGU5.js";
4
+ } from "./chunk-ALBSFXYR.js";
5
5
 
6
6
  // src/renderer/interpolate.ts
7
7
  var VARIABLE_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)(?:\s*\|\s*(compress|toon|compact|code))?\s*\}\}/g;
@@ -1632,6 +1632,7 @@ async function applyPromptCompressionForRender(asset, runtime) {
1632
1632
  aggressiveness: theTokenCompanyConfig?.aggressiveness
1633
1633
  });
1634
1634
  promptTemplate = result.output;
1635
+ warnings.push(...result.warnings ?? []);
1635
1636
  compression.push({
1636
1637
  provider: "thetokencompany",
1637
1638
  model,
@@ -1697,41 +1698,80 @@ function reportHeuristicCompressionWarnings2(warnings, compressionWarnings, scop
1697
1698
  async function compressWithTheTokenCompany(input, options) {
1698
1699
  const apiKey = options.apiKey ?? getEnv("THETOKENCOMPANY_API_KEY") ?? getEnv("TTC_API_KEY");
1699
1700
  if (!apiKey) {
1700
- throw new Error(
1701
- "TheTokenCompany compression is enabled, but no API key was provided. Pass theTokenCompany.apiKey to renderPrompt() or set THETOKENCOMPANY_API_KEY."
1701
+ return createTheTokenCompanyFallback(
1702
+ input,
1703
+ "no API key was provided"
1702
1704
  );
1703
1705
  }
1704
1706
  const fetchImpl = options.fetch ?? globalThis.fetch;
1705
1707
  if (!fetchImpl) {
1706
- throw new Error("TheTokenCompany compression requires a runtime with fetch support.");
1708
+ return createTheTokenCompanyFallback(
1709
+ input,
1710
+ "fetch is unavailable in this runtime"
1711
+ );
1707
1712
  }
1708
1713
  const baseURL = (options.baseURL ?? THETOKENCOMPANY_DEFAULT_BASE_URL).replace(/\/+$/, "");
1709
1714
  const compressionSettings = options.aggressiveness === void 0 ? void 0 : { aggressiveness: options.aggressiveness };
1710
- const response = await fetchImpl(`${baseURL}/v1/compress`, {
1711
- method: "POST",
1712
- headers: {
1713
- Authorization: `Bearer ${apiKey}`,
1714
- "Content-Type": "application/json"
1715
- },
1716
- body: JSON.stringify({
1717
- model: options.model,
1715
+ let response;
1716
+ try {
1717
+ response = await fetchImpl(`${baseURL}/v1/compress`, {
1718
+ method: "POST",
1719
+ headers: {
1720
+ Authorization: `Bearer ${apiKey}`,
1721
+ "Content-Type": "application/json"
1722
+ },
1723
+ body: JSON.stringify({
1724
+ model: options.model,
1725
+ input,
1726
+ ...compressionSettings ? { compression_settings: compressionSettings } : {}
1727
+ })
1728
+ });
1729
+ } catch (error) {
1730
+ return createTheTokenCompanyFallback(
1718
1731
  input,
1719
- ...compressionSettings ? { compression_settings: compressionSettings } : {}
1720
- })
1721
- });
1732
+ `request failed: ${toErrorMessage(error)}`
1733
+ );
1734
+ }
1722
1735
  if (!response.ok) {
1723
- const body = await response.text().catch(() => "");
1724
- throw new Error(
1725
- `TheTokenCompany compression failed with HTTP ${response.status}` + (body ? `: ${body}` : ".")
1736
+ return createTheTokenCompanyFallback(
1737
+ input,
1738
+ `service returned HTTP ${response.status}`
1739
+ );
1740
+ }
1741
+ let data;
1742
+ try {
1743
+ data = await response.json();
1744
+ } catch (error) {
1745
+ return createTheTokenCompanyFallback(
1746
+ input,
1747
+ `response body was not valid JSON: ${toErrorMessage(error)}`
1726
1748
  );
1727
1749
  }
1728
- const data = await response.json();
1729
1750
  const normalized = normalizeTheTokenCompanyCompressResponse(data);
1730
1751
  if (!normalized) {
1731
- throw new Error("TheTokenCompany compression returned an invalid response payload.");
1752
+ return createTheTokenCompanyFallback(
1753
+ input,
1754
+ "response payload was invalid"
1755
+ );
1732
1756
  }
1733
1757
  return normalized;
1734
1758
  }
1759
+ function createTheTokenCompanyFallback(input, reason) {
1760
+ const tokens = estimateHeuristicTokens(input);
1761
+ return {
1762
+ output: input,
1763
+ output_tokens: tokens,
1764
+ input_tokens: tokens,
1765
+ tokens_saved: 0,
1766
+ compression_ratio: tokens === 0 ? 0 : 1,
1767
+ warnings: [
1768
+ `POK057: TheTokenCompany compression skipped; using uncompressed prompt with zero token savings (${reason}).`
1769
+ ]
1770
+ };
1771
+ }
1772
+ function toErrorMessage(error) {
1773
+ return error instanceof Error && error.message ? error.message : "unknown error";
1774
+ }
1735
1775
  function normalizeTheTokenCompanyCompressResponse(data) {
1736
1776
  if (typeof data.output !== "string" || typeof data.output_tokens !== "number") {
1737
1777
  return void 0;
@@ -1857,4 +1897,4 @@ export {
1857
1897
  withPromptInputSupport,
1858
1898
  applyRawProviderBody
1859
1899
  };
1860
- //# sourceMappingURL=chunk-QZHR2YMK.js.map
1900
+ //# sourceMappingURL=chunk-46Z64RVO.js.map