promptopskit 0.4.2 → 0.5.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 (82) hide show
  1. package/README.md +98 -57
  2. package/SKILL.md +360 -6
  3. package/dist/chunk-6BOUQVSX.js +130 -0
  4. package/dist/chunk-6BOUQVSX.js.map +1 -0
  5. package/dist/{chunk-7MRMN3SW.js → chunk-6VLKZCNS.js} +6 -4
  6. package/dist/chunk-6VLKZCNS.js.map +1 -0
  7. package/dist/{chunk-HWEVRBKZ.js → chunk-AGTGIZMR.js} +6 -2
  8. package/dist/chunk-AGTGIZMR.js.map +1 -0
  9. package/dist/{chunk-XL76NHZR.js → chunk-D75HKF64.js} +6 -4
  10. package/dist/chunk-D75HKF64.js.map +1 -0
  11. package/dist/{chunk-5AAYDOPU.js → chunk-IN4KT5EU.js} +4 -3
  12. package/dist/chunk-IN4KT5EU.js.map +1 -0
  13. package/dist/{chunk-JKBWC5WJ.js → chunk-K6ZU3CGV.js} +22 -5
  14. package/dist/chunk-K6ZU3CGV.js.map +1 -0
  15. package/dist/{chunk-YI4LILPY.js → chunk-KN7H4JRK.js} +61 -4
  16. package/dist/chunk-KN7H4JRK.js.map +1 -0
  17. package/dist/{chunk-Z4IPWEUU.js → chunk-LNGHGGJN.js} +6 -4
  18. package/dist/chunk-LNGHGGJN.js.map +1 -0
  19. package/dist/{chunk-MI3M6KDD.js → chunk-QK3WKE3K.js} +6 -4
  20. package/dist/chunk-QK3WKE3K.js.map +1 -0
  21. package/dist/cli/index.js +27 -5
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/index.cjs +233 -21
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +9 -9
  26. package/dist/index.d.ts +9 -9
  27. package/dist/index.js +32 -10
  28. package/dist/index.js.map +1 -1
  29. package/dist/providers/anthropic.cjs +82 -8
  30. package/dist/providers/anthropic.cjs.map +1 -1
  31. package/dist/providers/anthropic.d.cts +2 -2
  32. package/dist/providers/anthropic.d.ts +2 -2
  33. package/dist/providers/anthropic.js +3 -3
  34. package/dist/providers/gemini.cjs +82 -8
  35. package/dist/providers/gemini.cjs.map +1 -1
  36. package/dist/providers/gemini.d.cts +2 -2
  37. package/dist/providers/gemini.d.ts +2 -2
  38. package/dist/providers/gemini.js +3 -3
  39. package/dist/providers/llmasaservice.cjs +1467 -0
  40. package/dist/providers/llmasaservice.cjs.map +1 -0
  41. package/dist/providers/llmasaservice.d.cts +28 -0
  42. package/dist/providers/llmasaservice.d.ts +28 -0
  43. package/dist/providers/llmasaservice.js +20 -0
  44. package/dist/providers/llmasaservice.js.map +1 -0
  45. package/dist/providers/openai-responses.cjs +82 -8
  46. package/dist/providers/openai-responses.cjs.map +1 -1
  47. package/dist/providers/openai-responses.d.cts +2 -2
  48. package/dist/providers/openai-responses.d.ts +2 -2
  49. package/dist/providers/openai-responses.js +3 -3
  50. package/dist/providers/openai.cjs +82 -8
  51. package/dist/providers/openai.cjs.map +1 -1
  52. package/dist/providers/openai.d.cts +2 -2
  53. package/dist/providers/openai.d.ts +2 -2
  54. package/dist/providers/openai.js +3 -3
  55. package/dist/providers/openrouter.cjs +83 -8
  56. package/dist/providers/openrouter.cjs.map +1 -1
  57. package/dist/providers/openrouter.d.cts +2 -2
  58. package/dist/providers/openrouter.d.ts +2 -2
  59. package/dist/providers/openrouter.js +4 -4
  60. package/dist/{schema-B9A1zLRk.d.cts → schema-D-RI4w-k.d.cts} +695 -183
  61. package/dist/{schema-B9A1zLRk.d.ts → schema-D-RI4w-k.d.ts} +695 -183
  62. package/dist/testing.cjs +21 -4
  63. package/dist/testing.cjs.map +1 -1
  64. package/dist/testing.d.cts +1 -1
  65. package/dist/testing.d.ts +1 -1
  66. package/dist/testing.js +1 -1
  67. package/dist/{types-DjGAwJxC.d.ts → types-B3dxBGu6.d.ts} +18 -6
  68. package/dist/{types-DpbzzZO2.d.cts → types-DbTAjlTN.d.cts} +18 -6
  69. package/dist/usagetap/index.cjs +6 -1
  70. package/dist/usagetap/index.cjs.map +1 -1
  71. package/dist/usagetap/index.d.cts +4 -3
  72. package/dist/usagetap/index.d.ts +4 -3
  73. package/dist/usagetap/index.js +3 -1
  74. package/package.json +11 -1
  75. package/dist/chunk-5AAYDOPU.js.map +0 -1
  76. package/dist/chunk-7MRMN3SW.js.map +0 -1
  77. package/dist/chunk-HWEVRBKZ.js.map +0 -1
  78. package/dist/chunk-JKBWC5WJ.js.map +0 -1
  79. package/dist/chunk-MI3M6KDD.js.map +0 -1
  80. package/dist/chunk-XL76NHZR.js.map +0 -1
  81. package/dist/chunk-YI4LILPY.js.map +0 -1
  82. package/dist/chunk-Z4IPWEUU.js.map +0 -1
