@botpress/zai 2.4.1 → 2.5.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/dist/index.d.ts +1680 -44
- package/dist/index.js +1 -0
- package/dist/micropatch.js +273 -0
- package/dist/operations/answer.js +6 -4
- package/dist/operations/patch.js +398 -0
- package/dist/response.js +166 -1
- package/dist/zai.js +106 -0
- package/e2e/data/cache.jsonl +107 -0
- package/package.json +1 -1
- package/src/context.ts +32 -0
- package/src/index.ts +1 -0
- package/src/micropatch.ts +364 -0
- package/src/operations/answer.ts +105 -9
- package/src/operations/check.ts +75 -1
- package/src/operations/extract.ts +67 -1
- package/src/operations/filter.ts +86 -1
- package/src/operations/group.ts +150 -0
- package/src/operations/label.ts +119 -1
- package/src/operations/patch.ts +656 -0
- package/src/operations/rate.ts +112 -2
- package/src/operations/rewrite.ts +84 -1
- package/src/operations/sort.ts +111 -9
- package/src/operations/summarize.ts +74 -1
- package/src/operations/text.ts +50 -1
- package/src/response.ts +264 -2
- package/src/zai.ts +214 -0
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
|
-
|
|
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
|
-
|
|
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
|
package/src/zai.ts
CHANGED
|
@@ -8,9 +8,27 @@ import { Adapter } from './adapters/adapter'
|
|
|
8
8
|
import { TableAdapter } from './adapters/botpress-table'
|
|
9
9
|
import { MemoryAdapter } from './adapters/memory'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Active learning configuration for improving AI operations over time.
|
|
13
|
+
*
|
|
14
|
+
* When enabled, Zai stores successful operation results in a table and uses them as examples
|
|
15
|
+
* for future operations, improving accuracy and consistency.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const activeLearning = {
|
|
20
|
+
* enable: true,
|
|
21
|
+
* tableName: 'MyAppLearningTable',
|
|
22
|
+
* taskId: 'sentiment-analysis'
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
11
26
|
type ActiveLearning = {
|
|
27
|
+
/** Whether to enable active learning for this Zai instance */
|
|
12
28
|
enable: boolean
|
|
29
|
+
/** Name of the Botpress table to store learning examples (must end with 'Table') */
|
|
13
30
|
tableName: string
|
|
31
|
+
/** Unique identifier for this learning task */
|
|
14
32
|
taskId: string
|
|
15
33
|
}
|
|
16
34
|
|
|
@@ -34,11 +52,39 @@ const _ActiveLearning = z.object({
|
|
|
34
52
|
.default('default'),
|
|
35
53
|
})
|
|
36
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Configuration options for creating a Zai instance.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* import { Client } from '@botpress/client'
|
|
61
|
+
* import { Zai } from '@botpress/zai'
|
|
62
|
+
*
|
|
63
|
+
* const client = new Client({ token: 'your-token' })
|
|
64
|
+
* const config: ZaiConfig = {
|
|
65
|
+
* client,
|
|
66
|
+
* modelId: 'best', // Use the best available model
|
|
67
|
+
* userId: 'user-123',
|
|
68
|
+
* namespace: 'my-app',
|
|
69
|
+
* activeLearning: {
|
|
70
|
+
* enable: true,
|
|
71
|
+
* tableName: 'MyLearningTable',
|
|
72
|
+
* taskId: 'extraction'
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* const zai = new Zai(config)
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
37
78
|
type ZaiConfig = {
|
|
79
|
+
/** Botpress client or Cognitive client instance */
|
|
38
80
|
client: BotpressClientLike | Cognitive
|
|
81
|
+
/** Optional user ID for tracking and attribution */
|
|
39
82
|
userId?: string
|
|
83
|
+
/** Model to use: 'best' (default), 'fast', or specific model like 'openai:gpt-4' */
|
|
40
84
|
modelId?: Models
|
|
85
|
+
/** Active learning configuration to improve operations over time */
|
|
41
86
|
activeLearning?: ActiveLearning
|
|
87
|
+
/** Namespace for organizing tasks (default: 'zai') */
|
|
42
88
|
namespace?: string
|
|
43
89
|
}
|
|
44
90
|
|
|
@@ -74,6 +120,68 @@ const _ZaiConfig = z.object({
|
|
|
74
120
|
.default('zai'),
|
|
75
121
|
})
|
|
76
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Zai - A type-safe LLM utility library for production-ready AI operations.
|
|
125
|
+
*
|
|
126
|
+
* Zai provides high-level abstractions for common AI tasks with built-in features like:
|
|
127
|
+
* - Active learning (learns from successful operations)
|
|
128
|
+
* - Automatic chunking for large inputs
|
|
129
|
+
* - Retry logic with error recovery
|
|
130
|
+
* - Usage tracking (tokens, cost, latency)
|
|
131
|
+
* - Type-safe schema validation with Zod
|
|
132
|
+
*
|
|
133
|
+
* @example Basic usage
|
|
134
|
+
* ```typescript
|
|
135
|
+
* import { Client } from '@botpress/client'
|
|
136
|
+
* import { Zai } from '@botpress/zai'
|
|
137
|
+
* import { z } from '@bpinternal/zui'
|
|
138
|
+
*
|
|
139
|
+
* const client = new Client({ token: process.env.BOTPRESS_TOKEN })
|
|
140
|
+
* const zai = new Zai({ client })
|
|
141
|
+
*
|
|
142
|
+
* // Extract structured data
|
|
143
|
+
* const schema = z.object({
|
|
144
|
+
* name: z.string(),
|
|
145
|
+
* age: z.number()
|
|
146
|
+
* })
|
|
147
|
+
* const person = await zai.extract('John is 30 years old', schema)
|
|
148
|
+
* // Output: { name: 'John', age: 30 }
|
|
149
|
+
*
|
|
150
|
+
* // Check conditions
|
|
151
|
+
* const isPositive = await zai.check('I love this product!', 'Is the sentiment positive?')
|
|
152
|
+
* // Output: true
|
|
153
|
+
*
|
|
154
|
+
* // Summarize text
|
|
155
|
+
* const summary = await zai.summarize(longDocument, { length: 100 })
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @example With active learning
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const zai = new Zai({
|
|
161
|
+
* client,
|
|
162
|
+
* activeLearning: {
|
|
163
|
+
* enable: true,
|
|
164
|
+
* tableName: 'SentimentTable',
|
|
165
|
+
* taskId: 'product-reviews'
|
|
166
|
+
* }
|
|
167
|
+
* })
|
|
168
|
+
*
|
|
169
|
+
* // Enable learning for specific task
|
|
170
|
+
* const result = await zai.learn('sentiment').check(review, 'Is this positive?')
|
|
171
|
+
* // Future calls will use approved examples for better accuracy
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* @example Chaining configuration
|
|
175
|
+
* ```typescript
|
|
176
|
+
* // Use fast model for quick operations
|
|
177
|
+
* const fastZai = zai.with({ modelId: 'fast' })
|
|
178
|
+
* await fastZai.check(text, 'Is this spam?')
|
|
179
|
+
*
|
|
180
|
+
* // Use specific model
|
|
181
|
+
* const gpt4Zai = zai.with({ modelId: 'openai:gpt-4' })
|
|
182
|
+
* await gpt4Zai.extract(document, complexSchema)
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
77
185
|
export class Zai {
|
|
78
186
|
protected static tokenizer: TextTokenizer = null!
|
|
79
187
|
protected client: Cognitive
|
|
@@ -88,6 +196,27 @@ export class Zai {
|
|
|
88
196
|
protected adapter: Adapter
|
|
89
197
|
protected activeLearning: ActiveLearning
|
|
90
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Creates a new Zai instance with the specified configuration.
|
|
201
|
+
*
|
|
202
|
+
* @param config - Configuration object containing client, model, and learning settings
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* import { Client } from '@botpress/client'
|
|
207
|
+
* import { Zai } from '@botpress/zai'
|
|
208
|
+
*
|
|
209
|
+
* const client = new Client({ token: 'your-token' })
|
|
210
|
+
* const zai = new Zai({
|
|
211
|
+
* client,
|
|
212
|
+
* modelId: 'best',
|
|
213
|
+
* namespace: 'my-app',
|
|
214
|
+
* userId: 'user-123'
|
|
215
|
+
* })
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @throws {Error} If the configuration is invalid (e.g., invalid modelId format)
|
|
219
|
+
*/
|
|
91
220
|
public constructor(config: ZaiConfig) {
|
|
92
221
|
this._originalConfig = config
|
|
93
222
|
const parsed = _ZaiConfig.parse(config) as ZaiConfig
|
|
@@ -146,6 +275,41 @@ export class Zai {
|
|
|
146
275
|
return `${this.namespace}/${this.activeLearning.taskId}`.replace(/\/+/g, '/')
|
|
147
276
|
}
|
|
148
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Creates a new Zai instance with merged configuration options.
|
|
280
|
+
*
|
|
281
|
+
* This method allows you to create variations of your Zai instance with different
|
|
282
|
+
* settings without modifying the original. Useful for switching models, namespaces,
|
|
283
|
+
* or other configuration on a per-operation basis.
|
|
284
|
+
*
|
|
285
|
+
* @param options - Partial configuration to override the current settings
|
|
286
|
+
* @returns A new Zai instance with the merged configuration
|
|
287
|
+
*
|
|
288
|
+
* @example Switch to a faster model
|
|
289
|
+
* ```typescript
|
|
290
|
+
* const zai = new Zai({ client })
|
|
291
|
+
*
|
|
292
|
+
* // Use fast model for simple operations
|
|
293
|
+
* const fastZai = zai.with({ modelId: 'fast' })
|
|
294
|
+
* await fastZai.check(text, 'Is this spam?')
|
|
295
|
+
*
|
|
296
|
+
* // Use best model for complex operations
|
|
297
|
+
* const bestZai = zai.with({ modelId: 'best' })
|
|
298
|
+
* await bestZai.extract(document, complexSchema)
|
|
299
|
+
* ```
|
|
300
|
+
*
|
|
301
|
+
* @example Change namespace
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const customerZai = zai.with({ namespace: 'customer-support' })
|
|
304
|
+
* const salesZai = zai.with({ namespace: 'sales' })
|
|
305
|
+
* ```
|
|
306
|
+
*
|
|
307
|
+
* @example Use specific model
|
|
308
|
+
* ```typescript
|
|
309
|
+
* const gpt4 = zai.with({ modelId: 'openai:gpt-4' })
|
|
310
|
+
* const claude = zai.with({ modelId: 'anthropic:claude-3-5-sonnet-20241022' })
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
149
313
|
public with(options: Partial<ZaiConfig>): Zai {
|
|
150
314
|
return new Zai({
|
|
151
315
|
...this._originalConfig,
|
|
@@ -153,6 +317,56 @@ export class Zai {
|
|
|
153
317
|
})
|
|
154
318
|
}
|
|
155
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Creates a new Zai instance with active learning enabled for a specific task.
|
|
322
|
+
*
|
|
323
|
+
* Active learning stores successful operation results and uses them as examples for
|
|
324
|
+
* future operations, improving accuracy and consistency over time. Each task ID
|
|
325
|
+
* maintains its own set of learned examples.
|
|
326
|
+
*
|
|
327
|
+
* @param taskId - Unique identifier for the learning task (alphanumeric, hyphens, underscores, slashes)
|
|
328
|
+
* @returns A new Zai instance with active learning enabled for the specified task
|
|
329
|
+
*
|
|
330
|
+
* @example Sentiment analysis with learning
|
|
331
|
+
* ```typescript
|
|
332
|
+
* const zai = new Zai({
|
|
333
|
+
* client,
|
|
334
|
+
* activeLearning: {
|
|
335
|
+
* enable: false,
|
|
336
|
+
* tableName: 'AppLearningTable',
|
|
337
|
+
* taskId: 'default'
|
|
338
|
+
* }
|
|
339
|
+
* })
|
|
340
|
+
*
|
|
341
|
+
* // Enable learning for sentiment analysis
|
|
342
|
+
* const sentimentZai = zai.learn('sentiment-analysis')
|
|
343
|
+
* const result = await sentimentZai.check(review, 'Is this review positive?')
|
|
344
|
+
*
|
|
345
|
+
* // Each successful call is stored and used to improve future calls
|
|
346
|
+
* ```
|
|
347
|
+
*
|
|
348
|
+
* @example Different tasks for different purposes
|
|
349
|
+
* ```typescript
|
|
350
|
+
* // Extract user info with learning
|
|
351
|
+
* const userExtractor = zai.learn('user-extraction')
|
|
352
|
+
* await userExtractor.extract(text, userSchema)
|
|
353
|
+
*
|
|
354
|
+
* // Extract product info with separate learning
|
|
355
|
+
* const productExtractor = zai.learn('product-extraction')
|
|
356
|
+
* await productExtractor.extract(text, productSchema)
|
|
357
|
+
*
|
|
358
|
+
* // Each task learns independently
|
|
359
|
+
* ```
|
|
360
|
+
*
|
|
361
|
+
* @example Combining with other configuration
|
|
362
|
+
* ```typescript
|
|
363
|
+
* // Use fast model + learning
|
|
364
|
+
* const fastLearner = zai.with({ modelId: 'fast' }).learn('quick-checks')
|
|
365
|
+
* await fastLearner.check(email, 'Is this spam?')
|
|
366
|
+
* ```
|
|
367
|
+
*
|
|
368
|
+
* @see {@link ZaiConfig.activeLearning} for configuration options
|
|
369
|
+
*/
|
|
156
370
|
public learn(taskId: string) {
|
|
157
371
|
return new Zai({
|
|
158
372
|
...this._originalConfig,
|