@botpress/zai 1.0.0-beta.9 → 1.0.1-beta.1
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/csj/adapters/adapter.js +2 -0
- package/dist/csj/adapters/botpress-table.js +173 -0
- package/dist/csj/adapters/memory.js +12 -0
- package/dist/csj/index.js +9 -0
- package/dist/csj/models.js +387 -0
- package/dist/csj/operations/check.js +143 -0
- package/dist/csj/operations/constants.js +2 -0
- package/dist/csj/operations/errors.js +15 -0
- package/dist/csj/operations/extract.js +214 -0
- package/dist/csj/operations/filter.js +182 -0
- package/dist/csj/operations/label.js +242 -0
- package/dist/csj/operations/rewrite.js +113 -0
- package/dist/csj/operations/summarize.js +134 -0
- package/dist/csj/operations/text.js +48 -0
- package/dist/csj/utils.js +44 -0
- package/dist/csj/zai.js +142 -0
- package/dist/esm/adapters/adapter.js +5 -0
- package/dist/esm/adapters/botpress-table.js +194 -0
- package/dist/esm/adapters/memory.js +15 -0
- package/dist/esm/index.js +11 -0
- package/dist/esm/models.js +390 -0
- package/dist/esm/operations/check.js +149 -0
- package/dist/esm/operations/constants.js +6 -0
- package/dist/esm/operations/errors.js +18 -0
- package/dist/esm/operations/extract.js +217 -0
- package/dist/esm/operations/filter.js +189 -0
- package/dist/esm/operations/label.js +246 -0
- package/dist/esm/operations/rewrite.js +113 -0
- package/dist/esm/operations/summarize.js +134 -0
- package/dist/esm/operations/text.js +48 -0
- package/dist/esm/utils.js +51 -0
- package/dist/esm/zai.js +161 -0
- package/package.json +17 -13
- package/scripts/update-models.mts +76 -0
- package/scripts/update-types.mts +59 -0
- package/src/adapters/adapter.ts +35 -0
- package/src/adapters/botpress-table.ts +214 -0
- package/src/adapters/memory.ts +13 -0
- package/src/index.ts +11 -0
- package/src/models.ts +394 -0
- package/src/operations/__tests/botpress_docs.txt +26040 -0
- package/src/operations/__tests/cache.jsonl +101 -0
- package/src/operations/__tests/index.ts +86 -0
- package/src/operations/check.ts +188 -0
- package/src/operations/constants.ts +2 -0
- package/src/operations/errors.ts +9 -0
- package/src/operations/extract.ts +292 -0
- package/src/operations/filter.ts +232 -0
- package/src/operations/label.ts +333 -0
- package/src/operations/rewrite.ts +149 -0
- package/src/operations/summarize.ts +194 -0
- package/src/operations/text.ts +64 -0
- package/src/sdk-interfaces/llm/generateContent.ts +127 -0
- package/src/sdk-interfaces/llm/listLanguageModels.ts +19 -0
- package/src/utils.ts +62 -0
- package/src/zai.ts +193 -0
- package/dist/index.cjs +0 -1903
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -916
- package/dist/index.d.ts +0 -916
- package/dist/index.js +0 -1873
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Client } from '@botpress/client'
|
|
2
|
+
import sdk from '@botpress/sdk'
|
|
3
|
+
|
|
4
|
+
import _ from 'lodash'
|
|
5
|
+
import fs from 'node:fs'
|
|
6
|
+
import path from 'node:path'
|
|
7
|
+
|
|
8
|
+
const { z } = sdk
|
|
9
|
+
|
|
10
|
+
const Interfaces = ['llm'] as const
|
|
11
|
+
|
|
12
|
+
const client = new Client({
|
|
13
|
+
apiUrl: process.env.CLOUD_API_ENDPOINT,
|
|
14
|
+
botId: process.env.CLOUD_BOT_ID,
|
|
15
|
+
token: process.env.CLOUD_PAT
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
for (const name of Interfaces) {
|
|
19
|
+
const { interfaces } = await client.listInterfaces({
|
|
20
|
+
name
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const { interface: latest } = await client.getInterface({
|
|
24
|
+
id: _.maxBy(interfaces, 'version')!.id
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
for (const action of Object.keys(latest.actions)) {
|
|
28
|
+
const references = Object.keys(latest.entities).reduce((acc, key) => {
|
|
29
|
+
return { ...acc, [key]: z.fromJsonSchema(latest.entities?.[key]?.schema!) }
|
|
30
|
+
}, {})
|
|
31
|
+
const input = latest.actions[action]?.input.schema!
|
|
32
|
+
const output = latest.actions[action]?.output.schema!
|
|
33
|
+
|
|
34
|
+
const types = `
|
|
35
|
+
// This file is generated. Do not edit it manually.
|
|
36
|
+
// See 'scripts/update-models.ts'
|
|
37
|
+
|
|
38
|
+
/* eslint-disable */
|
|
39
|
+
/* tslint:disable */
|
|
40
|
+
|
|
41
|
+
export namespace ${name} {
|
|
42
|
+
export namespace ${action} {
|
|
43
|
+
export ${sdk.z
|
|
44
|
+
.fromJsonSchema(input)
|
|
45
|
+
.title('Input')
|
|
46
|
+
.dereference(references)
|
|
47
|
+
.toTypescript({ declaration: 'type' })};
|
|
48
|
+
export ${sdk.z
|
|
49
|
+
.fromJsonSchema(output)
|
|
50
|
+
.title('Output')
|
|
51
|
+
.dereference(references)
|
|
52
|
+
.toTypescript({ declaration: 'type' })};
|
|
53
|
+
}
|
|
54
|
+
}`
|
|
55
|
+
|
|
56
|
+
fs.mkdirSync(path.resolve(`./src/sdk-interfaces/${name}`), { recursive: true })
|
|
57
|
+
fs.writeFileSync(path.resolve(`./src/sdk-interfaces/${name}/${action}.ts`), types)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GenerationMetadata } from '../utils'
|
|
2
|
+
|
|
3
|
+
export type SaveExampleProps<TInput, TOutput> = {
|
|
4
|
+
key: string
|
|
5
|
+
taskType: string
|
|
6
|
+
taskId: string
|
|
7
|
+
instructions: string
|
|
8
|
+
input: TInput
|
|
9
|
+
output: TOutput
|
|
10
|
+
explanation?: string
|
|
11
|
+
metadata: GenerationMetadata
|
|
12
|
+
status?: 'pending' | 'approved'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type GetExamplesProps<TInput> = {
|
|
16
|
+
taskType: string
|
|
17
|
+
taskId: string
|
|
18
|
+
input: TInput
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export abstract class Adapter {
|
|
22
|
+
abstract getExamples<TInput, TOutput>(
|
|
23
|
+
props: GetExamplesProps<TInput>
|
|
24
|
+
): Promise<
|
|
25
|
+
Array<{
|
|
26
|
+
key: string
|
|
27
|
+
input: TInput
|
|
28
|
+
output: TOutput
|
|
29
|
+
explanation?: string
|
|
30
|
+
similarity: number
|
|
31
|
+
}>
|
|
32
|
+
>
|
|
33
|
+
|
|
34
|
+
abstract saveExample<TInput, TOutput>(props: SaveExampleProps<TInput, TOutput>): Promise<void>
|
|
35
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { type Client } from '@botpress/client'
|
|
2
|
+
import sdk from '@botpress/sdk'
|
|
3
|
+
const { z } = sdk
|
|
4
|
+
|
|
5
|
+
import { BotpressClient, GenerationMetadata } from '../utils'
|
|
6
|
+
import { Adapter, GetExamplesProps, SaveExampleProps } from './adapter'
|
|
7
|
+
|
|
8
|
+
const CRITICAL_TAGS = {
|
|
9
|
+
system: 'true',
|
|
10
|
+
'schema-purpose': 'active-learning',
|
|
11
|
+
'schema-version': 'Oct-2024'
|
|
12
|
+
} as const
|
|
13
|
+
|
|
14
|
+
const OPTIONAL_TAGS = {
|
|
15
|
+
'x-studio-title': 'Active Learning',
|
|
16
|
+
'x-studio-description': 'Table for storing active learning tasks and examples',
|
|
17
|
+
'x-studio-readonly': 'true',
|
|
18
|
+
'x-studio-icon': 'lucide://atom',
|
|
19
|
+
'x-studio-color': 'green'
|
|
20
|
+
} as const
|
|
21
|
+
|
|
22
|
+
const FACTOR = 30
|
|
23
|
+
|
|
24
|
+
const Props = z.object({
|
|
25
|
+
client: BotpressClient,
|
|
26
|
+
tableName: z
|
|
27
|
+
.string()
|
|
28
|
+
.regex(
|
|
29
|
+
/^[a-zA-Z0-9_]{1,45}Table$/,
|
|
30
|
+
'Table name must be lowercase and contain only letters, numbers and underscores'
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export type TableSchema = sdk.z.input<typeof TableSchema>
|
|
35
|
+
const TableSchema = z.object({
|
|
36
|
+
taskType: z.string().describe('The type of the task (filter, extract, etc.)'),
|
|
37
|
+
taskId: z.string(),
|
|
38
|
+
key: z.string().describe('A unique key for the task (e.g. a hash of the input, taskId, taskType and instructions)'),
|
|
39
|
+
instructions: z.string(),
|
|
40
|
+
input: z.object({}).passthrough().describe('The input to the task'),
|
|
41
|
+
output: z.object({}).passthrough().describe('The expected output'),
|
|
42
|
+
explanation: z.string().nullable(),
|
|
43
|
+
metadata: GenerationMetadata,
|
|
44
|
+
status: z.enum(['pending', 'rejected', 'approved']),
|
|
45
|
+
feedback: z
|
|
46
|
+
.object({
|
|
47
|
+
rating: z.enum(['very-bad', 'bad', 'good', 'very-good']),
|
|
48
|
+
comment: z.string().nullable()
|
|
49
|
+
})
|
|
50
|
+
.nullable()
|
|
51
|
+
.default(null)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const searchableColumns = ['input'] as const satisfies Array<keyof typeof TableSchema.shape> as string[]
|
|
55
|
+
|
|
56
|
+
const TableJsonSchema = Object.entries(TableSchema.shape).reduce((acc, [key, value]) => {
|
|
57
|
+
acc[key] = value.toJsonSchema()
|
|
58
|
+
acc[key]['x-zui'] ??= {}
|
|
59
|
+
acc[key]['x-zui'].searchable = searchableColumns.includes(key)
|
|
60
|
+
return acc
|
|
61
|
+
}, {})
|
|
62
|
+
|
|
63
|
+
export class TableAdapter extends Adapter {
|
|
64
|
+
private client: Client
|
|
65
|
+
private tableName: string
|
|
66
|
+
|
|
67
|
+
private status: 'initialized' | 'ready' | 'error'
|
|
68
|
+
private errors = [] as string[]
|
|
69
|
+
|
|
70
|
+
constructor(props: sdk.z.input<typeof Props>) {
|
|
71
|
+
super()
|
|
72
|
+
props = Props.parse(props)
|
|
73
|
+
this.client = props.client
|
|
74
|
+
this.tableName = props.tableName
|
|
75
|
+
this.status = 'ready'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public async getExamples<TInput, TOutput>({ taskType, taskId, input }: GetExamplesProps<TInput>) {
|
|
79
|
+
await this.assertTableExists()
|
|
80
|
+
|
|
81
|
+
const { rows } = await this.client
|
|
82
|
+
.findTableRows({
|
|
83
|
+
table: this.tableName,
|
|
84
|
+
search: JSON.stringify({ value: input }).substring(0, 1023), // Search is limited to 1024 characters
|
|
85
|
+
limit: 10, // TODO
|
|
86
|
+
filter: {
|
|
87
|
+
// Proximity match of approved examples
|
|
88
|
+
taskType,
|
|
89
|
+
taskId,
|
|
90
|
+
status: 'approved'
|
|
91
|
+
} satisfies Partial<TableSchema>
|
|
92
|
+
})
|
|
93
|
+
.catch((err) => {
|
|
94
|
+
// TODO: handle error
|
|
95
|
+
console.error(`Error fetching examples: ${err.message}`)
|
|
96
|
+
return { rows: [] }
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
return rows.map((row) => ({
|
|
100
|
+
key: row.key,
|
|
101
|
+
input: row.input.value as TInput,
|
|
102
|
+
output: row.output.value as TOutput,
|
|
103
|
+
explanation: row.explanation,
|
|
104
|
+
similarity: row.similarity ?? 0
|
|
105
|
+
}))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public async saveExample<TInput, TOutput>({
|
|
109
|
+
key,
|
|
110
|
+
taskType,
|
|
111
|
+
taskId,
|
|
112
|
+
instructions,
|
|
113
|
+
input,
|
|
114
|
+
output,
|
|
115
|
+
explanation,
|
|
116
|
+
metadata,
|
|
117
|
+
status = 'pending'
|
|
118
|
+
}: SaveExampleProps<TInput, TOutput>) {
|
|
119
|
+
await this.assertTableExists()
|
|
120
|
+
|
|
121
|
+
await this.client
|
|
122
|
+
.upsertTableRows({
|
|
123
|
+
table: this.tableName,
|
|
124
|
+
keyColumn: 'key',
|
|
125
|
+
rows: [
|
|
126
|
+
{
|
|
127
|
+
key,
|
|
128
|
+
taskType,
|
|
129
|
+
taskId,
|
|
130
|
+
instructions,
|
|
131
|
+
input: { value: input },
|
|
132
|
+
output: { value: output },
|
|
133
|
+
explanation: explanation ?? null,
|
|
134
|
+
status,
|
|
135
|
+
metadata
|
|
136
|
+
} satisfies TableSchema
|
|
137
|
+
]
|
|
138
|
+
})
|
|
139
|
+
.catch(() => {
|
|
140
|
+
// TODO: handle error
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private async assertTableExists() {
|
|
145
|
+
if (this.status !== 'ready') {
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const { table, created } = await this.client
|
|
150
|
+
.getOrCreateTable({
|
|
151
|
+
table: this.tableName,
|
|
152
|
+
factor: FACTOR,
|
|
153
|
+
frozen: true,
|
|
154
|
+
isComputeEnabled: false,
|
|
155
|
+
tags: {
|
|
156
|
+
...CRITICAL_TAGS,
|
|
157
|
+
...OPTIONAL_TAGS
|
|
158
|
+
},
|
|
159
|
+
schema: TableJsonSchema
|
|
160
|
+
})
|
|
161
|
+
.catch((err) => {
|
|
162
|
+
this.status = 'error'
|
|
163
|
+
this.errors = [err.message]
|
|
164
|
+
return { table: null, created: false }
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
if (!table) {
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!created) {
|
|
172
|
+
const issues: string[] = []
|
|
173
|
+
|
|
174
|
+
if (table.factor !== FACTOR) {
|
|
175
|
+
issues.push(`Factor is ${table.factor} instead of ${FACTOR}`)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (table.frozen !== true) {
|
|
179
|
+
issues.push('Table is not frozen')
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
for (const [key, value] of Object.entries(CRITICAL_TAGS)) {
|
|
183
|
+
if (table.tags?.[key] !== value) {
|
|
184
|
+
issues.push(`Tag ${key} is ${table.tags?.[key]} instead of ${value}`)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
for (const key of Object.keys(TableJsonSchema)) {
|
|
189
|
+
const column = table.schema?.properties[key]
|
|
190
|
+
const expected = TableJsonSchema[key] as { type: string }
|
|
191
|
+
|
|
192
|
+
if (!column) {
|
|
193
|
+
issues.push(`Column ${key} is missing`)
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (column.type !== expected.type) {
|
|
198
|
+
issues.push(`Column ${key} has type ${column.type} instead of ${expected.type}`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (expected['x-zui'].searchable && !column['x-zui'].searchable) {
|
|
202
|
+
issues.push(`Column ${key} is not searchable but should be`)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (issues.length) {
|
|
207
|
+
this.status = 'error'
|
|
208
|
+
this.errors = issues
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this.status = 'initialized'
|
|
213
|
+
}
|
|
214
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Zai } from './zai'
|
|
2
|
+
|
|
3
|
+
import './operations/text'
|
|
4
|
+
import './operations/rewrite'
|
|
5
|
+
import './operations/summarize'
|
|
6
|
+
import './operations/check'
|
|
7
|
+
import './operations/filter'
|
|
8
|
+
import './operations/extract'
|
|
9
|
+
import './operations/label'
|
|
10
|
+
|
|
11
|
+
export { Zai }
|