package/SKILL.md CHANGED
@@ -8,7 +8,325 @@ description: Guidance for creating and editing promptopskit prompt files, defaul
8
8
  This project uses **promptopskit** to manage LLM prompts as code.
9
9
  Prompts live in markdown files with YAML front matter, are validated against
10
10
  a schema, and render into provider-specific request bodies (OpenAI, Anthropic,
11
- Gemini, OpenRouter, and OpenAI Responses). Follow these instructions when creating or editing prompts.
11
+ Gemini, OpenRouter, LLMAsAService, and OpenAI Responses). Follow these instructions when creating or editing prompts.
12
+
13
+ ---
14
+
15
+ ## User request intents
16
+
17
+ When a user asks for prompt work, infer their intent from phrasing and act directly.
18
+ Do not stop at explanation when the user is asking for a file or code artifact.
19
+
20
+ ### Create a new prompt
21
+
22
+ Treat requests like these as instructions to create a new prompt markdown file:
23
+
24
+ - "Create a prompt that ..."
25
+ - "Add a prompt that ..."
26
+ - "Write a prompt for ..."
27
+ - "Make a prompt to ..."
28
+ - "Build me a prompt that ..."
29
+ - "I need a prompt that ..."
30
+ - "Scaffold a prompt for ..."
31
+ - "Create an eval/rewrite/classifier/extractor/summarizer prompt ..."
32
+
33
+ Behavior:
34
+
35
+ 1. Create a new `kebab-case.md` file under the project's prompt source directory
36
+ (`./prompts` by default, or the existing prompt folder used by the repo).
37
+ 2. Give the file a meaningful name derived from the task, not a generic name like
38
+ `prompt.md` or `new-prompt.md`.
39
+ 3. Set `id` to a stable slash path or camel/snake identifier that matches local
40
+ conventions. Prefer path-like ids such as `support/reply`,
41
+ `content/seo-brief`, or `examples/basic` when prompts are organized in folders.
42
+ 4. Include all appropriate defaults for the requested use case:
43
+ - Always include `id` and `schema_version: 1`.
44
+ - Include `description` when the purpose is not obvious from the id.
45
+ - Include `provider` and `model` only if they are requested or not supplied by
46
+ a nearby `defaults.md`.
47
+ - Include `sampling`, `reasoning`, `response`, `tools`, `cache`,
48
+ `provider_options`, or `raw` only when the prompt behavior requires them.
49
+ - Include `context.inputs` for every `{{ variable }}` in the body.
50
+ - Use object-form inputs with `non_empty: true`, `max_size`, `trim`, and
51
+ validation controls when the input is user-provided or unbounded.
52
+ - Add `context.history.max_items` for chat or support prompts that should
53
+ preserve bounded conversation history through compaction.
54
+ - Add `# Notes` only for authoring details, examples, or explanations that
55
+ must not be sent to the model.
56
+ 5. If the prompt should return JSON or another structured result, define
57
+ `response.format: json` and a JSON Schema in `response.schema`.
58
+ 6. When the user gives a vague task, choose sensible placeholders and defaults
59
+ from the task instead of asking for every detail. Ask only if the missing
60
+ detail would change the prompt's purpose, provider, or output contract.
61
+ 7. After writing the file, run or recommend `promptopskit validate` for the prompt
62
+ source directory.
63
+
64
+ Example response to "Create a prompt that turns a support ticket into a concise triage summary":
65
+
66
+ ```markdown
67
+ ---
68
+ id: support/triage-summary
69
+ schema_version: 1
70
+ description: Summarize a support ticket for triage.
71
+ context:
72
+ inputs:
73
+ - name: ticket
74
+ non_empty: true
75
+ trim: true
76
+ max_size: 12000
77
+ reject_secrets: true
78
+ response:
79
+ format: json
80
+ schema_name: support_triage_summary
81
+ schema:
82
+ type: object
83
+ additionalProperties: false
84
+ required: [summary, urgency, category, next_action]
85
+ properties:
86
+ summary:
87
+ type: string
88
+ urgency:
89
+ type: string
90
+ enum: [low, medium, high]
91
+ category:
92
+ type: string
93
+ next_action:
94
+ type: string
95
+ ---
96
+
97
+ # System instructions
98
+
99
+ You summarize support tickets for a triage queue. Be concise, specific, and avoid
100
+ inventing details that are not in the ticket.
101
+
102
+ # Prompt template
103
+
104
+ Summarize this support ticket:
105
+
106
+ {{ ticket }}
107
+ ```
108
+
109
+ ### Generate provider render code
110
+
111
+ Treat requests like these as instructions to generate code that renders a prompt
112
+ into a provider request body:
113
+
114
+ - "render the body for the prompt [name] for openai"
115
+ - "generate the body for [name] using anthropic"
116
+ - "create the call for prompt [name] for google"
117
+ - "convert prompt [name] to an openrouter request"
118
+ - "show me the OpenAI body for [name]"
119
+ - "generate the Anthropic call for the prompt [name]"
120
+ - "render/generate/build/create/produce the request/body/call/payload/messages
121
+ for prompt [name] with provider [provider]"
122
+ - "turn [name] into a provider request for openai/anthropic/google/gemini/openrouter/llmasaservice"
123
+ - "wire up prompt [name] to OpenAI/Anthropic/Gemini/OpenRouter/LLMAsAService"
124
+ - "give me code to call [provider] with prompt [name]"
125
+
126
+ Provider aliases:
127
+
128
+ | User says | Use provider |
129
+ |-----------|--------------|
130
+ | `openai`, `chat completions`, `OpenAI chat` | `openai` |
131
+ | `responses`, `OpenAI Responses`, `responses api` | `openai-responses` |
132
+ | `anthropic`, `claude` | `anthropic` |
133
+ | `google`, `gemini` | `gemini` |
134
+ | `openrouter` | `openrouter` |
135
+ | `llmasaservice`, `llmasaservice.io`, `llm gateway` | `llmasaservice` |
136
+
137
+ Behavior:
138
+
139
+ 1. Generate code unless the user explicitly asks for only the raw rendered JSON.
140
+ 2. Prefer `createPromptOpsKit().renderPrompt()` for server-side app code that loads
141
+ prompt source or compiled JSON by path.
142
+ 3. Prefer provider adapters (`openaiAdapter`, `anthropicAdapter`,
143
+ `geminiAdapter`, `openrouterAdapter`, `llmasaserviceAdapter`) when the user asks for provider-specific
144
+ integration code or already has a compiled asset.
145
+ 4. Include `variables` for every declared prompt input, using realistic placeholder
146
+ values or function parameters.
147
+ 5. Include `history` only if the prompt is chat-style or declares
148
+ `context.history`.
149
+ 6. Check `returnMessage` before reading `request` when using `kit.renderPrompt()`
150
+ or `adapter.renderPrompt()`.
151
+ 7. Return or pass `request.body` as the provider request payload; `request.provider`
152
+ and `request.model` are metadata for the caller.
153
+ 8. Do not put API keys in generated snippets. Use environment variables and keep
154
+ provider calls on the server.
155
+
156
+ OpenAI example:
157
+
158
+ ```typescript
159
+ import OpenAI from 'openai';
160
+ import { createPromptOpsKit } from 'promptopskit';
161
+
162
+ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
163
+ const kit = createPromptOpsKit({
164
+ sourceDir: './prompts',
165
+ compiledDir: './.generated-prompts/json',
166
+ mode: 'auto',
167
+ });
168
+
169
+ const result = await kit.renderPrompt({
170
+ path: 'support/triage-summary',
171
+ provider: 'openai',
172
+ variables: {
173
+ ticket: ticketText,
174
+ },
175
+ strict: true,
176
+ });
177
+
178
+ if (result.returnMessage) {
179
+ return result.returnMessage;
180
+ }
181
+ if (!result.request) {
182
+ throw new Error('Prompt rendering did not produce an OpenAI request.');
183
+ }
184
+
185
+ const completion = await client.chat.completions.create(result.request.body as any);
186
+ ```
187
+
188
+ Anthropic example:
189
+
190
+ ```typescript
191
+ import Anthropic from '@anthropic-ai/sdk';
192
+ import { createPromptOpsKit } from 'promptopskit';
193
+
194
+ const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
195
+ const kit = createPromptOpsKit({ sourceDir: './prompts' });
196
+
197
+ const result = await kit.renderPrompt({
198
+ path: 'support/triage-summary',
199
+ provider: 'anthropic',
200
+ variables: { ticket: ticketText },
201
+ strict: true,
202
+ });
203
+
204
+ if (result.returnMessage) return result.returnMessage;
205
+ if (!result.request) throw new Error('Prompt rendering did not produce an Anthropic request.');
206
+
207
+ const message = await client.messages.create(result.request.body as any);
208
+ ```
209
+
210
+ Google Gemini example:
211
+
212
+ ```typescript
213
+ import { GoogleGenAI } from '@google/genai';
214
+ import { createPromptOpsKit } from 'promptopskit';
215
+
216
+ const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
217
+ const kit = createPromptOpsKit({ sourceDir: './prompts' });
218
+
219
+ const result = await kit.renderPrompt({
220
+ path: 'support/triage-summary',
221
+ provider: 'gemini',
222
+ variables: { ticket: ticketText },
223
+ strict: true,
224
+ });
225
+
226
+ if (result.returnMessage) return result.returnMessage;
227
+ if (!result.request) throw new Error('Prompt rendering did not produce a Gemini request.');
228
+
229
+ const response = await ai.models.generateContent({
230
+ model: result.request.model,
231
+ ...(result.request.body as Record<string, unknown>),
232
+ });
233
+ ```
234
+
235
+ OpenRouter example:
236
+
237
+ ```typescript
238
+ import OpenAI from 'openai';
239
+ import { createPromptOpsKit } from 'promptopskit';
240
+
241
+ const client = new OpenAI({
242
+ apiKey: process.env.OPENROUTER_API_KEY,
243
+ baseURL: 'https://openrouter.ai/api/v1',
244
+ });
245
+ const kit = createPromptOpsKit({ sourceDir: './prompts' });
246
+
247
+ const result = await kit.renderPrompt({
248
+ path: 'support/triage-summary',
249
+ provider: 'openrouter',
250
+ variables: { ticket: ticketText },
251
+ strict: true,
252
+ });
253
+
254
+ if (result.returnMessage) return result.returnMessage;
255
+ if (!result.request) throw new Error('Prompt rendering did not produce an OpenRouter request.');
256
+
257
+ const completion = await client.chat.completions.create(result.request.body as any);
258
+ ```
259
+
260
+ LLMAsAService example:
261
+
262
+ ```typescript
263
+ import OpenAI from 'openai';
264
+ import {
265
+ createLLMAsAServiceOpenAIConfig,
266
+ llmasaserviceAdapter,
267
+ } from 'promptopskit/llmasaservice';
268
+
269
+ const client = new OpenAI(createLLMAsAServiceOpenAIConfig({
270
+ baseURL: process.env.LLM_GATEWAY_BASE_URL,
271
+ projectId: process.env.LLM_GATEWAY_PROJECT_ID,
272
+ }));
273
+
274
+ const result = await llmasaserviceAdapter.renderPrompt(
275
+ {
276
+ path: 'support/triage-summary',
277
+ },
278
+ {
279
+ runtime: {
280
+ provider_options: {
281
+ llmasaservice: {
282
+ project_id: process.env.LLM_GATEWAY_PROJECT_ID,
283
+ customer: {
284
+ customer_id: customer.id,
285
+ customer_name: customer.name,
286
+ customer_user_id: user.id,
287
+ customer_user_email: user.email,
288
+ },
289
+ },
290
+ },
291
+ },
292
+ variables: { ticket: ticketText },
293
+ strict: true,
294
+ },
295
+ );
296
+
297
+ if (result.returnMessage) return result.returnMessage;
298
+ if (!('body' in result)) {
299
+ throw new Error('Prompt rendering did not produce an LLMAsAService request.');
300
+ }
301
+
302
+ const completion = await client.chat.completions.create(result.body as any);
303
+ ```
304
+
305
+ If the user asks for "just the body", render with `kit.renderPrompt()` and show
306
+ or return `result.request.body`, not the whole render result.
307
+
308
+ ### Other useful promptopskit request examples
309
+
310
+ Handle these common requests with the same conventions:
311
+
312
+ - "Add defaults for this prompt folder" -> create or update `defaults.md` with
313
+ shared `provider`, `model`, `metadata`, cache settings, and optional fallback
314
+ `# System instructions`.
315
+ - "Add inputs to this prompt" -> add exact `context.inputs` entries for every
316
+ placeholder and choose validation controls for risky or large values.
317
+ - "Make this prompt return JSON" -> add `response.format: json`,
318
+ `response.schema_name`, and a strict `response.schema`.
319
+ - "Add a test for this prompt" -> create a sidecar `.test.yaml` with realistic
320
+ `cases` and `variables`.
321
+ - "Compile/render/inspect/validate my prompts" -> use the matching
322
+ `promptopskit` CLI command and report validation errors with file references.
323
+ - "Move common instructions into a reusable prompt" -> create a shared fragment
324
+ and reference it with `includes`.
325
+ - "Add provider-specific options" -> prefer portable fields first, then
326
+ `provider_options`, and use `raw` only for unmodeled vendor fields with a note.
327
+ - "Make this safe for production" -> add validation for untrusted inputs, keep API
328
+ calls server-side, validate before compile, and avoid committing generated
329
+ artifacts unless the project already does.
12
330
 
