promptopskit 0.4.2 → 0.6.2
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.
- package/README.md +105 -62
- package/SKILL.md +376 -16
- package/dist/{chunk-7MRMN3SW.js → chunk-55B7QQBK.js} +6 -4
- package/dist/chunk-55B7QQBK.js.map +1 -0
- package/dist/{chunk-HWEVRBKZ.js → chunk-AGTGIZMR.js} +6 -2
- package/dist/chunk-AGTGIZMR.js.map +1 -0
- package/dist/chunk-FNCIBZJF.js +130 -0
- package/dist/chunk-FNCIBZJF.js.map +1 -0
- package/dist/{chunk-XL76NHZR.js → chunk-GLT3YYWK.js} +6 -4
- package/dist/chunk-GLT3YYWK.js.map +1 -0
- package/dist/{chunk-5AAYDOPU.js → chunk-IPFD5Y3O.js} +4 -3
- package/dist/chunk-IPFD5Y3O.js.map +1 -0
- package/dist/{chunk-YI4LILPY.js → chunk-JR7252DG.js} +584 -520
- package/dist/chunk-JR7252DG.js.map +1 -0
- package/dist/{chunk-JKBWC5WJ.js → chunk-UY5OKMVP.js} +302 -21
- package/dist/chunk-UY5OKMVP.js.map +1 -0
- package/dist/{chunk-MI3M6KDD.js → chunk-VMLGUI4F.js} +6 -4
- package/dist/chunk-VMLGUI4F.js.map +1 -0
- package/dist/{chunk-Z4IPWEUU.js → chunk-XEZJZ3IG.js} +6 -4
- package/dist/chunk-XEZJZ3IG.js.map +1 -0
- package/dist/cli/index.js +435 -106
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +1159 -636
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +79 -17
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +875 -533
- package/dist/providers/anthropic.cjs.map +1 -1
- package/dist/providers/anthropic.d.cts +2 -2
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +3 -3
- package/dist/providers/gemini.cjs +875 -533
- package/dist/providers/gemini.cjs.map +1 -1
- package/dist/providers/gemini.d.cts +2 -2
- package/dist/providers/gemini.d.ts +2 -2
- package/dist/providers/gemini.js +3 -3
- package/dist/providers/llmasaservice.cjs +1735 -0
- package/dist/providers/llmasaservice.cjs.map +1 -0
- package/dist/providers/llmasaservice.d.cts +28 -0
- package/dist/providers/llmasaservice.d.ts +28 -0
- package/dist/providers/llmasaservice.js +20 -0
- package/dist/providers/llmasaservice.js.map +1 -0
- package/dist/providers/openai-responses.cjs +875 -533
- package/dist/providers/openai-responses.cjs.map +1 -1
- package/dist/providers/openai-responses.d.cts +2 -2
- package/dist/providers/openai-responses.d.ts +2 -2
- package/dist/providers/openai-responses.js +3 -3
- package/dist/providers/openai.cjs +875 -533
- package/dist/providers/openai.cjs.map +1 -1
- package/dist/providers/openai.d.cts +2 -2
- package/dist/providers/openai.d.ts +2 -2
- package/dist/providers/openai.js +3 -3
- package/dist/providers/openrouter.cjs +876 -533
- package/dist/providers/openrouter.cjs.map +1 -1
- package/dist/providers/openrouter.d.cts +2 -2
- package/dist/providers/openrouter.d.ts +2 -2
- package/dist/providers/openrouter.js +4 -4
- package/dist/{schema-B9A1zLRk.d.cts → schema-CuYsv8JA.d.cts} +853 -7
- package/dist/{schema-B9A1zLRk.d.ts → schema-CuYsv8JA.d.ts} +853 -7
- package/dist/testing.cjs +64 -9
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-DjGAwJxC.d.ts → types-DpK0mTHL.d.ts} +18 -6
- package/dist/{types-DpbzzZO2.d.cts → types-UA_p9uJy.d.cts} +18 -6
- package/dist/usagetap/index.cjs +6 -1
- package/dist/usagetap/index.cjs.map +1 -1
- package/dist/usagetap/index.d.cts +4 -3
- package/dist/usagetap/index.d.ts +4 -3
- package/dist/usagetap/index.js +3 -1
- package/package.json +19 -2
- package/dist/chunk-5AAYDOPU.js.map +0 -1
- package/dist/chunk-7MRMN3SW.js.map +0 -1
- package/dist/chunk-HWEVRBKZ.js.map +0 -1
- package/dist/chunk-JKBWC5WJ.js.map +0 -1
- package/dist/chunk-MI3M6KDD.js.map +0 -1
- package/dist/chunk-XL76NHZR.js.map +0 -1
- package/dist/chunk-YI4LILPY.js.map +0 -1
- 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
|
-
| `context.inputs` | `Array<string | { name, max_size?, trim?, allow_regex?, deny_regex?, non_empty?, reject_secrets? }>` | no | Declared variable names used in templates, with
|
|
73
|
-
| `context.history` | object | no | `{ max_items: number }
|
|
390
|
+
| `context.inputs` | `Array<string | { name, optional?, warnings?, max_size?, trim?, allow_regex?, deny_regex?, non_empty?, reject_secrets? }>` | no | Declared variable names used in templates, with optionality, warning controls, size budgets, and runtime hardening controls |
|
|
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) |
|
|
@@ -103,6 +421,8 @@ Rules:
|
|
|
103
421
|
- Before finishing a new prompt file, scan the body for every `{{ variable }}` and
|
|
104
422
|
ensure each exact variable name appears in `context.inputs`
|
|
105
423
|
- Use object-form inputs with `max_size` when a variable is likely to grow large and should trigger early warnings
|
|
424
|
+
- Use `optional: true` when a variable may be absent; strict rendering will not throw for that missing variable
|
|
425
|
+
- Use `warnings: false` sparingly for intentional exceptions that should not emit input-scoped validation or size warnings
|
|
106
426
|
- Use `trim` to enforce byte budgets before interpolation when `max_size` is set
|
|
107
427
|
- Use `allow_regex` for allowlist checks and `deny_regex` for blocklist checks on risky inputs
|
|
108
428
|
- Prefer unquoted `/pattern/i` literals for regex validators so backslash escapes such as `\s` and `\b` stay copyable from regex tools
|
|
@@ -124,13 +444,39 @@ context:
|
|
|
124
444
|
max_size: 4096
|
|
125
445
|
```
|
|
126
446
|
|
|
127
|
-
If a rendered value exceeds `max_size`, `renderPrompt()` emits a non-blocking `POK030` warning
|
|
447
|
+
If a rendered value exceeds `max_size`, `renderPrompt()` emits a non-blocking `POK030` warning unless the input sets `warnings: false`.
|
|
128
448
|
At render time, callers can also pass `onContextOverflow` to transform oversized values before warnings/rendering.
|
|
129
449
|
|
|
130
450
|
If a validator declares `return_message`, `renderPrompt()` returns that message in a structured result and omits the provider request instead of throwing for that validation failure. Invalid regex definitions still fail during `validate` and `compile` as `POK013` prompt-authoring errors.
|
|
131
451
|
|
|
132
452
|
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
453
|
|
|
454
|
+
### Conversation history limits
|
|
455
|
+
|
|
456
|
+
Use `context.history.max_items` when a chat-style prompt should bound rendered conversation history:
|
|
457
|
+
|
|
458
|
+
```yaml
|
|
459
|
+
context:
|
|
460
|
+
history:
|
|
461
|
+
max_items: 10
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
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:
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
const result = await kit.renderPrompt({
|
|
468
|
+
path: 'support/reply',
|
|
469
|
+
provider: 'openai',
|
|
470
|
+
history,
|
|
471
|
+
onHistoryCompaction: ({ overflow }) => ({
|
|
472
|
+
role: 'user',
|
|
473
|
+
content: `Earlier conversation summary: ${summarizeConversationUsingLLM(overflow)}`,
|
|
474
|
+
}),
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
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.
|
|
479
|
+
|
|
134
480
|
Example: this is the minimal valid shape for a prompt that references
|
|
135
481
|
`{{ pull_request }}` even when provider/model are inherited from defaults:
|
|
136
482
|
|
|
@@ -178,28 +524,32 @@ folder:
|
|
|
178
524
|
|
|
179
525
|
```text
|
|
180
526
|
prompts/
|
|
181
|
-
├── defaults.md # global provider, model, metadata + system instructions
|
|
527
|
+
├── defaults.md # global provider, model, options, metadata + system instructions
|
|
182
528
|
└── support/
|
|
183
529
|
├── defaults.md # overrides for support/*
|
|
184
530
|
└── reply.md # inherits from support/defaults.md
|
|
185
531
|
```
|
|
186
532
|
|
|
187
533
|
Supported default fields:
|
|
188
|
-
- `provider` (front matter) — default
|
|
189
|
-
- `
|
|
190
|
-
- `cache` (front matter) — default provider-specific
|
|
534
|
+
- `provider`, `model`, `fallback_models` (front matter) — default routing
|
|
535
|
+
- `reasoning`, `sampling`, `response` (front matter) — default model behavior
|
|
536
|
+
- `cache`, `provider_options`, `raw` (front matter) — default provider-specific options
|
|
537
|
+
- `tools`, `mcp`, `context`, `includes` (front matter) — default bindings and input/include configuration
|
|
538
|
+
- `environments`, `tiers` (front matter) — default override maps
|
|
191
539
|
- `metadata` (front matter) — merged with prompt-local metadata
|
|
192
540
|
- `# System instructions` (body section) — used when the prompt has none
|
|
193
541
|
|
|
194
542
|
This lets you configure app-wide settings like `provider` and `model`
|
|
195
543
|
in a single root `defaults.md`, so individual prompts only declare what's unique to them.
|
|
196
544
|
|
|
197
|
-
Important: `
|
|
198
|
-
|
|
545
|
+
Important: use shared `context.inputs` in `defaults.md` only when every prompt
|
|
546
|
+
under that folder uses the same placeholders. Prompt-local `context.inputs`
|
|
547
|
+
replace the inherited array.
|
|
199
548
|
|
|
200
549
|
Rules:
|
|
201
550
|
- Nearest subfolder `defaults.md` overrides parent defaults
|
|
202
551
|
- Prompt-local values always take precedence over defaults
|
|
552
|
+
- Inherited `includes` are authored relative to the `defaults.md` file that declares them
|
|
203
553
|
- `defaults.md` files are skipped during compilation and validation
|
|
204
554
|
- `loadPromptFile` defaults the search boundary to the file's own directory;
|
|
205
555
|
pass `defaultsRoot` to enable ancestor traversal
|
|
@@ -250,7 +600,7 @@ Prefer portable fields first:
|
|
|
250
600
|
- Use `cache` for provider cache hints
|
|
251
601
|
- Use `tools` for tool definitions
|
|
252
602
|
|
|
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`.
|
|
603
|
+
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
604
|
|
|
255
605
|
Use `provider_options` for known non-portable mappings:
|
|
256
606
|
|
|
@@ -275,8 +625,16 @@ provider_options:
|
|
|
275
625
|
provider:
|
|
276
626
|
order: ["anthropic", "openai"]
|
|
277
627
|
transforms: ["middle-out"]
|
|
628
|
+
llmasaservice:
|
|
629
|
+
project_id: llm-project-id
|
|
630
|
+
# Optional default; usually pass the real customer at render time.
|
|
631
|
+
customer:
|
|
632
|
+
customer_id: cust_123
|
|
633
|
+
customer_name: Acme
|
|
278
634
|
```
|
|
279
635
|
|
|
636
|
+
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.
|
|
637
|
+
|
|
280
638
|
Use `raw` only when a vendor request-body field is important and PromptOpsKit does not model it yet:
|
|
281
639
|
|
|
282
640
|
```yaml
|
|
@@ -292,9 +650,11 @@ raw:
|
|
|
292
650
|
openrouter:
|
|
293
651
|
usage:
|
|
294
652
|
include: true
|
|
653
|
+
llmasaservice:
|
|
654
|
+
conversationId: conv_123
|
|
295
655
|
```
|
|
296
656
|
|
|
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.
|
|
657
|
+
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
658
|
|
|
299
659
|
---
|
|
300
660
|
|
|
@@ -535,8 +895,8 @@ Hello {{ name }}
|
|
|
535
895
|
|
|
536
896
|
1. **One prompt per file** — each `.md` file is a single prompt asset
|
|
537
897
|
2. **Always set `id` and `schema_version: 1`** unless a surrounding tool explicitly generates those fields
|
|
538
|
-
3. **Declare every placeholder** in `context.inputs`;
|
|
539
|
-
4. **Use `defaults.md` for shared provider, model, metadata, and fallback system instructions**
|
|
898
|
+
3. **Declare every placeholder** in `context.inputs`; use `defaults.md` only for input declarations that apply to every prompt under that folder
|
|
899
|
+
4. **Use `defaults.md` for shared provider, model, provider options, metadata, and fallback system instructions**
|
|
540
900
|
5. **Use includes for reusable system behavior**, not for user-specific prompt bodies
|
|
541
901
|
6. **Prefer `createPromptOpsKit().renderPrompt()` for server-side app code** when prompts live as source files
|
|
542
902
|
7. **Prefer direct adapters for compiled assets or provider-specific integration points**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
applyRawProviderBody,
|
|
3
|
+
compactHistoryForPrompt,
|
|
3
4
|
renderSections,
|
|
4
5
|
resolveAssetForProvider,
|
|
5
6
|
withPromptInputSupport
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JR7252DG.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
|
-
|
|
38
|
-
|
|
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-
|
|
115
|
+
//# sourceMappingURL=chunk-55B7QQBK.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-
|
|
391
|
+
//# sourceMappingURL=chunk-AGTGIZMR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/usagetap/client.ts","../src/usagetap/lifecycle.ts","../src/usagetap/providers.ts"],"sourcesContent":["import type {\n UsageTapBeginRequest,\n UsageTapBeginResponse,\n UsageTapClient,\n UsageTapClientConfig,\n UsageTapEndRequest,\n UsageTapEndResponse,\n UsageTapRequestInit,\n} from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://api.usagetap.com';\nconst ACCEPT_HEADER = 'application/vnd.usagetap.v1+json';\n\nfunction createUsageTapHttpError(status: number, body: unknown): Error & { statusCode: number; body: unknown } {\n const error = new Error(`UsageTap request failed with status ${status}`) as Error & {\n statusCode: number;\n body: unknown;\n };\n error.statusCode = status;\n error.body = body;\n return error;\n}\n\nexport function createUsageTapClient(config: UsageTapClientConfig): UsageTapClient {\n const fetchImpl = config.fetch ?? globalThis.fetch;\n\n if (!fetchImpl) {\n throw new Error('Fetch API is not available. Provide config.fetch when creating the UsageTap client.');\n }\n\n const baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n\n async function request<T>(path: string, body: unknown, init: UsageTapRequestInit = {}): Promise<T> {\n const response = await fetchImpl(`${baseUrl}${path}`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${config.apiKey}`,\n Accept: ACCEPT_HEADER,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n signal: init.signal,\n });\n\n const text = await response.text();\n const parsed = text ? JSON.parse(text) as unknown : {};\n\n if (!response.ok) {\n throw createUsageTapHttpError(response.status, parsed);\n }\n\n return parsed as T;\n }\n\n return {\n request,\n beginCall(begin: UsageTapBeginRequest, init?: UsageTapRequestInit): Promise<UsageTapBeginResponse> {\n return request<UsageTapBeginResponse>('/call_begin', begin, init);\n },\n endCall(end: UsageTapEndRequest, init?: UsageTapRequestInit): Promise<UsageTapEndResponse> {\n return request<UsageTapEndResponse>('/call_end', end, init);\n },\n };\n}\n","import type {\n UsageTapCallOptions,\n UsageTapCallResult,\n UsageTapClient,\n UsageTapEndRequest,\n UsageTapEndUsage,\n UsageTapErrorPayload,\n UsageTapInvokeResult,\n UsageTapRequestInit,\n} from './types.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isInvokeResult<TResult>(value: TResult | UsageTapInvokeResult<TResult>): value is UsageTapInvokeResult<TResult> {\n return isObject(value) && 'result' in value && 'usage' in value;\n}\n\nfunction getErrorStatusCode(error: unknown): number | undefined {\n if (!isObject(error)) {\n return undefined;\n }\n\n if (typeof error.statusCode === 'number') {\n return error.statusCode;\n }\n\n if (typeof error.status === 'number') {\n return error.status;\n }\n\n if (isObject(error.response) && typeof error.response.status === 'number') {\n return error.response.status;\n }\n\n return undefined;\n}\n\nfunction attachEndErrorCause(thrownError: unknown, endError: unknown): never {\n if (thrownError instanceof Error) {\n if (thrownError.cause === undefined) {\n Object.defineProperty(thrownError, 'cause', {\n value: endError,\n configurable: true,\n writable: true,\n });\n }\n\n throw thrownError;\n }\n\n throw new AggregateError([thrownError, endError], 'Vendor call failed and UsageTap call_end also failed.');\n}\n\nexport function defaultUsageTapErrorMapper(error: unknown): UsageTapErrorPayload {\n return {\n code: 'VENDOR_ERROR',\n message: String(error),\n };\n}\n\nexport function beginUsageTapCall(client: UsageTapClient, begin: Parameters<UsageTapClient['beginCall']>[0], init?: UsageTapRequestInit) {\n return client.beginCall(begin, init);\n}\n\nexport function endUsageTapCall(client: UsageTapClient, end: UsageTapEndRequest, init?: UsageTapRequestInit) {\n return client.endCall(end, init);\n}\n\nexport async function withUsageTapCall<TResult>(\n client: UsageTapClient,\n options: UsageTapCallOptions<TResult>,\n): Promise<UsageTapCallResult<TResult>> {\n const begin = await beginUsageTapCall(client, options.begin, { signal: options.signal });\n const onError = options.onError ?? defaultUsageTapErrorMapper;\n\n let result: TResult | undefined;\n let usage: UsageTapEndUsage | undefined;\n let thrownError: unknown;\n\n const setUsage = (nextUsage: UsageTapEndUsage): void => {\n usage = { ...usage, ...nextUsage };\n };\n\n try {\n const invoked = await options.invoke({\n begin,\n setUsage,\n signal: options.signal,\n });\n\n if (isInvokeResult(invoked)) {\n result = invoked.result;\n setUsage(invoked.usage);\n } else {\n result = invoked;\n }\n } catch (error) {\n thrownError = error;\n }\n\n const effectiveUsage: UsageTapEndUsage = {\n ...usage,\n };\n\n if (thrownError) {\n effectiveUsage.error = effectiveUsage.error ?? onError(thrownError);\n effectiveUsage.responseStatusCode = effectiveUsage.responseStatusCode ?? getErrorStatusCode(thrownError);\n } else {\n effectiveUsage.responseStatusCode = effectiveUsage.responseStatusCode ?? 200;\n }\n\n let end;\n try {\n end = await endUsageTapCall(client, {\n callId: begin.data.callId,\n ...effectiveUsage,\n }, { signal: options.signal });\n } catch (endError) {\n if (thrownError) {\n attachEndErrorCause(thrownError, endError);\n }\n throw endError;\n }\n\n if (thrownError) {\n throw thrownError;\n }\n\n return {\n result: result as TResult,\n begin,\n end,\n effectiveUsage,\n };\n}\n","import type { ProviderRequest } from '../providers/types.js';\nimport { defaultUsageTapErrorMapper, withUsageTapCall } from './lifecycle.js';\nimport type {\n UsageTapAllowed,\n UsageTapAllowedCapability,\n UsageTapBeginResponse,\n UsageTapClient,\n UsageTapEndUsage,\n UsageTapEntitlementOptions,\n UsageTapProviderRunOptions,\n UsageTapProviderRunResult,\n UsageTapReasoningLevel,\n} from './types.js';\n\nfunction cloneRequest(request: ProviderRequest): ProviderRequest {\n return structuredClone(request);\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction isRecordArray(value: unknown): value is Array<Record<string, unknown>> {\n return Array.isArray(value) && value.every((item) => isObject(item));\n}\n\nfunction isInvokeResult<TResult>(value: unknown): value is { result: TResult; usage: UsageTapEndUsage } {\n return isObject(value) && 'result' in value && 'usage' in value;\n}\n\nfunction capabilityAllowed(allowed: UsageTapAllowed, capability: UsageTapAllowedCapability): boolean {\n return allowed[capability] !== false;\n}\n\nfunction reasoningLevelOrder(level: UsageTapReasoningLevel | undefined): number {\n switch (level) {\n case 'HIGH':\n return 3;\n case 'MEDIUM':\n return 2;\n case 'LOW':\n return 1;\n default:\n return 0;\n }\n}\n\nfunction capOpenAIReasoning(body: Record<string, unknown>, allowed: UsageTapAllowed): void {\n if (typeof body.reasoning_effort !== 'string') {\n return;\n }\n\n const current = String(body.reasoning_effort).toUpperCase() as UsageTapReasoningLevel;\n const allowedLevel = allowed.reasoningLevel ?? 'HIGH';\n\n if (allowedLevel === 'NONE') {\n delete body.reasoning_effort;\n return;\n }\n\n if (reasoningLevelOrder(current) > reasoningLevelOrder(allowedLevel)) {\n body.reasoning_effort = allowedLevel.toLowerCase();\n }\n}\n\nfunction capGeminiReasoning(body: Record<string, unknown>, allowed: UsageTapAllowed): void {\n if (allowed.reasoningLevel === 'NONE') {\n delete body.thinkingConfig;\n return;\n }\n\n const budgets: Record<Exclude<UsageTapReasoningLevel, 'NONE'>, number> = {\n LOW: 1024,\n MEDIUM: 4096,\n HIGH: 8192,\n };\n\n const allowedBudget = allowed.reasoningLevel ? budgets[allowed.reasoningLevel as Exclude<UsageTapReasoningLevel, 'NONE'>] : undefined;\n\n if (allowedBudget === undefined) {\n return;\n }\n\n if (!isObject(body.thinkingConfig)) {\n body.thinkingConfig = { thinkingBudget: allowedBudget };\n return;\n }\n\n const thinkingConfig = body.thinkingConfig;\n\n if (typeof thinkingConfig.thinkingBudget === 'number') {\n thinkingConfig.thinkingBudget = Math.min(thinkingConfig.thinkingBudget, allowedBudget);\n return;\n }\n\n thinkingConfig.thinkingBudget = allowedBudget;\n}\n\nfunction applyModelTier(request: ProviderRequest, allowed: UsageTapAllowed, options: UsageTapEntitlementOptions): void {\n const nextModel = allowed.premium && options.modelTiers?.premium\n ? options.modelTiers.premium\n : allowed.standard && options.modelTiers?.standard\n ? options.modelTiers.standard\n : undefined;\n\n if (!nextModel) {\n return;\n }\n\n request.model = nextModel;\n if (isObject(request.body) && 'model' in request.body) {\n request.body.model = nextModel;\n }\n}\n\nfunction filterOpenAITools(tools: Array<Record<string, unknown>>, allowed: UsageTapAllowed, options: UsageTapEntitlementOptions): Array<Record<string, unknown>> {\n return tools.filter((tool) => {\n if (tool.type === 'web_search' && allowed.search === false) {\n return false;\n }\n\n const functionDef = isObject(tool.function) ? tool.function : undefined;\n const name = typeof functionDef?.name === 'string'\n ? functionDef.name\n : typeof tool.name === 'string'\n ? tool.name\n : typeof tool.type === 'string'\n ? tool.type\n : undefined;\n\n if (!name) {\n return true;\n }\n\n const capability = options.toolEntitlements?.[name];\n return capability ? capabilityAllowed(allowed, capability) : true;\n });\n}\n\nfunction filterAnthropicTools(tools: Array<Record<string, unknown>>, allowed: UsageTapAllowed, options: UsageTapEntitlementOptions): Array<Record<string, unknown>> {\n return tools.filter((tool) => {\n const name = typeof tool.name === 'string' ? tool.name : undefined;\n if (!name) {\n return true;\n }\n const capability = options.toolEntitlements?.[name];\n return capability ? capabilityAllowed(allowed, capability) : true;\n });\n}\n\nfunction filterGeminiTools(tools: Array<Record<string, unknown>>, allowed: UsageTapAllowed, options: UsageTapEntitlementOptions): Array<Record<string, unknown>> {\n return tools\n .map((tool) => {\n const declarations = Array.isArray(tool.functionDeclarations)\n ? tool.functionDeclarations.filter((declaration) => {\n if (!isObject(declaration) || typeof declaration.name !== 'string') {\n return true;\n }\n const capability = options.toolEntitlements?.[declaration.name];\n return capability ? capabilityAllowed(allowed, capability) : true;\n })\n : tool.functionDeclarations;\n\n return {\n ...tool,\n functionDeclarations: declarations,\n };\n })\n .filter((tool) => {\n if (!Array.isArray(tool.functionDeclarations)) {\n return true;\n }\n return tool.functionDeclarations.length > 0;\n });\n}\n\nexport function applyUsageTapEntitlements(\n request: ProviderRequest,\n begin: UsageTapBeginResponse,\n options: UsageTapEntitlementOptions = {},\n): ProviderRequest {\n const nextRequest = cloneRequest(request);\n const allowed = begin.data.allowed ?? {};\n\n applyModelTier(nextRequest, allowed, options);\n\n if (!isObject(nextRequest.body)) {\n return nextRequest;\n }\n\n if (nextRequest.provider === 'openai' || nextRequest.provider === 'openrouter' || nextRequest.provider === 'llmasaservice') {\n capOpenAIReasoning(nextRequest.body, allowed);\n if (isRecordArray(nextRequest.body.tools)) {\n nextRequest.body.tools = filterOpenAITools(nextRequest.body.tools, allowed, options);\n }\n return nextRequest;\n }\n\n if (nextRequest.provider === 'gemini') {\n capGeminiReasoning(nextRequest.body, allowed);\n if (isRecordArray(nextRequest.body.tools)) {\n nextRequest.body.tools = filterGeminiTools(nextRequest.body.tools, allowed, options);\n }\n return nextRequest;\n }\n\n if (nextRequest.provider === 'anthropic' && isRecordArray(nextRequest.body.tools)) {\n nextRequest.body.tools = filterAnthropicTools(nextRequest.body.tools, allowed, options);\n }\n\n return nextRequest;\n}\n\ninterface UsageMeta {\n modelUsed?: string;\n responseStatusCode?: number;\n}\n\nexport function extractOpenAIUsage(response: unknown, meta: UsageMeta = {}): UsageTapEndUsage {\n const usage = isObject(response) && isObject(response.usage) ? response.usage : {};\n const promptDetails = isObject(usage.prompt_tokens_details) ? usage.prompt_tokens_details : {};\n const completionDetails = isObject(usage.completion_tokens_details) ? usage.completion_tokens_details : {};\n\n return {\n modelUsed: meta.modelUsed,\n inputTokens: typeof usage.prompt_tokens === 'number' ? usage.prompt_tokens : 0,\n responseTokens: typeof usage.completion_tokens === 'number' ? usage.completion_tokens : 0,\n cachedInputTokens: typeof promptDetails.cached_tokens === 'number' ? promptDetails.cached_tokens : undefined,\n reasoningTokens: typeof completionDetails.reasoning_tokens === 'number' ? completionDetails.reasoning_tokens : undefined,\n responseStatusCode: meta.responseStatusCode ?? 200,\n };\n}\n\nexport function extractAnthropicUsage(response: unknown, meta: UsageMeta = {}): UsageTapEndUsage {\n const usage = isObject(response) && isObject(response.usage) ? response.usage : {};\n\n return {\n modelUsed: meta.modelUsed,\n inputTokens: typeof usage.input_tokens === 'number' ? usage.input_tokens : 0,\n responseTokens: typeof usage.output_tokens === 'number' ? usage.output_tokens : 0,\n cachedInputTokens: typeof usage.cache_read_input_tokens === 'number' ? usage.cache_read_input_tokens : undefined,\n responseStatusCode: meta.responseStatusCode ?? 200,\n };\n}\n\nexport function extractGeminiUsage(response: unknown, meta: UsageMeta = {}): UsageTapEndUsage {\n const usage = isObject(response) && isObject(response.usageMetadata) ? response.usageMetadata : {};\n\n return {\n modelUsed: meta.modelUsed,\n inputTokens: typeof usage.promptTokenCount === 'number' ? usage.promptTokenCount : 0,\n responseTokens: typeof usage.candidatesTokenCount === 'number' ? usage.candidatesTokenCount : 0,\n cachedInputTokens: typeof usage.cachedContentTokenCount === 'number' ? usage.cachedContentTokenCount : undefined,\n reasoningTokens: typeof usage.thoughtsTokenCount === 'number' ? usage.thoughtsTokenCount : undefined,\n responseStatusCode: meta.responseStatusCode ?? 200,\n };\n}\n\nasync function runProviderWithUsageTap<TResult>(\n client: UsageTapClient,\n options: UsageTapProviderRunOptions<TResult>,\n defaultExtractor: (response: TResult, meta: UsageMeta) => UsageTapEndUsage,\n): Promise<UsageTapProviderRunResult<TResult>> {\n let requestUsed = cloneRequest(options.request);\n\n const lifecycle = await withUsageTapCall(client, {\n begin: options.begin,\n signal: options.signal,\n onError: options.onError ?? defaultUsageTapErrorMapper,\n invoke: async ({ begin, setUsage }) => {\n requestUsed = options.entitlementMode === 'apply'\n ? applyUsageTapEntitlements(options.request, begin, options)\n : cloneRequest(options.request);\n\n const invoked = await options.invoke(requestUsed);\n\n if (isInvokeResult<TResult>(invoked)) {\n return invoked;\n }\n\n const response = invoked as TResult;\n const usage = (options.extractUsage ?? defaultExtractor)(response, {\n modelUsed: requestUsed.model,\n responseStatusCode: 200,\n });\n setUsage(usage);\n return response;\n },\n });\n\n return {\n response: lifecycle.result,\n begin: lifecycle.begin,\n end: lifecycle.end,\n requestUsed,\n effectiveUsage: lifecycle.effectiveUsage,\n allowed: lifecycle.begin.data.allowed ?? {},\n };\n}\n\nexport function runOpenAIWithUsageTap<TResult>(client: UsageTapClient, options: UsageTapProviderRunOptions<TResult>) {\n return runProviderWithUsageTap(client, options, extractOpenAIUsage);\n}\n\nexport function runOpenRouterWithUsageTap<TResult>(client: UsageTapClient, options: UsageTapProviderRunOptions<TResult>) {\n return runProviderWithUsageTap(client, options, extractOpenAIUsage);\n}\n\nexport function runLLMAsAServiceWithUsageTap<TResult>(client: UsageTapClient, options: UsageTapProviderRunOptions<TResult>) {\n return runProviderWithUsageTap(client, options, extractOpenAIUsage);\n}\n\nexport function runAnthropicWithUsageTap<TResult>(client: UsageTapClient, options: UsageTapProviderRunOptions<TResult>) {\n return runProviderWithUsageTap(client, options, extractAnthropicUsage);\n}\n\nexport function runGeminiWithUsageTap<TResult>(client: UsageTapClient, options: UsageTapProviderRunOptions<TResult>) {\n return runProviderWithUsageTap(client, options, extractGeminiUsage);\n}\n"],"mappings":"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","names":["isObject","isInvokeResult"]}
|