@promptlycms/prompts 0.1.0 → 0.1.1
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 +97 -30
- package/dist/cli.js +66 -0
- package/dist/index.cjs +68 -14
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +67 -14
- package/dist/schema.d.cts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/{types-DtbFuFmA.d.cts → types-W-omtl43.d.cts} +1 -0
- package/dist/{types-DtbFuFmA.d.ts → types-W-omtl43.d.ts} +1 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -2,15 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript SDK for the [Promptly CMS](https://promptlycms.com) API. Fetch prompts at runtime, get typed template variables via codegen, and integrate with the [Vercel AI SDK](https://sdk.vercel.ai).
|
|
4
4
|
|
|
5
|
+
- **Runtime client** — `getPrompt()`, `getPrompts()`, `aiParams()` with full TypeScript support
|
|
6
|
+
- **Codegen CLI** — generates typed template variables via declaration merging
|
|
7
|
+
- **AI SDK integration** — spread-ready params for `generateText` / `streamText`
|
|
8
|
+
- **Model auto-detection** — resolves Anthropic, OpenAI, Google, and Mistral models automatically
|
|
9
|
+
- **Structured output** — Zod schemas built from CMS-defined output schemas
|
|
10
|
+
|
|
5
11
|
## Install
|
|
6
12
|
|
|
7
13
|
```bash
|
|
8
14
|
npm install @promptlycms/prompts
|
|
9
|
-
# or
|
|
10
|
-
bun add @promptlycms/prompts
|
|
11
15
|
```
|
|
12
16
|
|
|
13
|
-
Peer dependencies:
|
|
17
|
+
Peer dependencies:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install zod ai typescript
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
You'll also need at least one AI provider SDK for model resolution:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Install the provider(s) your prompts use
|
|
27
|
+
npm install @ai-sdk/anthropic # Claude models
|
|
28
|
+
npm install @ai-sdk/openai # GPT / o-series models
|
|
29
|
+
npm install @ai-sdk/google # Gemini models
|
|
30
|
+
npm install @ai-sdk/mistral # Mistral / Mixtral models
|
|
31
|
+
```
|
|
14
32
|
|
|
15
33
|
## Quick start
|
|
16
34
|
|
|
@@ -27,7 +45,7 @@ PROMPTLY_API_KEY=pk_live_...
|
|
|
27
45
|
npx promptly generate
|
|
28
46
|
```
|
|
29
47
|
|
|
30
|
-
This fetches all your prompts from the API and generates a `promptly-env.d.ts` file in your project root
|
|
48
|
+
This fetches all your prompts from the API and generates a `promptly-env.d.ts` file in your project root with typed autocomplete for every prompt ID and its template variables.
|
|
31
49
|
|
|
32
50
|
```bash
|
|
33
51
|
# Custom output path
|
|
@@ -40,9 +58,9 @@ npx promptly generate --api-key pk_live_...
|
|
|
40
58
|
### 3. Create a client
|
|
41
59
|
|
|
42
60
|
```typescript
|
|
43
|
-
import {
|
|
61
|
+
import { createPromptlyClient } from '@promptlycms/prompts';
|
|
44
62
|
|
|
45
|
-
const promptly =
|
|
63
|
+
const promptly = createPromptlyClient({
|
|
46
64
|
apiKey: process.env.PROMPTLY_API_KEY,
|
|
47
65
|
});
|
|
48
66
|
```
|
|
@@ -52,13 +70,14 @@ const promptly = createPromptClient({
|
|
|
52
70
|
### Single prompt
|
|
53
71
|
|
|
54
72
|
```typescript
|
|
55
|
-
const result = await promptly.
|
|
73
|
+
const result = await promptly.getPrompt('JPxlUpstuhXB5OwOtKPpj');
|
|
56
74
|
|
|
57
75
|
// Access prompt metadata
|
|
58
76
|
result.promptId; // 'JPxlUpstuhXB5OwOtKPpj'
|
|
59
77
|
result.promptName; // 'Review Prompt'
|
|
60
78
|
result.systemMessage; // 'You are a helpful assistant.'
|
|
61
79
|
result.temperature; // 0.7
|
|
80
|
+
result.model; // LanguageModel (auto-resolved from CMS config)
|
|
62
81
|
|
|
63
82
|
// Interpolate template variables (typed if you ran codegen)
|
|
64
83
|
const message = result.userMessage({
|
|
@@ -74,7 +93,7 @@ const template = String(result.userMessage);
|
|
|
74
93
|
Fetch a specific version:
|
|
75
94
|
|
|
76
95
|
```typescript
|
|
77
|
-
const result = await promptly.
|
|
96
|
+
const result = await promptly.getPrompt('JPxlUpstuhXB5OwOtKPpj', {
|
|
78
97
|
version: '2.0.0',
|
|
79
98
|
});
|
|
80
99
|
```
|
|
@@ -102,23 +121,48 @@ welcomePrompt.userMessage({ email: 'a@b.com', subject: 'Hi' });
|
|
|
102
121
|
|
|
103
122
|
```typescript
|
|
104
123
|
import { generateText } from 'ai';
|
|
105
|
-
import { anthropic } from '@ai-sdk/anthropic';
|
|
106
124
|
|
|
107
125
|
const params = await promptly.aiParams('my-prompt', {
|
|
108
126
|
variables: { name: 'Alice', task: 'coding' },
|
|
109
127
|
});
|
|
110
128
|
|
|
111
129
|
const { text } = await generateText({
|
|
112
|
-
model: anthropic('claude-sonnet-4-5-20250929'),
|
|
113
130
|
...params,
|
|
131
|
+
// model is already included from your CMS prompt config
|
|
114
132
|
});
|
|
115
133
|
```
|
|
116
134
|
|
|
117
|
-
If the prompt has a structured output schema defined in the CMS, `params.output` is automatically populated with a Zod schema wrapped in `Output.object()`.
|
|
135
|
+
The model configured in the CMS is auto-resolved to the correct AI SDK provider. If the prompt has a structured output schema defined in the CMS, `params.output` is automatically populated with a Zod schema wrapped in `Output.object()`.
|
|
136
|
+
|
|
137
|
+
## Model auto-detection
|
|
138
|
+
|
|
139
|
+
The SDK automatically resolves models configured in the CMS to the correct AI SDK provider based on the model name prefix:
|
|
140
|
+
|
|
141
|
+
| Prefix | Provider | Package |
|
|
142
|
+
|--------|----------|---------|
|
|
143
|
+
| `claude-*` | Anthropic | `@ai-sdk/anthropic` |
|
|
144
|
+
| `gpt-*`, `o1-*`, `o3-*`, `o4-*`, `chatgpt-*` | OpenAI | `@ai-sdk/openai` |
|
|
145
|
+
| `gemini-*` | Google | `@ai-sdk/google` |
|
|
146
|
+
| `mistral-*`, `mixtral-*`, `codestral-*` | Mistral | `@ai-sdk/mistral` |
|
|
147
|
+
|
|
148
|
+
CMS model display names (e.g. `claude-sonnet-4.5`) are mapped to their full API model IDs automatically.
|
|
149
|
+
|
|
150
|
+
### Custom model resolver
|
|
151
|
+
|
|
152
|
+
If you need full control over model resolution, pass a `model` function:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { anthropic } from '@ai-sdk/anthropic';
|
|
156
|
+
|
|
157
|
+
const promptly = createPromptlyClient({
|
|
158
|
+
apiKey: process.env.PROMPTLY_API_KEY,
|
|
159
|
+
model: (modelId) => anthropic('claude-sonnet-4-5-20250929'),
|
|
160
|
+
});
|
|
161
|
+
```
|
|
118
162
|
|
|
119
163
|
## Type generation
|
|
120
164
|
|
|
121
|
-
Running `npx promptly generate` creates a `promptly-env.d.ts` file that uses [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) to
|
|
165
|
+
Running `npx promptly generate` creates a `promptly-env.d.ts` file that uses [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) to type your prompts:
|
|
122
166
|
|
|
123
167
|
```typescript
|
|
124
168
|
// Auto-generated by @promptlycms/prompts — do not edit
|
|
@@ -127,26 +171,24 @@ import '@promptlycms/prompts';
|
|
|
127
171
|
declare module '@promptlycms/prompts' {
|
|
128
172
|
interface PromptVariableMap {
|
|
129
173
|
'JPxlUpstuhXB5OwOtKPpj': {
|
|
130
|
-
|
|
131
|
-
|
|
174
|
+
[V in 'latest' | '2.0.0' | '1.0.0']: {
|
|
175
|
+
pickupLocation: string;
|
|
176
|
+
items: string;
|
|
177
|
+
};
|
|
132
178
|
};
|
|
133
179
|
'abc123': {
|
|
134
|
-
|
|
135
|
-
|
|
180
|
+
[V in 'latest' | '1.0.0']: {
|
|
181
|
+
email: string;
|
|
182
|
+
subject: string;
|
|
183
|
+
};
|
|
136
184
|
};
|
|
137
185
|
}
|
|
138
186
|
}
|
|
139
187
|
```
|
|
140
188
|
|
|
141
|
-
With this file present, `
|
|
189
|
+
With this file present, `getPrompt()` and `getPrompts()` return typed `userMessage` functions with autocomplete. Unknown prompt IDs fall back to `Record<string, string>`.
|
|
142
190
|
|
|
143
|
-
Add the generated file to version control so types are available without running codegen in CI
|
|
144
|
-
|
|
145
|
-
```bash
|
|
146
|
-
# .gitignore — do NOT ignore promptly-env.d.ts
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Re-run `npx promptly generate` whenever you add, remove, or rename template variables in the CMS.
|
|
191
|
+
Add the generated file to version control so types are available without running codegen in CI. Re-run `npx promptly generate` whenever you add, remove, or rename template variables in the CMS.
|
|
150
192
|
|
|
151
193
|
## Error handling
|
|
152
194
|
|
|
@@ -156,7 +198,7 @@ All API errors throw `PromptlyError`:
|
|
|
156
198
|
import { PromptlyError } from '@promptlycms/prompts';
|
|
157
199
|
|
|
158
200
|
try {
|
|
159
|
-
await promptly.
|
|
201
|
+
await promptly.getPrompt('nonexistent');
|
|
160
202
|
} catch (err) {
|
|
161
203
|
if (err instanceof PromptlyError) {
|
|
162
204
|
err.code; // 'NOT_FOUND' | 'INVALID_KEY' | 'USAGE_LIMIT_EXCEEDED' | ...
|
|
@@ -170,26 +212,47 @@ try {
|
|
|
170
212
|
|
|
171
213
|
## API reference
|
|
172
214
|
|
|
173
|
-
### `
|
|
215
|
+
### `createPromptlyClient(config?)`
|
|
174
216
|
|
|
175
217
|
| Option | Type | Required | Description |
|
|
176
218
|
|-----------|----------|----------|----------------------------------------------------|
|
|
177
|
-
| `apiKey` | `string` |
|
|
219
|
+
| `apiKey` | `string` | No | Your Promptly API key (defaults to `PROMPTLY_API_KEY` env var) |
|
|
178
220
|
| `baseUrl` | `string` | No | API base URL (default: `https://api.promptlycms.com`) |
|
|
221
|
+
| `model` | `(modelId: string) => LanguageModel` | No | Custom model resolver — overrides auto-detection |
|
|
179
222
|
|
|
180
|
-
Returns a `
|
|
223
|
+
Returns a `PromptlyClient` with `getPrompt()`, `getPrompts()`, and `aiParams()` methods.
|
|
181
224
|
|
|
182
|
-
### `client.
|
|
225
|
+
### `client.getPrompt(promptId, options?)`
|
|
183
226
|
|
|
184
227
|
Fetch a single prompt. Returns `PromptResult` with typed `userMessage` when codegen types are present.
|
|
185
228
|
|
|
229
|
+
| Option | Type | Description |
|
|
230
|
+
|-----------|----------|----------------------|
|
|
231
|
+
| `version` | `string` | Specific version to fetch (default: latest) |
|
|
232
|
+
|
|
186
233
|
### `client.getPrompts(entries)`
|
|
187
234
|
|
|
188
235
|
Fetch multiple prompts in parallel. Accepts `PromptRequest[]` and returns a typed tuple matching the input order.
|
|
189
236
|
|
|
190
237
|
### `client.aiParams(promptId, options?)`
|
|
191
238
|
|
|
192
|
-
Fetch a prompt and return params ready to spread into AI SDK functions (`system`, `prompt`, `temperature`, and optionally `output`).
|
|
239
|
+
Fetch a prompt and return params ready to spread into AI SDK functions (`system`, `prompt`, `temperature`, `model`, and optionally `output`).
|
|
240
|
+
|
|
241
|
+
| Option | Type | Description |
|
|
242
|
+
|-------------|-------------------------|--------------------------------|
|
|
243
|
+
| `version` | `string` | Specific version to fetch |
|
|
244
|
+
| `variables` | `Record<string, string>` | Template variables to interpolate |
|
|
245
|
+
|
|
246
|
+
### `@promptlycms/prompts/schema`
|
|
247
|
+
|
|
248
|
+
Subpath export for working with Zod schemas from CMS schema fields:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import { buildZodSchema, schemaFieldsToZodSource } from '@promptlycms/prompts/schema';
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- `buildZodSchema(fields)` — builds a Zod object schema at runtime from `SchemaField[]`
|
|
255
|
+
- `schemaFieldsToZodSource(fields)` — generates Zod source code as a string for codegen
|
|
193
256
|
|
|
194
257
|
### CLI: `npx promptly generate`
|
|
195
258
|
|
|
@@ -197,3 +260,7 @@ Fetch a prompt and return params ready to spread into AI SDK functions (`system`
|
|
|
197
260
|
|-------------|-------|------------------------------------------------------|
|
|
198
261
|
| `--api-key` | | API key (defaults to `PROMPTLY_API_KEY` env var) |
|
|
199
262
|
| `--output` | `-o` | Output path (default: `./promptly-env.d.ts`) |
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
package/dist/cli.js
CHANGED
|
@@ -41,6 +41,41 @@ var createErrorFromResponse = async (response) => {
|
|
|
41
41
|
|
|
42
42
|
// src/cli/generate.ts
|
|
43
43
|
import { writeFile } from "fs/promises";
|
|
44
|
+
import { createRequire } from "module";
|
|
45
|
+
|
|
46
|
+
// src/schema/builder.ts
|
|
47
|
+
import { z } from "zod";
|
|
48
|
+
|
|
49
|
+
// src/client.ts
|
|
50
|
+
var PROVIDER_PREFIXES = [
|
|
51
|
+
["claude", "anthropic"],
|
|
52
|
+
["gpt", "openai"],
|
|
53
|
+
["o1", "openai"],
|
|
54
|
+
["o3", "openai"],
|
|
55
|
+
["o4", "openai"],
|
|
56
|
+
["chatgpt", "openai"],
|
|
57
|
+
["gemini", "google"],
|
|
58
|
+
["mistral", "mistral"],
|
|
59
|
+
["mixtral", "mistral"],
|
|
60
|
+
["codestral", "mistral"]
|
|
61
|
+
];
|
|
62
|
+
var detectProviderName = (modelId) => {
|
|
63
|
+
const lower = modelId.toLowerCase();
|
|
64
|
+
for (const [prefix, provider] of PROVIDER_PREFIXES) {
|
|
65
|
+
if (lower.startsWith(prefix)) {
|
|
66
|
+
return provider;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return void 0;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/cli/generate.ts
|
|
73
|
+
var PROVIDER_PACKAGES = {
|
|
74
|
+
anthropic: "@ai-sdk/anthropic",
|
|
75
|
+
openai: "@ai-sdk/openai",
|
|
76
|
+
google: "@ai-sdk/google",
|
|
77
|
+
mistral: "@ai-sdk/mistral"
|
|
78
|
+
};
|
|
44
79
|
var DEFAULT_BASE_URL = "https://api.promptlycms.com";
|
|
45
80
|
var extractTemplateVariables = (text) => {
|
|
46
81
|
const matches = text.matchAll(/\$\{(\w+)\}/g);
|
|
@@ -215,6 +250,36 @@ var generateTypeDeclaration = (prompts) => {
|
|
|
215
250
|
lines.push("");
|
|
216
251
|
return lines.join("\n");
|
|
217
252
|
};
|
|
253
|
+
var warnMissingProviders = (prompts) => {
|
|
254
|
+
const require2 = createRequire(import.meta.url);
|
|
255
|
+
const needed = /* @__PURE__ */ new Map();
|
|
256
|
+
for (const prompt of prompts) {
|
|
257
|
+
const provider = detectProviderName(prompt.config.model);
|
|
258
|
+
if (!provider) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const pkg = PROVIDER_PACKAGES[provider];
|
|
262
|
+
if (!pkg) {
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
const existing = needed.get(pkg);
|
|
266
|
+
if (existing) {
|
|
267
|
+
existing.push(prompt.promptName);
|
|
268
|
+
} else {
|
|
269
|
+
needed.set(pkg, [prompt.promptName]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
for (const [pkg, promptNames] of needed) {
|
|
273
|
+
try {
|
|
274
|
+
require2.resolve(pkg);
|
|
275
|
+
} catch {
|
|
276
|
+
const names = promptNames.map((n) => `"${n}"`).join(", ");
|
|
277
|
+
console.warn(
|
|
278
|
+
` Warning: ${names} requires ${pkg} \u2014 install it: npm install ${pkg}`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
218
283
|
var generate = async (apiKey, outputPath, baseUrl) => {
|
|
219
284
|
const prompts = await fetchAllPrompts(apiKey, baseUrl);
|
|
220
285
|
if (prompts.length === 0) {
|
|
@@ -222,6 +287,7 @@ var generate = async (apiKey, outputPath, baseUrl) => {
|
|
|
222
287
|
return;
|
|
223
288
|
}
|
|
224
289
|
console.log(` Found ${prompts.length} prompt(s)`);
|
|
290
|
+
warnMissingProviders(prompts);
|
|
225
291
|
const content = generateTypeDeclaration(prompts);
|
|
226
292
|
await writeFile(outputPath, content, "utf-8");
|
|
227
293
|
console.log(` Generated ${outputPath}`);
|
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
PromptlyError: () => PromptlyError,
|
|
34
34
|
createPromptlyClient: () => createPromptlyClient,
|
|
35
|
+
getSdkModelId: () => getSdkModelId,
|
|
35
36
|
interpolate: () => interpolate
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -352,6 +353,22 @@ var buildZodSchema = (fields) => {
|
|
|
352
353
|
|
|
353
354
|
// src/client.ts
|
|
354
355
|
var DEFAULT_BASE_URL = "https://api.promptlycms.com";
|
|
356
|
+
var MODEL_ID_MAP = {
|
|
357
|
+
// Anthropic: CMS display IDs → API model IDs
|
|
358
|
+
"claude-opus-4.6": "claude-opus-4-6-20250917",
|
|
359
|
+
"claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
|
|
360
|
+
"claude-haiku-4.5": "claude-haiku-4-5-20251001",
|
|
361
|
+
"claude-opus-4": "claude-opus-4-20250514",
|
|
362
|
+
"claude-sonnet-4": "claude-sonnet-4-20250514",
|
|
363
|
+
"claude-3.7-sonnet": "claude-3-7-sonnet-20250219",
|
|
364
|
+
// Google: CMS display IDs → Gemini SDK model names
|
|
365
|
+
"gemini-3-pro": "gemini-3.0-pro",
|
|
366
|
+
"gemini-3-flash": "gemini-3.0-flash",
|
|
367
|
+
"gemini-3-deep-think": "gemini-3.0-deep-think",
|
|
368
|
+
"gemini-2.5-pro": "gemini-2.5-pro-latest",
|
|
369
|
+
"gemini-2.5-flash": "gemini-2.5-flash-preview-05-20"
|
|
370
|
+
};
|
|
371
|
+
var getSdkModelId = (modelId) => MODEL_ID_MAP[modelId] ?? modelId;
|
|
355
372
|
var PROVIDER_PREFIXES = [
|
|
356
373
|
["claude", "anthropic"],
|
|
357
374
|
["gpt", "openai"],
|
|
@@ -364,12 +381,6 @@ var PROVIDER_PREFIXES = [
|
|
|
364
381
|
["mixtral", "mistral"],
|
|
365
382
|
["codestral", "mistral"]
|
|
366
383
|
];
|
|
367
|
-
var PROVIDER_PACKAGES = {
|
|
368
|
-
anthropic: "@ai-sdk/anthropic",
|
|
369
|
-
openai: "@ai-sdk/openai",
|
|
370
|
-
google: "@ai-sdk/google",
|
|
371
|
-
mistral: "@ai-sdk/mistral"
|
|
372
|
-
};
|
|
373
384
|
var detectProviderName = (modelId) => {
|
|
374
385
|
const lower = modelId.toLowerCase();
|
|
375
386
|
for (const [prefix, provider] of PROVIDER_PREFIXES) {
|
|
@@ -384,13 +395,28 @@ var resolveModel = async (modelId) => {
|
|
|
384
395
|
if (!providerName) {
|
|
385
396
|
return void 0;
|
|
386
397
|
}
|
|
387
|
-
const
|
|
388
|
-
if (!pkg) {
|
|
389
|
-
return void 0;
|
|
390
|
-
}
|
|
398
|
+
const sdkModelId = getSdkModelId(modelId);
|
|
391
399
|
try {
|
|
392
|
-
|
|
393
|
-
|
|
400
|
+
switch (providerName) {
|
|
401
|
+
case "anthropic": {
|
|
402
|
+
const { anthropic } = await import("@ai-sdk/anthropic");
|
|
403
|
+
return anthropic(sdkModelId);
|
|
404
|
+
}
|
|
405
|
+
case "openai": {
|
|
406
|
+
const { openai } = await import("@ai-sdk/openai");
|
|
407
|
+
return openai(sdkModelId);
|
|
408
|
+
}
|
|
409
|
+
case "google": {
|
|
410
|
+
const { google } = await import("@ai-sdk/google");
|
|
411
|
+
return google(sdkModelId);
|
|
412
|
+
}
|
|
413
|
+
case "mistral": {
|
|
414
|
+
const { mistral } = await import("@ai-sdk/mistral");
|
|
415
|
+
return mistral(sdkModelId);
|
|
416
|
+
}
|
|
417
|
+
default:
|
|
418
|
+
return void 0;
|
|
419
|
+
}
|
|
394
420
|
} catch {
|
|
395
421
|
return void 0;
|
|
396
422
|
}
|
|
@@ -407,6 +433,32 @@ var createPromptMessage = (template) => {
|
|
|
407
433
|
fn.toString = () => template;
|
|
408
434
|
return fn;
|
|
409
435
|
};
|
|
436
|
+
var PROVIDER_PACKAGES = {
|
|
437
|
+
anthropic: "@ai-sdk/anthropic",
|
|
438
|
+
openai: "@ai-sdk/openai",
|
|
439
|
+
google: "@ai-sdk/google",
|
|
440
|
+
mistral: "@ai-sdk/mistral"
|
|
441
|
+
};
|
|
442
|
+
var createModelResolver = (config) => {
|
|
443
|
+
if (config?.model) {
|
|
444
|
+
const userResolver = config.model;
|
|
445
|
+
return async (modelId) => userResolver(modelId);
|
|
446
|
+
}
|
|
447
|
+
return async (modelId) => {
|
|
448
|
+
const model = await resolveModel(modelId);
|
|
449
|
+
if (model) {
|
|
450
|
+
return model;
|
|
451
|
+
}
|
|
452
|
+
const providerName = detectProviderName(modelId);
|
|
453
|
+
const pkg = providerName ? PROVIDER_PACKAGES[providerName] : void 0;
|
|
454
|
+
const hint = pkg ? `Make sure "${pkg}" is installed: npm install ${pkg}` : `Supported model prefixes: ${PROVIDER_PREFIXES.map(([p]) => p).join(", ")}`;
|
|
455
|
+
throw new PromptlyError(
|
|
456
|
+
`Failed to resolve model "${modelId}". ${hint}`,
|
|
457
|
+
"BAD_REQUEST",
|
|
458
|
+
0
|
|
459
|
+
);
|
|
460
|
+
};
|
|
461
|
+
};
|
|
410
462
|
var createPromptlyClient = (config) => {
|
|
411
463
|
const apiKey = config?.apiKey ?? process.env.PROMPTLY_API_KEY;
|
|
412
464
|
if (!apiKey) {
|
|
@@ -417,6 +469,7 @@ var createPromptlyClient = (config) => {
|
|
|
417
469
|
);
|
|
418
470
|
}
|
|
419
471
|
const baseUrl = config?.baseUrl ?? DEFAULT_BASE_URL;
|
|
472
|
+
const modelResolver = createModelResolver(config);
|
|
420
473
|
const fetchPrompt = async (promptId, options) => {
|
|
421
474
|
const url = new URL(`/prompts/${promptId}`, baseUrl);
|
|
422
475
|
if (options?.version) {
|
|
@@ -434,7 +487,7 @@ var createPromptlyClient = (config) => {
|
|
|
434
487
|
};
|
|
435
488
|
const getPrompt = async (promptId, options) => {
|
|
436
489
|
const response = await fetchPrompt(promptId, options);
|
|
437
|
-
const model = await
|
|
490
|
+
const model = await modelResolver(response.config.model);
|
|
438
491
|
return {
|
|
439
492
|
...response,
|
|
440
493
|
userMessage: createPromptMessage(response.userMessage),
|
|
@@ -455,7 +508,7 @@ var createPromptlyClient = (config) => {
|
|
|
455
508
|
version: options?.version
|
|
456
509
|
});
|
|
457
510
|
const userMessage = options?.variables ? interpolate(prompt.userMessage, options.variables) : prompt.userMessage;
|
|
458
|
-
const model = await
|
|
511
|
+
const model = await modelResolver(prompt.config.model);
|
|
459
512
|
const result = {
|
|
460
513
|
system: prompt.systemMessage,
|
|
461
514
|
prompt: userMessage,
|
|
@@ -475,5 +528,6 @@ var createPromptlyClient = (config) => {
|
|
|
475
528
|
0 && (module.exports = {
|
|
476
529
|
PromptlyError,
|
|
477
530
|
createPromptlyClient,
|
|
531
|
+
getSdkModelId,
|
|
478
532
|
interpolate
|
|
479
533
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { P as PromptlyClientConfig, a as PromptlyClient, E as ErrorCode } from './types-
|
|
2
|
-
export { A as AiParams, b as AiParamsOptions, c as ErrorResponse, G as GetOptions, d as PromptConfig, e as PromptId, f as PromptMessage, g as PromptRequest, h as PromptResponse, i as PromptResult, j as PromptVariableMap, k as PromptVersion, l as PublishedVersion, S as SchemaField, m as SchemaFieldParams, V as ValidationRule } from './types-
|
|
1
|
+
import { P as PromptlyClientConfig, a as PromptlyClient, E as ErrorCode } from './types-W-omtl43.cjs';
|
|
2
|
+
export { A as AiParams, b as AiParamsOptions, c as ErrorResponse, G as GetOptions, d as PromptConfig, e as PromptId, f as PromptMessage, g as PromptRequest, h as PromptResponse, i as PromptResult, j as PromptVariableMap, k as PromptVersion, l as PublishedVersion, S as SchemaField, m as SchemaFieldParams, V as ValidationRule } from './types-W-omtl43.cjs';
|
|
3
3
|
import 'ai';
|
|
4
4
|
|
|
5
|
+
declare const getSdkModelId: (modelId: string) => string;
|
|
5
6
|
declare const interpolate: (template: string, variables: Record<string, string>) => string;
|
|
6
7
|
declare const createPromptlyClient: (config?: PromptlyClientConfig) => PromptlyClient;
|
|
7
8
|
|
|
@@ -13,4 +14,4 @@ declare class PromptlyError extends Error {
|
|
|
13
14
|
constructor(message: string, code: ErrorCode, status: number, usage?: unknown, upgradeUrl?: string);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
export { ErrorCode, PromptlyClient, PromptlyClientConfig, PromptlyError, createPromptlyClient, interpolate };
|
|
17
|
+
export { ErrorCode, PromptlyClient, PromptlyClientConfig, PromptlyError, createPromptlyClient, getSdkModelId, interpolate };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { P as PromptlyClientConfig, a as PromptlyClient, E as ErrorCode } from './types-
|
|
2
|
-
export { A as AiParams, b as AiParamsOptions, c as ErrorResponse, G as GetOptions, d as PromptConfig, e as PromptId, f as PromptMessage, g as PromptRequest, h as PromptResponse, i as PromptResult, j as PromptVariableMap, k as PromptVersion, l as PublishedVersion, S as SchemaField, m as SchemaFieldParams, V as ValidationRule } from './types-
|
|
1
|
+
import { P as PromptlyClientConfig, a as PromptlyClient, E as ErrorCode } from './types-W-omtl43.js';
|
|
2
|
+
export { A as AiParams, b as AiParamsOptions, c as ErrorResponse, G as GetOptions, d as PromptConfig, e as PromptId, f as PromptMessage, g as PromptRequest, h as PromptResponse, i as PromptResult, j as PromptVariableMap, k as PromptVersion, l as PublishedVersion, S as SchemaField, m as SchemaFieldParams, V as ValidationRule } from './types-W-omtl43.js';
|
|
3
3
|
import 'ai';
|
|
4
4
|
|
|
5
|
+
declare const getSdkModelId: (modelId: string) => string;
|
|
5
6
|
declare const interpolate: (template: string, variables: Record<string, string>) => string;
|
|
6
7
|
declare const createPromptlyClient: (config?: PromptlyClientConfig) => PromptlyClient;
|
|
7
8
|
|
|
@@ -13,4 +14,4 @@ declare class PromptlyError extends Error {
|
|
|
13
14
|
constructor(message: string, code: ErrorCode, status: number, usage?: unknown, upgradeUrl?: string);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
export { ErrorCode, PromptlyClient, PromptlyClientConfig, PromptlyError, createPromptlyClient, interpolate };
|
|
17
|
+
export { ErrorCode, PromptlyClient, PromptlyClientConfig, PromptlyError, createPromptlyClient, getSdkModelId, interpolate };
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,22 @@ var createErrorFromResponse = async (response) => {
|
|
|
38
38
|
|
|
39
39
|
// src/client.ts
|
|
40
40
|
var DEFAULT_BASE_URL = "https://api.promptlycms.com";
|
|
41
|
+
var MODEL_ID_MAP = {
|
|
42
|
+
// Anthropic: CMS display IDs → API model IDs
|
|
43
|
+
"claude-opus-4.6": "claude-opus-4-6-20250917",
|
|
44
|
+
"claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
|
|
45
|
+
"claude-haiku-4.5": "claude-haiku-4-5-20251001",
|
|
46
|
+
"claude-opus-4": "claude-opus-4-20250514",
|
|
47
|
+
"claude-sonnet-4": "claude-sonnet-4-20250514",
|
|
48
|
+
"claude-3.7-sonnet": "claude-3-7-sonnet-20250219",
|
|
49
|
+
// Google: CMS display IDs → Gemini SDK model names
|
|
50
|
+
"gemini-3-pro": "gemini-3.0-pro",
|
|
51
|
+
"gemini-3-flash": "gemini-3.0-flash",
|
|
52
|
+
"gemini-3-deep-think": "gemini-3.0-deep-think",
|
|
53
|
+
"gemini-2.5-pro": "gemini-2.5-pro-latest",
|
|
54
|
+
"gemini-2.5-flash": "gemini-2.5-flash-preview-05-20"
|
|
55
|
+
};
|
|
56
|
+
var getSdkModelId = (modelId) => MODEL_ID_MAP[modelId] ?? modelId;
|
|
41
57
|
var PROVIDER_PREFIXES = [
|
|
42
58
|
["claude", "anthropic"],
|
|
43
59
|
["gpt", "openai"],
|
|
@@ -50,12 +66,6 @@ var PROVIDER_PREFIXES = [
|
|
|
50
66
|
["mixtral", "mistral"],
|
|
51
67
|
["codestral", "mistral"]
|
|
52
68
|
];
|
|
53
|
-
var PROVIDER_PACKAGES = {
|
|
54
|
-
anthropic: "@ai-sdk/anthropic",
|
|
55
|
-
openai: "@ai-sdk/openai",
|
|
56
|
-
google: "@ai-sdk/google",
|
|
57
|
-
mistral: "@ai-sdk/mistral"
|
|
58
|
-
};
|
|
59
69
|
var detectProviderName = (modelId) => {
|
|
60
70
|
const lower = modelId.toLowerCase();
|
|
61
71
|
for (const [prefix, provider] of PROVIDER_PREFIXES) {
|
|
@@ -70,13 +80,28 @@ var resolveModel = async (modelId) => {
|
|
|
70
80
|
if (!providerName) {
|
|
71
81
|
return void 0;
|
|
72
82
|
}
|
|
73
|
-
const
|
|
74
|
-
if (!pkg) {
|
|
75
|
-
return void 0;
|
|
76
|
-
}
|
|
83
|
+
const sdkModelId = getSdkModelId(modelId);
|
|
77
84
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
switch (providerName) {
|
|
86
|
+
case "anthropic": {
|
|
87
|
+
const { anthropic } = await import("@ai-sdk/anthropic");
|
|
88
|
+
return anthropic(sdkModelId);
|
|
89
|
+
}
|
|
90
|
+
case "openai": {
|
|
91
|
+
const { openai } = await import("@ai-sdk/openai");
|
|
92
|
+
return openai(sdkModelId);
|
|
93
|
+
}
|
|
94
|
+
case "google": {
|
|
95
|
+
const { google } = await import("@ai-sdk/google");
|
|
96
|
+
return google(sdkModelId);
|
|
97
|
+
}
|
|
98
|
+
case "mistral": {
|
|
99
|
+
const { mistral } = await import("@ai-sdk/mistral");
|
|
100
|
+
return mistral(sdkModelId);
|
|
101
|
+
}
|
|
102
|
+
default:
|
|
103
|
+
return void 0;
|
|
104
|
+
}
|
|
80
105
|
} catch {
|
|
81
106
|
return void 0;
|
|
82
107
|
}
|
|
@@ -93,6 +118,32 @@ var createPromptMessage = (template) => {
|
|
|
93
118
|
fn.toString = () => template;
|
|
94
119
|
return fn;
|
|
95
120
|
};
|
|
121
|
+
var PROVIDER_PACKAGES = {
|
|
122
|
+
anthropic: "@ai-sdk/anthropic",
|
|
123
|
+
openai: "@ai-sdk/openai",
|
|
124
|
+
google: "@ai-sdk/google",
|
|
125
|
+
mistral: "@ai-sdk/mistral"
|
|
126
|
+
};
|
|
127
|
+
var createModelResolver = (config) => {
|
|
128
|
+
if (config?.model) {
|
|
129
|
+
const userResolver = config.model;
|
|
130
|
+
return async (modelId) => userResolver(modelId);
|
|
131
|
+
}
|
|
132
|
+
return async (modelId) => {
|
|
133
|
+
const model = await resolveModel(modelId);
|
|
134
|
+
if (model) {
|
|
135
|
+
return model;
|
|
136
|
+
}
|
|
137
|
+
const providerName = detectProviderName(modelId);
|
|
138
|
+
const pkg = providerName ? PROVIDER_PACKAGES[providerName] : void 0;
|
|
139
|
+
const hint = pkg ? `Make sure "${pkg}" is installed: npm install ${pkg}` : `Supported model prefixes: ${PROVIDER_PREFIXES.map(([p]) => p).join(", ")}`;
|
|
140
|
+
throw new PromptlyError(
|
|
141
|
+
`Failed to resolve model "${modelId}". ${hint}`,
|
|
142
|
+
"BAD_REQUEST",
|
|
143
|
+
0
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
};
|
|
96
147
|
var createPromptlyClient = (config) => {
|
|
97
148
|
const apiKey = config?.apiKey ?? process.env.PROMPTLY_API_KEY;
|
|
98
149
|
if (!apiKey) {
|
|
@@ -103,6 +154,7 @@ var createPromptlyClient = (config) => {
|
|
|
103
154
|
);
|
|
104
155
|
}
|
|
105
156
|
const baseUrl = config?.baseUrl ?? DEFAULT_BASE_URL;
|
|
157
|
+
const modelResolver = createModelResolver(config);
|
|
106
158
|
const fetchPrompt = async (promptId, options) => {
|
|
107
159
|
const url = new URL(`/prompts/${promptId}`, baseUrl);
|
|
108
160
|
if (options?.version) {
|
|
@@ -120,7 +172,7 @@ var createPromptlyClient = (config) => {
|
|
|
120
172
|
};
|
|
121
173
|
const getPrompt = async (promptId, options) => {
|
|
122
174
|
const response = await fetchPrompt(promptId, options);
|
|
123
|
-
const model = await
|
|
175
|
+
const model = await modelResolver(response.config.model);
|
|
124
176
|
return {
|
|
125
177
|
...response,
|
|
126
178
|
userMessage: createPromptMessage(response.userMessage),
|
|
@@ -141,7 +193,7 @@ var createPromptlyClient = (config) => {
|
|
|
141
193
|
version: options?.version
|
|
142
194
|
});
|
|
143
195
|
const userMessage = options?.variables ? interpolate(prompt.userMessage, options.variables) : prompt.userMessage;
|
|
144
|
-
const model = await
|
|
196
|
+
const model = await modelResolver(prompt.config.model);
|
|
145
197
|
const result = {
|
|
146
198
|
system: prompt.systemMessage,
|
|
147
199
|
prompt: userMessage,
|
|
@@ -160,5 +212,6 @@ var createPromptlyClient = (config) => {
|
|
|
160
212
|
export {
|
|
161
213
|
PromptlyError,
|
|
162
214
|
createPromptlyClient,
|
|
215
|
+
getSdkModelId,
|
|
163
216
|
interpolate
|
|
164
217
|
};
|
package/dist/schema.d.cts
CHANGED
package/dist/schema.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@promptlycms/prompts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "TypeScript SDK for Promptly CMS — fetch prompts, build Zod schemas, generate typed code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"citty": "^0.2.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
+
"@ai-sdk/anthropic": "^3.0.44",
|
|
40
|
+
"@ai-sdk/google": "^3.0.29",
|
|
41
|
+
"@ai-sdk/mistral": "^3.0.20",
|
|
42
|
+
"@ai-sdk/openai": "^3.0.29",
|
|
39
43
|
"@biomejs/biome": "^2.3.15",
|
|
40
44
|
"@changesets/changelog-github": "^0.5.2",
|
|
41
45
|
"@changesets/cli": "^2.29.8",
|