13
331
  ---
14
332
 
@@ -58,7 +376,7 @@ the fields required by that specific file:
58
376
  | `id` | string | **yes** | Unique identifier for the prompt |
59
377
  | `schema_version` | number | yes | Always `1` |
60
378
  | `description` | string | no | Human-readable description |
61
- | `provider` | enum | no | `openai`, `openai-responses`, `anthropic`, `google`, `gemini`, `openrouter`, or `any` |
379
+ | `provider` | enum | no | `openai`, `openai-responses`, `anthropic`, `google`, `gemini`, `openrouter`, `llmasaservice`, or `any` |
62
380
  | `model` | string | no | Model identifier (e.g. `gpt-5.4`, `claude-sonnet-4-20250514`) |
63
381
  | `fallback_models` | string[] | no | Ordered fallback model list |
64
382
  | `reasoning` | object | no | `{ effort: low|medium|high, budget_tokens: number }` |
@@ -66,11 +384,11 @@ the fields required by that specific file:
66
384
  | `response` | object | no | `{ format: text|json|markdown, stream: boolean, schema?: object, schema_name?: string, schema_description?: string, schema_strict?: boolean }` |
67
385
  | `cache` | object | no | Provider-specific cache controls (`openai`, `anthropic`, `gemini`/`google`) |
