@cobbl-ai/sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -55
- package/dist/admin.d.mts +90 -0
- package/dist/admin.d.ts +90 -0
- package/dist/admin.js +185 -0
- package/dist/admin.js.map +1 -0
- package/dist/admin.mjs +182 -0
- package/dist/admin.mjs.map +1 -0
- package/dist/cobbl-sdk.global.js +2 -0
- package/dist/cobbl-sdk.global.js.map +1 -0
- package/dist/errors-BaYZ2rGo.d.mts +208 -0
- package/dist/errors-BaYZ2rGo.d.ts +208 -0
- package/dist/index.d.mts +3 -348
- package/dist/index.d.ts +3 -348
- package/dist/index.js +222 -75
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +221 -75
- package/dist/index.mjs.map +1 -1
- package/dist/public.d.mts +130 -0
- package/dist/public.d.ts +130 -0
- package/dist/public.js +271 -0
- package/dist/public.js.map +1 -0
- package/dist/public.mjs +268 -0
- package/dist/public.mjs.map +1 -0
- package/package.json +40 -11
- package/src/__tests__/client.test.ts +362 -107
- package/src/__tests__/integration.test.ts +129 -38
- package/src/admin.ts +184 -0
- package/src/browser.ts +12 -0
- package/src/errors.ts +49 -0
- package/src/index.ts +35 -10
- package/src/public.ts +270 -0
- package/src/types.ts +164 -58
- package/src/validation.ts +52 -0
- package/src/client.ts +0 -257
package/dist/index.mjs
CHANGED
|
@@ -27,28 +27,76 @@ var CobblError = class _CobblError extends Error {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
+
var handleErrorResponse = async (response) => {
|
|
31
|
+
let errorData;
|
|
32
|
+
try {
|
|
33
|
+
errorData = await response.json();
|
|
34
|
+
} catch {
|
|
35
|
+
throw new CobblError(
|
|
36
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
37
|
+
"API_ERROR",
|
|
38
|
+
{ status: response.status }
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const message = errorData.error || errorData.message || "Unknown error";
|
|
42
|
+
const details = errorData.details;
|
|
43
|
+
switch (response.status) {
|
|
44
|
+
case 400:
|
|
45
|
+
throw new CobblError(message, "INVALID_REQUEST", details);
|
|
46
|
+
case 401:
|
|
47
|
+
throw new CobblError(message, "UNAUTHORIZED", details);
|
|
48
|
+
case 403:
|
|
49
|
+
throw new CobblError(message, "FORBIDDEN", details);
|
|
50
|
+
case 404:
|
|
51
|
+
throw new CobblError(message, "NOT_FOUND", details);
|
|
52
|
+
case 410:
|
|
53
|
+
throw new CobblError(message, "ARCHIVED", details);
|
|
54
|
+
case 429:
|
|
55
|
+
throw new CobblError(message, "RATE_LIMIT_EXCEEDED", details);
|
|
56
|
+
case 500:
|
|
57
|
+
case 502:
|
|
58
|
+
case 503:
|
|
59
|
+
case 504:
|
|
60
|
+
throw new CobblError(message, "SERVER_ERROR", details);
|
|
61
|
+
default:
|
|
62
|
+
throw new CobblError(message, "API_ERROR", {
|
|
63
|
+
status: response.status,
|
|
64
|
+
...details
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
30
68
|
|
|
31
|
-
// src/
|
|
69
|
+
// src/admin.ts
|
|
32
70
|
var REQUEST_TIMEOUT_MS = 3e4;
|
|
33
|
-
var
|
|
71
|
+
var CobblAdminClient = class {
|
|
34
72
|
/**
|
|
35
|
-
* Initialize the Cobbl SDK client
|
|
73
|
+
* Initialize the Cobbl Admin SDK client
|
|
36
74
|
*
|
|
37
75
|
* @param config - Configuration object
|
|
38
76
|
* @param config.apiKey - Your Cobbl API key
|
|
77
|
+
* @param config.baseUrl - Optional base URL for the API (defaults to 'https://api.cobbl.ai')
|
|
39
78
|
*
|
|
40
|
-
* @example
|
|
79
|
+
* @example Production (uses default URL)
|
|
41
80
|
* ```typescript
|
|
42
|
-
* const client = new
|
|
81
|
+
* const client = new CobblAdminClient({
|
|
43
82
|
* apiKey: process.env.COBBL_API_KEY
|
|
44
83
|
* })
|
|
45
84
|
* ```
|
|
85
|
+
*
|
|
86
|
+
* @example Local development with Firebase emulators
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const client = new CobblAdminClient({
|
|
89
|
+
* apiKey: process.env.COBBL_API_KEY,
|
|
90
|
+
* baseUrl: 'http://localhost:5001/your-project-id/us-central1/externalApi'
|
|
91
|
+
* })
|
|
92
|
+
* ```
|
|
46
93
|
*/
|
|
47
94
|
constructor(config) {
|
|
48
95
|
if (!config.apiKey || config.apiKey.trim().length === 0) {
|
|
49
96
|
throw new CobblError("API key is required", "INVALID_CONFIG");
|
|
50
97
|
}
|
|
51
98
|
this.apiKey = config.apiKey;
|
|
99
|
+
this.baseUrl = config.baseUrl?.trim() || "https://api.cobbl.ai";
|
|
52
100
|
}
|
|
53
101
|
/**
|
|
54
102
|
* Execute a prompt with the given input variables
|
|
@@ -76,7 +124,7 @@ var CobblClient = class {
|
|
|
76
124
|
throw new CobblError("promptSlug is required", "INVALID_REQUEST");
|
|
77
125
|
}
|
|
78
126
|
try {
|
|
79
|
-
const response = await this.makeRequest("/prompt/run", {
|
|
127
|
+
const response = await this.makeRequest("/admin/v1/prompt/run", {
|
|
80
128
|
method: "POST",
|
|
81
129
|
body: JSON.stringify({
|
|
82
130
|
promptSlug: promptSlug.trim(),
|
|
@@ -84,7 +132,7 @@ var CobblClient = class {
|
|
|
84
132
|
})
|
|
85
133
|
});
|
|
86
134
|
if (!response.ok) {
|
|
87
|
-
await
|
|
135
|
+
await handleErrorResponse(response);
|
|
88
136
|
}
|
|
89
137
|
const data = await response.json();
|
|
90
138
|
return {
|
|
@@ -105,53 +153,191 @@ var CobblClient = class {
|
|
|
105
153
|
}
|
|
106
154
|
}
|
|
107
155
|
/**
|
|
108
|
-
*
|
|
156
|
+
* Make an HTTP request to the Cobbl API
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
async makeRequest(path, options) {
|
|
160
|
+
const url = `${this.baseUrl}${path}`;
|
|
161
|
+
const controller = new AbortController();
|
|
162
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
163
|
+
try {
|
|
164
|
+
const response = await fetch(url, {
|
|
165
|
+
...options,
|
|
166
|
+
headers: {
|
|
167
|
+
"Content-Type": "application/json",
|
|
168
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
169
|
+
...options.headers
|
|
170
|
+
},
|
|
171
|
+
signal: controller.signal
|
|
172
|
+
});
|
|
173
|
+
return response;
|
|
174
|
+
} finally {
|
|
175
|
+
clearTimeout(timeoutId);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// src/validation.ts
|
|
181
|
+
var VALID_HELPFUL_VALUES = ["helpful", "not_helpful"];
|
|
182
|
+
function validateCreateFeedback(feedback) {
|
|
183
|
+
if (!feedback.runId || feedback.runId.trim().length === 0) {
|
|
184
|
+
return "runId is required";
|
|
185
|
+
}
|
|
186
|
+
if (feedback.helpful !== void 0 && !VALID_HELPFUL_VALUES.includes(feedback.helpful)) {
|
|
187
|
+
return 'helpful must be "helpful" or "not_helpful"';
|
|
188
|
+
}
|
|
189
|
+
if (feedback.userFeedback !== void 0 && feedback.userFeedback.trim().length === 0) {
|
|
190
|
+
return "userFeedback cannot be empty";
|
|
191
|
+
}
|
|
192
|
+
if (feedback.helpful === void 0 && feedback.userFeedback === void 0) {
|
|
193
|
+
return "At least one of helpful or userFeedback is required";
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
function validateUpdateFeedback(update) {
|
|
198
|
+
if (update.helpful !== void 0 && !VALID_HELPFUL_VALUES.includes(update.helpful)) {
|
|
199
|
+
return 'helpful must be "helpful" or "not_helpful"';
|
|
200
|
+
}
|
|
201
|
+
if (update.userFeedback !== void 0 && update.userFeedback.trim().length === 0) {
|
|
202
|
+
return "userFeedback cannot be empty";
|
|
203
|
+
}
|
|
204
|
+
if (update.helpful === void 0 && update.userFeedback === void 0) {
|
|
205
|
+
return "At least one of helpful or userFeedback is required";
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/public.ts
|
|
211
|
+
var REQUEST_TIMEOUT_MS2 = 3e4;
|
|
212
|
+
var CobblPublicClient = class {
|
|
213
|
+
/**
|
|
214
|
+
* Initialize the Cobbl Public SDK client
|
|
215
|
+
*
|
|
216
|
+
* @param config - Configuration object
|
|
217
|
+
* @param config.baseUrl - Optional base URL for the API (defaults to 'https://api.cobbl.ai')
|
|
218
|
+
*/
|
|
219
|
+
constructor(config = {}) {
|
|
220
|
+
this.baseUrl = config.baseUrl?.trim() || "https://api.cobbl.ai";
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Create user feedback for a prompt run
|
|
224
|
+
* Supports segmented feedback - you can provide just helpful, just userFeedback, or both
|
|
225
|
+
* Use updateFeedback to add additional data later
|
|
109
226
|
*
|
|
110
227
|
* @param feedback - Feedback submission data
|
|
111
228
|
* @param feedback.runId - The run ID from a previous runPrompt call
|
|
112
|
-
* @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful')
|
|
113
|
-
* @param feedback.userFeedback - Detailed feedback message from the user
|
|
229
|
+
* @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional
|
|
230
|
+
* @param feedback.userFeedback - Detailed feedback message from the user - optional
|
|
114
231
|
* @returns Promise containing the created feedback ID
|
|
115
232
|
*
|
|
116
233
|
* @throws {CobblError} When the request fails or API returns an error
|
|
117
234
|
*
|
|
118
|
-
* @example
|
|
235
|
+
* @example Submit just thumbs down first
|
|
119
236
|
* ```typescript
|
|
120
|
-
* await client.
|
|
237
|
+
* const { id } = await client.createFeedback({
|
|
238
|
+
* runId: result.runId,
|
|
239
|
+
* helpful: 'not_helpful'
|
|
240
|
+
* })
|
|
241
|
+
* // Later, add details
|
|
242
|
+
* await client.updateFeedback(id, {
|
|
243
|
+
* userFeedback: 'The response was too formal and lengthy'
|
|
244
|
+
* })
|
|
245
|
+
* ```
|
|
246
|
+
*
|
|
247
|
+
* @example Submit both at once
|
|
248
|
+
* ```typescript
|
|
249
|
+
* await client.createFeedback({
|
|
121
250
|
* runId: result.runId,
|
|
122
251
|
* helpful: 'not_helpful',
|
|
123
252
|
* userFeedback: 'The response was too formal and lengthy'
|
|
124
253
|
* })
|
|
125
254
|
* ```
|
|
126
255
|
*/
|
|
127
|
-
async
|
|
128
|
-
|
|
129
|
-
|
|
256
|
+
async createFeedback(feedback) {
|
|
257
|
+
const validationError = validateCreateFeedback(feedback);
|
|
258
|
+
if (validationError) {
|
|
259
|
+
throw new CobblError(validationError, "INVALID_REQUEST");
|
|
130
260
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
261
|
+
try {
|
|
262
|
+
const body = {
|
|
263
|
+
runId: feedback.runId.trim(),
|
|
264
|
+
helpful: feedback.helpful,
|
|
265
|
+
userFeedback: feedback.userFeedback?.trim()
|
|
266
|
+
};
|
|
267
|
+
const response = await this.makeRequest("/public/v1/feedback", {
|
|
268
|
+
method: "POST",
|
|
269
|
+
body: JSON.stringify(body)
|
|
270
|
+
});
|
|
271
|
+
if (!response.ok) {
|
|
272
|
+
await handleErrorResponse(response);
|
|
273
|
+
}
|
|
274
|
+
const data = await response.json();
|
|
275
|
+
return {
|
|
276
|
+
id: data.id,
|
|
277
|
+
message: data.message
|
|
278
|
+
};
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (error instanceof CobblError) {
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
135
283
|
throw new CobblError(
|
|
136
|
-
|
|
137
|
-
"
|
|
284
|
+
`Failed to create feedback: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
285
|
+
"NETWORK_ERROR"
|
|
138
286
|
);
|
|
139
287
|
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Update existing feedback with additional data
|
|
291
|
+
* Use this to add helpful sentiment or detailed feedback after initial submission
|
|
292
|
+
*
|
|
293
|
+
* @param id - The ID returned from createFeedback
|
|
294
|
+
* @param update - The data to update
|
|
295
|
+
* @param update.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional
|
|
296
|
+
* @param update.userFeedback - Detailed feedback message from the user - optional
|
|
297
|
+
* @returns Promise containing the updated feedback ID
|
|
298
|
+
*
|
|
299
|
+
* @throws {CobblError} When the request fails or API returns an error
|
|
300
|
+
*
|
|
301
|
+
* @example Add details after initial thumbs down
|
|
302
|
+
* ```typescript
|
|
303
|
+
* // First, submit just the rating
|
|
304
|
+
* const { id } = await client.createFeedback({
|
|
305
|
+
* runId: result.runId,
|
|
306
|
+
* helpful: 'not_helpful'
|
|
307
|
+
* })
|
|
308
|
+
*
|
|
309
|
+
* // Later, add detailed feedback
|
|
310
|
+
* await client.updateFeedback(id, {
|
|
311
|
+
* userFeedback: 'The response was too formal and lengthy'
|
|
312
|
+
* })
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
async updateFeedback(id, update) {
|
|
316
|
+
if (!id || id.trim().length === 0) {
|
|
317
|
+
throw new CobblError("id is required", "INVALID_REQUEST");
|
|
318
|
+
}
|
|
319
|
+
const validationError = validateUpdateFeedback(update);
|
|
320
|
+
if (validationError) {
|
|
321
|
+
throw new CobblError(validationError, "INVALID_REQUEST");
|
|
322
|
+
}
|
|
140
323
|
try {
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
324
|
+
const body = {
|
|
325
|
+
helpful: update.helpful,
|
|
326
|
+
userFeedback: update.userFeedback?.trim()
|
|
327
|
+
};
|
|
328
|
+
const response = await this.makeRequest(
|
|
329
|
+
`/public/v1/feedback/${id.trim()}`,
|
|
330
|
+
{
|
|
331
|
+
method: "PATCH",
|
|
332
|
+
body: JSON.stringify(body)
|
|
333
|
+
}
|
|
334
|
+
);
|
|
149
335
|
if (!response.ok) {
|
|
150
|
-
await
|
|
336
|
+
await handleErrorResponse(response);
|
|
151
337
|
}
|
|
152
338
|
const data = await response.json();
|
|
153
339
|
return {
|
|
154
|
-
|
|
340
|
+
id: data.id,
|
|
155
341
|
message: data.message
|
|
156
342
|
};
|
|
157
343
|
} catch (error) {
|
|
@@ -159,7 +345,7 @@ var CobblClient = class {
|
|
|
159
345
|
throw error;
|
|
160
346
|
}
|
|
161
347
|
throw new CobblError(
|
|
162
|
-
`Failed to
|
|
348
|
+
`Failed to update feedback: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
163
349
|
"NETWORK_ERROR"
|
|
164
350
|
);
|
|
165
351
|
}
|
|
@@ -169,16 +355,14 @@ var CobblClient = class {
|
|
|
169
355
|
* @private
|
|
170
356
|
*/
|
|
171
357
|
async makeRequest(path, options) {
|
|
172
|
-
const
|
|
173
|
-
const url = `${baseUrl}${path}`;
|
|
358
|
+
const url = `${this.baseUrl}${path}`;
|
|
174
359
|
const controller = new AbortController();
|
|
175
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
360
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
176
361
|
try {
|
|
177
362
|
const response = await fetch(url, {
|
|
178
363
|
...options,
|
|
179
364
|
headers: {
|
|
180
365
|
"Content-Type": "application/json",
|
|
181
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
182
366
|
...options.headers
|
|
183
367
|
},
|
|
184
368
|
signal: controller.signal
|
|
@@ -188,46 +372,8 @@ var CobblClient = class {
|
|
|
188
372
|
clearTimeout(timeoutId);
|
|
189
373
|
}
|
|
190
374
|
}
|
|
191
|
-
/**
|
|
192
|
-
* Handle error responses from the API
|
|
193
|
-
* @private
|
|
194
|
-
*/
|
|
195
|
-
async handleErrorResponse(response) {
|
|
196
|
-
let errorData;
|
|
197
|
-
try {
|
|
198
|
-
errorData = await response.json();
|
|
199
|
-
} catch {
|
|
200
|
-
throw new CobblError(
|
|
201
|
-
`HTTP ${response.status}: ${response.statusText}`,
|
|
202
|
-
"API_ERROR",
|
|
203
|
-
{ status: response.status }
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
const message = errorData.error || errorData.message || "Unknown error";
|
|
207
|
-
const details = errorData.details;
|
|
208
|
-
switch (response.status) {
|
|
209
|
-
case 400:
|
|
210
|
-
throw new CobblError(message, "INVALID_REQUEST", details);
|
|
211
|
-
case 401:
|
|
212
|
-
throw new CobblError(message, "UNAUTHORIZED", details);
|
|
213
|
-
case 404:
|
|
214
|
-
throw new CobblError(message, "NOT_FOUND", details);
|
|
215
|
-
case 429:
|
|
216
|
-
throw new CobblError(message, "RATE_LIMIT_EXCEEDED", details);
|
|
217
|
-
case 500:
|
|
218
|
-
case 502:
|
|
219
|
-
case 503:
|
|
220
|
-
case 504:
|
|
221
|
-
throw new CobblError(message, "SERVER_ERROR", details);
|
|
222
|
-
default:
|
|
223
|
-
throw new CobblError(message, "API_ERROR", {
|
|
224
|
-
status: response.status,
|
|
225
|
-
...details
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
375
|
};
|
|
230
376
|
|
|
231
|
-
export {
|
|
377
|
+
export { CobblAdminClient, CobblError, CobblPublicClient };
|
|
232
378
|
//# sourceMappingURL=index.mjs.map
|
|
233
379
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Error types that can be thrown by the Cobbl SDK\n */\nexport type CobblErrorCode =\n | 'INVALID_CONFIG'\n | 'INVALID_REQUEST'\n | 'UNAUTHORIZED'\n | 'NOT_FOUND'\n | 'RATE_LIMIT_EXCEEDED'\n | 'SERVER_ERROR'\n | 'NETWORK_ERROR'\n | 'API_ERROR'\n\n/**\n * Custom error class for Cobbl SDK errors\n *\n * @example\n * ```typescript\n * try {\n * await client.runPrompt('my-prompt', { topic: 'test' })\n * } catch (error) {\n * if (error instanceof CobblError) {\n * console.error(`Error [${error.code}]: ${error.message}`)\n * console.error('Details:', error.details)\n * }\n * }\n * ```\n */\nexport class CobblError extends Error {\n /**\n * Error code indicating the type of error\n */\n public readonly code: CobblErrorCode\n\n /**\n * Additional details about the error (e.g., missing variables, validation issues)\n */\n public readonly details?: unknown\n\n constructor(message: string, code: CobblErrorCode, details?: unknown) {\n super(message)\n this.name = 'CobblError'\n this.code = code\n this.details = details\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CobblError)\n }\n }\n\n /**\n * Check if an error is a CobblError\n */\n static isCobblError(error: unknown): error is CobblError {\n return error instanceof CobblError\n }\n\n /**\n * Convert error to JSON-serializable object\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n details: this.details,\n }\n }\n}\n","/**\n * CobblClient - SDK for the Cobbl platform\n *\n * Provides methods to run prompts and submit feedback to the Cobbl API.\n */\n\nimport type { PromptInput, PromptVersionClient } from '@prompti/shared'\nimport type {\n RunPromptResponse,\n SubmitFeedbackResponse,\n CobblConfig,\n TokenUsage,\n FeedbackSubmission,\n} from './types'\nimport { CobblError } from './errors'\n\nconst REQUEST_TIMEOUT_MS = 30_000\n\nexport class CobblClient {\n private readonly apiKey: string\n\n /**\n * Initialize the Cobbl SDK client\n *\n * @param config - Configuration object\n * @param config.apiKey - Your Cobbl API key\n *\n * @example\n * ```typescript\n * const client = new CobblClient({\n * apiKey: process.env.COBBL_API_KEY\n * })\n * ```\n */\n constructor(config: CobblConfig) {\n if (!config.apiKey || config.apiKey.trim().length === 0) {\n throw new CobblError('API key is required', 'INVALID_CONFIG')\n }\n\n this.apiKey = config.apiKey\n }\n\n /**\n * Execute a prompt with the given input variables\n *\n * @param promptSlug - The unique slug identifier for the prompt\n * @param input - Input variables to populate the prompt template\n * @returns Promise containing the prompt execution results\n *\n * @throws {CobblError} When the request fails or API returns an error\n *\n * @example\n * ```typescript\n * const result = await client.runPrompt('sales_summary', {\n * topic: 'Q4 Results',\n * tone: 'friendly',\n * audience: 'investors'\n * })\n *\n * console.log(result.output) // AI-generated response\n * console.log(result.runId) // Save this to link feedback later\n * ```\n */\n async runPrompt(\n promptSlug: string,\n input: PromptInput\n ): Promise<RunPromptResponse> {\n if (!promptSlug || promptSlug.trim().length === 0) {\n throw new CobblError('promptSlug is required', 'INVALID_REQUEST')\n }\n\n try {\n const response = await this.makeRequest('/prompt/run', {\n method: 'POST',\n body: JSON.stringify({\n promptSlug: promptSlug.trim(),\n input,\n }),\n })\n\n if (!response.ok) {\n await this.handleErrorResponse(response)\n }\n\n const data = (await response.json()) as {\n runId: string\n output: string\n tokenUsage: TokenUsage\n renderedPrompt: string\n promptVersion: PromptVersionClient\n }\n\n return {\n runId: data.runId,\n output: data.output,\n tokenUsage: data.tokenUsage,\n renderedPrompt: data.renderedPrompt,\n promptVersion: data.promptVersion,\n }\n } catch (error) {\n if (error instanceof CobblError) {\n throw error\n }\n throw new CobblError(\n `Failed to run prompt: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n )\n }\n }\n\n /**\n * Submit user feedback for a prompt run\n *\n * @param feedback - Feedback submission data\n * @param feedback.runId - The run ID from a previous runPrompt call\n * @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful')\n * @param feedback.userFeedback - Detailed feedback message from the user\n * @returns Promise containing the created feedback ID\n *\n * @throws {CobblError} When the request fails or API returns an error\n *\n * @example\n * ```typescript\n * await client.submitFeedback({\n * runId: result.runId,\n * helpful: 'not_helpful',\n * userFeedback: 'The response was too formal and lengthy'\n * })\n * ```\n */\n async submitFeedback(\n feedback: FeedbackSubmission\n ): Promise<SubmitFeedbackResponse> {\n if (!feedback.runId || feedback.runId.trim().length === 0) {\n throw new CobblError('runId is required', 'INVALID_REQUEST')\n }\n\n if (!feedback.userFeedback || feedback.userFeedback.trim().length === 0) {\n throw new CobblError('userFeedback is required', 'INVALID_REQUEST')\n }\n\n if (\n !feedback.helpful ||\n !['helpful', 'not_helpful'].includes(feedback.helpful)\n ) {\n throw new CobblError(\n 'helpful must be either \"helpful\" or \"not_helpful\"',\n 'INVALID_REQUEST'\n )\n }\n\n try {\n const response = await this.makeRequest('/feedback', {\n method: 'POST',\n body: JSON.stringify({\n runId: feedback.runId.trim(),\n helpful: feedback.helpful,\n userFeedback: feedback.userFeedback.trim(),\n }),\n })\n\n if (!response.ok) {\n await this.handleErrorResponse(response)\n }\n\n const data = (await response.json()) as {\n feedbackId: string\n message: string\n }\n\n return {\n feedbackId: data.feedbackId,\n message: data.message,\n }\n } catch (error) {\n if (error instanceof CobblError) {\n throw error\n }\n throw new CobblError(\n `Failed to submit feedback: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n )\n }\n }\n\n /**\n * Make an HTTP request to the Cobbl API\n * @private\n */\n private async makeRequest(\n path: string,\n options: RequestInit\n ): Promise<Response> {\n const baseUrl = process.env.COBBL_API_URL || 'https://api.cobbl.ai'\n const url = `${baseUrl}${path}`\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n\n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n signal: controller.signal,\n })\n\n return response\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n /**\n * Handle error responses from the API\n * @private\n */\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorData: any\n try {\n errorData = await response.json()\n } catch {\n throw new CobblError(\n `HTTP ${response.status}: ${response.statusText}`,\n 'API_ERROR',\n { status: response.status }\n )\n }\n\n const message = errorData.error || errorData.message || 'Unknown error'\n const details = errorData.details\n\n switch (response.status) {\n case 400:\n throw new CobblError(message, 'INVALID_REQUEST', details)\n case 401:\n throw new CobblError(message, 'UNAUTHORIZED', details)\n case 404:\n throw new CobblError(message, 'NOT_FOUND', details)\n case 429:\n throw new CobblError(message, 'RATE_LIMIT_EXCEEDED', details)\n case 500:\n case 502:\n case 503:\n case 504:\n throw new CobblError(message, 'SERVER_ERROR', details)\n default:\n throw new CobblError(message, 'API_ERROR', {\n status: response.status,\n ...details,\n })\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/admin.ts","../src/validation.ts","../src/public.ts"],"names":["REQUEST_TIMEOUT_MS"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Error types that can be thrown by the Cobbl SDK\n */\nexport type CobblErrorCode =\n | 'INVALID_CONFIG'\n | 'INVALID_REQUEST'\n | 'UNAUTHORIZED'\n | 'FORBIDDEN'\n | 'NOT_FOUND'\n | 'ARCHIVED'\n | 'RATE_LIMIT_EXCEEDED'\n | 'SERVER_ERROR'\n | 'NETWORK_ERROR'\n | 'API_ERROR'\n\n/**\n * Custom error class for Cobbl SDK errors\n *\n * @example\n * ```typescript\n * try {\n * await client.runPrompt('my-prompt', { topic: 'test' })\n * } catch (error) {\n * if (error instanceof CobblError) {\n * console.error(`Error [${error.code}]: ${error.message}`)\n * console.error('Details:', error.details)\n * }\n * }\n * ```\n */\nexport class CobblError extends Error {\n /**\n * Error code indicating the type of error\n */\n public readonly code: CobblErrorCode\n\n /**\n * Additional details about the error (e.g., missing variables, validation issues)\n */\n public readonly details?: unknown\n\n constructor(message: string, code: CobblErrorCode, details?: unknown) {\n super(message)\n this.name = 'CobblError'\n this.code = code\n this.details = details\n\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CobblError)\n }\n }\n\n /**\n * Check if an error is a CobblError\n */\n static isCobblError(error: unknown): error is CobblError {\n return error instanceof CobblError\n }\n\n /**\n * Convert error to JSON-serializable object\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n details: this.details,\n }\n }\n}\n\n/**\n * Handle error responses from the API\n * @internal\n */\nexport const handleErrorResponse = async (\n response: Response\n): Promise<never> => {\n let errorData: any\n try {\n errorData = await response.json()\n } catch {\n throw new CobblError(\n `HTTP ${response.status}: ${response.statusText}`,\n 'API_ERROR',\n { status: response.status }\n )\n }\n\n const message = errorData.error || errorData.message || 'Unknown error'\n const details = errorData.details\n\n switch (response.status) {\n case 400:\n throw new CobblError(message, 'INVALID_REQUEST', details)\n case 401:\n throw new CobblError(message, 'UNAUTHORIZED', details)\n case 403:\n throw new CobblError(message, 'FORBIDDEN', details)\n case 404:\n throw new CobblError(message, 'NOT_FOUND', details)\n case 410:\n throw new CobblError(message, 'ARCHIVED', details)\n case 429:\n throw new CobblError(message, 'RATE_LIMIT_EXCEEDED', details)\n case 500:\n case 502:\n case 503:\n case 504:\n throw new CobblError(message, 'SERVER_ERROR', details)\n default:\n throw new CobblError(message, 'API_ERROR', {\n status: response.status,\n ...details,\n })\n }\n}\n","/**\n * Cobbl SDK - Admin API Client\n *\n * A client for admin/server-side operations like running prompts.\n * Use this in server-side contexts where you need to execute prompts.\n *\n * @example\n * ```typescript\n * import { CobblAdminClient } from '@cobbl-ai/sdk/admin'\n *\n * const client = new CobblAdminClient({\n * apiKey: process.env.COBBL_API_KEY\n * })\n *\n * // Run a prompt\n * const result = await client.runPrompt('sales_summary', {\n * topic: 'Q4 Results',\n * tone: 'friendly'\n * })\n *\n * console.log(result.output)\n * console.log(result.runId) // Use this to link feedback later\n * ```\n */\n\nimport type { PromptInput, PromptVersionClient } from './types'\nimport type { CobblConfig, RunPromptResponse, TokenUsage } from './types'\nimport { CobblError, handleErrorResponse } from './errors'\n\nconst REQUEST_TIMEOUT_MS = 30_000\n\n/**\n * Admin API Client for Cobbl\n *\n * Provides methods to run prompts via the admin API.\n * This client is suitable for use in server-side contexts.\n */\nexport class CobblAdminClient {\n private readonly apiKey: string\n private readonly baseUrl: string\n\n /**\n * Initialize the Cobbl Admin SDK client\n *\n * @param config - Configuration object\n * @param config.apiKey - Your Cobbl API key\n * @param config.baseUrl - Optional base URL for the API (defaults to 'https://api.cobbl.ai')\n *\n * @example Production (uses default URL)\n * ```typescript\n * const client = new CobblAdminClient({\n * apiKey: process.env.COBBL_API_KEY\n * })\n * ```\n *\n * @example Local development with Firebase emulators\n * ```typescript\n * const client = new CobblAdminClient({\n * apiKey: process.env.COBBL_API_KEY,\n * baseUrl: 'http://localhost:5001/your-project-id/us-central1/externalApi'\n * })\n * ```\n */\n constructor(config: CobblConfig) {\n if (!config.apiKey || config.apiKey.trim().length === 0) {\n throw new CobblError('API key is required', 'INVALID_CONFIG')\n }\n\n this.apiKey = config.apiKey\n this.baseUrl = config.baseUrl?.trim() || 'https://api.cobbl.ai'\n }\n\n /**\n * Execute a prompt with the given input variables\n *\n * @param promptSlug - The unique slug identifier for the prompt\n * @param input - Input variables to populate the prompt template\n * @returns Promise containing the prompt execution results\n *\n * @throws {CobblError} When the request fails or API returns an error\n *\n * @example\n * ```typescript\n * const result = await client.runPrompt('sales_summary', {\n * topic: 'Q4 Results',\n * tone: 'friendly',\n * audience: 'investors'\n * })\n *\n * console.log(result.output) // AI-generated response\n * console.log(result.runId) // Save this to link feedback later\n * ```\n */\n async runPrompt(\n promptSlug: string,\n input: PromptInput\n ): Promise<RunPromptResponse> {\n if (!promptSlug || promptSlug.trim().length === 0) {\n throw new CobblError('promptSlug is required', 'INVALID_REQUEST')\n }\n\n try {\n const response = await this.makeRequest('/admin/v1/prompt/run', {\n method: 'POST',\n body: JSON.stringify({\n promptSlug: promptSlug.trim(),\n input,\n }),\n })\n\n if (!response.ok) {\n await handleErrorResponse(response)\n }\n\n const data = (await response.json()) as {\n runId: string\n output: string\n tokenUsage: TokenUsage\n renderedPrompt: string\n promptVersion: PromptVersionClient\n }\n\n return {\n runId: data.runId,\n output: data.output,\n tokenUsage: data.tokenUsage,\n renderedPrompt: data.renderedPrompt,\n promptVersion: data.promptVersion,\n }\n } catch (error) {\n if (error instanceof CobblError) {\n throw error\n }\n throw new CobblError(\n `Failed to run prompt: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n )\n }\n }\n\n /**\n * Make an HTTP request to the Cobbl API\n * @private\n */\n private async makeRequest(\n path: string,\n options: RequestInit\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n\n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n ...options.headers,\n },\n signal: controller.signal,\n })\n\n return response\n } finally {\n clearTimeout(timeoutId)\n }\n }\n}\n\n// Export the client\nexport { CobblError } from './errors'\nexport type { CobblErrorCode } from './errors'\nexport type {\n CobblConfig,\n TokenUsage,\n RunPromptRequest,\n RunPromptResponse,\n PromptInput,\n PromptVersionClient,\n Provider,\n VariableConfig,\n} from './types'\n","import type {\n CreateFeedbackRequest,\n UpdateFeedbackRequest,\n Helpful,\n} from './types'\n\nconst VALID_HELPFUL_VALUES: Helpful[] = ['helpful', 'not_helpful']\n\nexport function validateCreateFeedback(\n feedback: CreateFeedbackRequest\n): string | null {\n if (!feedback.runId || feedback.runId.trim().length === 0) {\n return 'runId is required'\n }\n if (\n feedback.helpful !== undefined &&\n !VALID_HELPFUL_VALUES.includes(feedback.helpful)\n ) {\n return 'helpful must be \"helpful\" or \"not_helpful\"'\n }\n if (\n feedback.userFeedback !== undefined &&\n feedback.userFeedback.trim().length === 0\n ) {\n return 'userFeedback cannot be empty'\n }\n if (feedback.helpful === undefined && feedback.userFeedback === undefined) {\n return 'At least one of helpful or userFeedback is required'\n }\n return null\n}\n\nexport function validateUpdateFeedback(\n update: UpdateFeedbackRequest\n): string | null {\n if (\n update.helpful !== undefined &&\n !VALID_HELPFUL_VALUES.includes(update.helpful)\n ) {\n return 'helpful must be \"helpful\" or \"not_helpful\"'\n }\n if (\n update.userFeedback !== undefined &&\n update.userFeedback.trim().length === 0\n ) {\n return 'userFeedback cannot be empty'\n }\n if (update.helpful === undefined && update.userFeedback === undefined) {\n return 'At least one of helpful or userFeedback is required'\n }\n return null\n}\n","/**\n * Cobbl SDK - Public API Client\n *\n * A lightweight client for public-facing feedback operations.\n * Use this in client-side or user-facing contexts.\n * No authentication required - designed for end-user feedback submission.\n *\n * @example\n * ```typescript\n * import { CobblPublicClient } from '@cobbl-ai/sdk/public'\n *\n * const client = new CobblPublicClient({\n * baseUrl: 'https://api.cobbl.ai' // Optional, defaults to production\n * })\n *\n * // Submit feedback\n * const { id } = await client.createFeedback({\n * runId: 'run_abc123',\n * helpful: 'not_helpful'\n * })\n *\n * // Update feedback with details later\n * await client.updateFeedback(id, {\n * userFeedback: 'Too formal'\n * })\n * ```\n */\n\nimport type {\n CreateFeedbackRequest,\n CreateFeedbackResponse,\n UpdateFeedbackRequest,\n UpdateFeedbackResponse,\n} from './types'\nimport { CobblError, handleErrorResponse } from './errors'\nimport { validateCreateFeedback, validateUpdateFeedback } from './validation'\n\n/**\n * Configuration options for CobblPublicClient\n */\nexport interface CobblPublicConfig {\n /**\n * Base URL for the API\n * @optional\n * @default 'https://api.cobbl.ai'\n * @internal\n * @example 'http://localhost:5001/your-project/us-central1/externalApi' // For local development\n */\n baseUrl?: string\n}\n\nconst REQUEST_TIMEOUT_MS = 30_000\n\n/**\n * Public API Client for Cobbl\n *\n * Provides methods to submit and update feedback via the public API.\n * This client is suitable for use in client-side or user-facing contexts.\n * No authentication required - designed for end-user feedback submission.\n */\nexport class CobblPublicClient {\n private readonly baseUrl: string\n\n /**\n * Initialize the Cobbl Public SDK client\n *\n * @param config - Configuration object\n * @param config.baseUrl - Optional base URL for the API (defaults to 'https://api.cobbl.ai')\n */\n constructor(config: CobblPublicConfig = {}) {\n this.baseUrl = config.baseUrl?.trim() || 'https://api.cobbl.ai'\n }\n\n /**\n * Create user feedback for a prompt run\n * Supports segmented feedback - you can provide just helpful, just userFeedback, or both\n * Use updateFeedback to add additional data later\n *\n * @param feedback - Feedback submission data\n * @param feedback.runId - The run ID from a previous runPrompt call\n * @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional\n * @param feedback.userFeedback - Detailed feedback message from the user - optional\n * @returns Promise containing the created feedback ID\n *\n * @throws {CobblError} When the request fails or API returns an error\n *\n * @example Submit just thumbs down first\n * ```typescript\n * const { id } = await client.createFeedback({\n * runId: result.runId,\n * helpful: 'not_helpful'\n * })\n * // Later, add details\n * await client.updateFeedback(id, {\n * userFeedback: 'The response was too formal and lengthy'\n * })\n * ```\n *\n * @example Submit both at once\n * ```typescript\n * await client.createFeedback({\n * runId: result.runId,\n * helpful: 'not_helpful',\n * userFeedback: 'The response was too formal and lengthy'\n * })\n * ```\n */\n async createFeedback(\n feedback: CreateFeedbackRequest\n ): Promise<CreateFeedbackResponse> {\n const validationError = validateCreateFeedback(feedback)\n if (validationError) {\n throw new CobblError(validationError, 'INVALID_REQUEST')\n }\n\n try {\n // Build request body with only provided fields\n const body: CreateFeedbackRequest = {\n runId: feedback.runId.trim(),\n helpful: feedback.helpful,\n userFeedback: feedback.userFeedback?.trim(),\n }\n\n const response = await this.makeRequest('/public/v1/feedback', {\n method: 'POST',\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n await handleErrorResponse(response)\n }\n\n const data = (await response.json()) as {\n id: string\n message: string\n }\n\n return {\n id: data.id,\n message: data.message,\n }\n } catch (error) {\n if (error instanceof CobblError) {\n throw error\n }\n throw new CobblError(\n `Failed to create feedback: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n )\n }\n }\n\n /**\n * Update existing feedback with additional data\n * Use this to add helpful sentiment or detailed feedback after initial submission\n *\n * @param id - The ID returned from createFeedback\n * @param update - The data to update\n * @param update.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional\n * @param update.userFeedback - Detailed feedback message from the user - optional\n * @returns Promise containing the updated feedback ID\n *\n * @throws {CobblError} When the request fails or API returns an error\n *\n * @example Add details after initial thumbs down\n * ```typescript\n * // First, submit just the rating\n * const { id } = await client.createFeedback({\n * runId: result.runId,\n * helpful: 'not_helpful'\n * })\n *\n * // Later, add detailed feedback\n * await client.updateFeedback(id, {\n * userFeedback: 'The response was too formal and lengthy'\n * })\n * ```\n */\n async updateFeedback(\n id: string,\n update: UpdateFeedbackRequest\n ): Promise<UpdateFeedbackResponse> {\n if (!id || id.trim().length === 0) {\n throw new CobblError('id is required', 'INVALID_REQUEST')\n }\n\n const validationError = validateUpdateFeedback(update)\n if (validationError) {\n throw new CobblError(validationError, 'INVALID_REQUEST')\n }\n\n try {\n // Build request body with only provided fields\n const body: UpdateFeedbackRequest = {\n helpful: update.helpful,\n userFeedback: update.userFeedback?.trim(),\n }\n\n const response = await this.makeRequest(\n `/public/v1/feedback/${id.trim()}`,\n {\n method: 'PATCH',\n body: JSON.stringify(body),\n }\n )\n\n if (!response.ok) {\n await handleErrorResponse(response)\n }\n\n const data = (await response.json()) as {\n id: string\n message: string\n }\n\n return {\n id: data.id,\n message: data.message,\n }\n } catch (error) {\n if (error instanceof CobblError) {\n throw error\n }\n throw new CobblError(\n `Failed to update feedback: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'NETWORK_ERROR'\n )\n }\n }\n\n /**\n * Make an HTTP request to the Cobbl API\n * @private\n */\n private async makeRequest(\n path: string,\n options: RequestInit\n ): Promise<Response> {\n const url = `${this.baseUrl}${path}`\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)\n\n try {\n const response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n ...options.headers,\n },\n signal: controller.signal,\n })\n\n return response\n } finally {\n clearTimeout(timeoutId)\n }\n }\n}\n\n// Export the client\nexport { CobblError } from './errors'\nexport type { CobblErrorCode } from './errors'\nexport type {\n CreateFeedbackRequest,\n CreateFeedbackResponse,\n UpdateFeedbackRequest,\n UpdateFeedbackResponse,\n Helpful,\n} from './types'\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { d as CreateFeedbackRequest, e as CreateFeedbackResponse, U as UpdateFeedbackRequest, f as UpdateFeedbackResponse } from './errors-BaYZ2rGo.mjs';
|
|
2
|
+
export { C as CobblError, a as CobblErrorCode, H as Helpful } from './errors-BaYZ2rGo.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cobbl SDK - Public API Client
|
|
6
|
+
*
|
|
7
|
+
* A lightweight client for public-facing feedback operations.
|
|
8
|
+
* Use this in client-side or user-facing contexts.
|
|
9
|
+
* No authentication required - designed for end-user feedback submission.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { CobblPublicClient } from '@cobbl-ai/sdk/public'
|
|
14
|
+
*
|
|
15
|
+
* const client = new CobblPublicClient({
|
|
16
|
+
* baseUrl: 'https://api.cobbl.ai' // Optional, defaults to production
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* // Submit feedback
|
|
20
|
+
* const { id } = await client.createFeedback({
|
|
21
|
+
* runId: 'run_abc123',
|
|
22
|
+
* helpful: 'not_helpful'
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* // Update feedback with details later
|
|
26
|
+
* await client.updateFeedback(id, {
|
|
27
|
+
* userFeedback: 'Too formal'
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Configuration options for CobblPublicClient
|
|
34
|
+
*/
|
|
35
|
+
interface CobblPublicConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Base URL for the API
|
|
38
|
+
* @optional
|
|
39
|
+
* @default 'https://api.cobbl.ai'
|
|
40
|
+
* @internal
|
|
41
|
+
* @example 'http://localhost:5001/your-project/us-central1/externalApi' // For local development
|
|
42
|
+
*/
|
|
43
|
+
baseUrl?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Public API Client for Cobbl
|
|
47
|
+
*
|
|
48
|
+
* Provides methods to submit and update feedback via the public API.
|
|
49
|
+
* This client is suitable for use in client-side or user-facing contexts.
|
|
50
|
+
* No authentication required - designed for end-user feedback submission.
|
|
51
|
+
*/
|
|
52
|
+
declare class CobblPublicClient {
|
|
53
|
+
private readonly baseUrl;
|
|
54
|
+
/**
|
|
55
|
+
* Initialize the Cobbl Public SDK client
|
|
56
|
+
*
|
|
57
|
+
* @param config - Configuration object
|
|
58
|
+
* @param config.baseUrl - Optional base URL for the API (defaults to 'https://api.cobbl.ai')
|
|
59
|
+
*/
|
|
60
|
+
constructor(config?: CobblPublicConfig);
|
|
61
|
+
/**
|
|
62
|
+
* Create user feedback for a prompt run
|
|
63
|
+
* Supports segmented feedback - you can provide just helpful, just userFeedback, or both
|
|
64
|
+
* Use updateFeedback to add additional data later
|
|
65
|
+
*
|
|
66
|
+
* @param feedback - Feedback submission data
|
|
67
|
+
* @param feedback.runId - The run ID from a previous runPrompt call
|
|
68
|
+
* @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional
|
|
69
|
+
* @param feedback.userFeedback - Detailed feedback message from the user - optional
|
|
70
|
+
* @returns Promise containing the created feedback ID
|
|
71
|
+
*
|
|
72
|
+
* @throws {CobblError} When the request fails or API returns an error
|
|
73
|
+
*
|
|
74
|
+
* @example Submit just thumbs down first
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const { id } = await client.createFeedback({
|
|
77
|
+
* runId: result.runId,
|
|
78
|
+
* helpful: 'not_helpful'
|
|
79
|
+
* })
|
|
80
|
+
* // Later, add details
|
|
81
|
+
* await client.updateFeedback(id, {
|
|
82
|
+
* userFeedback: 'The response was too formal and lengthy'
|
|
83
|
+
* })
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @example Submit both at once
|
|
87
|
+
* ```typescript
|
|
88
|
+
* await client.createFeedback({
|
|
89
|
+
* runId: result.runId,
|
|
90
|
+
* helpful: 'not_helpful',
|
|
91
|
+
* userFeedback: 'The response was too formal and lengthy'
|
|
92
|
+
* })
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
createFeedback(feedback: CreateFeedbackRequest): Promise<CreateFeedbackResponse>;
|
|
96
|
+
/**
|
|
97
|
+
* Update existing feedback with additional data
|
|
98
|
+
* Use this to add helpful sentiment or detailed feedback after initial submission
|
|
99
|
+
*
|
|
100
|
+
* @param id - The ID returned from createFeedback
|
|
101
|
+
* @param update - The data to update
|
|
102
|
+
* @param update.helpful - Whether the output was helpful ('helpful' or 'not_helpful') - optional
|
|
103
|
+
* @param update.userFeedback - Detailed feedback message from the user - optional
|
|
104
|
+
* @returns Promise containing the updated feedback ID
|
|
105
|
+
*
|
|
106
|
+
* @throws {CobblError} When the request fails or API returns an error
|
|
107
|
+
*
|
|
108
|
+
* @example Add details after initial thumbs down
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // First, submit just the rating
|
|
111
|
+
* const { id } = await client.createFeedback({
|
|
112
|
+
* runId: result.runId,
|
|
113
|
+
* helpful: 'not_helpful'
|
|
114
|
+
* })
|
|
115
|
+
*
|
|
116
|
+
* // Later, add detailed feedback
|
|
117
|
+
* await client.updateFeedback(id, {
|
|
118
|
+
* userFeedback: 'The response was too formal and lengthy'
|
|
119
|
+
* })
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
updateFeedback(id: string, update: UpdateFeedbackRequest): Promise<UpdateFeedbackResponse>;
|
|
123
|
+
/**
|
|
124
|
+
* Make an HTTP request to the Cobbl API
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
private makeRequest;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { CobblPublicClient, type CobblPublicConfig, CreateFeedbackRequest, CreateFeedbackResponse, UpdateFeedbackRequest, UpdateFeedbackResponse };
|