@forprompt/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +302 -0
- package/dist/cli/index.js +3143 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.cjs +439 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +308 -0
- package/dist/index.d.ts +308 -0
- package/dist/index.js +406 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/chunk-2ABKAGKB.js +2145 -0
- package/dist/mcp/chunk-2ABKAGKB.js.map +1 -0
- package/dist/mcp/index.d.ts +36 -0
- package/dist/mcp/index.js +241 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +39 -0
- package/dist/mcp/server.js +10 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/version.cjs +118 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.d.cts +12 -0
- package/dist/version.d.ts +12 -0
- package/dist/version.js +91 -0
- package/dist/version.js.map +1 -0
- package/package.json +83 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ForPrompt: () => ForPrompt,
|
|
24
|
+
ForPromptError: () => ForPromptError,
|
|
25
|
+
ForPromptLogger: () => ForPromptLogger,
|
|
26
|
+
createForPrompt: () => createForPrompt,
|
|
27
|
+
createLogger: () => createLogger,
|
|
28
|
+
forprompt: () => forprompt,
|
|
29
|
+
logger: () => logger
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
|
|
33
|
+
// src/types.ts
|
|
34
|
+
var ForPromptError = class extends Error {
|
|
35
|
+
constructor(message, statusCode, code) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.statusCode = statusCode;
|
|
38
|
+
this.code = code;
|
|
39
|
+
this.name = "ForPromptError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/client.ts
|
|
44
|
+
var DEFAULT_BASE_URL = "https://wooden-fox-811.convex.site";
|
|
45
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
46
|
+
var DEFAULT_RETRIES = 3;
|
|
47
|
+
function getBackoffDelay(attempt) {
|
|
48
|
+
const baseDelay = Math.pow(2, attempt) * 1e3;
|
|
49
|
+
const jitter = Math.random() * 500;
|
|
50
|
+
return Math.min(baseDelay + jitter, 3e4);
|
|
51
|
+
}
|
|
52
|
+
var ForPrompt = class {
|
|
53
|
+
baseUrl;
|
|
54
|
+
apiKey;
|
|
55
|
+
timeout;
|
|
56
|
+
retries;
|
|
57
|
+
constructor(config) {
|
|
58
|
+
this.apiKey = config.apiKey || "";
|
|
59
|
+
this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
60
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
61
|
+
this.retries = config.retries ?? DEFAULT_RETRIES;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetch with timeout support using AbortController
|
|
65
|
+
*/
|
|
66
|
+
async fetchWithTimeout(url, options) {
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(url, {
|
|
71
|
+
...options,
|
|
72
|
+
signal: controller.signal
|
|
73
|
+
});
|
|
74
|
+
return response;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
77
|
+
throw new ForPromptError(
|
|
78
|
+
`Request timeout after ${this.timeout}ms`,
|
|
79
|
+
408,
|
|
80
|
+
"TIMEOUT"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
} finally {
|
|
85
|
+
clearTimeout(timeoutId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Fetch with retry and exponential backoff
|
|
90
|
+
*/
|
|
91
|
+
async fetchWithRetry(url, options) {
|
|
92
|
+
let lastError = null;
|
|
93
|
+
for (let attempt = 0; attempt < this.retries; attempt++) {
|
|
94
|
+
try {
|
|
95
|
+
const response = await this.fetchWithTimeout(url, options);
|
|
96
|
+
if (response.status >= 400 && response.status < 500) {
|
|
97
|
+
return response;
|
|
98
|
+
}
|
|
99
|
+
if (response.ok) {
|
|
100
|
+
return response;
|
|
101
|
+
}
|
|
102
|
+
lastError = new ForPromptError(
|
|
103
|
+
`Server error: ${response.status}`,
|
|
104
|
+
response.status,
|
|
105
|
+
"SERVER_ERROR"
|
|
106
|
+
);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
109
|
+
if (error instanceof ForPromptError && error.code === "TIMEOUT") {
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (attempt < this.retries - 1) {
|
|
114
|
+
const delay = getBackoffDelay(attempt);
|
|
115
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
throw lastError || new ForPromptError(
|
|
119
|
+
"Request failed after retries",
|
|
120
|
+
500,
|
|
121
|
+
"RETRY_EXHAUSTED"
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a prompt by its key
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const prompt = await forprompt.getPrompt("userContextPrompt");
|
|
130
|
+
* console.log(prompt.systemPrompt);
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @example With specific version
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const prompt = await forprompt.getPrompt("userContextPrompt", { version: 2 });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
async getPrompt(key, options) {
|
|
139
|
+
if (!this.apiKey) {
|
|
140
|
+
throw new ForPromptError(
|
|
141
|
+
"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.",
|
|
142
|
+
401,
|
|
143
|
+
"MISSING_API_KEY"
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
if (!key || typeof key !== "string") {
|
|
147
|
+
throw new ForPromptError(
|
|
148
|
+
"Prompt key must be a non-empty string",
|
|
149
|
+
400,
|
|
150
|
+
"INVALID_INPUT"
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
if (key.length > 256) {
|
|
154
|
+
throw new ForPromptError(
|
|
155
|
+
"Prompt key must be 256 characters or less",
|
|
156
|
+
400,
|
|
157
|
+
"INVALID_INPUT"
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
if (options?.version !== void 0) {
|
|
161
|
+
if (!Number.isInteger(options.version) || options.version < 1) {
|
|
162
|
+
throw new ForPromptError(
|
|
163
|
+
"Version must be a positive integer",
|
|
164
|
+
400,
|
|
165
|
+
"INVALID_INPUT"
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const url = new URL(`${this.baseUrl}/api/prompts`);
|
|
170
|
+
url.searchParams.set("key", key);
|
|
171
|
+
if (options?.version !== void 0) {
|
|
172
|
+
url.searchParams.set("version", String(options.version));
|
|
173
|
+
}
|
|
174
|
+
const response = await this.fetchWithRetry(url.toString(), {
|
|
175
|
+
method: "GET",
|
|
176
|
+
headers: {
|
|
177
|
+
"Content-Type": "application/json",
|
|
178
|
+
"X-API-Key": this.apiKey
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (!response.ok) {
|
|
182
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
183
|
+
throw new ForPromptError(
|
|
184
|
+
errorData.error || `Failed to fetch prompt: ${key}`,
|
|
185
|
+
response.status,
|
|
186
|
+
response.status === 404 ? "PROMPT_NOT_FOUND" : "API_ERROR"
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return response.json();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get multiple prompts by their keys
|
|
193
|
+
*
|
|
194
|
+
* Requests are made in parallel with concurrency limit to avoid overwhelming the server.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const prompts = await forprompt.getPrompts(["userContext", "chatDefault"]);
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
async getPrompts(keys, options) {
|
|
202
|
+
const CONCURRENCY_LIMIT = 5;
|
|
203
|
+
const promptMap = /* @__PURE__ */ new Map();
|
|
204
|
+
for (let i = 0; i < keys.length; i += CONCURRENCY_LIMIT) {
|
|
205
|
+
const batch = keys.slice(i, i + CONCURRENCY_LIMIT);
|
|
206
|
+
const results = await Promise.allSettled(
|
|
207
|
+
batch.map((key) => this.getPrompt(key, options))
|
|
208
|
+
);
|
|
209
|
+
results.forEach((result, index) => {
|
|
210
|
+
if (result.status === "fulfilled") {
|
|
211
|
+
promptMap.set(batch[index], result.value);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return promptMap;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
function createForPrompt(config) {
|
|
219
|
+
const apiKey = config?.apiKey || process.env.FORPROMPT_API_KEY || "";
|
|
220
|
+
const baseUrl = config?.baseUrl || process.env.FORPROMPT_BASE_URL;
|
|
221
|
+
return new ForPrompt({
|
|
222
|
+
apiKey,
|
|
223
|
+
baseUrl,
|
|
224
|
+
timeout: config?.timeout,
|
|
225
|
+
retries: config?.retries
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
var forprompt = createForPrompt();
|
|
229
|
+
|
|
230
|
+
// src/trace.ts
|
|
231
|
+
var DEFAULT_BASE_URL2 = "https://wooden-fox-811.convex.site";
|
|
232
|
+
function generateId() {
|
|
233
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
234
|
+
const r = Math.random() * 16 | 0;
|
|
235
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
236
|
+
return v.toString(16);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
var ForPromptLogger = class {
|
|
240
|
+
baseUrl;
|
|
241
|
+
apiKey;
|
|
242
|
+
traceId = null;
|
|
243
|
+
promptKey = null;
|
|
244
|
+
versionNumber = null;
|
|
245
|
+
source = "sdk";
|
|
246
|
+
constructor(config) {
|
|
247
|
+
this.apiKey = config?.apiKey || process.env.FORPROMPT_API_KEY || "";
|
|
248
|
+
this.baseUrl = (config?.baseUrl || DEFAULT_BASE_URL2).replace(/\/$/, "");
|
|
249
|
+
this.source = config?.source || "sdk";
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Start a new trace (conversation)
|
|
253
|
+
* Returns the generated traceId
|
|
254
|
+
*
|
|
255
|
+
* @param promptKey - The prompt identifier
|
|
256
|
+
* @param options.traceId - Optional custom trace ID (auto-generated if not provided)
|
|
257
|
+
* @param options.versionNumber - Prompt version number for analytics tracking
|
|
258
|
+
*/
|
|
259
|
+
startTrace(promptKey, options) {
|
|
260
|
+
this.traceId = options?.traceId || generateId();
|
|
261
|
+
this.promptKey = promptKey;
|
|
262
|
+
this.versionNumber = options?.versionNumber ?? null;
|
|
263
|
+
return this.traceId;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Log a span (message, LLM call, etc.)
|
|
267
|
+
* Automatically creates a trace if none exists
|
|
268
|
+
*/
|
|
269
|
+
async log(options) {
|
|
270
|
+
if (!this.apiKey) {
|
|
271
|
+
throw new ForPromptError(
|
|
272
|
+
"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.",
|
|
273
|
+
401,
|
|
274
|
+
"MISSING_API_KEY"
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
if (!this.traceId) {
|
|
278
|
+
this.traceId = generateId();
|
|
279
|
+
}
|
|
280
|
+
const payload = {
|
|
281
|
+
traceId: this.traceId,
|
|
282
|
+
promptKey: this.promptKey || "unknown",
|
|
283
|
+
versionNumber: this.versionNumber ?? void 0,
|
|
284
|
+
type: "message",
|
|
285
|
+
role: options.role,
|
|
286
|
+
content: options.content,
|
|
287
|
+
model: options.model,
|
|
288
|
+
inputTokens: options.tokens?.input,
|
|
289
|
+
outputTokens: options.tokens?.output,
|
|
290
|
+
durationMs: options.durationMs,
|
|
291
|
+
source: this.source,
|
|
292
|
+
metadata: options.metadata ? JSON.stringify(options.metadata) : void 0
|
|
293
|
+
};
|
|
294
|
+
const response = await fetch(`${this.baseUrl}/api/log`, {
|
|
295
|
+
method: "POST",
|
|
296
|
+
headers: {
|
|
297
|
+
"Content-Type": "application/json",
|
|
298
|
+
"X-API-Key": this.apiKey
|
|
299
|
+
},
|
|
300
|
+
body: JSON.stringify(payload)
|
|
301
|
+
});
|
|
302
|
+
if (!response.ok) {
|
|
303
|
+
const errorData = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
304
|
+
throw new ForPromptError(
|
|
305
|
+
errorData.error || "Failed to log span",
|
|
306
|
+
response.status,
|
|
307
|
+
"LOG_ERROR"
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* End the current trace
|
|
313
|
+
* This is optional - traces can be left open
|
|
314
|
+
*/
|
|
315
|
+
async endTrace() {
|
|
316
|
+
if (!this.traceId) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
this.traceId = null;
|
|
320
|
+
this.promptKey = null;
|
|
321
|
+
this.versionNumber = null;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Get the current version number
|
|
325
|
+
*/
|
|
326
|
+
getVersionNumber() {
|
|
327
|
+
return this.versionNumber;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Get the current trace ID
|
|
331
|
+
*/
|
|
332
|
+
getTraceId() {
|
|
333
|
+
return this.traceId;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Check if a trace is active
|
|
337
|
+
*/
|
|
338
|
+
isTracing() {
|
|
339
|
+
return this.traceId !== null;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Log a single AI request/response without conversation tracking
|
|
343
|
+
* Creates a new trace with input and output spans automatically
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const { traceId } = await logger.logRequest({
|
|
348
|
+
* promptKey: "aicoaching",
|
|
349
|
+
* versionNumber: 2,
|
|
350
|
+
* input: "How do I learn Python?",
|
|
351
|
+
* output: "Here are 5 steps...",
|
|
352
|
+
* model: "gpt-4o",
|
|
353
|
+
* tokens: { input: 10, output: 150 },
|
|
354
|
+
* durationMs: 1200,
|
|
355
|
+
* });
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
async logRequest(options) {
|
|
359
|
+
if (!this.apiKey) {
|
|
360
|
+
throw new ForPromptError(
|
|
361
|
+
"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.",
|
|
362
|
+
401,
|
|
363
|
+
"MISSING_API_KEY"
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
const traceId = options.traceId || generateId();
|
|
367
|
+
const inputPayload = {
|
|
368
|
+
traceId,
|
|
369
|
+
promptKey: options.promptKey,
|
|
370
|
+
versionNumber: options.versionNumber,
|
|
371
|
+
type: "message",
|
|
372
|
+
role: "user",
|
|
373
|
+
content: options.input,
|
|
374
|
+
source: this.source
|
|
375
|
+
};
|
|
376
|
+
const inputResponse = await fetch(`${this.baseUrl}/api/log`, {
|
|
377
|
+
method: "POST",
|
|
378
|
+
headers: {
|
|
379
|
+
"Content-Type": "application/json",
|
|
380
|
+
"X-API-Key": this.apiKey
|
|
381
|
+
},
|
|
382
|
+
body: JSON.stringify(inputPayload)
|
|
383
|
+
});
|
|
384
|
+
if (!inputResponse.ok) {
|
|
385
|
+
const errorData = await inputResponse.json().catch(() => ({ error: "Unknown error" }));
|
|
386
|
+
throw new ForPromptError(
|
|
387
|
+
errorData.error || "Failed to log input span",
|
|
388
|
+
inputResponse.status,
|
|
389
|
+
"LOG_ERROR"
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
const outputPayload = {
|
|
393
|
+
traceId,
|
|
394
|
+
promptKey: options.promptKey,
|
|
395
|
+
versionNumber: options.versionNumber,
|
|
396
|
+
type: "message",
|
|
397
|
+
role: "assistant",
|
|
398
|
+
content: options.output,
|
|
399
|
+
model: options.model,
|
|
400
|
+
inputTokens: options.tokens?.input,
|
|
401
|
+
outputTokens: options.tokens?.output,
|
|
402
|
+
durationMs: options.durationMs,
|
|
403
|
+
source: this.source,
|
|
404
|
+
metadata: options.metadata ? JSON.stringify(options.metadata) : void 0
|
|
405
|
+
};
|
|
406
|
+
const outputResponse = await fetch(`${this.baseUrl}/api/log`, {
|
|
407
|
+
method: "POST",
|
|
408
|
+
headers: {
|
|
409
|
+
"Content-Type": "application/json",
|
|
410
|
+
"X-API-Key": this.apiKey
|
|
411
|
+
},
|
|
412
|
+
body: JSON.stringify(outputPayload)
|
|
413
|
+
});
|
|
414
|
+
if (!outputResponse.ok) {
|
|
415
|
+
const errorData = await outputResponse.json().catch(() => ({ error: "Unknown error" }));
|
|
416
|
+
throw new ForPromptError(
|
|
417
|
+
errorData.error || "Failed to log output span",
|
|
418
|
+
outputResponse.status,
|
|
419
|
+
"LOG_ERROR"
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
return { traceId };
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
function createLogger(config) {
|
|
426
|
+
return new ForPromptLogger(config);
|
|
427
|
+
}
|
|
428
|
+
var logger = createLogger();
|
|
429
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
430
|
+
0 && (module.exports = {
|
|
431
|
+
ForPrompt,
|
|
432
|
+
ForPromptError,
|
|
433
|
+
ForPromptLogger,
|
|
434
|
+
createForPrompt,
|
|
435
|
+
createLogger,
|
|
436
|
+
forprompt,
|
|
437
|
+
logger
|
|
438
|
+
});
|
|
439
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/client.ts","../src/trace.ts"],"sourcesContent":["/**\n * ForPrompt SDK\n *\n * Simple usage with auto-configuration:\n * @example\n * ```typescript\n * import { forprompt } from \"@forprompt/sdk\";\n *\n * // Auto-loads from FORPROMPT_API_KEY environment variable\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\");\n * console.log(prompt.systemPrompt);\n * ```\n *\n * @example With explicit configuration\n * ```typescript\n * import { createForPrompt } from \"@forprompt/sdk\";\n *\n * const client = createForPrompt({\n * apiKey: \"fp_xxx\",\n * });\n *\n * const prompt = await client.getPrompt(\"userContextPrompt\");\n * ```\n *\n * @example Using local prompts (after `npx forprompt deploy`)\n * ```typescript\n * import { userContextPrompt } from \"./forprompt\";\n *\n * // Or use getPrompt helper\n * import { getPrompt } from \"./forprompt\";\n * const prompt = getPrompt(\"userContextPrompt\");\n * ```\n */\n\n// Main client\nexport { ForPrompt, createForPrompt, forprompt } from \"./client\";\n\n// Logger\nexport { ForPromptLogger, createLogger, logger } from \"./trace\";\nexport type { LogOptions, SingleRequestOptions } from \"./trace\";\n\n// Types\nexport type { ForPromptConfig, Prompt, GetPromptOptions } from \"./types\";\nexport { ForPromptError } from \"./types\";\n","/**\n * ForPrompt SDK Types\n */\n\nexport interface ForPromptConfig {\n /** API key from ForPrompt dashboard (required) */\n apiKey: string;\n /** Custom base URL (optional, defaults to https://wooden-fox-811.convex.site) */\n baseUrl?: string;\n}\n\nexport interface Prompt {\n /** Unique key identifier for the prompt */\n key: string;\n /** Display name of the prompt */\n name: string;\n /** Optional description */\n description?: string;\n /** Version number */\n versionNumber: number;\n /** The system prompt content */\n systemPrompt: string;\n /** Last update timestamp */\n updatedAt: number;\n /** Prompt information fields */\n purpose?: string;\n expectedBehavior?: string;\n inputFormat?: string;\n outputFormat?: string;\n constraints?: string;\n useCases?: string;\n additionalNotes?: string;\n toolsNotes?: string;\n}\n\nexport interface Tool {\n /** Tool ID */\n id: string;\n /** Tool name */\n name: string;\n /** Tool description */\n description: string;\n /** JSON schema of parameters */\n parameters: string;\n /** Tool category */\n category?: string;\n /** Example usage */\n exampleUsage?: string;\n}\n\nexport interface PromptTool {\n /** Tool reference */\n tool: Tool;\n /** Whether the tool is required */\n isRequired: boolean;\n /** Usage notes for this prompt */\n usageNotes?: string;\n}\n\nexport interface GetPromptOptions {\n /** Specific version number to fetch (optional, defaults to active version) */\n version?: number;\n}\n\nexport class ForPromptError extends Error {\n constructor(\n message: string,\n public statusCode: number,\n public code: string\n ) {\n super(message);\n this.name = \"ForPromptError\";\n }\n}\n\n/**\n * Sync configuration\n */\nexport interface SyncConfig {\n // Connection\n baseUrl: string;\n projectId: string;\n apiKey: string;\n\n // Webhook settings\n webhookPort?: number; // Default: 3847\n webhookPath?: string; // Default: \"/forprompt-webhook\"\n\n // Polling fallback\n pollingInterval?: number; // Default: 60000 (1 minute)\n enablePolling?: boolean; // Default: true\n\n // Output settings\n outputDir: string; // e.g., \"./prompts\"\n format: \"typescript\" | \"json\" | \"yaml\" | \"all\";\n\n // Callbacks\n onSync?: (prompts: Prompt[]) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Webhook event payload\n */\nexport interface WebhookEvent {\n event: string;\n timestamp: number;\n projectId: string;\n data: {\n promptId?: string;\n promptKey?: string;\n versionNumber?: number;\n systemPrompt?: string;\n [key: string]: any;\n };\n}\n\n/**\n * Sync response from API\n */\nexport interface SyncResponse {\n projectId: string;\n syncedAt: number;\n prompts: Prompt[];\n}\n","/**\n * ForPrompt Client\n *\n * Simple usage with auto-configuration:\n * @example\n * ```typescript\n * import { forprompt } from \"@forprompt/sdk\";\n *\n * // Auto-loads from FORPROMPT_API_KEY env variable\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\");\n * ```\n */\n\nimport type { ForPromptConfig, Prompt, GetPromptOptions } from \"./types\";\nimport { ForPromptError } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://wooden-fox-811.convex.site\";\nconst DEFAULT_TIMEOUT = 30_000; // 30 seconds\nconst DEFAULT_RETRIES = 3;\n\n/**\n * Extended client configuration with security options\n */\nexport interface ForPromptClientConfig {\n /** Project API key (required) */\n apiKey: string;\n /** Base URL for API (default: https://wooden-fox-811.convex.site) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Number of retry attempts for failed requests (default: 3) */\n retries?: number;\n}\n\n/**\n * Calculate exponential backoff delay with jitter\n */\nfunction getBackoffDelay(attempt: number): number {\n const baseDelay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s, ...\n const jitter = Math.random() * 500; // 0-500ms random jitter\n return Math.min(baseDelay + jitter, 30_000); // Max 30s\n}\n\nexport class ForPrompt {\n private baseUrl: string;\n private apiKey: string;\n private timeout: number;\n private retries: number;\n\n constructor(config: ForPromptClientConfig | ForPromptConfig | { apiKey: string; baseUrl?: string }) {\n this.apiKey = config.apiKey || \"\";\n this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.timeout = (config as ForPromptClientConfig).timeout ?? DEFAULT_TIMEOUT;\n this.retries = (config as ForPromptClientConfig).retries ?? DEFAULT_RETRIES;\n }\n\n /**\n * Fetch with timeout support using AbortController\n */\n private async fetchWithTimeout(\n url: string,\n options: RequestInit\n ): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n signal: controller.signal,\n });\n return response;\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new ForPromptError(\n `Request timeout after ${this.timeout}ms`,\n 408,\n \"TIMEOUT\"\n );\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Fetch with retry and exponential backoff\n */\n private async fetchWithRetry(\n url: string,\n options: RequestInit\n ): Promise<Response> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt < this.retries; attempt++) {\n try {\n const response = await this.fetchWithTimeout(url, options);\n\n // Don't retry client errors (4xx) - they won't succeed on retry\n if (response.status >= 400 && response.status < 500) {\n return response;\n }\n\n // Success\n if (response.ok) {\n return response;\n }\n\n // Server error (5xx) - will retry\n lastError = new ForPromptError(\n `Server error: ${response.status}`,\n response.status,\n \"SERVER_ERROR\"\n );\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry timeout errors\n if (error instanceof ForPromptError && error.code === \"TIMEOUT\") {\n throw error;\n }\n }\n\n // Wait before retrying (unless this is the last attempt)\n if (attempt < this.retries - 1) {\n const delay = getBackoffDelay(attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw lastError || new ForPromptError(\n \"Request failed after retries\",\n 500,\n \"RETRY_EXHAUSTED\"\n );\n }\n\n /**\n * Get a prompt by its key\n *\n * @example\n * ```typescript\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\");\n * console.log(prompt.systemPrompt);\n * ```\n *\n * @example With specific version\n * ```typescript\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\", { version: 2 });\n * ```\n */\n async getPrompt(key: string, options?: GetPromptOptions): Promise<Prompt> {\n if (!this.apiKey) {\n throw new ForPromptError(\n \"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.\",\n 401,\n \"MISSING_API_KEY\"\n );\n }\n\n // Input validation\n if (!key || typeof key !== \"string\") {\n throw new ForPromptError(\n \"Prompt key must be a non-empty string\",\n 400,\n \"INVALID_INPUT\"\n );\n }\n\n if (key.length > 256) {\n throw new ForPromptError(\n \"Prompt key must be 256 characters or less\",\n 400,\n \"INVALID_INPUT\"\n );\n }\n\n if (options?.version !== undefined) {\n if (!Number.isInteger(options.version) || options.version < 1) {\n throw new ForPromptError(\n \"Version must be a positive integer\",\n 400,\n \"INVALID_INPUT\"\n );\n }\n }\n\n const url = new URL(`${this.baseUrl}/api/prompts`);\n url.searchParams.set(\"key\", key);\n\n if (options?.version !== undefined) {\n url.searchParams.set(\"version\", String(options.version));\n }\n\n const response = await this.fetchWithRetry(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({ error: \"Unknown error\" }))) as { error?: string };\n throw new ForPromptError(\n errorData.error || `Failed to fetch prompt: ${key}`,\n response.status,\n response.status === 404 ? \"PROMPT_NOT_FOUND\" : \"API_ERROR\"\n );\n }\n\n return response.json() as Promise<Prompt>;\n }\n\n /**\n * Get multiple prompts by their keys\n *\n * Requests are made in parallel with concurrency limit to avoid overwhelming the server.\n *\n * @example\n * ```typescript\n * const prompts = await forprompt.getPrompts([\"userContext\", \"chatDefault\"]);\n * ```\n */\n async getPrompts(\n keys: string[],\n options?: GetPromptOptions\n ): Promise<Map<string, Prompt>> {\n // Limit concurrent requests to avoid overwhelming the server\n const CONCURRENCY_LIMIT = 5;\n const promptMap = new Map<string, Prompt>();\n\n // Process in batches\n for (let i = 0; i < keys.length; i += CONCURRENCY_LIMIT) {\n const batch = keys.slice(i, i + CONCURRENCY_LIMIT);\n\n const results = await Promise.allSettled(\n batch.map((key) => this.getPrompt(key, options))\n );\n\n results.forEach((result, index) => {\n if (result.status === \"fulfilled\") {\n promptMap.set(batch[index]!, result.value);\n }\n });\n }\n\n return promptMap;\n }\n}\n\n/**\n * Create a ForPrompt client instance\n *\n * @example With explicit config\n * ```typescript\n * import { createForPrompt } from \"@forprompt/sdk\";\n *\n * const client = createForPrompt({\n * apiKey: \"fp_xxx\",\n * });\n *\n * const prompt = await client.getPrompt(\"userContextPrompt\");\n * ```\n *\n * @example With timeout and retry config\n * ```typescript\n * const client = createForPrompt({\n * apiKey: \"fp_xxx\",\n * timeout: 10000, // 10 seconds\n * retries: 5,\n * });\n * ```\n *\n * @example Auto-config from environment\n * ```typescript\n * import { forprompt } from \"@forprompt/sdk\";\n *\n * // Uses FORPROMPT_API_KEY from environment\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\");\n * ```\n */\nexport function createForPrompt(config?: Partial<ForPromptClientConfig>): ForPrompt {\n const apiKey = config?.apiKey || process.env.FORPROMPT_API_KEY || \"\";\n const baseUrl = config?.baseUrl || process.env.FORPROMPT_BASE_URL;\n\n return new ForPrompt({\n apiKey,\n baseUrl,\n timeout: config?.timeout,\n retries: config?.retries,\n });\n}\n\n/**\n * Default ForPrompt client instance\n *\n * Auto-configured from environment variables:\n * - FORPROMPT_API_KEY: Your project API key\n * - FORPROMPT_BASE_URL: Custom base URL (optional)\n *\n * @example\n * ```typescript\n * import { forprompt } from \"@forprompt/sdk\";\n *\n * const prompt = await forprompt.getPrompt(\"userContextPrompt\");\n * console.log(prompt.systemPrompt);\n * ```\n */\nexport const forprompt = createForPrompt();\n","/**\n * ForPrompt Logger\n * \n * Implements trace/span model for logging AI conversations\n * \n * @example Basic usage\n * ```typescript\n * import { logger } from \"@forprompt/sdk\";\n * \n * // Start a trace\n * logger.startTrace(\"onboardingprompt\");\n * \n * // Log user message\n * await logger.log({ role: \"user\", content: \"Hello\" });\n * \n * // Log AI response\n * await logger.log({\n * role: \"assistant\",\n * content: \"Hi! How can I help?\",\n * model: \"gpt-4o\",\n * tokens: { output: 120 }\n * });\n * \n * // End trace (optional)\n * logger.endTrace();\n * ```\n */\n\nimport { ForPromptError } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://wooden-fox-811.convex.site\";\n\n/**\n * Generate a simple unique ID (UUID v4-like)\n */\nfunction generateId(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\nexport interface LogOptions {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n model?: string;\n tokens?: {\n input?: number;\n output?: number;\n };\n durationMs?: number;\n metadata?: Record<string, any>;\n}\n\n/**\n * Options for logging a single AI request/response\n * Use this for one-shot interactions without conversation tracking\n */\nexport interface SingleRequestOptions {\n /** The prompt identifier */\n promptKey: string;\n /** Prompt version number for analytics tracking */\n versionNumber?: number;\n /** Optional custom trace ID (auto-generated if not provided) */\n traceId?: string;\n /** The user's input/prompt */\n input: string;\n /** The AI's output/response */\n output: string;\n /** The model used (e.g., \"gpt-4o\", \"claude-sonnet-4\") */\n model?: string;\n /** Token counts */\n tokens?: {\n input?: number;\n output?: number;\n };\n /** Total duration in milliseconds */\n durationMs?: number;\n /** Additional metadata */\n metadata?: Record<string, any>;\n}\n\nexport class ForPromptLogger {\n private baseUrl: string;\n private apiKey: string;\n private traceId: string | null = null;\n private promptKey: string | null = null;\n private versionNumber: number | null = null;\n private source: string = \"sdk\";\n\n constructor(config?: { apiKey?: string; baseUrl?: string; source?: string }) {\n this.apiKey = config?.apiKey || process.env.FORPROMPT_API_KEY || \"\";\n this.baseUrl = (config?.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n this.source = config?.source || \"sdk\";\n }\n\n /**\n * Start a new trace (conversation)\n * Returns the generated traceId\n *\n * @param promptKey - The prompt identifier\n * @param options.traceId - Optional custom trace ID (auto-generated if not provided)\n * @param options.versionNumber - Prompt version number for analytics tracking\n */\n startTrace(promptKey: string, options?: { traceId?: string; versionNumber?: number }): string {\n this.traceId = options?.traceId || generateId();\n this.promptKey = promptKey;\n this.versionNumber = options?.versionNumber ?? null;\n return this.traceId;\n }\n\n /**\n * Log a span (message, LLM call, etc.)\n * Automatically creates a trace if none exists\n */\n async log(options: LogOptions): Promise<void> {\n if (!this.apiKey) {\n throw new ForPromptError(\n \"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.\",\n 401,\n \"MISSING_API_KEY\"\n );\n }\n\n // Auto-generate traceId if not started\n if (!this.traceId) {\n this.traceId = generateId();\n }\n\n const payload = {\n traceId: this.traceId,\n promptKey: this.promptKey || \"unknown\",\n versionNumber: this.versionNumber ?? undefined,\n type: \"message\",\n role: options.role,\n content: options.content,\n model: options.model,\n inputTokens: options.tokens?.input,\n outputTokens: options.tokens?.output,\n durationMs: options.durationMs,\n source: this.source,\n metadata: options.metadata ? JSON.stringify(options.metadata) : undefined,\n };\n\n const response = await fetch(`${this.baseUrl}/api/log`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({ error: \"Unknown error\" }))) as { error?: string };\n throw new ForPromptError(\n errorData.error || \"Failed to log span\",\n response.status,\n \"LOG_ERROR\"\n );\n }\n }\n\n /**\n * End the current trace\n * This is optional - traces can be left open\n */\n async endTrace(): Promise<void> {\n if (!this.traceId) {\n return;\n }\n\n // Optionally update trace status to \"completed\"\n // For now, we just clear the local state\n this.traceId = null;\n this.promptKey = null;\n this.versionNumber = null;\n }\n\n /**\n * Get the current version number\n */\n getVersionNumber(): number | null {\n return this.versionNumber;\n }\n\n /**\n * Get the current trace ID\n */\n getTraceId(): string | null {\n return this.traceId;\n }\n\n /**\n * Check if a trace is active\n */\n isTracing(): boolean {\n return this.traceId !== null;\n }\n\n /**\n * Log a single AI request/response without conversation tracking\n * Creates a new trace with input and output spans automatically\n *\n * @example\n * ```typescript\n * const { traceId } = await logger.logRequest({\n * promptKey: \"aicoaching\",\n * versionNumber: 2,\n * input: \"How do I learn Python?\",\n * output: \"Here are 5 steps...\",\n * model: \"gpt-4o\",\n * tokens: { input: 10, output: 150 },\n * durationMs: 1200,\n * });\n * ```\n */\n async logRequest(options: SingleRequestOptions): Promise<{ traceId: string }> {\n if (!this.apiKey) {\n throw new ForPromptError(\n \"API key is required. Set FORPROMPT_API_KEY environment variable or pass apiKey in config.\",\n 401,\n \"MISSING_API_KEY\"\n );\n }\n\n const traceId = options.traceId || generateId();\n\n // Log input (user message)\n const inputPayload = {\n traceId,\n promptKey: options.promptKey,\n versionNumber: options.versionNumber,\n type: \"message\",\n role: \"user\",\n content: options.input,\n source: this.source,\n };\n\n const inputResponse = await fetch(`${this.baseUrl}/api/log`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n body: JSON.stringify(inputPayload),\n });\n\n if (!inputResponse.ok) {\n const errorData = (await inputResponse.json().catch(() => ({ error: \"Unknown error\" }))) as { error?: string };\n throw new ForPromptError(\n errorData.error || \"Failed to log input span\",\n inputResponse.status,\n \"LOG_ERROR\"\n );\n }\n\n // Log output (assistant response)\n const outputPayload = {\n traceId,\n promptKey: options.promptKey,\n versionNumber: options.versionNumber,\n type: \"message\",\n role: \"assistant\",\n content: options.output,\n model: options.model,\n inputTokens: options.tokens?.input,\n outputTokens: options.tokens?.output,\n durationMs: options.durationMs,\n source: this.source,\n metadata: options.metadata ? JSON.stringify(options.metadata) : undefined,\n };\n\n const outputResponse = await fetch(`${this.baseUrl}/api/log`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n body: JSON.stringify(outputPayload),\n });\n\n if (!outputResponse.ok) {\n const errorData = (await outputResponse.json().catch(() => ({ error: \"Unknown error\" }))) as { error?: string };\n throw new ForPromptError(\n errorData.error || \"Failed to log output span\",\n outputResponse.status,\n \"LOG_ERROR\"\n );\n }\n\n return { traceId };\n }\n}\n\n/**\n * Create a ForPrompt logger instance\n */\nexport function createLogger(config?: { apiKey?: string; baseUrl?: string; source?: string }): ForPromptLogger {\n return new ForPromptLogger(config);\n}\n\n/**\n * Default logger instance\n * Auto-configured from environment variables\n */\nexport const logger = createLogger();\n\n\n\n\n"],"mappings":"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","names":["DEFAULT_BASE_URL"]}
|