68
386
  | `tools` | array | no | Tool names (strings) or inline definitions with `{ name, description, input_schema }` |
69
- | `provider_options` | object | no | Provider-specific advanced options (`anthropic`, `gemini`, `openrouter`) |
387
+ | `provider_options` | object | no | Provider-specific advanced options (`anthropic`, `gemini`, `openrouter`, `llmasaservice`) |
70
388
  | `raw` | object | no | Provider-scoped request-body passthrough for unmodeled vendor fields |
71
389
  | `mcp` | object | no | `{ servers: [string | { name, config }] }` |
72
390
  | `context.inputs` | `Array<string | { name, max_size?, trim?, allow_regex?, deny_regex?, non_empty?, reject_secrets? }>` | no | Declared variable names used in templates, with optional size budgets and runtime hardening controls |
73
- | `context.history` | object | no | `{ max_items: number }` |
391
+ | `context.history` | object | no | `{ max_items: number }`; caps rendered history by compacting older turns into one preserved message |
74
392
  | `includes` | string[] | no | Relative paths to other prompt files to include |
75
393
  | `environments` | object | no | Per-environment overrides (see Overrides) |
76
394
  | `tiers` | object | no | Per-tier overrides (see Overrides) |
@@ -131,6 +449,32 @@ If a validator declares `return_message`, `renderPrompt()` returns that message
131
449
 
132
450
  Malformed `allow_regex` and `deny_regex` values fail during `validate` and `compile`, not just at render time. When regex compilation fails, the error includes the prompt id, variable name, field name, and raw configured value. Double-quoted YAML regex strings with raw backslashes fail as `POK013`; use `/pattern/i`, single-quoted `pattern: '...'`, or doubled backslashes.
133
451
 
452
+ ### Conversation history limits
453
+
454
+ Use `context.history.max_items` when a chat-style prompt should bound rendered conversation history:
455
+
456
+ ```yaml
457
+ context:
458
+ history:
459
+ max_items: 10
460
+ ```
461
+
462
+ When runtime `history` exceeds `max_items`, PromptOpsKit preserves history by compacting older turns into one synthetic history message and keeping the most recent turns. Callers can provide `onHistoryCompaction` to create a custom summary:
463
+
464
+ ```typescript
465
+ const result = await kit.renderPrompt({
466
+ path: 'support/reply',
467
+ provider: 'openai',
468
+ history,
469
+ onHistoryCompaction: ({ overflow }) => ({
470
+ role: 'user',
471
+ content: `Earlier conversation summary: ${summarizeConversationUsingLLM(overflow)}`,
472
+ }),
473
+ });
474
+ ```
475
+
476
+ If no callback is supplied, PromptOpsKit creates a plain text compacted history message. Do not describe `max_items` as dropping history; it preserves overflow through compaction.
477
+
134
478
  Example: this is the minimal valid shape for a prompt that references
