@botpress/zai 1.0.0-beta.9 → 1.0.1-beta.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.
Files changed (48) hide show
  1. package/dist/browser/index.js +4071 -0
  2. package/dist/browser/index.js.map +7 -0
  3. package/dist/node/adapters/adapter.js +2 -0
  4. package/dist/node/adapters/botpress-table.js +172 -0
  5. package/dist/node/adapters/memory.js +12 -0
  6. package/dist/node/index.js +9 -0
  7. package/dist/node/models.js +387 -0
  8. package/dist/node/operations/check.js +142 -0
  9. package/dist/node/operations/constants.js +2 -0
  10. package/dist/node/operations/errors.js +15 -0
  11. package/dist/node/operations/extract.js +213 -0
  12. package/dist/node/operations/filter.js +181 -0
  13. package/dist/node/operations/label.js +241 -0
  14. package/dist/node/operations/rewrite.js +112 -0
  15. package/dist/node/operations/summarize.js +133 -0
  16. package/dist/node/operations/text.js +47 -0
  17. package/dist/node/utils.js +43 -0
  18. package/dist/node/zai.js +141 -0
  19. package/package.json +21 -13
  20. package/scripts/update-models.mts +76 -0
  21. package/scripts/update-types.mts +49 -0
  22. package/src/adapters/adapter.ts +35 -0
  23. package/src/adapters/botpress-table.ts +213 -0
  24. package/src/adapters/memory.ts +13 -0
  25. package/src/index.ts +11 -0
  26. package/src/models.ts +394 -0
  27. package/src/operations/__tests/botpress_docs.txt +26040 -0
  28. package/src/operations/__tests/cache.jsonl +101 -0
  29. package/src/operations/__tests/index.ts +86 -0
  30. package/src/operations/check.ts +187 -0
  31. package/src/operations/constants.ts +2 -0
  32. package/src/operations/errors.ts +9 -0
  33. package/src/operations/extract.ts +291 -0
  34. package/src/operations/filter.ts +231 -0
  35. package/src/operations/label.ts +332 -0
  36. package/src/operations/rewrite.ts +148 -0
  37. package/src/operations/summarize.ts +193 -0
  38. package/src/operations/text.ts +63 -0
  39. package/src/sdk-interfaces/llm/generateContent.ts +127 -0
  40. package/src/sdk-interfaces/llm/listLanguageModels.ts +19 -0
  41. package/src/utils.ts +61 -0
  42. package/src/zai.ts +192 -0
  43. package/dist/index.cjs +0 -1903
  44. package/dist/index.cjs.map +0 -1
  45. package/dist/index.d.cts +0 -916
  46. package/dist/index.d.ts +0 -916
  47. package/dist/index.js +0 -1873
  48. package/dist/index.js.map +0 -1
