@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/src/client.ts DELETED
@@ -1,257 +0,0 @@
1
- /**
2
- * CobblClient - SDK for the Cobbl platform
3
- *
4
- * Provides methods to run prompts and submit feedback to the Cobbl API.
5
- */
6
-
7
- import type { PromptInput, PromptVersionClient } from '@prompti/shared'
8
- import type {
9
- RunPromptResponse,
10
- SubmitFeedbackResponse,
11
- CobblConfig,
12
- TokenUsage,
13
- FeedbackSubmission,
14
- } from './types'
15
- import { CobblError } from './errors'
16
-
17
- const REQUEST_TIMEOUT_MS = 30_000
18
-
19
- export class CobblClient {
20
- private readonly apiKey: string
21
-
22
- /**
23
- * Initialize the Cobbl SDK client
24
- *
25
- * @param config - Configuration object
26
- * @param config.apiKey - Your Cobbl API key
27
- *
28
- * @example
29
- * ```typescript
30
- * const client = new CobblClient({
31
- * apiKey: process.env.COBBL_API_KEY
32
- * })
33
- * ```
34
- */
35
- constructor(config: CobblConfig) {
36
- if (!config.apiKey || config.apiKey.trim().length === 0) {
37
- throw new CobblError('API key is required', 'INVALID_CONFIG')
38
- }
39
-
40
- this.apiKey = config.apiKey
41
- }
42
-
43
- /**
44
- * Execute a prompt with the given input variables
45
- *
46
- * @param promptSlug - The unique slug identifier for the prompt
47
- * @param input - Input variables to populate the prompt template
48
- * @returns Promise containing the prompt execution results
49
- *
50
- * @throws {CobblError} When the request fails or API returns an error
51
- *
52
- * @example
53
- * ```typescript
54
- * const result = await client.runPrompt('sales_summary', {
55
- * topic: 'Q4 Results',
56
- * tone: 'friendly',
57
- * audience: 'investors'
58
- * })
59
- *
60
- * console.log(result.output) // AI-generated response
61
- * console.log(result.runId) // Save this to link feedback later
62
- * ```
63
- */
64
- async runPrompt(
65
- promptSlug: string,
66
- input: PromptInput
67
- ): Promise<RunPromptResponse> {
68
- if (!promptSlug || promptSlug.trim().length === 0) {
69
- throw new CobblError('promptSlug is required', 'INVALID_REQUEST')
70
- }
71
-
72
- try {
73
- const response = await this.makeRequest('/prompt/run', {
74
- method: 'POST',
75
- body: JSON.stringify({
76
- promptSlug: promptSlug.trim(),
77
- input,
78
- }),
79
- })
80
-
81
- if (!response.ok) {
82
- await this.handleErrorResponse(response)
83
- }
84
-
85
- const data = (await response.json()) as {
86
- runId: string
87
- output: string
88
- tokenUsage: TokenUsage
89
- renderedPrompt: string
90
- promptVersion: PromptVersionClient
91
- }
92
-
93
- return {
94
- runId: data.runId,
95
- output: data.output,
96
- tokenUsage: data.tokenUsage,
97
- renderedPrompt: data.renderedPrompt,
98
- promptVersion: data.promptVersion,
99
- }
100
- } catch (error) {
101
- if (error instanceof CobblError) {
102
- throw error
103
- }
104
- throw new CobblError(
105
- `Failed to run prompt: ${error instanceof Error ? error.message : 'Unknown error'}`,
106
- 'NETWORK_ERROR'
107
- )
108
- }
109
- }
110
-
111
- /**
112
- * Submit user feedback for a prompt run
113
- *
114
- * @param feedback - Feedback submission data
115
- * @param feedback.runId - The run ID from a previous runPrompt call
116
- * @param feedback.helpful - Whether the output was helpful ('helpful' or 'not_helpful')
117
- * @param feedback.userFeedback - Detailed feedback message from the user
118
- * @returns Promise containing the created feedback ID
119
- *
120
- * @throws {CobblError} When the request fails or API returns an error
121
- *
122
- * @example
123
- * ```typescript
124
- * await client.submitFeedback({
125
- * runId: result.runId,
126
- * helpful: 'not_helpful',
127
- * userFeedback: 'The response was too formal and lengthy'
128
- * })
129
- * ```
130
- */
131
- async submitFeedback(
132
- feedback: FeedbackSubmission
133
- ): Promise<SubmitFeedbackResponse> {
134
- if (!feedback.runId || feedback.runId.trim().length === 0) {
135
- throw new CobblError('runId is required', 'INVALID_REQUEST')
136
- }
137
-
138
- if (!feedback.userFeedback || feedback.userFeedback.trim().length === 0) {
139
- throw new CobblError('userFeedback is required', 'INVALID_REQUEST')
140
- }
141
-
142
- if (
143
- !feedback.helpful ||
144
- !['helpful', 'not_helpful'].includes(feedback.helpful)
145
- ) {
146
- throw new CobblError(
147
- 'helpful must be either "helpful" or "not_helpful"',
148
- 'INVALID_REQUEST'
149
- )
150
- }
151
-
152
- try {
153
- const response = await this.makeRequest('/feedback', {
154
- method: 'POST',
155
- body: JSON.stringify({
156
- runId: feedback.runId.trim(),
157
- helpful: feedback.helpful,
158
- userFeedback: feedback.userFeedback.trim(),
159
- }),
160
- })
161
-
162
- if (!response.ok) {
163
- await this.handleErrorResponse(response)
164
- }
165
-
166
- const data = (await response.json()) as {
167
- feedbackId: string
168
- message: string
169
- }
170
-
171
- return {
172
- feedbackId: data.feedbackId,
173
- message: data.message,
174
- }
175
- } catch (error) {
176
- if (error instanceof CobblError) {
177
- throw error
178
- }
179
- throw new CobblError(
180
- `Failed to submit feedback: ${error instanceof Error ? error.message : 'Unknown error'}`,
181
- 'NETWORK_ERROR'
182
- )
183
- }
184
- }
185
-
186
- /**
187
- * Make an HTTP request to the Cobbl API
188
- * @private
189
- */
190
- private async makeRequest(
191
- path: string,
192
- options: RequestInit
193
- ): Promise<Response> {
194
- const baseUrl = process.env.COBBL_API_URL || 'https://api.cobbl.ai'
195
- const url = `${baseUrl}${path}`
196
-
197
- const controller = new AbortController()
198
- const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS)
199
-
200
- try {
201
- const response = await fetch(url, {
202
- ...options,
203
- headers: {
204
- 'Content-Type': 'application/json',
205
- Authorization: `Bearer ${this.apiKey}`,
206
- ...options.headers,
207
- },
208
- signal: controller.signal,
209
- })
210
-
211
- return response
212
- } finally {
213
- clearTimeout(timeoutId)
214
- }
215
- }
216
-
217
- /**
218
- * Handle error responses from the API
219
- * @private
220
- */
221
- private async handleErrorResponse(response: Response): Promise<never> {
222
- let errorData: any
223
- try {
224
- errorData = await response.json()
225
- } catch {
226
- throw new CobblError(
227
- `HTTP ${response.status}: ${response.statusText}`,
228
- 'API_ERROR',
229
- { status: response.status }
230
- )
231
- }
232
-
233
- const message = errorData.error || errorData.message || 'Unknown error'
234
- const details = errorData.details
235
-
236
- switch (response.status) {
237
- case 400:
238
- throw new CobblError(message, 'INVALID_REQUEST', details)
239
- case 401:
240
- throw new CobblError(message, 'UNAUTHORIZED', details)
241
- case 404:
242
- throw new CobblError(message, 'NOT_FOUND', details)
243
- case 429:
244
- throw new CobblError(message, 'RATE_LIMIT_EXCEEDED', details)
245
- case 500:
246
- case 502:
247
- case 503:
248
- case 504:
249
- throw new CobblError(message, 'SERVER_ERROR', details)
250
- default:
251
- throw new CobblError(message, 'API_ERROR', {
252
- status: response.status,
253
- ...details,
254
- })
255
- }
256
- }
257
- }