135
479
  `{{ pull_request }}` even when provider/model are inherited from defaults:
136
480
 
@@ -250,7 +594,7 @@ Prefer portable fields first:
250
594
  - Use `cache` for provider cache hints
251
595
  - Use `tools` for tool definitions
252
596
 
253
- Treat `response.schema` as the provider-neutral JSON Schema contract. The adapters emit it through provider-specific request fields: OpenAI/OpenRouter `response_format`, OpenAI Responses `text.format`, Anthropic `output_config.format`, and Gemini `generationConfig.responseJsonSchema`.
597
+ Treat `response.schema` as the provider-neutral JSON Schema contract. The adapters emit it through provider-specific request fields: OpenAI/OpenRouter/LLMAsAService `response_format`, OpenAI Responses `text.format`, Anthropic `output_config.format`, and Gemini `generationConfig.responseJsonSchema`.
254
598
 
255
599
  Use `provider_options` for known non-portable mappings:
256
600
 
@@ -275,8 +619,16 @@ provider_options:
275
619
  provider:
276
620
  order: ["anthropic", "openai"]
277
621
  transforms: ["middle-out"]
622
+ llmasaservice:
623
+ project_id: llm-project-id
624
+ # Optional default; usually pass the real customer at render time.
625
+ customer:
626
+ customer_id: cust_123
627
+ customer_name: Acme
278
628
  ```
279
629
 
630
+ 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.
631
+
280
632
  Use `raw` only when a vendor request-body field is important and PromptOpsKit does not model it yet:
281
633
 
282
634
  ```yaml
@@ -292,9 +644,11 @@ raw:
292
644
  openrouter:
293
645
  usage:
294
646
  include: true
647
+ llmasaservice:
648
+ conversationId: conv_123
295
649
  ```
296
650
 
297
- Raw blocks are provider-scoped (`openai`, `openai-responses`/`openai_responses`, `anthropic`, `gemini`/`google`, `openrouter`) and are shallow-merged into the final request body after normalized fields. When adding `raw`, include a short note in `# Notes` explaining why a first-class field is not being used.
651
+ Raw blocks are provider-scoped (`openai`, `openai-responses`/`openai_responses`, `anthropic`, `gemini`/`google`, `openrouter`, `llmasaservice`) and are shallow-merged into the final request body after normalized fields. When adding `raw`, include a short note in `# Notes` explaining why a first-class field is not being used.
298
652
 
299
653
  ---
300
654
 