@@ -0,0 +1,141 @@
1
+ import { z } from "@bpinternal/zui";
2
+ import { getWasmTokenizer } from "@botpress/wasm";
3
+ import { TableAdapter } from "./adapters/botpress-table";
4
+ import { MemoryAdapter } from "./adapters/memory";
5
+ import { Models } from "./models";
6
+ import { BotpressClient } from "./utils";
7
+ const ActiveLearning = z.object({
8
+ enable: z.boolean().describe("Whether to enable active learning").default(false),
9
+ tableName: z.string().regex(
10
+ /^[A-Za-z0-9_/-]{1,100}Table$/,
11
+ "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
12
+ ).describe("The name of the table to store active learning tasks").default("ActiveLearningTable"),
13
+ taskId: z.string().regex(
14
+ /^[A-Za-z0-9_/-]{1,100}$/,
15
+ "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
16
+ ).describe("The ID of the task").default("default")
17
+ });
18
+ const ZaiConfig = z.object({
19
+ client: BotpressClient,
20
+ userId: z.string().describe("The ID of the user consuming the API").optional(),
21
+ retry: z.object({ maxRetries: z.number().min(0).max(100) }).default({ maxRetries: 3 }),
22
+ modelId: z.custom(
23
+ (value) => {
24
+ if (typeof value !== "string" || !value.includes("__")) {
25
+ return false;
26
+ }
27
+ return true;
28
+ },
29
+ {
30
+ message: "Invalid model ID"
31
+ }
32
+ ).describe("The ID of the model you want to use").default("openai__gpt-4o-mini-2024-07-18"),
33
+ activeLearning: ActiveLearning.default({ enable: false }),
34
+ namespace: z.string().regex(
35
+ /^[A-Za-z0-9_/-]{1,100}$/,
36
+ "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes"
37
+ ).default("zai")
38
+ });
39
+ export class Zai {
40
+ static tokenizer = null;
41
+ client;
42
+ originalConfig;
43
+ userId;
44
+ integration;
45
+ model;
46
+ retry;
47
+ Model;
48
+ namespace;
49
+ adapter;
50
+ activeLearning;
51
+ constructor(config) {
52
+ var _a;
53
+ this.originalConfig = config;
54
+ const parsed = ZaiConfig.parse(config);
55
+ this.client = parsed.client;
56
+ const [integration, modelId] = parsed.modelId.split("__");
57
+ if (!(integration == null ? void 0 : integration.length) || !(modelId == null ? void 0 : modelId.length)) {
58
+ throw new Error(`Invalid model ID: ${parsed.modelId}. Expected format: <integration>__<modelId>`);
59
+ }
60
+ this.integration = integration;
61
+ this.model = modelId;
62
+ this.namespace = parsed.namespace;
63
+ this.userId = parsed.userId;
64
+ this.retry = parsed.retry;
65
+ this.Model = Models.find((m) => m.id === parsed.modelId);
66
+ this.activeLearning = parsed.activeLearning;
67
+ this.adapter = ((_a = parsed.activeLearning) == null ? void 0 : _a.enable) ? new TableAdapter({ client: this.client, tableName: parsed.activeLearning.tableName }) : new MemoryAdapter([]);
68
+ }
69
+ /** @internal */
70
+ async callModel(props) {
71
+ let retries = this.retry.maxRetries;
72
+ while (retries-- >= 0) {
73
+ try {
74
+ return await this._callModel(props);
75
+ } catch (e) {
76
+ if (retries >= 0) {
77
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
78
+ } else {
79
+ throw new Error("Failed to call model after multiple retries");
80
+ }
81
+ }
82
+ }
83
+ throw new Error("Failed to call model after multiple retries");
84
+ }
85
+ /** @internal */
86
+ async _callModel(props) {
87
+ let retries = this.retry.maxRetries;
88
+ do {
89
+ const start = Date.now();
90
+ const input = {
91
+ messages: [],
92
+ temperature: 0,
93
+ topP: 1,
94
+ model: { id: this.model },
95
+ userId: this.userId,
96
+ ...props
97
+ };
98
+ const { output } = await this.client.callAction({
99
+ type: `${this.integration}:generateContent`,
100
+ input
101
+ });
102
+ const latency = Date.now() - start;
103
+ return {
104
+ ...output,
105
+ metadata: {
106
+ model: this.model,
107
+ latency,
108
+ cost: { input: output.usage.inputCost, output: output.usage.outputCost },
109
+ tokens: { input: output.usage.inputTokens, output: output.usage.outputTokens }
110
+ }
111
+ };
112
+ } while (--retries > 0);
113
+ }
114
+ async getTokenizer() {
115
+ Zai.tokenizer ??= await (async () => {
116
+ while (!getWasmTokenizer) {
117
+ await new Promise((resolve) => setTimeout(resolve, 25));
118
+ }
119
+ return getWasmTokenizer();
120
+ })();
121
+ return Zai.tokenizer;
122
+ }
123
+ get taskId() {
124
+ if (!this.activeLearning.enable) {
125
+ return void 0;
126
+ }
127
+ return `${this.namespace}/${this.activeLearning.taskId}`.replace(/\/+/g, "/");
128
+ }
129
+ with(options) {
130
+ return new Zai({
131
+ ...this.originalConfig,
132
+ ...options
133
+ });
134
+ }
135
+ learn(taskId) {
136
+ return new Zai({
137
+ ...this.originalConfig,
138
+ activeLearning: { ...this.activeLearning, taskId, enable: true }
139
+ });
140
+ }
141
+ }
package/package.json CHANGED
@@ -1,25 +1,32 @@
1
1
  {
2
2
  "name": "@botpress/zai",
3
- "version": "1.0.0-beta.9",
4
- "type": "module",
5
- "private": false,
6
3
  "description": "Zui AI (zai) – An LLM utility library written on top of Zui and the Botpress API",
4
+ "version": "1.0.1-beta.2",
7
5
  "exports": {
8
6
  ".": {
9
- "types": "./dist/index.d.ts",
10
- "import": "./dist/index.js",
11
- "require": "./dist/index.cjs"
7
+ "types": "./src/index.ts",
8
+ "node": "./dist/node/index.js",
9
+ "default": "./dist/node/index.js"
10
+ },
11
+ "./browser": {
12
+ "types": "./src/index.ts",
13
+ "browser": "./dist/browser/index.js"
12
14
  }
13
15
  },
16
+ "main": "./dist/node/index.js",
17
+ "browser": "./dist/browser/index.js",
18
+ "types": "./src/index.ts",
14
19
  "scripts": {
15
- "build": "tsup",
20
+ "build": "npm run build:nodejs && npm run build:browser",
21
+ "build:nodejs": "esbuild src/**/*.ts src/*.ts --platform=node --target=node16 --outdir=dist/node",
22
+ "build:browser": "esbuild src/index.ts --bundle --external:@bpinternal/zui --external:@botpress/client --external:@botpress/wasm --platform=browser --target=chrome58,firefox57,safari11 --outdir=dist/browser",
16
23
  "watch": "tsup --watch",
17
24
  "test": "vitest run --config vitest.config.ts",
18
25
  "test:update": "vitest -u run --config vitest.config.ts",
19
26
  "test:watch": "vitest --config vitest.config.ts",
20
27
  "build-with-latest-models": "pnpm run update-types && pnpm run update-models && pnpm run build",
21
- "update-models": "ts-node ./src/scripts/update-models.ts",
22
- "update-types": "ts-node ./src/scripts/update-types.ts"
28
+ "update-models": "ts-node ./scripts/update-models.mts",
29
+ "update-types": "ts-node ./scripts/update-types.mts"
23
30
  },
24
31
  "keywords": [],
25
32
  "author": "",
@@ -27,20 +34,21 @@
27
34
  "dependencies": {
28
35
  "json5": "^2.2.1",
29
36
  "jsonrepair": "^3.2.0",
30
- "lodash": "^4.17.21"
37
+ "lodash-es": "^4.17.21"
31
38
  },
32
39
  "devDependencies": {
33
40
  "@botpress/vai": "0.0.1-beta.7",
34
- "@types/lodash": "^4.17.0",
41
+ "@types/lodash-es": "^4.17.0",
35
42
  "dotenv": "^16.3.1",
43
+ "esbuild": "^0.24.2",
36
44
  "ts-node": "^10.9.2",
37
45
  "tsup": "^8.3.5",
38
46
  "typescript": "^5.7.2",
39
47
  "vitest": "^2.0.5"
40
48
  },
41
49
  "peerDependencies": {
42
- "@botpress/client": "^0.36.2",
43
- "@botpress/sdk": "^1.6.1",
50
+ "@botpress/client": "^0.40.0",
51
+ "@bpinternal/zui": "^0.13.3",
44
52
  "@botpress/wasm": "^1.0.0"
45
53
  }
46
54
  }
