@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,81 @@ const _Options = z.object({
33
33
 
34
34
  declare module '@botpress/zai' {
35
35
  interface Zai {
36
- /** Checks wether a condition is true or not */
36
+ /**
37
+ * Checks whether a condition is true for the given input, with an explanation.
38
+ *
39
+ * This operation evaluates natural language conditions against your input data,
40
+ * returning both a boolean result and a detailed explanation. Perfect for
41
+ * content moderation, sentiment analysis, quality checks, and business rule validation.
42
+ *
43
+ * @param input - The data to evaluate (text, object, or any value)
44
+ * @param condition - Natural language description of the condition to check
45
+ * @param options - Optional examples to guide the evaluation
46
+ * @returns Response with { value: boolean, explanation: string }, simplified to boolean when awaited
47
+ *
48
+ * @example Basic sentiment check
49
+ * ```typescript
50
+ * const review = "This product exceeded my expectations!"
51
+ * const isPositive = await zai.check(review, 'Is the sentiment positive?')
52
+ * // Result: true
53
+ *
54
+ * // Get full details
55
+ * const { value, explanation } = await zai.check(review, 'Is the sentiment positive?').result()
56
+ * // value: true
57
+ * // explanation: "The review expresses satisfaction and exceeded expectations..."
58
+ * ```
59
+ *
60
+ * @example Content moderation
61
+ * ```typescript
62
+ * const comment = "Great article! Very informative."
63
+ * const isSpam = await zai.check(comment, 'Is this spam or promotional content?')
64
+ * // Result: false
65
+ *
66
+ * const hasProfanity = await zai.check(comment, 'Does this contain profanity or offensive language?')
67
+ * // Result: false
68
+ * ```
69
+ *
70
+ * @example Business rules validation
71
+ * ```typescript
72
+ * const invoice = {
73
+ * total: 1500,
74
+ * items: ['laptop', 'mouse'],
75
+ * customer: 'Enterprise Corp'
76
+ * }
77
+ *
78
+ * const needsApproval = await zai.check(
79
+ * invoice,
80
+ * 'Does this invoice require manager approval? (over $1000 or enterprise customer)'
81
+ * )
82
+ * // Result: true
83
+ * ```
84
+ *
85
+ * @example With examples for consistency
86
+ * ```typescript
87
+ * const result = await zai.check(text, 'Is this a technical question?', {
88
+ * examples: [
89
+ * {
90
+ * input: 'How do I deploy to production?',
91
+ * check: true,
92
+ * reason: 'Question about deployment process'
93
+ * },
94
+ * {
95
+ * input: 'What time is the meeting?',
96
+ * check: false,
97
+ * reason: 'Not a technical question'
98
+ * }
99
+ * ]
100
+ * })
101
+ * ```
102
+ *
103
+ * @example Quality assurance
104
+ * ```typescript
105
+ * const code = "function add(a, b) { return a + b }"
106
+ * const hasDocumentation = await zai.check(code, 'Is this code properly documented?')
107
+ * const hasTests = await zai.check(code, 'Does this include unit tests?')
108
+ * const followsConventions = await zai.check(code, 'Does this follow naming conventions?')
109
+ * ```
110
+ */
37
111
  check(
38
112
  input: unknown,
39
113
  condition: string,
@@ -41,11 +41,77 @@ type AnyObjectOrArray = Record<string, unknown> | Array<unknown>
41
41
 
42
42
  declare module '@botpress/zai' {
43
43
  interface Zai {
44
- /** Extracts one or many elements from an arbitrary input */
44
+ /**
45
+ * Extracts structured data from unstructured text using a Zod schema.
46
+ *
47
+ * This operation uses LLMs to intelligently parse text and extract information
48
+ * according to your schema. It handles large inputs automatically by chunking
49
+ * and supports both objects and arrays.
50
+ *
51
+ * @param input - The text or data to extract information from
52
+ * @param schema - Zod schema defining the structure to extract
53
+ * @param options - Optional configuration for extraction behavior
54
+ * @returns A Response promise that resolves to data matching your schema
55
+ *
56
+ * @example Extract a single object
57
+ * ```typescript
58
+ * import { z } from '@bpinternal/zui'
59
+ *
60
+ * const personSchema = z.object({
61
+ * name: z.string(),
62
+ * age: z.number(),
63
+ * email: z.string().email()
64
+ * })
65
+ *
66
+ * const text = "Contact John Doe (35) at john@example.com"
67
+ * const person = await zai.extract(text, personSchema)
68
+ * // Result: { name: 'John Doe', age: 35, email: 'john@example.com' }
69
+ * ```
70
+ *
71
+ * @example Extract an array of items
72
+ * ```typescript
73
+ * const productSchema = z.array(z.object({
74
+ * name: z.string(),
75
+ * price: z.number()
76
+ * }))
77
+ *
78
+ * const text = "We have Apple ($1.50), Banana ($0.80), and Orange ($1.20)"
79
+ * const products = await zai.extract(text, productSchema)
80
+ * // Result: [
81
+ * // { name: 'Apple', price: 1.50 },
82
+ * // { name: 'Banana', price: 0.80 },
83
+ * // { name: 'Orange', price: 1.20 }
84
+ * // ]
85
+ * ```
86
+ *
87
+ * @example With custom instructions
88
+ * ```typescript
89
+ * const result = await zai.extract(document, schema, {
90
+ * instructions: 'Only extract confirmed information, skip uncertain data',
91
+ * chunkLength: 10000, // Smaller chunks for better accuracy
92
+ * strict: true // Enforce strict schema validation
93
+ * })
94
+ * ```
95
+ *
96
+ * @example Track usage and cost
97
+ * ```typescript
98
+ * const response = zai.extract(text, schema)
99
+ *
100
+ * // Monitor progress
101
+ * response.on('progress', (usage) => {
102
+ * console.log(`Tokens used: ${usage.tokens.total}`)
103
+ * console.log(`Cost so far: $${usage.cost.total}`)
104
+ * })
105
+ *
106
+ * // Get full results
107
+ * const { output, usage, elapsed } = await response.result()
108
+ * console.log(`Extraction took ${elapsed}ms and cost $${usage.cost.total}`)
109
+ * ```
110
+ */
45
111
  extract<S extends OfType<any>>(input: unknown, schema: S, options?: Options): Response<S['_output']>
46
112
  }
47
113
  }
48
-
114
+ const SPECIAL_CHAR = '■'
49
115
  const START = '■json_start■'
50
116
  const END = '■json_end■'
51
117
  const NO_MORE = '■NO_MORE_ELEMENT■'
@@ -330,7 +396,12 @@ ${instructions.map((x) => `• ${x}`).join('\n')}
330
396
  .filter((x) => x.trim().length > 0 && x.includes('}'))
331
397
  .map((x) => {
332
398
  try {
333
- const json = x.slice(0, x.indexOf(END)).trim()
399
+ let json = x.slice(0, x.indexOf(END)).trim()
400
+
401
+ if (json.includes(SPECIAL_CHAR)) {
402
+ json = json.slice(0, json.indexOf(SPECIAL_CHAR)).trim()
403
+ }
404
+
334
405
  const repairedJson = jsonrepair(json)
335
406
  const parsedJson = JSON5.parse(repairedJson)
336
407
  const safe = schema.safeParse(parsedJson)
@@ -42,7 +42,92 @@ const _Options = z.object({
42
42
 
43
43
  declare module '@botpress/zai' {
44
44
  interface Zai {
45
- /** Filters elements of an array against a condition */
45
+ /**
46
+ * Filters array elements based on a natural language condition.
47
+ *
48
+ * This operation evaluates each element against a condition using LLMs,
49
+ * returning only elements that match. Handles large arrays automatically
50
+ * by processing in parallel chunks.
51
+ *
52
+ * @param input - Array of elements to filter
53
+ * @param condition - Natural language description of what to keep
54
+ * @param options - Configuration for token limits per item and examples
55
+ * @returns Response promise resolving to filtered array
56
+ *
57
+ * @example Filter positive reviews
58
+ * ```typescript
59
+ * const reviews = [
60
+ * "Great product, love it!",
61
+ * "Terrible quality, broke immediately",
62
+ * "Amazing! Exceeded expectations",
63
+ * "Worst purchase ever"
64
+ * ]
65
+ *
66
+ * const positive = await zai.filter(reviews, 'Keep only positive reviews')
67
+ * // Result: ["Great product, love it!", "Amazing! Exceeded expectations"]
68
+ * ```
69
+ *
70
+ * @example Filter technical questions
71
+ * ```typescript
72
+ * const questions = [
73
+ * "How do I deploy to production?",
74
+ * "What time is lunch?",
75
+ * "Why is the API returning 500 errors?",
76
+ * "Can you book the conference room?"
77
+ * ]
78
+ *
79
+ * const technical = await zai.filter(
80
+ * questions,
81
+ * 'Keep only technical or engineering questions'
82
+ * )
83
+ * // Result: ["How do I deploy to production?", "Why is the API returning 500 errors?"]
84
+ * ```
85
+ *
86
+ * @example Filter with object array
87
+ * ```typescript
88
+ * const products = [
89
+ * { name: 'Laptop', category: 'Electronics', inStock: true },
90
+ * { name: 'Desk', category: 'Furniture', inStock: false },
91
+ * { name: 'Mouse', category: 'Electronics', inStock: true },
92
+ * { name: 'Chair', category: 'Furniture', inStock: true }
93
+ * ]
94
+ *
95
+ * const available = await zai.filter(
96
+ * products,
97
+ * 'Keep only products that are in stock'
98
+ * )
99
+ * // Returns products where inStock === true
100
+ * ```
101
+ *
102
+ * @example Complex filtering logic
103
+ * ```typescript
104
+ * const emails = [...] // Array of email objects
105
+ *
106
+ * const urgent = await zai.filter(
107
+ * emails,
108
+ * 'Keep emails that are urgent, from the CEO, or mention "critical bug"'
109
+ * )
110
+ * ```
111
+ *
112
+ * @example With examples for consistency
113
+ * ```typescript
114
+ * const filtered = await zai.filter(items, 'Keep valid entries', {
115
+ * examples: [
116
+ * {
117
+ * input: { status: 'active', verified: true },
118
+ * filter: true,
119
+ * reason: 'Active and verified'
120
+ * },
121
+ * {
122
+ * input: { status: 'pending', verified: false },
123
+ * filter: false,
124
+ * reason: 'Not yet verified'
125
+ * }
126
+ * ],
127
+ * tokensPerItem: 100 // Limit tokens per item for performance
128
+ * })
129
+ * ```
130
+ */
46
131
  filter<T>(input: Array<T>, condition: string, options?: Options): Response<Array<T>>
47
132
  }
48
133
  }
@@ -43,6 +43,156 @@ const _Options = z.object({
43
43
 
44
44
  declare module '@botpress/zai' {
45
45
  interface Zai {
46
+ /**
47
+ * Groups array items into categories based on semantic similarity or criteria.
48
+ *
49
+ * This operation intelligently categorizes items by analyzing their content and
50
+ * creating meaningful groups. It can discover natural groupings automatically or
51
+ * use predefined categories. Perfect for clustering, classification, and organization.
52
+ *
53
+ * @param input - Array of items to group
54
+ * @param options - Configuration for grouping behavior, instructions, and initial categories
55
+ * @returns Response with groups array (simplified to Record<groupLabel, items[]>)
56
+ *
57
+ * @example Automatic grouping
58
+ * ```typescript
59
+ * const messages = [
60
+ * "I can't log in to my account",
61
+ * "How do I reset my password?",
62
+ * "When will my order arrive?",
63
+ * "The app keeps crashing",
64
+ * "I haven't received my package",
65
+ * "Error 500 on checkout"
66
+ * ]
67
+ *
68
+ * const groups = await zai.group(messages, {
69
+ * instructions: 'Group by type of customer issue'
70
+ * })
71
+ * // Result (simplified):
72
+ * // {
73
+ * // "Login Issues": ["I can't log in...", "How do I reset..."],
74
+ * // "Shipping Questions": ["When will my order...", "I haven't received..."],
75
+ * // "Technical Errors": ["The app keeps crashing", "Error 500..."]
76
+ * // }
77
+ *
78
+ * // Full result:
79
+ * const { output } = await zai.group(messages, { instructions: '...' }).result()
80
+ * // output: [
81
+ * // { id: 'login_issues', label: 'Login Issues', elements: [...] },
82
+ * // { id: 'shipping', label: 'Shipping Questions', elements: [...] },
83
+ * // { id: 'errors', label: 'Technical Errors', elements: [...] }
84
+ * // ]
85
+ * ```
86
+ *
87
+ * @example With predefined categories
88
+ * ```typescript
89
+ * const articles = [
90
+ * "How to build a React app",
91
+ * "Python machine learning tutorial",
92
+ * "Understanding Docker containers",
93
+ * "Vue.js best practices",
94
+ * "Deep learning with TensorFlow"
95
+ * ]
96
+ *
97
+ * const groups = await zai.group(articles, {
98
+ * instructions: 'Categorize by technology',
99
+ * initialGroups: [
100
+ * { id: 'frontend', label: 'Frontend Development' },
101
+ * { id: 'backend', label: 'Backend Development' },
102
+ * { id: 'ml', label: 'Machine Learning' },
103
+ * { id: 'devops', label: 'DevOps & Infrastructure' }
104
+ * ]
105
+ * })
106
+ * // Groups articles into predefined categories
107
+ * ```
108
+ *
109
+ * @example Grouping products
110
+ * ```typescript
111
+ * const products = [
112
+ * { name: 'Laptop', price: 999, category: 'Electronics' },
113
+ * { name: 'Desk', price: 299, category: 'Furniture' },
114
+ * { name: 'Mouse', price: 29, category: 'Electronics' },
115
+ * { name: 'Chair', price: 199, category: 'Furniture' }
116
+ * ]
117
+ *
118
+ * const grouped = await zai.group(products, {
119
+ * instructions: 'Group by price range: budget (< $100), mid-range ($100-$500), premium (> $500)'
120
+ * })
121
+ * // Result:
122
+ * // {
123
+ * // "Budget": [Mouse],
124
+ * // "Mid-range": [Chair, Desk],
125
+ * // "Premium": [Laptop]
126
+ * // }
127
+ * ```
128
+ *
129
+ * @example Content categorization
130
+ * ```typescript
131
+ * const emails = [
132
+ * { subject: 'Meeting tomorrow', body: '...', from: 'boss@company.com' },
133
+ * { subject: 'Invoice #1234', body: '...', from: 'billing@vendor.com' },
134
+ * { subject: 'Weekly report', body: '...', from: 'team@company.com' },
135
+ * { subject: 'Payment received', body: '...', from: 'accounting@company.com' }
136
+ * ]
137
+ *
138
+ * const categorized = await zai.group(emails, {
139
+ * instructions: 'Categorize by email type: work communication, financial, reports',
140
+ * tokensPerElement: 300 // Allow more context per email
141
+ * })
142
+ * ```
143
+ *
144
+ * @example Customer feedback grouping
145
+ * ```typescript
146
+ * const feedback = [
147
+ * "Love the new UI!",
148
+ * "App is too slow",
149
+ * "Great customer service",
150
+ * "Confusing navigation",
151
+ * "Fast shipping!",
152
+ * "Hard to find features"
153
+ * ]
154
+ *
155
+ * const grouped = await zai.group(feedback, {
156
+ * instructions: 'Group by aspect: UI/UX, Performance, Customer Service, Shipping'
157
+ * })
158
+ * ```
159
+ *
160
+ * @example Topic clustering for research
161
+ * ```typescript
162
+ * const papers = [
163
+ * { title: 'Transformer Networks for NLP', abstract: '...' },
164
+ * { title: 'CNN Image Classification', abstract: '...' },
165
+ * { title: 'BERT Language Understanding', abstract: '...' },
166
+ * { title: 'Object Detection with YOLO', abstract: '...' }
167
+ * ]
168
+ *
169
+ * const clusters = await zai.group(papers, {
170
+ * instructions: 'Group by research area',
171
+ * chunkLength: 10000 // Allow more tokens for detailed abstracts
172
+ * })
173
+ * // Result: Groups papers by topic (NLP, Computer Vision, etc.)
174
+ * ```
175
+ *
176
+ * @example With initial seed groups
177
+ * ```typescript
178
+ * const tasks = [
179
+ * "Fix login bug",
180
+ * "Update documentation",
181
+ * "Add dark mode",
182
+ * "Optimize database queries"
183
+ * ]
184
+ *
185
+ * const grouped = await zai.group(tasks, {
186
+ * instructions: 'Categorize development tasks',
187
+ * initialGroups: [
188
+ * { id: 'bugs', label: 'Bug Fixes', elements: [] },
189
+ * { id: 'features', label: 'New Features', elements: [] },
190
+ * { id: 'docs', label: 'Documentation', elements: [] },
191
+ * { id: 'performance', label: 'Performance', elements: [] }
192
+ * ]
193
+ * })
194
+ * ```
195
+ */
46
196
  group<T>(input: Array<T>, options?: Options): Response<Array<Group<T>>, Record<string, T[]>>
47
197
  }
48
198
  }
@@ -82,7 +82,125 @@ const _Labels = z.record(z.string().min(1).max(250), z.string()).superRefine((la
82
82
 
83
83
  declare module '@botpress/zai' {
84
84
  interface Zai {
85
- /** Tags the provided input with a list of predefined labels */
85
+ /**
86
+ * Tags input with multiple labels, each with explanation, value, and confidence level.
87
+ *
88
+ * This operation evaluates input against multiple categories simultaneously, providing
89
+ * nuanced confidence levels (ABSOLUTELY_YES, PROBABLY_YES, AMBIGUOUS, PROBABLY_NOT, ABSOLUTELY_NOT).
90
+ * Perfect for content classification, intent detection, and multi-criteria evaluation.
91
+ *
92
+ * @param input - The data to label (text, object, or any value)
93
+ * @param labels - Object mapping label keys to their descriptions
94
+ * @param options - Configuration for examples, instructions, and chunking
95
+ * @returns Response with detailed results per label (explanation, value, confidence), simplified to booleans
96
+ *
97
+ * @example Content moderation
98
+ * ```typescript
99
+ * const comment = "This is a great article! Click here for cheap products!"
100
+ *
101
+ * const result = await zai.label(comment, {
102
+ * spam: 'Is this spam or promotional content?',
103
+ * helpful: 'Is this comment helpful and constructive?',
104
+ * profanity: 'Does this contain profanity or offensive language?'
105
+ * }).result()
106
+ *
107
+ * // result.output:
108
+ * // {
109
+ * // spam: { value: true, confidence: 0.5, explanation: 'Contains promotional link...' },
110
+ * // helpful: { value: true, confidence: 1, explanation: 'Positive feedback...' },
111
+ * // profanity: { value: false, confidence: 1, explanation: 'No offensive language' }
112
+ * // }
113
+ *
114
+ * // Simplified (when awaited directly):
115
+ * const simple = await zai.label(comment, { spam: 'Is this spam?' })
116
+ * // simple: { spam: true }
117
+ * ```
118
+ *
119
+ * @example Intent classification
120
+ * ```typescript
121
+ * const message = "I can't log in to my account"
122
+ *
123
+ * const intents = await zai.label(message, {
124
+ * technical_issue: 'Is this a technical problem?',
125
+ * urgent: 'Does this require immediate attention?',
126
+ * needs_human: 'Should this be escalated to a human agent?',
127
+ * billing_related: 'Is this about billing or payments?'
128
+ * })
129
+ * // Returns boolean for each intent
130
+ * ```
131
+ *
132
+ * @example Sentiment analysis with nuance
133
+ * ```typescript
134
+ * const review = "The product is okay, but shipping was slow"
135
+ *
136
+ * const { output } = await zai.label(review, {
137
+ * positive: 'Is the overall sentiment positive?',
138
+ * negative: 'Is the overall sentiment negative?',
139
+ * mixed: 'Does this express mixed feelings?'
140
+ * }).result()
141
+ *
142
+ * // Check confidence levels
143
+ * if (output.mixed.confidence > 0.5) {
144
+ * console.log('Mixed sentiment detected:', output.mixed.explanation)
145
+ * }
146
+ * ```
147
+ *
148
+ * @example Product categorization
149
+ * ```typescript
150
+ * const product = {
151
+ * name: 'Wireless Headphones',
152
+ * description: 'Noise-canceling Bluetooth headphones for music lovers',
153
+ * price: 199
154
+ * }
155
+ *
156
+ * const categories = await zai.label(product, {
157
+ * electronics: 'Is this an electronic device?',
158
+ * audio: 'Is this audio equipment?',
159
+ * premium: 'Is this a premium/luxury product?',
160
+ * portable: 'Is this portable/mobile?'
161
+ * })
162
+ * // Returns: { electronics: true, audio: true, premium: true, portable: true }
163
+ * ```
164
+ *
165
+ * @example With examples for consistency
166
+ * ```typescript
167
+ * const result = await zai.label(email, {
168
+ * urgent: 'Requires immediate response',
169
+ * complaint: 'Customer is dissatisfied'
170
+ * }, {
171
+ * examples: [
172
+ * {
173
+ * input: 'ASAP! System is down!',
174
+ * labels: {
175
+ * urgent: { label: 'ABSOLUTELY_YES', explanation: 'Critical issue' },
176
+ * complaint: { label: 'PROBABLY_YES', explanation: 'Implicit complaint' }
177
+ * }
178
+ * }
179
+ * ],
180
+ * instructions: 'Consider tone, urgency keywords, and context'
181
+ * })
182
+ * ```
183
+ *
184
+ * @example Understanding confidence levels
185
+ * ```typescript
186
+ * const { output } = await zai.label(text, labels).result()
187
+ *
188
+ * // Confidence values:
189
+ * // ABSOLUTELY_YES: confidence = 1.0, value = true
190
+ * // PROBABLY_YES: confidence = 0.5, value = true
191
+ * // AMBIGUOUS: confidence = 0, value = false
192
+ * // PROBABLY_NOT: confidence = 0.5, value = false
193
+ * // ABSOLUTELY_NOT: confidence = 1.0, value = false
194
+ *
195
+ * Object.entries(output).forEach(([key, result]) => {
196
+ * if (result.value && result.confidence === 1) {
197
+ * console.log(`Definitely ${key}:`, result.explanation)
198
+ * } else if (result.value && result.confidence === 0.5) {
199
+ * console.log(`Probably ${key}:`, result.explanation)
200
+ * }
201
+ * })
202
+ * ```
203
+ */
86
204
  label<T extends string>(
87
205
  input: unknown,
88
206
  labels: Labels<T>,
@@ -76,8 +76,118 @@ export type SimplifiedRatingResult<T extends RatingInstructions> = T extends str
76
76
  declare module '@botpress/zai' {
77
77
  interface Zai {
78
78
  /**
79
- * Rates an array of items based on provided instructions.
80
- * Returns a number (1-5) if instructions is a string, or a Record<string, number> if instructions is a Record.
79
+ * Rates array items on a 1-5 scale based on single or multiple criteria.
80
+ *
81
+ * This operation evaluates each item and assigns numeric ratings (1-5) where:
82
+ * - 1 = Very Bad, 2 = Bad, 3 = Average, 4 = Good, 5 = Very Good
83
+ *
84
+ * Supports both simple single-criterion rating (string instructions) and
85
+ * multi-criteria rating (object with criterion → description mapping).
86
+ *
87
+ * @param input - Array of items to rate
88
+ * @param instructions - Single criterion (string) or multiple criteria (object)
89
+ * @param options - Configuration for chunking and tokens per item
90
+ * @returns Response with ratings array (simplified to numbers for single criterion)
91
+ *
92
+ * @example Single criterion rating
93
+ * ```typescript
94
+ * const reviews = [
95
+ * "Amazing product! Best purchase ever!",
96
+ * "It's okay, nothing special",
97
+ * "Terrible quality, broke immediately"
98
+ * ]
99
+ *
100
+ * const ratings = await zai.rate(reviews, 'Rate the sentiment')
101
+ * // Result: [5, 3, 1] (simplified to numbers)
102
+ *
103
+ * // Get full details
104
+ * const { output } = await zai.rate(reviews, 'Rate the sentiment').result()
105
+ * // output[0]: { sentiment: 5, total: 5 }
106
+ * ```
107
+ *
108
+ * @example Multi-criteria rating
109
+ * ```typescript
110
+ * const essays = [
111
+ * "... student essay text ...",
112
+ * "... another essay ...",
113
+ * ]
114
+ *
115
+ * const ratings = await zai.rate(essays, {
116
+ * grammar: 'Rate the grammar and spelling',
117
+ * clarity: 'Rate how clear and well-organized the writing is',
118
+ * argumentation: 'Rate the strength of arguments and evidence'
119
+ * })
120
+ *
121
+ * // Result: [
122
+ * // { grammar: 4, clarity: 5, argumentation: 3, total: 12 },
123
+ * // { grammar: 3, clarity: 4, argumentation: 4, total: 11 }
124
+ * // ]
125
+ * ```
126
+ *
127
+ * @example Rating customer support conversations
128
+ * ```typescript
129
+ * const conversations = [
130
+ * { agent: 'John', messages: [...], duration: 300 },
131
+ * { agent: 'Jane', messages: [...], duration: 180 }
132
+ * ]
133
+ *
134
+ * const ratings = await zai.rate(conversations, {
135
+ * professionalism: 'How professional was the agent?',
136
+ * helpfulness: 'How helpful was the agent in solving the issue?',
137
+ * efficiency: 'How efficiently was the conversation handled?'
138
+ * })
139
+ *
140
+ * // Calculate average scores
141
+ * const avgProfessionalism = ratings.reduce((sum, r) => sum + r.professionalism, 0) / ratings.length
142
+ * ```
143
+ *
144
+ * @example Rating code quality
145
+ * ```typescript
146
+ * const codeSamples = [
147
+ * "function foo() { return x + y }",
148
+ * "const calculateTotal = (items) => items.reduce((sum, item) => sum + item.price, 0)",
149
+ * ]
150
+ *
151
+ * const quality = await zai.rate(codeSamples, {
152
+ * readability: 'How readable and clear is the code?',
153
+ * best_practices: 'Does it follow coding best practices?',
154
+ * documentation: 'Is the code well-documented?'
155
+ * })
156
+ * ```
157
+ *
158
+ * @example Product review rating
159
+ * ```typescript
160
+ * const products = [
161
+ * { name: 'Laptop', reviews: [...], avgStars: 4.2 },
162
+ * { name: 'Mouse', reviews: [...], avgStars: 3.8 }
163
+ * ]
164
+ *
165
+ * const ratings = await zai.rate(
166
+ * products,
167
+ * 'Rate overall product quality based on reviews and rating',
168
+ * {
169
+ * tokensPerItem: 500, // Allow more tokens for detailed reviews
170
+ * maxItemsPerChunk: 20 // Process 20 products per chunk
171
+ * }
172
+ * )
173
+ * ```
174
+ *
175
+ * @example Finding highest-rated items
176
+ * ```typescript
177
+ * const ratings = await zai.rate(items, {
178
+ * quality: 'Product quality',
179
+ * value: 'Value for money',
180
+ * design: 'Design and aesthetics'
181
+ * })
182
+ *
183
+ * // Sort by total score
184
+ * const sorted = items
185
+ * .map((item, idx) => ({ item, rating: ratings[idx] }))
186
+ * .sort((a, b) => b.rating.total - a.rating.total)
187
+ *
188
+ * console.log('Top rated:', sorted[0].item)
189
+ * console.log('Score breakdown:', sorted[0].rating)
190
+ * ```
81
191
  */
82
192
  rate<T, I extends RatingInstructions>(
83
193
  input: Array<T>,