@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 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: `zod@^4`, `ai@^4 || ^5 || ^6`, `typescript@^5`
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. This gives you typed autocomplete on `userMessage()` variables for every prompt ID.
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 { createPromptClient } from '@promptlycms/prompts';
61
+ import { createPromptlyClient } from '@promptlycms/prompts';
44
62
 
45
- const promptly = createPromptClient({
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.get('JPxlUpstuhXB5OwOtKPpj');
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.get('JPxlUpstuhXB5OwOtKPpj', {
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 narrow types:
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
- pickupLocation: string;
131
- items: string;
174
+ [V in 'latest' | '2.0.0' | '1.0.0']: {
175
+ pickupLocation: string;
176
+ items: string;
177
+ };
132
178
  };
133
179
  'abc123': {
134
- email: string;
135
- subject: string;
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, `get()` and `getPrompts()` return typed `userMessage` functions with autocomplete. Unknown prompt IDs fall back to `Record<string, string>`.
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.get('nonexistent');
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
- ### `createPromptClient(config)`
215
+ ### `createPromptlyClient(config?)`
174
216
 
175
217
  | Option | Type | Required | Description |
176
218
  |-----------|----------|----------|----------------------------------------------------|
177
- | `apiKey` | `string` | Yes | Your Promptly CMS API key |
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 `PromptClient` with `get()`, `getPrompts()`, and `aiParams()` methods.
223
+ Returns a `PromptlyClient` with `getPrompt()`, `getPrompts()`, and `aiParams()` methods.
181
224
 
182
- ### `client.get(promptId, options?)`
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 pkg = PROVIDER_PACKAGES[providerName];
388
- if (!pkg) {
389
- return void 0;
390
- }
398
+ const sdkModelId = getSdkModelId(modelId);
391
399
  try {
392
- const mod = await import(pkg);
393
- return mod[providerName](modelId);
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 resolveModel(response.config.model);
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 resolveModel(prompt.config.model);
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-DtbFuFmA.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-DtbFuFmA.cjs';
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-DtbFuFmA.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-DtbFuFmA.js';
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 pkg = PROVIDER_PACKAGES[providerName];
74
- if (!pkg) {
75
- return void 0;
76
- }
83
+ const sdkModelId = getSdkModelId(modelId);
77
84
  try {
78
- const mod = await import(pkg);
79
- return mod[providerName](modelId);
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 resolveModel(response.config.model);
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 resolveModel(prompt.config.model);
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
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { S as SchemaField } from './types-DtbFuFmA.cjs';
2
+ import { S as SchemaField } from './types-W-omtl43.cjs';
3
3
  import 'ai';
4
4
 
5
5
  declare const buildFieldSchema: (field: SchemaField) => z.ZodTypeAny;
package/dist/schema.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { S as SchemaField } from './types-DtbFuFmA.js';
2
+ import { S as SchemaField } from './types-W-omtl43.js';
3
3
  import 'ai';
4
4
 
5
5
  declare const buildFieldSchema: (field: SchemaField) => z.ZodTypeAny;
@@ -105,6 +105,7 @@ type ErrorResponse = {
105
105
  type PromptlyClientConfig = {
106
106
  apiKey?: string;
107
107
  baseUrl?: string;
108
+ model?: (modelId: string) => ai.LanguageModel;
108
109
  };
109
110
  type GetOptions<V extends string = string> = {
110
111
  version?: V;
@@ -105,6 +105,7 @@ type ErrorResponse = {
105
105
  type PromptlyClientConfig = {
106
106
  apiKey?: string;
107
107
  baseUrl?: string;
108
+ model?: (modelId: string) => ai.LanguageModel;
108
109
  };
109
110
  type GetOptions<V extends string = string> = {
110
111
  version?: V;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptlycms/prompts",
3
- "version": "0.1.0",
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",