@botpress/zai 2.0.7 → 2.0.10
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/adapters/botpress-table.js +4 -3
- package/dist/index.d.ts +73 -280
- package/dist/operations/check.js +19 -8
- package/dist/operations/filter.js +4 -4
- package/dist/operations/label.js +5 -5
- package/dist/operations/rewrite.js +2 -2
- package/dist/utils.js +0 -13
- package/dist/zai.js +8 -5
- package/e2e/client.ts +151 -0
- package/e2e/data/cache.jsonl +113 -118
- package/e2e/utils.ts +2 -54
- package/package.json +4 -3
- package/src/adapters/botpress-table.ts +25 -4
- package/src/operations/check.ts +32 -10
- package/src/operations/extract.ts +7 -1
- package/src/operations/filter.ts +17 -6
- package/src/operations/label.ts +18 -8
- package/src/operations/rewrite.ts +17 -6
- package/src/operations/summarize.ts +19 -2
- package/src/operations/text.ts +5 -1
- package/src/utils.ts +12 -19
- package/src/zai.ts +24 -8
package/e2e/utils.ts
CHANGED
|
@@ -4,10 +4,9 @@ import fs from 'node:fs'
|
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
import { beforeAll } from 'vitest'
|
|
6
6
|
import { Zai } from '../src'
|
|
7
|
-
import {
|
|
7
|
+
import { getCachedCognitiveClient } from './client'
|
|
8
8
|
|
|
9
9
|
const DATA_PATH = path.join(__dirname, 'data')
|
|
10
|
-
const CACHE_PATH = path.join(DATA_PATH, 'cache.jsonl')
|
|
11
10
|
const DOC_PATH = path.join(DATA_PATH, 'botpress_docs.txt')
|
|
12
11
|
|
|
13
12
|
export const getClient = () => {
|
|
@@ -18,59 +17,8 @@ export const getClient = () => {
|
|
|
18
17
|
})
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
function readJSONL<T>(filePath: string, keyProperty: keyof T): Map<string, T> {
|
|
22
|
-
const lines = fs.readFileSync(filePath, 'utf-8').split(/\r?\n/).filter(Boolean)
|
|
23
|
-
|
|
24
|
-
const map = new Map<string, T>()
|
|
25
|
-
|
|
26
|
-
for (const line of lines) {
|
|
27
|
-
const obj = JSON.parse(line) as T
|
|
28
|
-
const key = String(obj[keyProperty])
|
|
29
|
-
map.set(key, obj)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return map
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const cache: Map<string, { key: string; value: any }> = readJSONL(CACHE_PATH, 'key')
|
|
36
|
-
|
|
37
20
|
export const getCachedClient = () => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const proxy = new Proxy(client, {
|
|
41
|
-
get(target, prop) {
|
|
42
|
-
if (prop === 'callAction') {
|
|
43
|
-
return async (...args: Parameters<Client['callAction']>) => {
|
|
44
|
-
const key = fastHash(JSON.stringify(args))
|
|
45
|
-
const cached = cache.get(key)
|
|
46
|
-
|
|
47
|
-
if (cached) {
|
|
48
|
-
return cached.value
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const response = await target.callAction(...args)
|
|
52
|
-
cache.set(key, { key, value: response })
|
|
53
|
-
|
|
54
|
-
fs.appendFileSync(
|
|
55
|
-
CACHE_PATH,
|
|
56
|
-
JSON.stringify({
|
|
57
|
-
key,
|
|
58
|
-
value: response,
|
|
59
|
-
}) + '\n'
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
return response
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return Reflect.get(target, prop)
|
|
66
|
-
},
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
;(proxy as any).clone = () => {
|
|
70
|
-
return getCachedClient()
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return proxy
|
|
21
|
+
return getCachedCognitiveClient()
|
|
74
22
|
}
|
|
75
23
|
|
|
76
24
|
export const getZai = () => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/zai",
|
|
3
3
|
"description": "Zui AI (zai) – An LLM utility library written on top of Zui and the Botpress API",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.10",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"author": "",
|
|
24
24
|
"license": "ISC",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@botpress/cognitive": "0.1.
|
|
26
|
+
"@botpress/cognitive": "0.1.24",
|
|
27
27
|
"json5": "^2.2.3",
|
|
28
28
|
"jsonrepair": "^3.10.0",
|
|
29
29
|
"lodash-es": "^4.17.21"
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"@botpress/common": "workspace:*",
|
|
34
34
|
"@botpress/vai": "workspace:*",
|
|
35
35
|
"@types/lodash-es": "^4.17.12",
|
|
36
|
+
"diff": "^8.0.1",
|
|
36
37
|
"dotenv": "^16.4.4",
|
|
37
38
|
"esbuild": "^0.16.12",
|
|
38
39
|
"glob": "^9.3.4",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"@bpinternal/thicktoken": "^1.0.0",
|
|
44
|
-
"@bpinternal/zui": "^0.
|
|
45
|
+
"@bpinternal/zui": "^0.22.5"
|
|
45
46
|
},
|
|
46
47
|
"engines": {
|
|
47
48
|
"node": ">=18.0.0"
|
|
@@ -20,6 +20,11 @@ const OPTIONAL_TAGS = {
|
|
|
20
20
|
|
|
21
21
|
const FACTOR = 30
|
|
22
22
|
|
|
23
|
+
type Props = {
|
|
24
|
+
client: Client
|
|
25
|
+
tableName: string
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
const Props = z.object({
|
|
24
29
|
client: z.custom(() => true),
|
|
25
30
|
tableName: z
|
|
@@ -30,7 +35,22 @@ const Props = z.object({
|
|
|
30
35
|
),
|
|
31
36
|
})
|
|
32
37
|
|
|
33
|
-
export type TableSchema =
|
|
38
|
+
export type TableSchema = {
|
|
39
|
+
taskType: string
|
|
40
|
+
taskId: string
|
|
41
|
+
key: string
|
|
42
|
+
instructions: string
|
|
43
|
+
input: Record<string, unknown>
|
|
44
|
+
output: Record<string, unknown>
|
|
45
|
+
explanation: string | null
|
|
46
|
+
metadata: GenerationMetadata
|
|
47
|
+
status: 'pending' | 'rejected' | 'approved'
|
|
48
|
+
feedback: {
|
|
49
|
+
rating: 'very-bad' | 'bad' | 'good' | 'very-good'
|
|
50
|
+
comment: string | null
|
|
51
|
+
} | null
|
|
52
|
+
}
|
|
53
|
+
|
|
34
54
|
const TableSchema = z.object({
|
|
35
55
|
taskType: z.string().describe('The type of the task (filter, extract, etc.)'),
|
|
36
56
|
taskId: z.string(),
|
|
@@ -39,7 +59,7 @@ const TableSchema = z.object({
|
|
|
39
59
|
input: z.object({}).passthrough().describe('The input to the task'),
|
|
40
60
|
output: z.object({}).passthrough().describe('The expected output'),
|
|
41
61
|
explanation: z.string().nullable(),
|
|
42
|
-
metadata:
|
|
62
|
+
metadata: z.object({}).passthrough(),
|
|
43
63
|
status: z.enum(['pending', 'rejected', 'approved']),
|
|
44
64
|
feedback: z
|
|
45
65
|
.object({
|
|
@@ -65,9 +85,9 @@ export class TableAdapter extends Adapter {
|
|
|
65
85
|
|
|
66
86
|
private _status: 'initialized' | 'ready' | 'error'
|
|
67
87
|
|
|
68
|
-
public constructor(props:
|
|
88
|
+
public constructor(props: Props) {
|
|
69
89
|
super()
|
|
70
|
-
props = Props.parse(props)
|
|
90
|
+
props = Props.parse(props) as Props
|
|
71
91
|
this._client = props.client
|
|
72
92
|
this._tableName = props.tableName
|
|
73
93
|
this._status = 'ready'
|
|
@@ -131,6 +151,7 @@ export class TableAdapter extends Adapter {
|
|
|
131
151
|
explanation: explanation ?? null,
|
|
132
152
|
status,
|
|
133
153
|
metadata,
|
|
154
|
+
feedback: null, // Feedback is not provided at this point
|
|
134
155
|
} satisfies TableSchema,
|
|
135
156
|
],
|
|
136
157
|
})
|
package/src/operations/check.ts
CHANGED
|
@@ -5,15 +5,27 @@ import { fastHash, stringify, takeUntilTokens } from '../utils'
|
|
|
5
5
|
import { Zai } from '../zai'
|
|
6
6
|
import { PROMPT_INPUT_BUFFER } from './constants'
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const _Example = z.object({
|
|
9
9
|
input: z.any(),
|
|
10
10
|
check: z.boolean(),
|
|
11
11
|
reason: z.string().optional(),
|
|
12
|
+
condition: z.string().optional(),
|
|
12
13
|
})
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
type Example = {
|
|
16
|
+
input: unknown
|
|
17
|
+
check: boolean
|
|
18
|
+
reason?: string
|
|
19
|
+
condition?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type Options = {
|
|
23
|
+
/** Examples to check the condition against */
|
|
24
|
+
examples?: Array<Example>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const _Options = z.object({
|
|
28
|
+
examples: z.array(_Example).describe('Examples to check the condition against').default([]),
|
|
17
29
|
})
|
|
18
30
|
|
|
19
31
|
declare module '@botpress/zai' {
|
|
@@ -36,8 +48,8 @@ const TRUE = '■TRUE■'
|
|
|
36
48
|
const FALSE = '■FALSE■'
|
|
37
49
|
const END = '■END■'
|
|
38
50
|
|
|
39
|
-
Zai.prototype.check = async function (this: Zai, input, condition, _options) {
|
|
40
|
-
const options =
|
|
51
|
+
Zai.prototype.check = async function (this: Zai, input: unknown, condition: string, _options: Options | undefined) {
|
|
52
|
+
const options = _Options.parse(_options ?? {}) as Options
|
|
41
53
|
const tokenizer = await this.getTokenizer()
|
|
42
54
|
await this.fetchModelDetails()
|
|
43
55
|
const PROMPT_COMPONENT = Math.max(this.ModelDetails.input.maxTokens - PROMPT_INPUT_BUFFER, 100)
|
|
@@ -80,14 +92,20 @@ Zai.prototype.check = async function (this: Zai, input, condition, _options) {
|
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
const defaultExamples = [
|
|
83
|
-
{
|
|
95
|
+
{
|
|
96
|
+
input: '50 Cent',
|
|
97
|
+
check: true,
|
|
98
|
+
reason: '50 Cent is widely recognized as a public personality.',
|
|
99
|
+
condition: 'Is the input a public personality?',
|
|
100
|
+
},
|
|
84
101
|
{
|
|
85
102
|
input: ['apple', 'banana', 'carrot', 'house'],
|
|
86
103
|
check: false,
|
|
87
104
|
reason:
|
|
88
105
|
'The list contains a house, which is not a fruit. Also, the list contains a carrot, which is a vegetable.',
|
|
106
|
+
condition: 'Is the input exclusively a list of fruits?',
|
|
89
107
|
},
|
|
90
|
-
]
|
|
108
|
+
] satisfies Example[]
|
|
91
109
|
|
|
92
110
|
const userExamples = [
|
|
93
111
|
...examples.map((e) => ({ input: e.input, check: e.output, reason: e.explanation })),
|
|
@@ -115,8 +133,12 @@ ${END}
|
|
|
115
133
|
`.trim()
|
|
116
134
|
}
|
|
117
135
|
|
|
118
|
-
const formatExample = (example:
|
|
119
|
-
{
|
|
136
|
+
const formatExample = (example: Example) => [
|
|
137
|
+
{
|
|
138
|
+
type: 'text' as const,
|
|
139
|
+
content: formatInput(stringify(example.input ?? null), example.condition ?? condition),
|
|
140
|
+
role: 'user' as const,
|
|
141
|
+
},
|
|
120
142
|
{
|
|
121
143
|
type: 'text' as const,
|
|
122
144
|
content: formatOutput(example.check, example.reason ?? ''),
|
|
@@ -10,7 +10,13 @@ import { Zai } from '../zai'
|
|
|
10
10
|
import { PROMPT_INPUT_BUFFER } from './constants'
|
|
11
11
|
import { JsonParsingError } from './errors'
|
|
12
12
|
|
|
13
|
-
export type Options =
|
|
13
|
+
export type Options = {
|
|
14
|
+
/** Instructions to guide the user on how to extract the data */
|
|
15
|
+
instructions?: string
|
|
16
|
+
/** The maximum number of tokens per chunk */
|
|
17
|
+
chunkLength?: number
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
const Options = z.object({
|
|
15
21
|
instructions: z.string().optional().describe('Instructions to guide the user on how to extract the data'),
|
|
16
22
|
chunkLength: z
|
package/src/operations/filter.ts
CHANGED
|
@@ -6,15 +6,26 @@ import { fastHash, stringify, takeUntilTokens } from '../utils'
|
|
|
6
6
|
import { Zai } from '../zai'
|
|
7
7
|
import { PROMPT_INPUT_BUFFER, PROMPT_OUTPUT_BUFFER } from './constants'
|
|
8
8
|
|
|
9
|
-
type Example =
|
|
10
|
-
|
|
9
|
+
type Example = {
|
|
10
|
+
input: unknown
|
|
11
|
+
filter: boolean
|
|
12
|
+
reason?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const _Example = z.object({
|
|
11
16
|
input: z.any(),
|
|
12
17
|
filter: z.boolean(),
|
|
13
18
|
reason: z.string().optional(),
|
|
14
19
|
})
|
|
15
20
|
|
|
16
|
-
export type Options =
|
|
17
|
-
|
|
21
|
+
export type Options = {
|
|
22
|
+
/** The maximum number of tokens per item */
|
|
23
|
+
tokensPerItem?: number
|
|
24
|
+
/** Examples to filter the condition against */
|
|
25
|
+
examples?: Array<Example>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const _Options = z.object({
|
|
18
29
|
tokensPerItem: z
|
|
19
30
|
.number()
|
|
20
31
|
.min(1)
|
|
@@ -22,7 +33,7 @@ const Options = z.object({
|
|
|
22
33
|
.optional()
|
|
23
34
|
.describe('The maximum number of tokens per item')
|
|
24
35
|
.default(250),
|
|
25
|
-
examples: z.array(
|
|
36
|
+
examples: z.array(_Example).describe('Examples to filter the condition against').default([]),
|
|
26
37
|
})
|
|
27
38
|
|
|
28
39
|
declare module '@botpress/zai' {
|
|
@@ -35,7 +46,7 @@ declare module '@botpress/zai' {
|
|
|
35
46
|
const END = '■END■'
|
|
36
47
|
|
|
37
48
|
Zai.prototype.filter = async function (this: Zai, input, condition, _options) {
|
|
38
|
-
const options =
|
|
49
|
+
const options = _Options.parse(_options ?? {}) as Options
|
|
39
50
|
const tokenizer = await this.getTokenizer()
|
|
40
51
|
await this.fetchModelDetails()
|
|
41
52
|
|
package/src/operations/label.ts
CHANGED
|
@@ -22,11 +22,16 @@ type Example<T extends string> = {
|
|
|
22
22
|
labels: Partial<Record<T, { label: Label; explanation?: string }>>
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export type Options<T extends string> =
|
|
26
|
-
|
|
25
|
+
export type Options<T extends string> = {
|
|
26
|
+
/** Examples to help the user make a decision */
|
|
27
|
+
examples?: Array<Example<T>>
|
|
28
|
+
/** Instructions to guide the user on how to extract the data */
|
|
29
|
+
instructions?: string
|
|
30
|
+
/** The maximum number of tokens per chunk */
|
|
31
|
+
chunkLength?: number
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
const
|
|
34
|
+
const _Options = z.object({
|
|
30
35
|
examples: z
|
|
31
36
|
.array(
|
|
32
37
|
z.object({
|
|
@@ -48,7 +53,7 @@ const Options = z.object({
|
|
|
48
53
|
|
|
49
54
|
type Labels<T extends string> = Record<T, string>
|
|
50
55
|
|
|
51
|
-
const
|
|
56
|
+
const _Labels = z.record(z.string().min(1).max(250), z.string()).superRefine((labels, ctx) => {
|
|
52
57
|
const keys = Object.keys(labels)
|
|
53
58
|
|
|
54
59
|
for (const key of keys) {
|
|
@@ -119,9 +124,14 @@ const getConfidence = (label: Label) => {
|
|
|
119
124
|
}
|
|
120
125
|
}
|
|
121
126
|
|
|
122
|
-
Zai.prototype.label = async function <T extends string>(
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
Zai.prototype.label = async function <T extends string>(
|
|
128
|
+
this: Zai,
|
|
129
|
+
input: unknown,
|
|
130
|
+
_labels: Labels<T>,
|
|
131
|
+
_options: Options<T> | undefined
|
|
132
|
+
) {
|
|
133
|
+
const options = _Options.parse(_options ?? {}) as unknown as Options<T>
|
|
134
|
+
const labels = _Labels.parse(_labels) as Labels<T>
|
|
125
135
|
const tokenizer = await this.getTokenizer()
|
|
126
136
|
await this.fetchModelDetails()
|
|
127
137
|
|
|
@@ -211,7 +221,7 @@ Zai.prototype.label = async function <T extends string>(this: Zai, input, _label
|
|
|
211
221
|
options.examples.forEach((example) => {
|
|
212
222
|
examples.push({
|
|
213
223
|
key: fastHash(JSON.stringify(example)),
|
|
214
|
-
input: example.input,
|
|
224
|
+
input: stringify(example.input),
|
|
215
225
|
similarity: 1,
|
|
216
226
|
explanation: '',
|
|
217
227
|
output: example.labels as unknown as {
|
|
@@ -5,15 +5,26 @@ import { fastHash, stringify, takeUntilTokens } from '../utils'
|
|
|
5
5
|
import { Zai } from '../zai'
|
|
6
6
|
import { PROMPT_INPUT_BUFFER } from './constants'
|
|
7
7
|
|
|
8
|
-
type Example =
|
|
9
|
-
|
|
8
|
+
type Example = {
|
|
9
|
+
input: string
|
|
10
|
+
output: string
|
|
11
|
+
instructions?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const _Example = z.object({
|
|
10
15
|
input: z.string(),
|
|
11
16
|
output: z.string(),
|
|
12
17
|
})
|
|
13
18
|
|
|
14
|
-
export type Options =
|
|
19
|
+
export type Options = {
|
|
20
|
+
/** Examples to guide the rewriting */
|
|
21
|
+
examples?: Array<Example>
|
|
22
|
+
/** The maximum number of tokens to generate */
|
|
23
|
+
length?: number
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
const Options = z.object({
|
|
16
|
-
examples: z.array(
|
|
27
|
+
examples: z.array(_Example).default([]),
|
|
17
28
|
length: z.number().min(10).max(16_000).optional().describe('The maximum number of tokens to generate'),
|
|
18
29
|
})
|
|
19
30
|
|
|
@@ -28,7 +39,7 @@ const START = '■START■'
|
|
|
28
39
|
const END = '■END■'
|
|
29
40
|
|
|
30
41
|
Zai.prototype.rewrite = async function (this: Zai, original, prompt, _options) {
|
|
31
|
-
const options = Options.parse(_options ?? {})
|
|
42
|
+
const options = Options.parse(_options ?? {}) as Options
|
|
32
43
|
const tokenizer = await this.getTokenizer()
|
|
33
44
|
await this.fetchModelDetails()
|
|
34
45
|
|
|
@@ -101,7 +112,7 @@ ${END}
|
|
|
101
112
|
}
|
|
102
113
|
|
|
103
114
|
const savedExamples: Example[] = [
|
|
104
|
-
...tableExamples.map((x) => ({ input: x.input as string, output: x.output as string })),
|
|
115
|
+
...tableExamples.map((x) => ({ input: x.input as string, output: x.output as string }) satisfies Example),
|
|
105
116
|
...options.examples,
|
|
106
117
|
]
|
|
107
118
|
|
|
@@ -5,7 +5,24 @@ import { chunk } from 'lodash-es'
|
|
|
5
5
|
import { Zai } from '../zai'
|
|
6
6
|
import { PROMPT_INPUT_BUFFER, PROMPT_OUTPUT_BUFFER } from './constants'
|
|
7
7
|
|
|
8
|
-
export type Options =
|
|
8
|
+
export type Options = {
|
|
9
|
+
/** What should the text be summarized to? */
|
|
10
|
+
prompt?: string
|
|
11
|
+
/** How to format the example text */
|
|
12
|
+
format?: string
|
|
13
|
+
/** The length of the summary in tokens */
|
|
14
|
+
length?: number
|
|
15
|
+
/** How many times longer (than final length) are the intermediate summaries generated */
|
|
16
|
+
intermediateFactor?: number
|
|
17
|
+
/** The maximum number of iterations to perform */
|
|
18
|
+
maxIterations?: number
|
|
19
|
+
/** Sliding window options */
|
|
20
|
+
sliding?: {
|
|
21
|
+
window: number
|
|
22
|
+
overlap: number
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
const Options = z.object({
|
|
10
27
|
prompt: z
|
|
11
28
|
.string()
|
|
@@ -45,7 +62,7 @@ const START = '■START■'
|
|
|
45
62
|
const END = '■END■'
|
|
46
63
|
|
|
47
64
|
Zai.prototype.summarize = async function (this: Zai, original, _options) {
|
|
48
|
-
const options = Options.parse(_options ?? {})
|
|
65
|
+
const options = Options.parse(_options ?? {}) as Options
|
|
49
66
|
const tokenizer = await this.getTokenizer()
|
|
50
67
|
await this.fetchModelDetails()
|
|
51
68
|
|
package/src/operations/text.ts
CHANGED
|
@@ -5,7 +5,11 @@ import { clamp } from 'lodash-es'
|
|
|
5
5
|
import { Zai } from '../zai'
|
|
6
6
|
import { PROMPT_INPUT_BUFFER, PROMPT_OUTPUT_BUFFER } from './constants'
|
|
7
7
|
|
|
8
|
-
export type Options =
|
|
8
|
+
export type Options = {
|
|
9
|
+
/** The maximum number of tokens to generate */
|
|
10
|
+
length?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
const Options = z.object({
|
|
10
14
|
length: z.number().min(1).max(100_000).optional().describe('The maximum number of tokens to generate'),
|
|
11
15
|
})
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { z } from '@bpinternal/zui'
|
|
2
|
-
|
|
3
1
|
export const stringify = (input: unknown, beautify = true) => {
|
|
4
2
|
return typeof input === 'string' && !!input.length
|
|
5
3
|
? input
|
|
@@ -33,20 +31,15 @@ export const takeUntilTokens = <T>(arr: T[], tokens: number, count: (el: T) => n
|
|
|
33
31
|
return result
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
export type GenerationMetadata =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
input: z.number(),
|
|
49
|
-
output: z.number(),
|
|
50
|
-
})
|
|
51
|
-
.describe('Number of tokens used'),
|
|
52
|
-
})
|
|
34
|
+
export type GenerationMetadata = {
|
|
35
|
+
model: string
|
|
36
|
+
cost: {
|
|
37
|
+
input: number
|
|
38
|
+
output: number
|
|
39
|
+
}
|
|
40
|
+
latency: number
|
|
41
|
+
tokens: {
|
|
42
|
+
input: number
|
|
43
|
+
output: number
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/zai.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Client } from '@botpress/client'
|
|
1
2
|
import { BotpressClientLike, Cognitive, Model } from '@botpress/cognitive'
|
|
2
3
|
|
|
3
4
|
import { type TextTokenizer, getWasmTokenizer } from '@bpinternal/thicktoken'
|
|
@@ -9,8 +10,13 @@ import { MemoryAdapter } from './adapters/memory'
|
|
|
9
10
|
|
|
10
11
|
type ModelId = Required<Parameters<Cognitive['generateContent']>[0]['model']>
|
|
11
12
|
|
|
12
|
-
type ActiveLearning =
|
|
13
|
-
|
|
13
|
+
type ActiveLearning = {
|
|
14
|
+
enable: boolean
|
|
15
|
+
tableName: string
|
|
16
|
+
taskId: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const _ActiveLearning = z.object({
|
|
14
20
|
enable: z.boolean().describe('Whether to enable active learning').default(false),
|
|
15
21
|
tableName: z
|
|
16
22
|
.string()
|
|
@@ -30,8 +36,15 @@ const ActiveLearning = z.object({
|
|
|
30
36
|
.default('default'),
|
|
31
37
|
})
|
|
32
38
|
|
|
33
|
-
type ZaiConfig =
|
|
34
|
-
|
|
39
|
+
type ZaiConfig = {
|
|
40
|
+
client: BotpressClientLike | Cognitive
|
|
41
|
+
userId?: string
|
|
42
|
+
modelId?: ModelId | string
|
|
43
|
+
activeLearning?: ActiveLearning
|
|
44
|
+
namespace?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const _ZaiConfig = z.object({
|
|
35
48
|
client: z.custom<BotpressClientLike | Cognitive>(),
|
|
36
49
|
userId: z.string().describe('The ID of the user consuming the API').optional(),
|
|
37
50
|
modelId: z
|
|
@@ -53,7 +66,7 @@ const ZaiConfig = z.object({
|
|
|
53
66
|
)
|
|
54
67
|
.describe('The ID of the model you want to use')
|
|
55
68
|
.default('best' satisfies ModelId),
|
|
56
|
-
activeLearning:
|
|
69
|
+
activeLearning: _ActiveLearning.default({ enable: false }),
|
|
57
70
|
namespace: z
|
|
58
71
|
.string()
|
|
59
72
|
.regex(
|
|
@@ -79,7 +92,7 @@ export class Zai {
|
|
|
79
92
|
|
|
80
93
|
public constructor(config: ZaiConfig) {
|
|
81
94
|
this._originalConfig = config
|
|
82
|
-
const parsed =
|
|
95
|
+
const parsed = _ZaiConfig.parse(config) as ZaiConfig
|
|
83
96
|
|
|
84
97
|
this.client = Cognitive.isCognitiveClient(parsed.client)
|
|
85
98
|
? (parsed.client as unknown as Cognitive)
|
|
@@ -88,10 +101,13 @@ export class Zai {
|
|
|
88
101
|
this.namespace = parsed.namespace
|
|
89
102
|
this._userId = parsed.userId
|
|
90
103
|
this.Model = parsed.modelId as ModelId
|
|
91
|
-
this.activeLearning = parsed.activeLearning
|
|
104
|
+
this.activeLearning = parsed.activeLearning as ActiveLearning
|
|
92
105
|
|
|
93
106
|
this.adapter = parsed.activeLearning?.enable
|
|
94
|
-
? new TableAdapter({
|
|
107
|
+
? new TableAdapter({
|
|
108
|
+
client: this.client.client as unknown as Client,
|
|
109
|
+
tableName: parsed.activeLearning.tableName,
|
|
110
|
+
})
|
|
95
111
|
: new MemoryAdapter([])
|
|
96
112
|
}
|
|
97
113
|
|