@@ -0,0 +1,130 @@
1
+ import {
2
+ openaiAdapter
3
+ } from "./chunk-D75HKF64.js";
4
+ import {
5
+ applyRawProviderBody,
6
+ resolveAssetForProvider,
7
+ withPromptInputSupport
8
+ } from "./chunk-KN7H4JRK.js";
9
+
10
+ // src/providers/llmasaservice.ts
11
+ var LLMASASERVICE_BASE_URL = "https://gateway.llmasaservice.io";
12
+ var LLMASASERVICE_SDK_PLACEHOLDER_API_KEY = "not-used-by-llm-gateway";
13
+ var LLMASASERVICE_DEFAULT_MODEL = "group:standard";
14
+ var LLMASASERVICE_RESPONSE_HEADER_NAMES = [
15
+ "x-request-id",
16
+ "x-llm-model-id",
17
+ "x-llm-model-group"
18
+ ];
19
+ function createLLMAsAServiceOpenAIConfig(options = {}) {
20
+ return {
21
+ baseURL: options.baseURL ?? LLMASASERVICE_BASE_URL,
22
+ apiKey: LLMASASERVICE_SDK_PLACEHOLDER_API_KEY,
23
+ defaultHeaders: {
24
+ "x-project-id": options.projectId ?? ""
25
+ }
26
+ };
27
+ }
28
+ function isGPT5ModelSelector(model) {
29
+ if (!model) return false;
30
+ return model.split(/[|,]/).map((candidate) => candidate.trim()).some((candidate) => candidate.startsWith("gpt-5") || candidate.startsWith("openai:gpt-5"));
31
+ }
32
+ function defaultModel() {
33
+ return LLMASASERVICE_DEFAULT_MODEL;
34
+ }
35
+ function isRecord(value) {
36
+ return typeof value === "object" && value !== null && !Array.isArray(value);
37
+ }
38
+ function rawCustomerId(asset) {
39
+ const customer = isRecord(asset.raw?.llmasaservice?.customer) ? asset.raw.llmasaservice.customer : void 0;
40
+ return customer?.customer_id;
41
+ }
42
+ function isGatewayRenderValidation(runtime) {
43
+ return runtime?.runtime !== void 0;
44
+ }
45
+ var llmasaserviceAdapter = withPromptInputSupport({
46
+ name: "llmasaservice",
47
+ validate(asset, runtime) {
48
+ const resolvedAsset = resolveAssetForProvider(asset, runtime);
49
+ const validation = openaiAdapter.validate(
50
+ {
51
+ ...resolvedAsset,
52
+ model: resolvedAsset.model ?? defaultModel()
53
+ },
54
+ runtime
55
+ );
56
+ const warnings = validation.warnings.filter(
57
+ (warning) => warning !== "OpenAI adapter requires a model to be specified."
58
+ );
59
+ const errors = [...validation.errors];
60
+ const gatewayOptions = resolvedAsset.provider_options?.llmasaservice;
61
+ const missingProjectId = !gatewayOptions?.project_id;
62
+ const missingCustomerId = !gatewayOptions?.customer?.customer_id && typeof rawCustomerId(resolvedAsset) !== "string";
63
+ const validateRenderMetadata = isGatewayRenderValidation(runtime);
64
+ if (missingProjectId && validateRenderMetadata) {
65
+ errors.push(
66
+ "LLMAsAService adapter requires provider_options.llmasaservice.project_id for x-project-id routing."
67
+ );
68
+ }
69
+ if (missingCustomerId && validateRenderMetadata) {
70
+ errors.push(
71
+ "LLMAsAService adapter requires customer.customer_id in provider_options.llmasaservice.customer or raw.llmasaservice.customer."
72
+ );
73
+ }
74
+ if ((missingProjectId || missingCustomerId) && !validateRenderMetadata) {
75
+ warnings.push(
76
+ "LLMAsAService project_id and customer.customer_id must be supplied before rendering, usually through runtime provider_options."
77
+ );
78
+ }
79
+ return {
80
+ valid: errors.length === 0,
81
+ errors,
82
+ warnings
83
+ };
84
+ },
85
+ render(asset, runtime) {
86
+ const resolvedAsset = resolveAssetForProvider(asset, runtime);
87
+ const options = resolvedAsset.provider_options?.llmasaservice;
88
+ const model = resolvedAsset.model ?? defaultModel();
89
+ const result = openaiAdapter.render(
90
+ { ...resolvedAsset, model, raw: void 0 },
91
+ {
92
+ variables: runtime.variables,
93
+ history: runtime.history,
94
+ onHistoryCompaction: runtime.onHistoryCompaction,
95
+ toolRegistry: runtime.toolRegistry,
96
+ strict: runtime.strict
97
+ }
98
+ );
99
+ let body = { ...result.body };
100
+ if (isGPT5ModelSelector(model) && body.max_tokens !== void 0 && body.max_completion_tokens === void 0) {
101
+ body.max_completion_tokens = body.max_tokens;
102
+ delete body.max_tokens;
103
+ }
104
+ if (options?.customer !== void 0) body.customer = options.customer;
105
+ if (options?.conversationId !== void 0) body.conversationId = options.conversationId;
106
+ if (options?.conversationTitle !== void 0) body.conversationTitle = options.conversationTitle;
107
+ if (options?.projectId !== void 0) body.projectId = options.projectId;
108
+ body = applyRawProviderBody(body, resolvedAsset, "llmasaservice");
109
+ const projectId = options?.project_id ?? "";
110
+ return {
111
+ body,
112
+ provider: "llmasaservice",
113
+ model,
114
+ baseURL: options?.base_url ?? LLMASASERVICE_BASE_URL,
115
+ headers: {
116
+ "x-project-id": projectId
117
+ }
118
+ };
119
+ }
120
+ });
121
+
122
+ export {
123
+ LLMASASERVICE_BASE_URL,
124
+ LLMASASERVICE_SDK_PLACEHOLDER_API_KEY,
125
+ LLMASASERVICE_DEFAULT_MODEL,
126
+ LLMASASERVICE_RESPONSE_HEADER_NAMES,
127
+ createLLMAsAServiceOpenAIConfig,
128
+ llmasaserviceAdapter
129
+ };
130
+ //# sourceMappingURL=chunk-6BOUQVSX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/llmasaservice.ts"],"sourcesContent":["import { openaiAdapter } from './openai.js';\nimport type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n RuntimeRenderOptions,\n ValidationResult,\n} from './types.js';\nimport { applyRawProviderBody } from './raw.js';\nimport { resolveAssetForProvider } from './resolve-asset.js';\nimport { withPromptInputSupport } from './prompt-input.js';\n\nexport const LLMASASERVICE_BASE_URL = 'https://gateway.llmasaservice.io';\nexport const LLMASASERVICE_SDK_PLACEHOLDER_API_KEY = 'not-used-by-llm-gateway';\nexport const LLMASASERVICE_DEFAULT_MODEL = 'group:standard';\nexport const LLMASASERVICE_RESPONSE_HEADER_NAMES = [\n 'x-request-id',\n 'x-llm-model-id',\n 'x-llm-model-group',\n] as const;\n\nexport interface LLMAsAServiceOpenAIConfig {\n baseURL: string;\n apiKey: string;\n defaultHeaders: {\n 'x-project-id': string;\n };\n}\n\nexport interface LLMAsAServiceOpenAIConfigOptions {\n baseURL?: string;\n projectId?: string;\n}\n\nexport function createLLMAsAServiceOpenAIConfig(\n options: LLMAsAServiceOpenAIConfigOptions = {},\n): LLMAsAServiceOpenAIConfig {\n return {\n baseURL: options.baseURL ?? LLMASASERVICE_BASE_URL,\n apiKey: LLMASASERVICE_SDK_PLACEHOLDER_API_KEY,\n defaultHeaders: {\n 'x-project-id': options.projectId ?? '',\n },\n };\n}\n\nfunction isGPT5ModelSelector(model: string | undefined): boolean {\n if (!model) return false;\n return model\n .split(/[|,]/)\n .map((candidate) => candidate.trim())\n .some((candidate) => candidate.startsWith('gpt-5') || candidate.startsWith('openai:gpt-5'));\n}\n\nfunction defaultModel(): string {\n return LLMASASERVICE_DEFAULT_MODEL;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction rawCustomerId(asset: ResolvedPromptAsset): unknown {\n const customer = isRecord(asset.raw?.llmasaservice?.customer)\n ? asset.raw.llmasaservice.customer\n : undefined;\n return customer?.customer_id;\n}\n\nfunction isGatewayRenderValidation(runtime: RuntimeRenderOptions | undefined): boolean {\n return runtime?.runtime !== undefined;\n}\n\n/**\n * LLMAsAService gateway adapter.\n * Uses the OpenAI Chat Completions body shape, plus gateway routing and\n * attribution fields supported by gateway.llmasaservice.io.\n */\nexport const llmasaserviceAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'llmasaservice',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const validation = openaiAdapter.validate(\n {\n ...resolvedAsset,\n model: resolvedAsset.model ?? defaultModel(),\n },\n runtime,\n );\n const warnings = validation.warnings.filter(\n (warning) => warning !== 'OpenAI adapter requires a model to be specified.',\n );\n\n const errors = [...validation.errors];\n const gatewayOptions = resolvedAsset.provider_options?.llmasaservice;\n const missingProjectId = !gatewayOptions?.project_id;\n const missingCustomerId =\n !gatewayOptions?.customer?.customer_id && typeof rawCustomerId(resolvedAsset) !== 'string';\n const validateRenderMetadata = isGatewayRenderValidation(runtime);\n\n if (missingProjectId && validateRenderMetadata) {\n errors.push(\n 'LLMAsAService adapter requires provider_options.llmasaservice.project_id for x-project-id routing.',\n );\n }\n\n if (missingCustomerId && validateRenderMetadata) {\n errors.push(\n 'LLMAsAService adapter requires customer.customer_id in provider_options.llmasaservice.customer or raw.llmasaservice.customer.',\n );\n }\n\n if ((missingProjectId || missingCustomerId) && !validateRenderMetadata) {\n warnings.push(\n 'LLMAsAService project_id and customer.customer_id must be supplied before rendering, usually through runtime provider_options.',\n );\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const options = resolvedAsset.provider_options?.llmasaservice;\n const model = resolvedAsset.model ?? defaultModel();\n const result = openaiAdapter.render(\n { ...resolvedAsset, model, raw: undefined },\n {\n variables: runtime.variables,\n history: runtime.history,\n onHistoryCompaction: runtime.onHistoryCompaction,\n toolRegistry: runtime.toolRegistry,\n strict: runtime.strict,\n },\n );\n let body = { ...result.body };\n\n if (isGPT5ModelSelector(model) && body.max_tokens !== undefined && body.max_completion_tokens === undefined) {\n body.max_completion_tokens = body.max_tokens;\n delete body.max_tokens;\n }\n\n if (options?.customer !== undefined) body.customer = options.customer;\n if (options?.conversationId !== undefined) body.conversationId = options.conversationId;\n if (options?.conversationTitle !== undefined) body.conversationTitle = options.conversationTitle;\n if (options?.projectId !== undefined) body.projectId = options.projectId;\n\n body = applyRawProviderBody(body, resolvedAsset, 'llmasaservice');\n\n const projectId = options?.project_id ?? '';\n\n return {\n body,\n provider: 'llmasaservice',\n model,\n baseURL: options?.base_url ?? LLMASASERVICE_BASE_URL,\n headers: {\n 'x-project-id': projectId,\n },\n };\n },\n});\n"],"mappings":"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","names":[]}
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  applyRawProviderBody,
3
+ compactHistoryForPrompt,
3
4
  renderSections,