@@ -0,0 +1,76 @@
1
+ import { Client } from '@botpress/client'
2
+
3
+ import { orderBy, isArray } from 'lodash-es'
4
+ import fs from 'node:fs'
5
+
6
+ const LLM_LIST_MODELS = 'listLanguageModels'
7
+
8
+ const client = new Client({
9
+ apiUrl: process.env.CLOUD_API_ENDPOINT,
10
+ botId: process.env.CLOUD_BOT_ID,
11
+ token: process.env.CLOUD_PAT
12
+ })
13
+
14
+ const { bot } = await client.getBot({
15
+ id: process.env.CLOUD_BOT_ID!
16
+ })
17
+
18
+ type Model = {
19
+ id: string
20
+ name: string
21
+ integration: string
22
+ input: { maxTokens: number }
23
+ output: { maxTokens: number }
24
+ }
25
+
26
+ const models: Model[] = []
27
+
28
+ for (const integrationId in bot.integrations) {
29
+ const botIntegration = bot.integrations[integrationId]
30
+ if (botIntegration?.public && botIntegration?.enabled && botIntegration?.status === 'registered') {
31
+ try {
32
+ const { integration } = await client.getPublicIntegrationById({
33
+ id: botIntegration.id
34
+ })
35
+
36
+ const canListModels = Object.keys(integration.actions).includes(LLM_LIST_MODELS)
37
+ if (!canListModels) {
38
+ continue
39
+ }
40
+
41
+ const { output } = await client.callAction({
42
+ type: `${integration.name}:${LLM_LIST_MODELS}`,
43
+ input: {}
44
+ })
45
+
46
+ if (isArray(output?.models)) {
47
+ for (const model of output.models) {
48
+ models.push({
49
+ id: `${integration.name}__${model.id}`,
50
+ name: model.name,
51
+ integration: integration.name,
52
+ input: { maxTokens: model.input.maxTokens },
53
+ output: { maxTokens: model.output.maxTokens }
54
+ })
55
+ }
56
+ }
57
+ } catch (err: unknown) {
58
+ console.error('Error fetching integration:', err instanceof Error ? err.message : `${err}`)
59
+ }
60
+ }
61
+ }
62
+
63
+ const content = JSON.stringify(orderBy(models, ['integration', 'name']), null, 2)
64
+
65
+ fs.writeFileSync(
66
+ './src/models.ts',
67
+ `
68
+ // This file is generated. Do not edit it manually.
69
+ // See 'scripts/update-models.ts'
70
+
71
+ /* eslint-disable */
72
+ /* tslint:disable */
73
+
74
+ export const Models = ${content} as const`,
75
+ 'utf-8'
76
+ )
@@ -0,0 +1,49 @@
1
+ import { Client } from '@botpress/client'
2
+ import { z } from '@bpinternal/zui'
3
+
4
+ import { maxBy } from 'lodash-es'
5
+ import fs from 'node:fs'
6
+ import path from 'node:path'
7
+
8
+ const Interfaces = ['llm'] as const
9
+
10
+ const client = new Client({
11
+ apiUrl: process.env.CLOUD_API_ENDPOINT,
12
+ botId: process.env.CLOUD_BOT_ID,
13
+ token: process.env.CLOUD_PAT
14
+ })
15
+
16
+ for (const name of Interfaces) {
17
+ const { interfaces } = await client.listInterfaces({
18
+ name
19
+ })
20
+
21
+ const { interface: latest } = await client.getInterface({
22
+ id: maxBy(interfaces, 'version')!.id
23
+ })
24
+
25
+ for (const action of Object.keys(latest.actions)) {
26
+ const references = Object.keys(latest.entities).reduce((acc, key) => {
27
+ return { ...acc, [key]: z.fromJsonSchema(latest.entities?.[key]?.schema!) }
28
+ }, {})
29
+ const input = latest.actions[action]?.input.schema!
30
+ const output = latest.actions[action]?.output.schema!
31
+
32
+ const types = `
33
+ // This file is generated. Do not edit it manually.
34
+ // See 'scripts/update-models.ts'
35
+
36
+ /* eslint-disable */
37
+ /* tslint:disable */
38
+
39
+ export namespace ${name} {
40
+ export namespace ${action} {
41
+ export ${z.fromJsonSchema(input).title('Input').dereference(references).toTypescript({ declaration: 'type' })};
42
+ export ${z.fromJsonSchema(output).title('Output').dereference(references).toTypescript({ declaration: 'type' })};
43
+ }
44
+ }`
45
+
46
+ fs.mkdirSync(path.resolve(`./src/sdk-interfaces/${name}`), { recursive: true })
47
+ fs.writeFileSync(path.resolve(`./src/sdk-interfaces/${name}/${action}.ts`), types)
48
+ }
49
+ }
@@ -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,213 @@
1
+ import { type Client } from '@botpress/client'
2
+ import { z } from '@bpinternal/zui'
3
+
4
+ import { BotpressClient, GenerationMetadata } from '../utils'
5
+ import { Adapter, GetExamplesProps, SaveExampleProps } from './adapter'
6
+
7
+ const CRITICAL_TAGS = {
8
+ system: 'true',
9
+ 'schema-purpose': 'active-learning',
10
+ 'schema-version': 'Oct-2024'
11
+ } as const
12
+
13
+ const OPTIONAL_TAGS = {
14
+ 'x-studio-title': 'Active Learning',
15
+ 'x-studio-description': 'Table for storing active learning tasks and examples',
16
+ 'x-studio-readonly': 'true',
17
+ 'x-studio-icon': 'lucide://atom',
18
+ 'x-studio-color': 'green'
19
+ } as const
20
+
21
+ const FACTOR = 30
22
+
23
+ const Props = z.object({
24
+ client: BotpressClient,
25
+ tableName: z
26
+ .string()
27
+ .regex(
28
+ /^[a-zA-Z0-9_]{1,45}Table$/,
29
+ 'Table name must be lowercase and contain only letters, numbers and underscores'
30
+ )
31
+ })
32
+
33
+ export type TableSchema = z.input<typeof TableSchema>
34
+ const TableSchema = z.object({
35
+ taskType: z.string().describe('The type of the task (filter, extract, etc.)'),
36
+ taskId: z.string(),
37
+ key: z.string().describe('A unique key for the task (e.g. a hash of the input, taskId, taskType and instructions)'),
38
+ instructions: z.string(),
39
+ input: z.object({}).passthrough().describe('The input to the task'),
40
+ output: z.object({}).passthrough().describe('The expected output'),
41
+ explanation: z.string().nullable(),
42
+ metadata: GenerationMetadata,
43
+ status: z.enum(['pending', 'rejected', 'approved']),
44
+ feedback: z
45
+ .object({
46
+ rating: z.enum(['very-bad', 'bad', 'good', 'very-good']),
47
+ comment: z.string().nullable()
48
+ })
49
+ .nullable()
50
+ .default(null)
51
+ })
52
+
53
+ const searchableColumns = ['input'] as const satisfies Array<keyof typeof TableSchema.shape> as string[]
54
+
55
+ const TableJsonSchema = Object.entries(TableSchema.shape).reduce((acc, [key, value]) => {
56
+ acc[key] = value.toJsonSchema()
57
+ acc[key]['x-zui'] ??= {}
58
+ acc[key]['x-zui'].searchable = searchableColumns.includes(key)
59
+ return acc
60
+ }, {})
61
+
62
+ export class TableAdapter extends Adapter {
63
+ private client: Client
64
+ private tableName: string
65
+
66
+ private status: 'initialized' | 'ready' | 'error'
67
+ private errors = [] as string[]
68
+
69
+ constructor(props: z.input<typeof Props>) {
70
+ super()
71
+ props = Props.parse(props)
72
+ this.client = props.client
73
+ this.tableName = props.tableName
74
+ this.status = 'ready'
75
+ }
76
+
77
+ public async getExamples<TInput, TOutput>({ taskType, taskId, input }: GetExamplesProps<TInput>) {
78
+ await this.assertTableExists()
79
+
80
+ const { rows } = await this.client
81
+ .findTableRows({
82
+ table: this.tableName,
83
+ search: JSON.stringify({ value: input }).substring(0, 1023), // Search is limited to 1024 characters
84
+ limit: 10, // TODO
85
+ filter: {
86
+ // Proximity match of approved examples
87
+ taskType,
88
+ taskId,
89
+ status: 'approved'
90
+ } satisfies Partial<TableSchema>
91
+ })
92
+ .catch((err) => {
93
+ // TODO: handle error
94
+ console.error(`Error fetching examples: ${err.message}`)
95
+ return { rows: [] }
96
+ })
97
+
98
+ return rows.map((row) => ({
99
+ key: row.key,
100
+ input: row.input.value as TInput,
101
+ output: row.output.value as TOutput,
102
+ explanation: row.explanation,
103
+ similarity: row.similarity ?? 0
104
+ }))
105
+ }
106
+
107
+ public async saveExample<TInput, TOutput>({
108
+ key,
109
+ taskType,
110
+ taskId,
111
+ instructions,
112
+ input,
113
+ output,
114
+ explanation,
115
+ metadata,
116
+ status = 'pending'
117
+ }: SaveExampleProps<TInput, TOutput>) {
118
+ await this.assertTableExists()
119
+
120
+ await this.client
121
+ .upsertTableRows({
122
+ table: this.tableName,
123
+ keyColumn: 'key',
124
+ rows: [
125
+ {
126
+ key,
127
+ taskType,
128
+ taskId,
129
+ instructions,
130
+ input: { value: input },
131
+ output: { value: output },
132
+ explanation: explanation ?? null,
133
+ status,
134
+ metadata
135
+ } satisfies TableSchema
136
+ ]
137
+ })
138
+ .catch(() => {
139
+ // TODO: handle error
140
+ })
141
+ }
142
+
143
+ private async assertTableExists() {
144
+ if (this.status !== 'ready') {
145
+ return
146
+ }
147
+
148
+ const { table, created } = await this.client
149
+ .getOrCreateTable({
150
+ table: this.tableName,
151
+ factor: FACTOR,
152
+ frozen: true,
153
+ isComputeEnabled: false,
154
+ tags: {
155
+ ...CRITICAL_TAGS,
156
+ ...OPTIONAL_TAGS
157
+ },
158
+ schema: TableJsonSchema
159
+ })
160
+ .catch((err) => {
161
+ this.status = 'error'
162
+ this.errors = [err.message]
163
+ return { table: null, created: false }
164
+ })
165
+
166
+ if (!table) {
167
+ return
168
+ }
169
+
170
+ if (!created) {
171
+ const issues: string[] = []
172
+
173
+ if (table.factor !== FACTOR) {
174
+ issues.push(`Factor is ${table.factor} instead of ${FACTOR}`)
175
+ }
176
+
177
+ if (table.frozen !== true) {
178
+ issues.push('Table is not frozen')
179
+ }
180
+
181
+ for (const [key, value] of Object.entries(CRITICAL_TAGS)) {
182
+ if (table.tags?.[key] !== value) {
183
+ issues.push(`Tag ${key} is ${table.tags?.[key]} instead of ${value}`)
184
+ }
185
+ }
186
+
187
+ for (const key of Object.keys(TableJsonSchema)) {
188
+ const column = table.schema?.properties[key]
189
+ const expected = TableJsonSchema[key] as { type: string }
190
+
191
+ if (!column) {
192
+ issues.push(`Column ${key} is missing`)
193
+ continue
194
+ }
195
+
196
+ if (column.type !== expected.type) {
197
+ issues.push(`Column ${key} has type ${column.type} instead of ${expected.type}`)
198
+ }
199
+
200
+ if (expected['x-zui'].searchable && !column['x-zui'].searchable) {
201
+ issues.push(`Column ${key} is not searchable but should be`)
202
+ }
203
+ }
204
+
205
+ if (issues.length) {
206
+ this.status = 'error'
207
+ this.errors = issues
208
+ }
209
+ }
210
+
211
+ this.status = 'initialized'
212
+ }
213
+ }
@@ -0,0 +1,13 @@
1
+ import { Adapter } from './adapter'
2
+
3
+ export class MemoryAdapter extends Adapter {
4
+ constructor(public examples: any[]) {
5
+ super()
6
+ }
7
+
8
+ async getExamples() {
9
+ return this.examples
10
+ }
11
+
12
+ async saveExample() {}
13
+ }
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 }