promptopskit 0.3.1 → 0.3.4
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 +28 -2
- package/SKILL.md +121 -107
- package/dist/{chunk-LRRSI4ON.js → chunk-R5PKK6Y7.js} +6 -5
- package/dist/chunk-R5PKK6Y7.js.map +1 -0
- package/dist/chunk-S5YHGHK5.js +311 -0
- package/dist/chunk-S5YHGHK5.js.map +1 -0
- package/dist/{chunk-DDXFDVA6.js → chunk-U7IDX2P7.js} +7 -4
- package/dist/chunk-U7IDX2P7.js.map +1 -0
- package/dist/{chunk-LNZS3TIJ.js → chunk-UJA7XBQZ.js} +6 -5
- package/dist/chunk-UJA7XBQZ.js.map +1 -0
- package/dist/{chunk-Y2YYEGOY.js → chunk-VU3WKLFI.js} +6 -5
- package/dist/chunk-VU3WKLFI.js.map +1 -0
- package/dist/cli/index.js +36 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +258 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +24 -163
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.cjs +470 -2
- package/dist/providers/anthropic.cjs.map +1 -1
- package/dist/providers/anthropic.d.cts +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +3 -2
- package/dist/providers/gemini.cjs +470 -2
- package/dist/providers/gemini.cjs.map +1 -1
- package/dist/providers/gemini.d.cts +1 -1
- package/dist/providers/gemini.d.ts +1 -1
- package/dist/providers/gemini.js +3 -2
- package/dist/providers/openai.cjs +470 -2
- package/dist/providers/openai.cjs.map +1 -1
- package/dist/providers/openai.d.cts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.js +3 -2
- package/dist/providers/openrouter.cjs +472 -4
- package/dist/providers/openrouter.cjs.map +1 -1
- package/dist/providers/openrouter.d.cts +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +4 -3
- package/dist/types-CgA7_wNI.d.cts +68 -0
- package/dist/types-D_-336jx.d.ts +68 -0
- package/dist/usagetap/index.d.cts +1 -1
- package/dist/usagetap/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-DDXFDVA6.js.map +0 -1
- package/dist/chunk-DGFBS7YW.js +0 -101
- package/dist/chunk-DGFBS7YW.js.map +0 -1
- package/dist/chunk-LNZS3TIJ.js.map +0 -1
- package/dist/chunk-LRRSI4ON.js.map +0 -1
- package/dist/chunk-Y2YYEGOY.js.map +0 -1
- package/dist/types-BsYdPHTU.d.ts +0 -43
- package/dist/types-DC-jI6iV.d.cts +0 -43
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import {
|
|
2
|
+
loadPromptFile,
|
|
3
|
+
parsePrompt
|
|
4
|
+
} from "./chunk-2LK6IILW.js";
|
|
5
|
+
|
|
6
|
+
// src/renderer/interpolate.ts
|
|
7
|
+
var VARIABLE_RE = /\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;
|
|
8
|
+
var ESCAPED_OPEN = /\\\{\\\{/g;
|
|
9
|
+
var ESCAPE_PLACEHOLDER = "\0ESCAPED_OPEN\0";
|
|
10
|
+
function interpolate(template, variables, options = {}) {
|
|
11
|
+
const { strict = false } = options;
|
|
12
|
+
let result = template.replace(ESCAPED_OPEN, ESCAPE_PLACEHOLDER);
|
|
13
|
+
result = result.replace(VARIABLE_RE, (match, name) => {
|
|
14
|
+
if (name in variables) {
|
|
15
|
+
return variables[name];
|
|
16
|
+
}
|
|
17
|
+
if (strict) {
|
|
18
|
+
throw new Error(`Missing required variable: "${name}"`);
|
|
19
|
+
}
|
|
20
|
+
return match;
|
|
21
|
+
});
|
|
22
|
+
result = result.replaceAll(ESCAPE_PLACEHOLDER, "{{");
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
function extractVariables(template) {
|
|
26
|
+
const vars = /* @__PURE__ */ new Set();
|
|
27
|
+
let match;
|
|
28
|
+
const re = new RegExp(VARIABLE_RE.source, "g");
|
|
29
|
+
while ((match = re.exec(template)) !== null) {
|
|
30
|
+
vars.add(match[1]);
|
|
31
|
+
}
|
|
32
|
+
return [...vars];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/renderer/renderer.ts
|
|
36
|
+
function renderSections(asset, options = {}) {
|
|
37
|
+
const { variables = {}, strict = false } = options;
|
|
38
|
+
const result = {};
|
|
39
|
+
if (asset.sections.system_instructions) {
|
|
40
|
+
result.system_instructions = interpolate(
|
|
41
|
+
asset.sections.system_instructions,
|
|
42
|
+
variables,
|
|
43
|
+
{ strict }
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (asset.sections.prompt_template) {
|
|
47
|
+
result.prompt_template = interpolate(
|
|
48
|
+
asset.sections.prompt_template,
|
|
49
|
+
variables,
|
|
50
|
+
{ strict }
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/overrides/apply-overrides.ts
|
|
57
|
+
function applyOverrides(asset, options = {}) {
|
|
58
|
+
let result = { ...asset };
|
|
59
|
+
if (options.environment && result.environments?.[options.environment]) {
|
|
60
|
+
result = mergeOverride(result, result.environments[options.environment]);
|
|
61
|
+
}
|
|
62
|
+
if (options.tier && result.tiers?.[options.tier]) {
|
|
63
|
+
result = mergeOverride(result, result.tiers[options.tier]);
|
|
64
|
+
}
|
|
65
|
+
if (options.runtime) {
|
|
66
|
+
result = mergeOverride(result, options.runtime);
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
function mergeOverride(base, override) {
|
|
71
|
+
const result = { ...base };
|
|
72
|
+
if (override.model !== void 0) result.model = override.model;
|
|
73
|
+
if (override.fallback_models !== void 0) result.fallback_models = override.fallback_models;
|
|
74
|
+
if (override.tools !== void 0) result.tools = override.tools;
|
|
75
|
+
if (override.reasoning !== void 0) {
|
|
76
|
+
result.reasoning = { ...result.reasoning, ...override.reasoning };
|
|
77
|
+
}
|
|
78
|
+
if (override.sampling !== void 0) {
|
|
79
|
+
result.sampling = { ...result.sampling, ...override.sampling };
|
|
80
|
+
}
|
|
81
|
+
if (override.response !== void 0) {
|
|
82
|
+
result.response = { ...result.response, ...override.response };
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/providers/resolve-asset.ts
|
|
88
|
+
function resolveAssetForProvider(asset, runtime = {}) {
|
|
89
|
+
if (!runtime.environment && !runtime.tier && !runtime.runtime) {
|
|
90
|
+
return asset;
|
|
91
|
+
}
|
|
92
|
+
return applyOverrides(asset, {
|
|
93
|
+
environment: runtime.environment,
|
|
94
|
+
tier: runtime.tier,
|
|
95
|
+
runtime: runtime.runtime
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/cache.ts
|
|
100
|
+
import { statSync } from "fs";
|
|
101
|
+
var PromptCache = class {
|
|
102
|
+
cache = /* @__PURE__ */ new Map();
|
|
103
|
+
maxSize;
|
|
104
|
+
constructor(maxSize = 100) {
|
|
105
|
+
this.maxSize = maxSize;
|
|
106
|
+
}
|
|
107
|
+
get(filePath) {
|
|
108
|
+
const entry = this.cache.get(filePath);
|
|
109
|
+
if (!entry) return void 0;
|
|
110
|
+
try {
|
|
111
|
+
const stat = statSync(filePath);
|
|
112
|
+
if (stat.mtimeMs !== entry.mtime) {
|
|
113
|
+
this.cache.delete(filePath);
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
117
|
+
this.cache.delete(filePath);
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
this.cache.delete(filePath);
|
|
121
|
+
this.cache.set(filePath, entry);
|
|
122
|
+
return entry.value;
|
|
123
|
+
}
|
|
124
|
+
set(filePath, value) {
|
|
125
|
+
try {
|
|
126
|
+
const stat = statSync(filePath);
|
|
127
|
+
if (this.cache.has(filePath)) {
|
|
128
|
+
this.cache.delete(filePath);
|
|
129
|
+
} else if (this.cache.size >= this.maxSize) {
|
|
130
|
+
const oldest = this.cache.keys().next().value;
|
|
131
|
+
if (oldest) this.cache.delete(oldest);
|
|
132
|
+
}
|
|
133
|
+
this.cache.set(filePath, { value, mtime: stat.mtimeMs });
|
|
134
|
+
} catch {
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
clear() {
|
|
138
|
+
this.cache.clear();
|
|
139
|
+
}
|
|
140
|
+
get size() {
|
|
141
|
+
return this.cache.size;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/composition/resolve-includes.ts
|
|
146
|
+
import { readFile } from "fs/promises";
|
|
147
|
+
import { resolve, dirname } from "path";
|
|
148
|
+
async function resolveIncludes(asset, basePath, visited = /* @__PURE__ */ new Set()) {
|
|
149
|
+
if (!asset.includes || asset.includes.length === 0) {
|
|
150
|
+
return asset;
|
|
151
|
+
}
|
|
152
|
+
const baseDir = dirname(basePath);
|
|
153
|
+
const resolvedPath = resolve(basePath);
|
|
154
|
+
if (visited.has(resolvedPath)) {
|
|
155
|
+
throw new Error(`Circular include detected: ${resolvedPath}`);
|
|
156
|
+
}
|
|
157
|
+
visited.add(resolvedPath);
|
|
158
|
+
let mergedSystemInstructions = "";
|
|
159
|
+
for (const includePath of asset.includes) {
|
|
160
|
+
const fullPath = resolve(baseDir, includePath);
|
|
161
|
+
if (visited.has(fullPath)) {
|
|
162
|
+
throw new Error(`Circular include detected: ${fullPath} (included from ${basePath})`);
|
|
163
|
+
}
|
|
164
|
+
const content = await readFile(fullPath, "utf-8");
|
|
165
|
+
const { asset: includedAsset } = parsePrompt(content, fullPath);
|
|
166
|
+
const resolved = await resolveIncludes(includedAsset, fullPath, new Set(visited));
|
|
167
|
+
if (resolved.sections?.system_instructions) {
|
|
168
|
+
mergedSystemInstructions += resolved.sections.system_instructions + "\n\n";
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const localSystem = asset.sections?.system_instructions ?? "";
|
|
172
|
+
const combinedSystem = (mergedSystemInstructions + localSystem).trim() || void 0;
|
|
173
|
+
return {
|
|
174
|
+
...asset,
|
|
175
|
+
sections: {
|
|
176
|
+
...asset.sections,
|
|
177
|
+
system_instructions: combinedSystem
|
|
178
|
+
},
|
|
179
|
+
// Drop includes from the resolved asset — they've been inlined
|
|
180
|
+
includes: void 0
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/prompt-resolution.ts
|
|
185
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
186
|
+
import { existsSync, statSync as statSync2 } from "fs";
|
|
187
|
+
import { resolve as resolve2 } from "path";
|
|
188
|
+
var sharedPromptCache = new PromptCache();
|
|
189
|
+
async function loadPromptAsset(promptPath, config, promptCache = sharedPromptCache) {
|
|
190
|
+
const mode = config.mode ?? "auto";
|
|
191
|
+
if (mode !== "source-only" && config.compiledDir) {
|
|
192
|
+
const compiledFile = resolve2(config.compiledDir, promptPath + ".json");
|
|
193
|
+
if (existsSync(compiledFile)) {
|
|
194
|
+
if (mode === "auto") {
|
|
195
|
+
const sourceFile = resolve2(config.sourceDir, promptPath + ".md");
|
|
196
|
+
if (existsSync(sourceFile)) {
|
|
197
|
+
const compiledMtime = statSync2(compiledFile).mtimeMs;
|
|
198
|
+
const sourceMtime = statSync2(sourceFile).mtimeMs;
|
|
199
|
+
if (sourceMtime > compiledMtime) {
|
|
200
|
+
console.warn(
|
|
201
|
+
`[promptopskit] Warning: compiled artifact for "${promptPath}" is older than source .md file.
|
|
202
|
+
Run "promptopskit compile" or switch to source-only mode.`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const content = await readFile2(compiledFile, "utf-8");
|
|
208
|
+
return JSON.parse(content);
|
|
209
|
+
}
|
|
210
|
+
if (mode === "compiled-only") {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Compiled artifact not found: ${compiledFile}
|
|
213
|
+
Run "promptopskit compile" to generate it.`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (mode !== "compiled-only") {
|
|
218
|
+
const sourceFile = resolve2(config.sourceDir, promptPath + ".md");
|
|
219
|
+
if (config.cache !== false) {
|
|
220
|
+
const cached = promptCache.get(sourceFile);
|
|
221
|
+
if (cached) {
|
|
222
|
+
return cached;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (!existsSync(sourceFile)) {
|
|
226
|
+
const paths = [sourceFile];
|
|
227
|
+
if (config.compiledDir) {
|
|
228
|
+
paths.unshift(resolve2(config.compiledDir, promptPath + ".json"));
|
|
229
|
+
}
|
|
230
|
+
throw new Error(
|
|
231
|
+
`Prompt not found: "${promptPath}"
|
|
232
|
+
Searched:
|
|
233
|
+
${paths.map((candidate) => ` - ${candidate}`).join("\n")}`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
const { asset } = await loadPromptFile(sourceFile, { defaultsRoot: config.sourceDir });
|
|
237
|
+
if (config.cache !== false) {
|
|
238
|
+
promptCache.set(sourceFile, asset);
|
|
239
|
+
}
|
|
240
|
+
return asset;
|
|
241
|
+
}
|
|
242
|
+
throw new Error(`Prompt not found: "${promptPath}"`);
|
|
243
|
+
}
|
|
244
|
+
async function resolvePromptAsset(promptPath, config, options = {}, promptCache = sharedPromptCache) {
|
|
245
|
+
let asset = await loadPromptAsset(promptPath, config, promptCache);
|
|
246
|
+
const sourceFile = resolve2(config.sourceDir, promptPath + ".md");
|
|
247
|
+
if (asset.includes && asset.includes.length > 0 && existsSync(sourceFile)) {
|
|
248
|
+
asset = await resolveIncludes(asset, sourceFile);
|
|
249
|
+
}
|
|
250
|
+
asset = applyOverrides(asset, {
|
|
251
|
+
environment: options.environment,
|
|
252
|
+
tier: options.tier,
|
|
253
|
+
runtime: options.runtime
|
|
254
|
+
});
|
|
255
|
+
return asset;
|
|
256
|
+
}
|
|
257
|
+
function resolveInlinePromptSource(source, options = {}) {
|
|
258
|
+
const { asset } = parsePrompt(source);
|
|
259
|
+
return applyOverrides(asset, {
|
|
260
|
+
environment: options.environment,
|
|
261
|
+
tier: options.tier,
|
|
262
|
+
runtime: options.runtime
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// src/providers/prompt-input.ts
|
|
267
|
+
function isPromptLookup(input) {
|
|
268
|
+
return "path" in input && typeof input.path === "string" && "sourceDir" in input;
|
|
269
|
+
}
|
|
270
|
+
function isInlinePromptSource(input) {
|
|
271
|
+
return "source" in input && typeof input.source === "string";
|
|
272
|
+
}
|
|
273
|
+
async function resolveProviderPromptInput(input, runtime) {
|
|
274
|
+
if (isPromptLookup(input)) {
|
|
275
|
+
return resolvePromptAsset(input.path, input, runtime);
|
|
276
|
+
}
|
|
277
|
+
if (isInlinePromptSource(input)) {
|
|
278
|
+
return resolveInlinePromptSource(input.source, runtime);
|
|
279
|
+
}
|
|
280
|
+
return input;
|
|
281
|
+
}
|
|
282
|
+
function withPromptInputSupport(adapter) {
|
|
283
|
+
const validatePrompt = async (input, runtime) => {
|
|
284
|
+
const resolved = await resolveProviderPromptInput(input, runtime);
|
|
285
|
+
return adapter.validate(resolved, runtime);
|
|
286
|
+
};
|
|
287
|
+
const renderPrompt = async (input, runtime) => {
|
|
288
|
+
const resolved = await resolveProviderPromptInput(input, runtime);
|
|
289
|
+
return adapter.render(resolved, runtime);
|
|
290
|
+
};
|
|
291
|
+
return {
|
|
292
|
+
...adapter,
|
|
293
|
+
validatePrompt,
|
|
294
|
+
renderPrompt
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export {
|
|
299
|
+
interpolate,
|
|
300
|
+
extractVariables,
|
|
301
|
+
renderSections,
|
|
302
|
+
applyOverrides,
|
|
303
|
+
resolveAssetForProvider,
|
|
304
|
+
PromptCache,
|
|
305
|
+
resolveIncludes,
|
|
306
|
+
loadPromptAsset,
|
|
307
|
+
resolvePromptAsset,
|
|
308
|
+
resolveInlinePromptSource,
|
|
309
|
+
withPromptInputSupport
|
|
310
|
+
};
|
|
311
|
+
//# sourceMappingURL=chunk-S5YHGHK5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/renderer/interpolate.ts","../src/renderer/renderer.ts","../src/overrides/apply-overrides.ts","../src/providers/resolve-asset.ts","../src/cache.ts","../src/composition/resolve-includes.ts","../src/prompt-resolution.ts","../src/providers/prompt-input.ts"],"sourcesContent":["export interface InterpolateOptions {\n strict?: boolean;\n}\n\nconst VARIABLE_RE = /\\{\\{\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\}\\}/g;\nconst ESCAPED_OPEN = /\\\\\\{\\\\\\{/g;\nconst ESCAPE_PLACEHOLDER = '\\x00ESCAPED_OPEN\\x00';\n\n/**\n * Interpolate variables into a template string.\n *\n * Syntax: {{ variable_name }}\n * Escape: \\{\\{ produces literal {{\n *\n * In strict mode, throws on missing variables.\n * In permissive mode, leaves {{ placeholder }} intact.\n */\nexport function interpolate(\n template: string,\n variables: Record<string, string>,\n options: InterpolateOptions = {},\n): string {\n const { strict = false } = options;\n\n // Replace escaped sequences with placeholder\n let result = template.replace(ESCAPED_OPEN, ESCAPE_PLACEHOLDER);\n\n result = result.replace(VARIABLE_RE, (match, name: string) => {\n if (name in variables) {\n return variables[name];\n }\n if (strict) {\n throw new Error(`Missing required variable: \"${name}\"`);\n }\n return match; // leave placeholder intact in permissive mode\n });\n\n // Restore escaped sequences\n result = result.replaceAll(ESCAPE_PLACEHOLDER, '{{');\n\n return result;\n}\n\n/**\n * Extract all variable names referenced in a template.\n */\nexport function extractVariables(template: string): string[] {\n const vars = new Set<string>();\n let match: RegExpExecArray | null;\n const re = new RegExp(VARIABLE_RE.source, 'g');\n while ((match = re.exec(template)) !== null) {\n vars.add(match[1]);\n }\n return [...vars];\n}\n","import type { ResolvedPromptAsset } from '../schema/index.js';\nimport { interpolate, extractVariables } from './interpolate.js';\n\nexport interface RenderOptions {\n variables?: Record<string, string>;\n strict?: boolean;\n}\n\nexport interface RenderedSections {\n system_instructions?: string;\n prompt_template?: string;\n}\n\n/**\n * Render the sections of a resolved prompt asset with variable interpolation.\n */\nexport function renderSections(\n asset: ResolvedPromptAsset,\n options: RenderOptions = {},\n): RenderedSections {\n const { variables = {}, strict = false } = options;\n\n const result: RenderedSections = {};\n\n if (asset.sections.system_instructions) {\n result.system_instructions = interpolate(\n asset.sections.system_instructions,\n variables,\n { strict },\n );\n }\n\n if (asset.sections.prompt_template) {\n result.prompt_template = interpolate(\n asset.sections.prompt_template,\n variables,\n { strict },\n );\n }\n\n return result;\n}\n\n/**\n * Get all variable names used across all sections.\n */\nexport function getRequiredVariables(asset: ResolvedPromptAsset): string[] {\n const vars = new Set<string>();\n\n if (asset.sections.system_instructions) {\n for (const v of extractVariables(asset.sections.system_instructions)) {\n vars.add(v);\n }\n }\n\n if (asset.sections.prompt_template) {\n for (const v of extractVariables(asset.sections.prompt_template)) {\n vars.add(v);\n }\n }\n\n return [...vars];\n}\n","import type { PromptAsset, PromptAssetOverrides } from '../schema/index.js';\n\nexport interface OverrideOptions {\n environment?: string;\n tier?: string;\n runtime?: Partial<PromptAssetOverrides>;\n}\n\n/**\n * Apply environment, tier, and runtime overrides to a prompt asset.\n *\n * Precedence: base → environment → tier → runtime\n * Scalars are replaced. Arrays are replaced (not concatenated).\n */\nexport function applyOverrides(\n asset: PromptAsset,\n options: OverrideOptions = {},\n): PromptAsset {\n let result = { ...asset };\n\n // Apply environment override\n if (options.environment && result.environments?.[options.environment]) {\n result = mergeOverride(result, result.environments[options.environment]);\n }\n\n // Apply tier override\n if (options.tier && result.tiers?.[options.tier]) {\n result = mergeOverride(result, result.tiers[options.tier]);\n }\n\n // Apply runtime overrides\n if (options.runtime) {\n result = mergeOverride(result, options.runtime);\n }\n\n return result;\n}\n\nfunction mergeOverride(\n base: PromptAsset,\n override: Partial<PromptAssetOverrides>,\n): PromptAsset {\n const result = { ...base };\n\n if (override.model !== undefined) result.model = override.model;\n if (override.fallback_models !== undefined) result.fallback_models = override.fallback_models;\n if (override.tools !== undefined) result.tools = override.tools;\n\n if (override.reasoning !== undefined) {\n result.reasoning = { ...result.reasoning, ...override.reasoning };\n }\n if (override.sampling !== undefined) {\n result.sampling = { ...result.sampling, ...override.sampling };\n }\n if (override.response !== undefined) {\n result.response = { ...result.response, ...override.response };\n }\n\n return result;\n}\n","import { applyOverrides } from '../overrides/index.js';\nimport type { ResolvedPromptAsset } from '../schema/index.js';\nimport type { RuntimeRenderOptions } from './types.js';\n\nexport function resolveAssetForProvider(\n asset: ResolvedPromptAsset,\n runtime: Pick<RuntimeRenderOptions, 'environment' | 'tier' | 'runtime'> = {},\n): ResolvedPromptAsset {\n if (!runtime.environment && !runtime.tier && !runtime.runtime) {\n return asset;\n }\n\n return applyOverrides(asset, {\n environment: runtime.environment,\n tier: runtime.tier,\n runtime: runtime.runtime,\n }) as ResolvedPromptAsset;\n}","import { statSync } from 'node:fs';\n\ninterface CacheEntry<T> {\n value: T;\n mtime: number;\n}\n\n/**\n * Simple in-memory LRU cache keyed by file path + mtime.\n * Used to avoid re-parsing prompt files on every renderPrompt() call.\n */\nexport class PromptCache<T> {\n private cache = new Map<string, CacheEntry<T>>();\n private maxSize: number;\n\n constructor(maxSize = 100) {\n this.maxSize = maxSize;\n }\n\n get(filePath: string): T | undefined {\n const entry = this.cache.get(filePath);\n if (!entry) return undefined;\n\n try {\n const stat = statSync(filePath);\n if (stat.mtimeMs !== entry.mtime) {\n this.cache.delete(filePath);\n return undefined;\n }\n } catch {\n this.cache.delete(filePath);\n return undefined;\n }\n\n // Refresh recency for true LRU semantics.\n this.cache.delete(filePath);\n this.cache.set(filePath, entry);\n\n return entry.value;\n }\n\n set(filePath: string, value: T): void {\n try {\n const stat = statSync(filePath);\n\n if (this.cache.has(filePath)) {\n this.cache.delete(filePath);\n } else if (this.cache.size >= this.maxSize) {\n const oldest = this.cache.keys().next().value;\n if (oldest) this.cache.delete(oldest);\n }\n\n this.cache.set(filePath, { value, mtime: stat.mtimeMs });\n } catch {\n // Can't stat the file — don't cache\n }\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, dirname } from 'node:path';\nimport { parsePrompt } from '../parser/index.js';\nimport type { PromptAsset } from '../schema/index.js';\n\n/**\n * Resolve includes for a prompt asset, inlining content from referenced files.\n * Detects and rejects circular includes.\n */\nexport async function resolveIncludes(\n asset: PromptAsset,\n basePath: string,\n visited: Set<string> = new Set(),\n): Promise<PromptAsset> {\n if (!asset.includes || asset.includes.length === 0) {\n return asset;\n }\n\n const baseDir = dirname(basePath);\n const resolvedPath = resolve(basePath);\n\n if (visited.has(resolvedPath)) {\n throw new Error(`Circular include detected: ${resolvedPath}`);\n }\n visited.add(resolvedPath);\n\n let mergedSystemInstructions = '';\n\n for (const includePath of asset.includes) {\n const fullPath = resolve(baseDir, includePath);\n\n if (visited.has(fullPath)) {\n throw new Error(`Circular include detected: ${fullPath} (included from ${basePath})`);\n }\n\n const content = await readFile(fullPath, 'utf-8');\n const { asset: includedAsset } = parsePrompt(content, fullPath);\n\n // Recursively resolve nested includes\n const resolved = await resolveIncludes(includedAsset, fullPath, new Set(visited));\n\n // Append included system instructions before local ones\n if (resolved.sections?.system_instructions) {\n mergedSystemInstructions += resolved.sections.system_instructions + '\\n\\n';\n }\n }\n\n // Prepend included system instructions before the local ones\n const localSystem = asset.sections?.system_instructions ?? '';\n const combinedSystem = (mergedSystemInstructions + localSystem).trim() || undefined;\n\n return {\n ...asset,\n sections: {\n ...asset.sections,\n system_instructions: combinedSystem,\n },\n // Drop includes from the resolved asset — they've been inlined\n includes: undefined,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { PromptCache } from './cache.js';\nimport { resolveIncludes } from './composition/index.js';\nimport { applyOverrides } from './overrides/index.js';\nimport { parsePrompt, loadPromptFile } from './parser/index.js';\nimport type { PromptAsset, PromptAssetOverrides, ResolvedPromptAsset } from './schema/index.js';\n\nexport type PromptResolutionMode = 'auto' | 'compiled-only' | 'source-only';\n\nexport interface PromptResolutionConfig {\n sourceDir: string;\n compiledDir?: string;\n mode?: PromptResolutionMode;\n cache?: boolean;\n}\n\nconst sharedPromptCache = new PromptCache<PromptAsset>();\n\nexport async function loadPromptAsset(\n promptPath: string,\n config: PromptResolutionConfig,\n promptCache: PromptCache<PromptAsset> = sharedPromptCache,\n): Promise<PromptAsset> {\n const mode = config.mode ?? 'auto';\n\n if (mode !== 'source-only' && config.compiledDir) {\n const compiledFile = resolve(config.compiledDir, promptPath + '.json');\n if (existsSync(compiledFile)) {\n if (mode === 'auto') {\n const sourceFile = resolve(config.sourceDir, promptPath + '.md');\n if (existsSync(sourceFile)) {\n const compiledMtime = statSync(compiledFile).mtimeMs;\n const sourceMtime = statSync(sourceFile).mtimeMs;\n if (sourceMtime > compiledMtime) {\n console.warn(\n `[promptopskit] Warning: compiled artifact for \"${promptPath}\" is older than source .md file.\\n`\n + ' Run \"promptopskit compile\" or switch to source-only mode.',\n );\n }\n }\n }\n\n const content = await readFile(compiledFile, 'utf-8');\n return JSON.parse(content) as PromptAsset;\n }\n\n if (mode === 'compiled-only') {\n throw new Error(\n `Compiled artifact not found: ${compiledFile}\\n`\n + 'Run \"promptopskit compile\" to generate it.',\n );\n }\n }\n\n if (mode !== 'compiled-only') {\n const sourceFile = resolve(config.sourceDir, promptPath + '.md');\n\n if (config.cache !== false) {\n const cached = promptCache.get(sourceFile);\n if (cached) {\n return cached;\n }\n }\n\n if (!existsSync(sourceFile)) {\n const paths = [sourceFile];\n if (config.compiledDir) {\n paths.unshift(resolve(config.compiledDir, promptPath + '.json'));\n }\n\n throw new Error(\n `Prompt not found: \"${promptPath}\"\\nSearched:\\n${paths.map((candidate) => ` - ${candidate}`).join('\\n')}`,\n );\n }\n\n const { asset } = await loadPromptFile(sourceFile, { defaultsRoot: config.sourceDir });\n\n if (config.cache !== false) {\n promptCache.set(sourceFile, asset);\n }\n\n return asset;\n }\n\n throw new Error(`Prompt not found: \"${promptPath}\"`);\n}\n\nexport async function resolvePromptAsset(\n promptPath: string,\n config: PromptResolutionConfig,\n options: { environment?: string; tier?: string; runtime?: Partial<PromptAssetOverrides> } = {},\n promptCache: PromptCache<PromptAsset> = sharedPromptCache,\n): Promise<ResolvedPromptAsset> {\n let asset = await loadPromptAsset(promptPath, config, promptCache);\n\n const sourceFile = resolve(config.sourceDir, promptPath + '.md');\n if (asset.includes && asset.includes.length > 0 && existsSync(sourceFile)) {\n asset = await resolveIncludes(asset, sourceFile);\n }\n\n asset = applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n runtime: options.runtime,\n });\n\n return asset as ResolvedPromptAsset;\n}\n\nexport function resolveInlinePromptSource(\n source: string,\n options: { environment?: string; tier?: string; runtime?: Partial<PromptAssetOverrides> } = {},\n): ResolvedPromptAsset {\n const { asset } = parsePrompt(source);\n return applyOverrides(asset, {\n environment: options.environment,\n tier: options.tier,\n runtime: options.runtime,\n }) as ResolvedPromptAsset;\n}","import { resolveInlinePromptSource, resolvePromptAsset } from '../prompt-resolution.js';\nimport type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderPromptInput,\n RenderPromptMethod,\n RuntimeRenderOptions,\n ValidatePromptMethod,\n} from './types.js';\n\ntype SyncProviderAdapter = Omit<ProviderAdapter, 'validatePrompt' | 'renderPrompt'>;\n\nfunction isPromptLookup(input: ProviderPromptInput): input is Extract<ProviderPromptInput, { path: string }> {\n return 'path' in input && typeof input.path === 'string' && 'sourceDir' in input;\n}\n\nfunction isInlinePromptSource(input: ProviderPromptInput): input is Extract<ProviderPromptInput, { source: string }> {\n return 'source' in input && typeof input.source === 'string';\n}\n\nasync function resolveProviderPromptInput(\n input: ProviderPromptInput,\n runtime?: Pick<RuntimeRenderOptions, 'environment' | 'tier' | 'runtime'>,\n): Promise<ResolvedPromptAsset> {\n if (isPromptLookup(input)) {\n return resolvePromptAsset(input.path, input, runtime);\n }\n\n if (isInlinePromptSource(input)) {\n return resolveInlinePromptSource(input.source, runtime);\n }\n\n return input;\n}\n\nexport function withPromptInputSupport(adapter: SyncProviderAdapter): ProviderAdapter {\n const validatePrompt: ValidatePromptMethod = async (input, runtime) => {\n const resolved = await resolveProviderPromptInput(input, runtime);\n return adapter.validate(resolved, runtime);\n };\n\n const renderPrompt: RenderPromptMethod = async (input, runtime) => {\n const resolved = await resolveProviderPromptInput(input, runtime);\n return adapter.render(resolved, runtime);\n };\n\n return {\n ...adapter,\n validatePrompt,\n renderPrompt,\n };\n}"],"mappings":"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","names":["readFile","statSync","resolve","resolve","statSync","readFile"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
openaiAdapter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VU3WKLFI.js";
|
|
4
|
+
import {
|
|
5
|
+
withPromptInputSupport
|
|
6
|
+
} from "./chunk-S5YHGHK5.js";
|
|
4
7
|
|
|
5
8
|
// src/providers/openrouter.ts
|
|
6
|
-
var openrouterAdapter = {
|
|
9
|
+
var openrouterAdapter = withPromptInputSupport({
|
|
7
10
|
name: "openrouter",
|
|
8
11
|
validate(asset, runtime) {
|
|
9
12
|
return openaiAdapter.validate(asset, runtime);
|
|
@@ -15,9 +18,9 @@ var openrouterAdapter = {
|
|
|
15
18
|
provider: "openrouter"
|
|
16
19
|
};
|
|
17
20
|
}
|
|
18
|
-
};
|
|
21
|
+
});
|
|
19
22
|
|
|
20
23
|
export {
|
|
21
24
|
openrouterAdapter
|
|
22
25
|
};
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
26
|
+
//# sourceMappingURL=chunk-U7IDX2P7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/openrouter.ts"],"sourcesContent":["import { openaiAdapter } from './openai.js';\nimport type { ResolvedPromptAsset } from '../schema/index.js';\nimport type {\n ProviderAdapter,\n ProviderRequest,\n ValidationResult,\n RuntimeRenderOptions,\n} from './types.js';\nimport { withPromptInputSupport } from './prompt-input.js';\n\n/**\n * OpenRouter provider adapter.\n * Thin preset over the OpenAI adapter — body format is identical,\n * only the provider label differs. The app handles the different\n * base URL and extra headers (HTTP-Referer, X-Title).\n */\nexport const openrouterAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'openrouter',\n\n validate(asset: ResolvedPromptAsset, runtime?: RuntimeRenderOptions): ValidationResult {\n return openaiAdapter.validate(asset, runtime);\n },\n\n render(asset: ResolvedPromptAsset, runtime: RuntimeRenderOptions): ProviderRequest {\n const result = openaiAdapter.render(asset, runtime);\n return {\n ...result,\n provider: 'openrouter',\n };\n },\n});\n"],"mappings":";;;;;;;;AAgBO,IAAM,oBAAqC,uBAAuB;AAAA,EACvE,MAAM;AAAA,EAEN,SAAS,OAA4B,SAAkD;AACrF,WAAO,cAAc,SAAS,OAAO,OAAO;AAAA,EAC9C;AAAA,EAEA,OAAO,OAA4B,SAAgD;AACjF,UAAM,SAAS,cAAc,OAAO,OAAO,OAAO;AAClD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderSections,
|
|
3
|
-
resolveAssetForProvider
|
|
4
|
-
|
|
3
|
+
resolveAssetForProvider,
|
|
4
|
+
withPromptInputSupport
|
|
5
|
+
} from "./chunk-S5YHGHK5.js";
|
|
5
6
|
|
|
6
7
|
// src/providers/gemini.ts
|
|
7
|
-
var geminiAdapter = {
|
|
8
|
+
var geminiAdapter = withPromptInputSupport({
|
|
8
9
|
name: "gemini",
|
|
9
10
|
validate(asset, runtime) {
|
|
10
11
|
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
@@ -87,9 +88,9 @@ var geminiAdapter = {
|
|
|
87
88
|
model: resolvedAsset.model ?? "unknown"
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
|
-
};
|
|
91
|
+
});
|
|
91
92
|
|
|
92
93
|
export {
|
|
93
94
|
geminiAdapter
|
|
94
95
|
};
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
96
|
+
//# sourceMappingURL=chunk-UJA7XBQZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/gemini.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';\n\n/**\n * Google Gemini provider adapter.\n * Produces request bodies compatible with the Gemini generateContent API.\n */\nexport const geminiAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'gemini',\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('Gemini adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.sampling?.frequency_penalty !== undefined) {\n warnings.push('Gemini does not support frequency_penalty. It will be ignored.');\n }\n if (resolvedAsset.sampling?.presence_penalty !== undefined) {\n warnings.push('Gemini does not support presence_penalty. It will be ignored.');\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\n const contents: Array<Record<string, unknown>> = [];\n\n // History\n if (runtime.history) {\n for (const msg of runtime.history) {\n contents.push({\n role: msg.role === 'assistant' ? 'model' : 'user',\n parts: [{ text: msg.content }],\n });\n }\n }\n\n // User message (prompt template)\n if (sections.prompt_template) {\n contents.push({\n role: 'user',\n parts: [{ text: sections.prompt_template }],\n });\n }\n\n const body: Record<string, unknown> = {\n contents,\n };\n\n // System instruction\n if (sections.system_instructions) {\n body.systemInstruction = {\n parts: [{ text: sections.system_instructions }],\n };\n }\n\n // Generation config\n const generationConfig: Record<string, unknown> = {};\n\n if (resolvedAsset.sampling?.temperature !== undefined) generationConfig.temperature = resolvedAsset.sampling.temperature;\n if (resolvedAsset.sampling?.top_p !== undefined) generationConfig.topP = resolvedAsset.sampling.top_p;\n if (resolvedAsset.sampling?.max_output_tokens !== undefined) generationConfig.maxOutputTokens = resolvedAsset.sampling.max_output_tokens;\n if (resolvedAsset.sampling?.stop !== undefined) generationConfig.stopSequences = resolvedAsset.sampling.stop;\n\n if (resolvedAsset.response?.format === 'json') {\n generationConfig.responseMimeType = 'application/json';\n }\n\n // Thinking config\n if (resolvedAsset.reasoning?.effort) {\n body.thinkingConfig = {\n thinkingBudget: resolvedAsset.reasoning.effort === 'high' ? 8192 : resolvedAsset.reasoning.effort === 'medium' ? 4096 : 1024,\n };\n }\n\n if (Object.keys(generationConfig).length > 0) {\n body.generationConfig = generationConfig;\n }\n\n // Tools\n if (resolvedAsset.tools && resolvedAsset.tools.length > 0) {\n const functionDeclarations = resolvedAsset.tools.map((tool) => {\n if (typeof tool === 'string') {\n const def = runtime.toolRegistry?.[tool];\n if (def) return def;\n return { name: tool };\n }\n return {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n };\n });\n body.tools = [{ functionDeclarations }];\n }\n\n return {\n body,\n provider: 'gemini',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":";;;;;;;AAeO,IAAM,gBAAiC,uBAAuB;AAAA,EACnE,MAAM;AAAA,EAEN,SAAS,OAA4B,SAAkD;AACrF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,SAAmB,CAAC;AAC1B,UAAM,WAAqB,CAAC;AAE5B,QAAI,CAAC,cAAc,OAAO;AACxB,aAAO,KAAK,kDAAkD;AAAA,IAChE;AAEA,QAAI,cAAc,UAAU,sBAAsB,QAAW;AAC3D,eAAS,KAAK,gEAAgE;AAAA,IAChF;AACA,QAAI,cAAc,UAAU,qBAAqB,QAAW;AAC1D,eAAS,KAAK,+DAA+D;AAAA,IAC/E;AAEA,WAAO,EAAE,OAAO,OAAO,WAAW,GAAG,QAAQ,SAAS;AAAA,EACxD;AAAA,EAEA,OAAO,OAA4B,SAAgD;AACjF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,WAAW,eAAe,eAAe;AAAA,MAC7C,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,UAAM,WAA2C,CAAC;AAGlD,QAAI,QAAQ,SAAS;AACnB,iBAAW,OAAO,QAAQ,SAAS;AACjC,iBAAS,KAAK;AAAA,UACZ,MAAM,IAAI,SAAS,cAAc,UAAU;AAAA,UAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,QAAQ,CAAC;AAAA,QAC/B,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,SAAS,iBAAiB;AAC5B,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,OAAO,CAAC,EAAE,MAAM,SAAS,gBAAgB,CAAC;AAAA,MAC5C,CAAC;AAAA,IACH;AAEA,UAAM,OAAgC;AAAA,MACpC;AAAA,IACF;AAGA,QAAI,SAAS,qBAAqB;AAChC,WAAK,oBAAoB;AAAA,QACvB,OAAO,CAAC,EAAE,MAAM,SAAS,oBAAoB,CAAC;AAAA,MAChD;AAAA,IACF;AAGA,UAAM,mBAA4C,CAAC;AAEnD,QAAI,cAAc,UAAU,gBAAgB,OAAW,kBAAiB,cAAc,cAAc,SAAS;AAC7G,QAAI,cAAc,UAAU,UAAU,OAAW,kBAAiB,OAAO,cAAc,SAAS;AAChG,QAAI,cAAc,UAAU,sBAAsB,OAAW,kBAAiB,kBAAkB,cAAc,SAAS;AACvH,QAAI,cAAc,UAAU,SAAS,OAAW,kBAAiB,gBAAgB,cAAc,SAAS;AAExG,QAAI,cAAc,UAAU,WAAW,QAAQ;AAC7C,uBAAiB,mBAAmB;AAAA,IACtC;AAGA,QAAI,cAAc,WAAW,QAAQ;AACnC,WAAK,iBAAiB;AAAA,QACpB,gBAAgB,cAAc,UAAU,WAAW,SAAS,OAAO,cAAc,UAAU,WAAW,WAAW,OAAO;AAAA,MAC1H;AAAA,IACF;AAEA,QAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC5C,WAAK,mBAAmB;AAAA,IAC1B;AAGA,QAAI,cAAc,SAAS,cAAc,MAAM,SAAS,GAAG;AACzD,YAAM,uBAAuB,cAAc,MAAM,IAAI,CAAC,SAAS;AAC7D,YAAI,OAAO,SAAS,UAAU;AAC5B,gBAAM,MAAM,QAAQ,eAAe,IAAI;AACvC,cAAI,IAAK,QAAO;AAChB,iBAAO,EAAE,MAAM,KAAK;AAAA,QACtB;AACA,eAAO;AAAA,UACL,MAAM,KAAK;AAAA,UACX,aAAa,KAAK;AAAA,UAClB,YAAY,KAAK;AAAA,QACnB;AAAA,MACF,CAAC;AACD,WAAK,QAAQ,CAAC,EAAE,qBAAqB,CAAC;AAAA,IACxC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO,cAAc,SAAS;AAAA,IAChC;AAAA,EACF;AACF,CAAC;","names":[]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderSections,
|
|
3
|
-
resolveAssetForProvider
|
|
4
|
-
|
|
3
|
+
resolveAssetForProvider,
|
|
4
|
+
withPromptInputSupport
|
|
5
|
+
} from "./chunk-S5YHGHK5.js";
|
|
5
6
|
|
|
6
7
|
// src/providers/openai.ts
|
|
7
|
-
var openaiAdapter = {
|
|
8
|
+
var openaiAdapter = withPromptInputSupport({
|
|
8
9
|
name: "openai",
|
|
9
10
|
validate(asset, runtime) {
|
|
10
11
|
const resolvedAsset = resolveAssetForProvider(asset, runtime);
|
|
@@ -78,9 +79,9 @@ var openaiAdapter = {
|
|
|
78
79
|
model: resolvedAsset.model ?? "unknown"
|
|
79
80
|
};
|
|
80
81
|
}
|
|
81
|
-
};
|
|
82
|
+
});
|
|
82
83
|
|
|
83
84
|
export {
|
|
84
85
|
openaiAdapter
|
|
85
86
|
};
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
87
|
+
//# sourceMappingURL=chunk-VU3WKLFI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/openai.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';\n\n/**\n * OpenAI provider adapter.\n * Produces request bodies compatible with the OpenAI Chat Completions API.\n */\nexport const openaiAdapter: ProviderAdapter = withPromptInputSupport({\n name: 'openai',\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 adapter requires a model to be specified.');\n }\n\n if (resolvedAsset.reasoning?.budget_tokens !== undefined) {\n warnings.push('OpenAI uses reasoning_effort, not budget_tokens. budget_tokens will be ignored.');\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\n const messages: Array<Record<string, unknown>> = [];\n\n // System message\n if (sections.system_instructions) {\n messages.push({ role: 'system', content: sections.system_instructions });\n }\n\n // History\n if (runtime.history) {\n for (const msg of runtime.history) {\n messages.push({ role: msg.role, content: msg.content });\n }\n }\n\n // User message (prompt template)\n if (sections.prompt_template) {\n messages.push({ role: 'user', content: sections.prompt_template });\n }\n\n const body: Record<string, unknown> = {\n model: resolvedAsset.model,\n messages,\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_tokens = resolvedAsset.sampling.max_output_tokens;\n\n // Reasoning\n if (resolvedAsset.reasoning?.effort) {\n body.reasoning_effort = resolvedAsset.reasoning.effort;\n }\n\n // Response format\n if (resolvedAsset.response?.format === 'json') {\n body.response_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 // Look up from registry\n const def = runtime.toolRegistry?.[tool];\n if (def) return def;\n return { type: 'function', function: { name: tool } };\n }\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n };\n });\n }\n\n return {\n body,\n provider: 'openai',\n model: resolvedAsset.model ?? 'unknown',\n };\n },\n});\n"],"mappings":";;;;;;;AAeO,IAAM,gBAAiC,uBAAuB;AAAA,EACnE,MAAM;AAAA,EAEN,SAAS,OAA4B,SAAkD;AACrF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,SAAmB,CAAC;AAC1B,UAAM,WAAqB,CAAC;AAE5B,QAAI,CAAC,cAAc,OAAO;AACxB,aAAO,KAAK,kDAAkD;AAAA,IAChE;AAEA,QAAI,cAAc,WAAW,kBAAkB,QAAW;AACxD,eAAS,KAAK,iFAAiF;AAAA,IACjG;AAEA,WAAO,EAAE,OAAO,OAAO,WAAW,GAAG,QAAQ,SAAS;AAAA,EACxD;AAAA,EAEA,OAAO,OAA4B,SAAgD;AACjF,UAAM,gBAAgB,wBAAwB,OAAO,OAAO;AAC5D,UAAM,WAAW,eAAe,eAAe;AAAA,MAC7C,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,UAAM,WAA2C,CAAC;AAGlD,QAAI,SAAS,qBAAqB;AAChC,eAAS,KAAK,EAAE,MAAM,UAAU,SAAS,SAAS,oBAAoB,CAAC;AAAA,IACzE;AAGA,QAAI,QAAQ,SAAS;AACnB,iBAAW,OAAO,QAAQ,SAAS;AACjC,iBAAS,KAAK,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,CAAC;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,SAAS,iBAAiB;AAC5B,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,SAAS,gBAAgB,CAAC;AAAA,IACnE;AAEA,UAAM,OAAgC;AAAA,MACpC,OAAO,cAAc;AAAA,MACrB;AAAA,IACF;AAGA,QAAI,cAAc,UAAU,gBAAgB,OAAW,MAAK,cAAc,cAAc,SAAS;AACjG,QAAI,cAAc,UAAU,UAAU,OAAW,MAAK,QAAQ,cAAc,SAAS;AACrF,QAAI,cAAc,UAAU,sBAAsB,OAAW,MAAK,oBAAoB,cAAc,SAAS;AAC7G,QAAI,cAAc,UAAU,qBAAqB,OAAW,MAAK,mBAAmB,cAAc,SAAS;AAC3G,QAAI,cAAc,UAAU,SAAS,OAAW,MAAK,OAAO,cAAc,SAAS;AACnF,QAAI,cAAc,UAAU,sBAAsB,OAAW,MAAK,aAAa,cAAc,SAAS;AAGtG,QAAI,cAAc,WAAW,QAAQ;AACnC,WAAK,mBAAmB,cAAc,UAAU;AAAA,IAClD;AAGA,QAAI,cAAc,UAAU,WAAW,QAAQ;AAC7C,WAAK,kBAAkB,EAAE,MAAM,cAAc;AAAA,IAC/C;AAGA,QAAI,cAAc,UAAU,WAAW,QAAW;AAChD,WAAK,SAAS,cAAc,SAAS;AAAA,IACvC;AAGA,QAAI,cAAc,SAAS,cAAc,MAAM,SAAS,GAAG;AACzD,WAAK,QAAQ,cAAc,MAAM,IAAI,CAAC,SAAS;AAC7C,YAAI,OAAO,SAAS,UAAU;AAE5B,gBAAM,MAAM,QAAQ,eAAe,IAAI;AACvC,cAAI,IAAK,QAAO;AAChB,iBAAO,EAAE,MAAM,YAAY,UAAU,EAAE,MAAM,KAAK,EAAE;AAAA,QACtD;AACA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,UAAU;AAAA,YACR,MAAM,KAAK;AAAA,YACX,aAAa,KAAK;AAAA,YAClB,YAAY,KAAK;AAAA,UACnB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,OAAO,cAAc,SAAS;AAAA,IAChC;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/cli/index.js
CHANGED
|
@@ -569,11 +569,13 @@ async function collectPromptFiles(dir) {
|
|
|
569
569
|
import { readdir as readdir2, writeFile, mkdir, rm } from "fs/promises";
|
|
570
570
|
import { join as join3, extname as extname2, relative, dirname as dirname3 } from "path";
|
|
571
571
|
var HELP2 = `
|
|
572
|
-
promptopskit compile
|
|
572
|
+
promptopskit compile [sourceDir] [outputDir] [options]
|
|
573
573
|
|
|
574
|
-
Compile .md prompt files to JSON artifacts.
|
|
574
|
+
Compile .md prompt files to JSON or ESM artifacts.
|
|
575
575
|
|
|
576
576
|
Options:
|
|
577
|
+
--source, -s Source directory (default: ./prompts)
|
|
578
|
+
--output, -o Output directory (default: ./.generated-prompts/<format>)
|
|
577
579
|
--no-clean Don't clear the output directory before compiling
|
|
578
580
|
--dry-run Show what would be compiled without writing files
|
|
579
581
|
--format Output format: json (default) or esm
|
|
@@ -584,14 +586,7 @@ async function compile(args) {
|
|
|
584
586
|
console.log(HELP2);
|
|
585
587
|
return;
|
|
586
588
|
}
|
|
587
|
-
const positional = args
|
|
588
|
-
const sourceDir = positional[0];
|
|
589
|
-
const outputDir = positional[1];
|
|
590
|
-
if (!sourceDir || !outputDir) {
|
|
591
|
-
console.error("Error: Please provide source and output directories.");
|
|
592
|
-
console.error("Usage: promptopskit compile <sourceDir> <outputDir>");
|
|
593
|
-
process.exit(1);
|
|
594
|
-
}
|
|
589
|
+
const positional = getPositionalArgs(args, /* @__PURE__ */ new Set(["--format", "--source", "--output", "-s", "-o"]));
|
|
595
590
|
const dryRun = args.includes("--dry-run");
|
|
596
591
|
const noClean = args.includes("--no-clean");
|
|
597
592
|
const format = getFlag(args, "--format") ?? "json";
|
|
@@ -599,6 +594,8 @@ async function compile(args) {
|
|
|
599
594
|
console.error(`Error: Unknown format "${format}". Use "json" or "esm".`);
|
|
600
595
|
process.exit(1);
|
|
601
596
|
}
|
|
597
|
+
const sourceDir = getFlag(args, "--source", "-s") ?? positional[0] ?? "./prompts";
|
|
598
|
+
const outputDir = getFlag(args, "--output", "-o") ?? positional[1] ?? defaultOutputDirForFormat(format);
|
|
602
599
|
const files = await collectPromptFiles2(sourceDir);
|
|
603
600
|
if (files.length === 0) {
|
|
604
601
|
console.log(`No .md prompt files found in ${sourceDir}`);
|
|
@@ -647,10 +644,30 @@ async function compile(args) {
|
|
|
647
644
|
process.exit(1);
|
|
648
645
|
}
|
|
649
646
|
}
|
|
650
|
-
function
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
647
|
+
function defaultOutputDirForFormat(format) {
|
|
648
|
+
return format === "esm" ? "./.generated-prompts/esm" : "./.generated-prompts/json";
|
|
649
|
+
}
|
|
650
|
+
function getPositionalArgs(args, flagsWithValues) {
|
|
651
|
+
const positional = [];
|
|
652
|
+
for (let index = 0; index < args.length; index++) {
|
|
653
|
+
const arg = args[index];
|
|
654
|
+
if (flagsWithValues.has(arg)) {
|
|
655
|
+
index++;
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
if (arg.startsWith("-")) {
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
positional.push(arg);
|
|
662
|
+
}
|
|
663
|
+
return positional;
|
|
664
|
+
}
|
|
665
|
+
function getFlag(args, ...flags) {
|
|
666
|
+
for (const flag of flags) {
|
|
667
|
+
const idx = args.indexOf(flag);
|
|
668
|
+
if (idx >= 0 && idx + 1 < args.length) {
|
|
669
|
+
return args[idx + 1];
|
|
670
|
+
}
|
|
654
671
|
}
|
|
655
672
|
return void 0;
|
|
656
673
|
}
|
|
@@ -848,6 +865,9 @@ promptopskit init [dir]
|
|
|
848
865
|
|
|
849
866
|
Scaffold a prompts directory with starter files.
|
|
850
867
|
|
|
868
|
+
Arguments:
|
|
869
|
+
dir Target directory (default: ./prompts)
|
|
870
|
+
|
|
851
871
|
Options:
|
|
852
872
|
--help, -h Show this help
|
|
853
873
|
`.trim();
|
|
@@ -1008,7 +1028,7 @@ async function init(args) {
|
|
|
1008
1028
|
if (!pkg.scripts?.["build:prompts"]) {
|
|
1009
1029
|
console.log();
|
|
1010
1030
|
console.log(`Tip: Add to your package.json scripts:`);
|
|
1011
|
-
console.log(` "build:prompts": "promptopskit compile ${dir}
|
|
1031
|
+
console.log(` "build:prompts": "promptopskit compile ${dir}"`);
|
|
1012
1032
|
}
|
|
1013
1033
|
} catch {
|
|
1014
1034
|
}
|
|
@@ -1169,7 +1189,7 @@ Usage:
|
|
|
1169
1189
|
Commands:
|
|
1170
1190
|
init [dir] Scaffold a prompts directory with starter files
|
|
1171
1191
|
validate <dir> Validate prompt files
|
|
1172
|
-
compile
|
|
1192
|
+
compile [src] [out] [options] Compile .md prompts to JSON/ESM artifacts
|
|
1173
1193
|
render <file> [options] Render a prompt preview
|
|
1174
1194
|
inspect <file> Print normalized prompt asset
|
|
1175
1195
|
skill [options] Deploy AI agent instructions into your project
|