@botpress/zai 2.4.0 → 2.4.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.
@@ -33,7 +33,90 @@ const Options = z.object({
33
33
 
34
34
  declare module '@botpress/zai' {
35
35
  interface Zai {
36
- /** Rewrites a string according to match the prompt */
36
+ /**
37
+ * Rewrites text according to specific instructions while preserving the core meaning.
38
+ *
39
+ * This operation transforms text based on natural language instructions. Perfect for
40
+ * tone adjustment, format conversion, translation, simplification, and style changes.
41
+ *
42
+ * @param original - The text to rewrite
43
+ * @param prompt - Instructions describing how to transform the text
44
+ * @param options - Configuration for examples and length constraints
45
+ * @returns Response promise resolving to the rewritten text
46
+ *
47
+ * @example Change tone
48
+ * ```typescript
49
+ * const original = "Your request has been denied due to insufficient funds."
50
+ * const friendly = await zai.rewrite(
51
+ * original,
52
+ * 'Make this sound more friendly and empathetic'
53
+ * )
54
+ * // Result: "We appreciate your interest, but unfortunately we're unable to proceed..."
55
+ * ```
56
+ *
57
+ * @example Simplify technical content
58
+ * ```typescript
59
+ * const technical = "The API implements RESTful architecture with OAuth 2.0 authentication..."
60
+ * const simple = await zai.rewrite(
61
+ * technical,
62
+ * 'Explain this in simple terms for non-technical users'
63
+ * )
64
+ * ```
65
+ *
66
+ * @example Professional email conversion
67
+ * ```typescript
68
+ * const casual = "Hey, can you send me that report? Thanks!"
69
+ * const professional = await zai.rewrite(
70
+ * casual,
71
+ * 'Rewrite this as a formal business email'
72
+ * )
73
+ * // Result: "Dear colleague, I would appreciate it if you could share the report..."
74
+ * ```
75
+ *
76
+ * @example Format conversion
77
+ * ```typescript
78
+ * const paragraph = "First do this. Then do that. Finally do this other thing."
79
+ * const bullets = await zai.rewrite(
80
+ * paragraph,
81
+ * 'Convert this to a bulleted list'
82
+ * )
83
+ * // Result:
84
+ * // - First do this
85
+ * // - Then do that
86
+ * // - Finally do this other thing
87
+ * ```
88
+ *
89
+ * @example With examples for consistent style
90
+ * ```typescript
91
+ * const result = await zai.rewrite(
92
+ * original,
93
+ * 'Rewrite in our brand voice',
94
+ * {
95
+ * examples: [
96
+ * {
97
+ * input: 'We offer many products.',
98
+ * output: 'Discover our curated collection of innovative solutions.'
99
+ * },
100
+ * {
101
+ * input: 'Contact us for help.',
102
+ * output: "We're here to support your success. Let's connect!"
103
+ * }
104
+ * ],
105
+ * length: 200 // Limit output length
106
+ * }
107
+ * )
108
+ * ```
109
+ *
110
+ * @example Translation-like transformation
111
+ * ```typescript
112
+ * const code = "if (user.isActive && user.hasPermission) { allowAccess() }"
113
+ * const pseudocode = await zai.rewrite(
114
+ * code,
115
+ * 'Convert this code to natural language pseudocode'
116
+ * )
117
+ * // Result: "If the user is active AND has permission, then allow access"
118
+ * ```
119
+ */
37
120
  rewrite(original: string, prompt: string, options?: Options): Response<string>
38
121
  }
39
122
  }
@@ -35,17 +35,119 @@ type SortingCriteria = Record<
35
35
  declare module '@botpress/zai' {
36
36
  interface Zai {
37
37
  /**
38
- * Sorts an array of items based on provided instructions.
39
- * Returns the sorted array directly when awaited.
40
- * Use .result() to get detailed scoring information including why each item got its position.
38
+ * Sorts array items based on natural language sorting criteria.
41
39
  *
42
- * @example
43
- * // Simple usage
44
- * const sorted = await zai.sort(items, 'from least expensive to most expensive')
40
+ * This operation intelligently orders items according to your instructions, understanding
41
+ * complex sorting logic like priority, quality, chronology, or any custom criteria.
42
+ * Perfect for ranking, organizing, and prioritizing lists based on subjective or
43
+ * multi-faceted criteria.
45
44
  *
46
- * @example
47
- * // Get detailed results
48
- * const { output: sorted, usage } = await zai.sort(items, 'by priority').result()
45
+ * @param input - Array of items to sort
46
+ * @param instructions - Natural language description of how to sort (e.g., "by priority", "newest first")
47
+ * @param options - Configuration for tokens per item
48
+ * @returns Response resolving to the sorted array
49
+ *
50
+ * @example Sort by price
51
+ * ```typescript
52
+ * const products = [
53
+ * { name: 'Laptop', price: 999 },
54
+ * { name: 'Mouse', price: 29 },
55
+ * { name: 'Keyboard', price: 79 }
56
+ * ]
57
+ *
58
+ * const sorted = await zai.sort(products, 'from least expensive to most expensive')
59
+ * // Result: [Mouse ($29), Keyboard ($79), Laptop ($999)]
60
+ * ```
61
+ *
62
+ * @example Sort by priority/urgency
63
+ * ```typescript
64
+ * const tasks = [
65
+ * "Update documentation",
66
+ * "Fix critical security bug",
67
+ * "Add new feature",
68
+ * "System is down - all users affected"
69
+ * ]
70
+ *
71
+ * const prioritized = await zai.sort(tasks, 'by urgency and impact, most urgent first')
72
+ * // Result: ["System is down...", "Fix critical security bug", "Add new feature", "Update documentation"]
73
+ * ```
74
+ *
75
+ * @example Sort by quality/rating
76
+ * ```typescript
77
+ * const reviews = [
78
+ * "Product is okay",
79
+ * "Absolutely amazing! Best purchase ever!",
80
+ * "Terrible, broke immediately",
81
+ * "Good quality for the price"
82
+ * ]
83
+ *
84
+ * const sorted = await zai.sort(reviews, 'by sentiment, most positive first')
85
+ * // Result: [amazing review, good review, okay review, terrible review]
86
+ * ```
87
+ *
88
+ * @example Sort by complexity
89
+ * ```typescript
90
+ * const problems = [
91
+ * "Fix typo in README",
92
+ * "Redesign entire authentication system",
93
+ * "Update a dependency version",
94
+ * "Implement new microservice architecture"
95
+ * ]
96
+ *
97
+ * const sorted = await zai.sort(problems, 'by complexity, simplest first')
98
+ * ```
99
+ *
100
+ * @example Sort by relevance to query
101
+ * ```typescript
102
+ * const documents = [
103
+ * "Article about cats",
104
+ * "Article about dogs and their training",
105
+ * "Article about dog breeds",
106
+ * "Article about fish"
107
+ * ]
108
+ *
109
+ * const sorted = await zai.sort(
110
+ * documents,
111
+ * 'by relevance to "dog training", most relevant first'
112
+ * )
113
+ * // Result: [dogs and training, dog breeds, cats, fish]
114
+ * ```
115
+ *
116
+ * @example Sort candidates by fit
117
+ * ```typescript
118
+ * const candidates = [
119
+ * { name: 'Alice', experience: 5, skills: ['React', 'Node'] },
120
+ * { name: 'Bob', experience: 10, skills: ['Python', 'ML'] },
121
+ * { name: 'Charlie', experience: 3, skills: ['React', 'TypeScript'] }
122
+ * ]
123
+ *
124
+ * const sorted = await zai.sort(
125
+ * candidates,
126
+ * 'by fit for a senior React developer position, best fit first'
127
+ * )
128
+ * ```
129
+ *
130
+ * @example Sort chronologically
131
+ * ```typescript
132
+ * const events = [
133
+ * "Started the project last month",
134
+ * "Will launch next week",
135
+ * "Met with client yesterday",
136
+ * "Planning meeting tomorrow"
137
+ * ]
138
+ *
139
+ * const chronological = await zai.sort(events, 'in chronological order')
140
+ * // Understands relative time expressions
141
+ * ```
142
+ *
143
+ * @example With token limit per item
144
+ * ```typescript
145
+ * const sorted = await zai.sort(
146
+ * longDocuments,
147
+ * 'by relevance to climate change research',
148
+ * { tokensPerItem: 500 } // Allow 500 tokens per document
149
+ * )
150
+ * ```
49
151
  */
50
152
  sort<T>(input: Array<T>, instructions: string, options?: Options): Response<Array<T>, Array<T>>
51
153
  }
@@ -58,7 +58,80 @@ const Options = z.object({
58
58
 
59
59
  declare module '@botpress/zai' {
60
60
  interface Zai {
61
- /** Summarizes a text of any length to a summary of the desired length */
61
+ /**
62
+ * Summarizes text of any length to a target length using intelligent chunking strategies.
63
+ *
64
+ * This operation can handle documents from a few paragraphs to entire books. It uses
65
+ * two strategies based on document size:
66
+ * - **Sliding window**: For moderate documents, processes overlapping chunks iteratively
67
+ * - **Merge sort**: For very large documents, recursively summarizes and merges
68
+ *
69
+ * @param original - The text to summarize
70
+ * @param options - Configuration for length, focus, format, and chunking strategy
71
+ * @returns Response promise resolving to the summary text
72
+ *
73
+ * @example Basic summarization
74
+ * ```typescript
75
+ * const article = "Long article text here..."
76
+ * const summary = await zai.summarize(article, {
77
+ * length: 100 // Target 100 tokens (~75 words)
78
+ * })
79
+ * ```
80
+ *
81
+ * @example Custom focus and format
82
+ * ```typescript
83
+ * const meetingNotes = "... detailed meeting transcript ..."
84
+ * const summary = await zai.summarize(meetingNotes, {
85
+ * length: 200,
86
+ * prompt: 'Key decisions, action items, and next steps',
87
+ * format: 'Bullet points with clear sections for Decisions, Actions, and Next Steps'
88
+ * })
89
+ * ```
90
+ *
91
+ * @example Summarizing very large documents
92
+ * ```typescript
93
+ * const book = await readFile('large-book.txt', 'utf-8') // 100k+ tokens
94
+ * const summary = await zai.summarize(book, {
95
+ * length: 500,
96
+ * intermediateFactor: 4, // Intermediate summaries can be 4x target length
97
+ * prompt: 'Main themes, key events, and character development'
98
+ * })
99
+ * // Automatically uses merge-sort strategy for efficiency
100
+ * ```
101
+ *
102
+ * @example Technical documentation summary
103
+ * ```typescript
104
+ * const docs = "... API documentation ..."
105
+ * const summary = await zai.summarize(docs, {
106
+ * length: 300,
107
+ * prompt: 'Core API endpoints, authentication methods, and rate limits',
108
+ * format: 'Structured markdown with code examples where relevant'
109
+ * })
110
+ * ```
111
+ *
112
+ * @example Adjusting chunking strategy
113
+ * ```typescript
114
+ * const summary = await zai.summarize(document, {
115
+ * length: 150,
116
+ * sliding: {
117
+ * window: 30000, // Process 30k tokens at a time
118
+ * overlap: 500 // 500 token overlap between windows
119
+ * }
120
+ * })
121
+ * ```
122
+ *
123
+ * @example Progress tracking for long documents
124
+ * ```typescript
125
+ * const response = zai.summarize(veryLongDocument, { length: 400 })
126
+ *
127
+ * response.on('progress', (usage) => {
128
+ * console.log(`Progress: ${Math.round(usage.requests.percentage * 100)}%`)
129
+ * console.log(`Tokens used: ${usage.tokens.total}`)
130
+ * })
131
+ *
132
+ * const summary = await response
133
+ * ```
134
+ */
62
135
  summarize(original: string, options?: Options): Response<string>
63
136
  }
64
137
  }
@@ -19,7 +19,56 @@ const Options = z.object({
19
19
 
20
20
  declare module '@botpress/zai' {
21
21
  interface Zai {
22
- /** Generates a text of the desired length according to the prompt */
22
+ /**
23
+ * Generates text content based on a natural language prompt.
24
+ *
25
+ * This operation creates original text content using LLMs with optional length constraints.
26
+ * Perfect for generating descriptions, emails, articles, creative content, and more.
27
+ *
28
+ * @param prompt - Natural language description of what text to generate
29
+ * @param options - Optional configuration for text length
30
+ * @returns Response promise resolving to the generated text
31
+ *
32
+ * @example Product description
33
+ * ```typescript
34
+ * const description = await zai.text(
35
+ * 'Write a compelling product description for eco-friendly bamboo toothbrushes'
36
+ * )
37
+ * ```
38
+ *
39
+ * @example With length constraint
40
+ * ```typescript
41
+ * const tagline = await zai.text(
42
+ * 'Create a catchy tagline for a fitness app',
43
+ * { length: 10 } // ~10 tokens (7-8 words)
44
+ * )
45
+ * ```
46
+ *
47
+ * @example Email generation
48
+ * ```typescript
49
+ * const email = await zai.text(`
50
+ * Write a professional email to a customer explaining
51
+ * that their order will be delayed by 2 days due to weather.
52
+ * Apologize and offer a 10% discount on their next purchase.
53
+ * `, { length: 150 })
54
+ * ```
55
+ *
56
+ * @example Blog post
57
+ * ```typescript
58
+ * const blogPost = await zai.text(`
59
+ * Write an informative blog post about the benefits of meditation
60
+ * for software developers. Include practical tips and scientific research.
61
+ * `, { length: 500 })
62
+ * ```
63
+ *
64
+ * @example Social media content
65
+ * ```typescript
66
+ * const tweet = await zai.text(
67
+ * 'Write an engaging tweet announcing our new AI-powered chatbot feature',
68
+ * { length: 30 } // Twitter-friendly length
69
+ * )
70
+ * ```
71
+ */
23
72
  text(prompt: string, options?: Options): Response<string>
24
73
  }
25
74
  }
package/src/response.ts CHANGED
@@ -1,13 +1,110 @@
1
1
  import { Usage, ZaiContext } from './context'
2
2
  import { EventEmitter } from './emitter'
3
3
 
4
- // Event types for the Response class
4
+ /**
5
+ * Event types emitted during operation execution.
6
+ *
7
+ * @property progress - Emitted periodically with usage statistics (tokens, cost, requests)
8
+ * @property complete - Emitted when operation completes successfully with the result
9
+ * @property error - Emitted when operation fails with the error
10
+ */
5
11
  export type ResponseEvents<TComplete = any> = {
12
+ /** Emitted during execution with updated usage statistics */
6
13
  progress: Usage
14
+ /** Emitted when the operation completes with the full result */
7
15
  complete: TComplete
16
+ /** Emitted when the operation fails with an error */
8
17
  error: unknown
9
18
  }
10
19
 
20
+ /**
21
+ * Promise-like wrapper for Zai operations with observability and control.
22
+ *
23
+ * Response provides a dual-value system:
24
+ * - **Simplified value**: When awaited directly, returns a simplified result (e.g., boolean for `check()`)
25
+ * - **Full result**: Via `.result()` method, returns `{ output, usage, elapsed }`
26
+ *
27
+ * All Zai operations return a Response instance, allowing you to:
28
+ * - Track progress and usage in real-time
29
+ * - Abort operations
30
+ * - Bind to external abort signals
31
+ * - Get detailed cost and performance metrics
32
+ *
33
+ * @template T - The full output type
34
+ * @template S - The simplified output type (defaults to T)
35
+ *
36
+ * @example Basic usage (simplified)
37
+ * ```typescript
38
+ * // Simplified result (boolean)
39
+ * const isPositive = await zai.check(review, 'Is this positive?')
40
+ * console.log(isPositive) // true or false
41
+ * ```
42
+ *
43
+ * @example Full result with usage
44
+ * ```typescript
45
+ * const response = zai.check(review, 'Is this positive?')
46
+ * const { output, usage, elapsed } = await response.result()
47
+ *
48
+ * console.log(output.value) // true/false
49
+ * console.log(output.explanation) // "The review expresses satisfaction..."
50
+ * console.log(usage.tokens.total) // 150
51
+ * console.log(usage.cost.total) // 0.002
52
+ * console.log(elapsed) // 1234 (ms)
53
+ * ```
54
+ *
55
+ * @example Progress tracking
56
+ * ```typescript
57
+ * const response = zai.summarize(longDocument, { length: 500 })
58
+ *
59
+ * response.on('progress', (usage) => {
60
+ * console.log(`Progress: ${usage.requests.percentage * 100}%`)
61
+ * console.log(`Tokens: ${usage.tokens.total}`)
62
+ * console.log(`Cost: $${usage.cost.total}`)
63
+ * })
64
+ *
65
+ * const summary = await response
66
+ * ```
67
+ *
68
+ * @example Aborting operations
69
+ * ```typescript
70
+ * const response = zai.extract(hugeDocument, schema)
71
+ *
72
+ * // Abort after 5 seconds
73
+ * setTimeout(() => response.abort('Timeout'), 5000)
74
+ *
75
+ * try {
76
+ * const result = await response
77
+ * } catch (error) {
78
+ * console.log('Operation aborted:', error)
79
+ * }
80
+ * ```
81
+ *
82
+ * @example External abort signal
83
+ * ```typescript
84
+ * const controller = new AbortController()
85
+ * const response = zai.answer(documents, question).bindSignal(controller.signal)
86
+ *
87
+ * // User clicks cancel button
88
+ * cancelButton.onclick = () => controller.abort()
89
+ *
90
+ * const answer = await response
91
+ * ```
92
+ *
93
+ * @example Error handling
94
+ * ```typescript
95
+ * const response = zai.extract(text, schema)
96
+ *
97
+ * response.on('error', (error) => {
98
+ * console.error('Operation failed:', error)
99
+ * })
100
+ *
101
+ * try {
102
+ * const result = await response
103
+ * } catch (error) {
104
+ * // Handle error
105
+ * }
106
+ * ```
107
+ */
11
108
  export class Response<T = any, S = T> implements PromiseLike<S> {
12
109
  private _promise: Promise<T>
13
110
  private _eventEmitter: EventEmitter<ResponseEvents<T>>
@@ -41,22 +138,107 @@ export class Response<T = any, S = T> implements PromiseLike<S> {
41
138
  })
42
139
  }
43
140
 
44
- // Event emitter methods
141
+ /**
142
+ * Subscribes to events emitted during operation execution.
143
+ *
144
+ * @param type - Event type: 'progress', 'complete', or 'error'
145
+ * @param listener - Callback function to handle the event
146
+ * @returns This Response instance for chaining
147
+ *
148
+ * @example Track progress
149
+ * ```typescript
150
+ * response.on('progress', (usage) => {
151
+ * console.log(`${usage.requests.percentage * 100}% complete`)
152
+ * console.log(`Cost: $${usage.cost.total}`)
153
+ * })
154
+ * ```
155
+ *
156
+ * @example Handle completion
157
+ * ```typescript
158
+ * response.on('complete', (result) => {
159
+ * console.log('Operation completed:', result)
160
+ * })
161
+ * ```
162
+ *
163
+ * @example Handle errors
164
+ * ```typescript
165
+ * response.on('error', (error) => {
166
+ * console.error('Operation failed:', error)
167
+ * })
168
+ * ```
169
+ */
45
170
  public on<K extends keyof ResponseEvents<T>>(type: K, listener: (event: ResponseEvents<T>[K]) => void) {
46
171
  this._eventEmitter.on(type, listener)
47
172
  return this
48
173
  }
49
174
 
175
+ /**
176
+ * Unsubscribes from events.
177
+ *
178
+ * @param type - Event type to unsubscribe from
179
+ * @param listener - The exact listener function to remove
180
+ * @returns This Response instance for chaining
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * const progressHandler = (usage) => console.log(usage.tokens.total)
185
+ * response.on('progress', progressHandler)
186
+ * // Later...
187
+ * response.off('progress', progressHandler)
188
+ * ```
189
+ */
50
190
  public off<K extends keyof ResponseEvents<T>>(type: K, listener: (event: ResponseEvents<T>[K]) => void) {
51
191
  this._eventEmitter.off(type, listener)
52
192
  return this
53
193
  }
54
194
 
195
+ /**
196
+ * Subscribes to an event for a single emission.
197
+ *
198
+ * The listener is automatically removed after being called once.
199
+ *
200
+ * @param type - Event type: 'progress', 'complete', or 'error'
201
+ * @param listener - Callback function to handle the event once
202
+ * @returns This Response instance for chaining
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * response.once('complete', (result) => {
207
+ * console.log('Finished:', result)
208
+ * })
209
+ * ```
210
+ */
55
211
  public once<K extends keyof ResponseEvents<T>>(type: K, listener: (event: ResponseEvents<T>[K]) => void) {
56
212
  this._eventEmitter.once(type, listener)
57
213
  return this
58
214
  }
59
215
 
216
+ /**
217
+ * Binds an external AbortSignal to this operation.
218
+ *
219
+ * When the signal is aborted, the operation will be cancelled automatically.
220
+ * Useful for integrating with UI cancel buttons or request timeouts.
221
+ *
222
+ * @param signal - AbortSignal to bind
223
+ * @returns This Response instance for chaining
224
+ *
225
+ * @example With AbortController
226
+ * ```typescript
227
+ * const controller = new AbortController()
228
+ * const response = zai.extract(data, schema).bindSignal(controller.signal)
229
+ *
230
+ * // Cancel from elsewhere
231
+ * cancelButton.onclick = () => controller.abort()
232
+ * ```
233
+ *
234
+ * @example With timeout
235
+ * ```typescript
236
+ * const controller = new AbortController()
237
+ * setTimeout(() => controller.abort('Timeout'), 10000)
238
+ *
239
+ * const response = zai.answer(docs, question).bindSignal(controller.signal)
240
+ * ```
241
+ */
60
242
  public bindSignal(signal: AbortSignal): this {
61
243
  if (signal.aborted) {
62
244
  this.abort(signal.reason)
@@ -74,10 +256,49 @@ export class Response<T = any, S = T> implements PromiseLike<S> {
74
256
  return this
75
257
  }
76
258
 
259
+ /**
260
+ * Aborts the operation in progress.
261
+ *
262
+ * The operation will be cancelled and throw an abort error.
263
+ * Any partial results will not be returned.
264
+ *
265
+ * @param reason - Optional reason for aborting (string or Error)
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * const response = zai.extract(largeDocument, schema)
270
+ *
271
+ * // Abort after 5 seconds
272
+ * setTimeout(() => response.abort('Operation timeout'), 5000)
273
+ *
274
+ * try {
275
+ * await response
276
+ * } catch (error) {
277
+ * console.log('Aborted:', error)
278
+ * }
279
+ * ```
280
+ */
77
281
  public abort(reason?: string | Error) {
78
282
  this._context.controller.abort(reason)
79
283
  }
80
284
 
285
+ /**
286
+ * Promise interface - allows awaiting the Response.
287
+ *
288
+ * When awaited, returns the simplified value (S).
289
+ * Use `.result()` for full output with usage statistics.
290
+ *
291
+ * @param onfulfilled - Success handler
292
+ * @param onrejected - Error handler
293
+ * @returns Promise resolving to simplified value
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * // Simplified value
298
+ * const isPositive = await zai.check(review, 'Is positive?')
299
+ * console.log(isPositive) // true
300
+ * ```
301
+ */
81
302
  // oxlint-disable-next-line no-thenable
82
303
  public then<TResult1 = S, TResult2 = never>(
83
304
  onfulfilled?: ((value: S) => TResult1 | PromiseLike<TResult1>) | null,
@@ -97,12 +318,53 @@ export class Response<T = any, S = T> implements PromiseLike<S> {
97
318
  ) as PromiseLike<TResult1 | TResult2>
98
319
  }
99
320
 
321
+ /**
322
+ * Promise interface - handles errors.
323
+ *
324
+ * @param onrejected - Error handler
325
+ * @returns Promise resolving to simplified value or error result
326
+ */
100
327
  public catch<TResult = never>(
101
328
  onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
102
329
  ): PromiseLike<S | TResult> {
103
330
  return this._promise.catch(onrejected) as PromiseLike<S | TResult>
104
331
  }
105
332
 
333
+ /**
334
+ * Gets the full result with detailed usage statistics and timing.
335
+ *
336
+ * Unlike awaiting the Response directly (which returns simplified value),
337
+ * this method provides:
338
+ * - `output`: Full operation result (not simplified)
339
+ * - `usage`: Detailed token usage, cost, and request statistics
340
+ * - `elapsed`: Operation duration in milliseconds
341
+ *
342
+ * @returns Promise resolving to full result object
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const { output, usage, elapsed } = await zai.check(text, condition).result()
347
+ *
348
+ * console.log(output.value) // true/false
349
+ * console.log(output.explanation) // "The text expresses..."
350
+ * console.log(usage.tokens.total) // 245
351
+ * console.log(usage.cost.total) // 0.0012
352
+ * console.log(elapsed) // 1523 (ms)
353
+ * ```
354
+ *
355
+ * @example Usage statistics breakdown
356
+ * ```typescript
357
+ * const { usage } = await response.result()
358
+ *
359
+ * console.log('Requests:', usage.requests.requests)
360
+ * console.log('Cached:', usage.requests.cached)
361
+ * console.log('Input tokens:', usage.tokens.input)
362
+ * console.log('Output tokens:', usage.tokens.output)
363
+ * console.log('Input cost:', usage.cost.input)
364
+ * console.log('Output cost:', usage.cost.output)
365
+ * console.log('Total cost:', usage.cost.total)
366
+ * ```
367
+ */
106
368
  public async result(): Promise<{
107
369
  output: T
108
370
  usage: Usage