4
5
  resolveAssetForProvider,
5
6
  withPromptInputSupport
6
- } from "./chunk-YI4LILPY.js";
7
+ } from "./chunk-KN7H4JRK.js";
7
8
 
8
9
  // src/providers/openai-responses.ts
9
10
  var openaiResponsesAdapter = withPromptInputSupport({
@@ -34,8 +35,9 @@ var openaiResponsesAdapter = withPromptInputSupport({
34
35
  });
35
36
  const responseOptions = runtime.openaiResponses;
36
37
  const input = [];
37
- if (runtime.history) {
38
- for (const msg of runtime.history) {
38
+ const history = compactHistoryForPrompt(resolvedAsset, runtime);
39
+ if (history) {
40
+ for (const msg of history) {
39
41
  input.push({ role: msg.role, content: msg.content });
40
42
  }
41
43
  }
@@ -110,4 +112,4 @@ var openaiResponsesAdapter = withPromptInputSupport({
110
112
  export {
111
113
  openaiResponsesAdapter
112
114
  };
113
- //# sourceMappingURL=chunk-7MRMN3SW.js.map
115
+ //# sourceMappingURL=chunk-6VLKZCNS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/providers/openai-responses.ts"],"sourcesContent":["import type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n ValidationResult,\n RuntimeRenderOptions,\n} from './types.js';\nimport { renderSections } from '../renderer/index.js';\nimport { resolveAssetForProvider } from './resolve-asset.js';\nimport { withPromptInputSupport } from './prompt-input.js';\nimport { applyRawProviderBody } from './raw.js';\nimport { compactHistoryForPrompt } from '../history.js';\n\n/**\n * OpenAI Responses provider adapter.\n * Produces request bodies compatible with the OpenAI Responses API.\n */\nexport const openaiResponsesAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'openai-responses',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!resolvedAsset.model) {\n errors.push('OpenAI Responses adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.reasoning?.budget_tokens !== undefined) {\n warnings.push('OpenAI Responses uses reasoning.effort, not budget_tokens. budget_tokens will be ignored.');\n }\n\n if (resolvedAsset.response?.schema !== undefined && resolvedAsset.response?.format !== 'json') {\n warnings.push('OpenAI Responses response.schema requires response.format: json. schema will still be applied as JSON schema output.');\n }\n\n if (runtime?.openaiResponses?.conversation !== undefined && runtime?.openaiResponses?.previous_response_id !== undefined) {\n errors.push('OpenAI Responses options \"conversation\" and \"previous_response_id\" cannot both be set.');\n }\n\n return { valid: errors.length === 0, errors, warnings };\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const resolvedAsset = resolveAssetForProvider(asset, runtime);\n const sections = renderSections(resolvedAsset, {\n variables: runtime.variables,\n strict: runtime.strict,\n });\n const responseOptions = runtime.openaiResponses;\n\n const input: Array<Record<string, unknown>> = [];\n\n const history = compactHistoryForPrompt(resolvedAsset, runtime);\n if (history) {\n for (const msg of history) {\n input.push({ role: msg.role, content: msg.content });\n }\n }\n\n if (sections.prompt_template) {\n input.push({ role: 'user', content: sections.prompt_template });\n }\n\n const body: Record<string, unknown> = {\n model: resolvedAsset.model,\n input,\n };\n\n if (responseOptions?.instructions !== undefined) {\n body.instructions = responseOptions.instructions;\n } else if (sections.system_instructions) {\n body.instructions = sections.system_instructions;\n }\n\n // Sampling params\n if (resolvedAsset.sampling?.temperature !== undefined) body.temperature = resolvedAsset.sampling.temperature;\n if (resolvedAsset.sampling?.top_p !== undefined) body.top_p = resolvedAsset.sampling.top_p;\n if (resolvedAsset.sampling?.frequency_penalty !== undefined) body.frequency_penalty = resolvedAsset.sampling.frequency_penalty;\n if (resolvedAsset.sampling?.presence_penalty !== undefined) body.presence_penalty = resolvedAsset.sampling.presence_penalty;\n if (resolvedAsset.sampling?.stop !== undefined) body.stop = resolvedAsset.sampling.stop;\n if (resolvedAsset.sampling?.max_output_tokens !== undefined) body.max_output_tokens = resolvedAsset.sampling.max_output_tokens;\n\n // Reasoning\n if (resolvedAsset.reasoning?.effort) {\n body.reasoning = { effort: resolvedAsset.reasoning.effort };\n }\n\n // Structured output / response format\n if (resolvedAsset.response?.schema) {\n body.text = {\n format: {\n type: 'json_schema',\n name: resolvedAsset.response.schema_name ?? `${resolvedAsset.id}_response`,\n ...(resolvedAsset.response.schema_description ? { description: resolvedAsset.response.schema_description } : {}),\n schema: resolvedAsset.response.schema,\n strict: resolvedAsset.response.schema_strict ?? true,\n },\n };\n } else if (resolvedAsset.response?.format === 'json') {\n body.text = { format: { type: 'json_object' } };\n }\n\n // Streaming\n if (resolvedAsset.response?.stream !== undefined) {\n body.stream = resolvedAsset.response.stream;\n }\n\n // Tools\n if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {\n body.tools = resolvedAsset.tools.map((tool) => {\n if (typeof tool === 'string') {\n const def = runtime.toolRegistry?.[tool];\n if (def) return def;\n return { type: 'function', name: tool };\n }\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n };\n });\n }\n\n if (responseOptions?.previous_response_id !== undefined) body.previous_response_id = responseOptions.previous_response_id;\n if (responseOptions?.conversation !== undefined) body.conversation = responseOptions.conversation;\n if (responseOptions?.parallel_tool_calls !== undefined) body.parallel_tool_calls = responseOptions.parallel_tool_calls;\n if (responseOptions?.max_tool_calls !== undefined) body.max_tool_calls = responseOptions.max_tool_calls;\n if (responseOptions?.store !== undefined) body.store = responseOptions.store;\n if (responseOptions?.metadata !== undefined) body.metadata = responseOptions.metadata;\n if (responseOptions?.include !== undefined) body.include = responseOptions.include;\n if (responseOptions?.background !== undefined) body.background = responseOptions.background;\n\n return {\n body: applyRawProviderBody(body, resolvedAsset, 'openai-responses'),\n provider: 'openai-responses',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":"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","names":[]}
@@ -273,7 +273,7 @@ function applyUsageTapEntitlements(request, begin, options = {}) {
273
273
  if (!isObject2(nextRequest.body)) {
274
274
  return nextRequest;
275
275
  }
276
- if (nextRequest.provider === "openai" || nextRequest.provider === "openrouter") {
276
+ if (nextRequest.provider === "openai" || nextRequest.provider === "openrouter" || nextRequest.provider === "llmasaservice") {
277
277
  capOpenAIReasoning(nextRequest.body, allowed);
278
278
  if (isRecordArray(nextRequest.body.tools)) {
279
279
  nextRequest.body.tools = filterOpenAITools(nextRequest.body.tools, allowed, options);
@@ -362,6 +362,9 @@ function runOpenAIWithUsageTap(client, options) {
362
362
  function runOpenRouterWithUsageTap(client, options) {
363
363
  return runProviderWithUsageTap(client, options, extractOpenAIUsage);
364
364
  }
365
+ function runLLMAsAServiceWithUsageTap(client, options) {
366
+ return runProviderWithUsageTap(client, options, extractOpenAIUsage);
367
+ }
365
368
  function runAnthropicWithUsageTap(client, options) {
366
369
  return runProviderWithUsageTap(client, options, extractAnthropicUsage);
367
370
  }
@@ -381,7 +384,8 @@ export {
381
384
  extractGeminiUsage,
382
385
  runOpenAIWithUsageTap,
383
386
  runOpenRouterWithUsageTap,
387
+ runLLMAsAServiceWithUsageTap,
384
388
  runAnthropicWithUsageTap,
385
389
  runGeminiWithUsageTap
386
390
  };
387
- //# sourceMappingURL=chunk-HWEVRBKZ.js.map
391
+ //# sourceMappingURL=chunk-AGTGIZMR.js.map