@botpress/vai 0.0.1 → 0.0.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.
package/dist/models.js ADDED
@@ -0,0 +1,388 @@
1
+ "use strict";
2
+ export const Models = [
3
+ {
4
+ "id": "anthropic__claude-3-haiku-20240307",
5
+ "name": "Claude 3 Haiku",
6
+ "integration": "anthropic",
7
+ "input": {
8
+ "maxTokens": 2e5
9
+ },
10
+ "output": {
11
+ "maxTokens": 4096
12
+ }
13
+ },
14
+ {
15
+ "id": "anthropic__claude-3-5-sonnet-20240620",
16
+ "name": "Claude 3.5 Sonnet",
17
+ "integration": "anthropic",
18
+ "input": {
19
+ "maxTokens": 2e5
20
+ },
21
+ "output": {
22
+ "maxTokens": 4096
23
+ }
24
+ },
25
+ {
26
+ "id": "cerebras__llama3.1-70b",
27
+ "name": "Llama 3.1 70B",
28
+ "integration": "cerebras",
29
+ "input": {
30
+ "maxTokens": 8192
31
+ },
32
+ "output": {
33
+ "maxTokens": 8192
34
+ }
35
+ },
36
+ {
37
+ "id": "cerebras__llama3.1-8b",
38
+ "name": "Llama 3.1 8B",
39
+ "integration": "cerebras",
40
+ "input": {
41
+ "maxTokens": 8192
42
+ },
43
+ "output": {
44
+ "maxTokens": 8192
45
+ }
46
+ },
47
+ {
48
+ "id": "fireworks-ai__accounts/fireworks/models/deepseek-coder-v2-instruct",
49
+ "name": "DeepSeek Coder V2 Instruct",
50
+ "integration": "fireworks-ai",
51
+ "input": {
52
+ "maxTokens": 131072
53
+ },
54
+ "output": {
55
+ "maxTokens": 131072
56
+ }
57
+ },
58
+ {
59
+ "id": "fireworks-ai__accounts/fireworks/models/deepseek-coder-v2-lite-instruct",
60
+ "name": "DeepSeek Coder V2 Lite",
61
+ "integration": "fireworks-ai",
62
+ "input": {
63
+ "maxTokens": 163840
64
+ },
65
+ "output": {
66
+ "maxTokens": 163840
67
+ }
68
+ },
69
+ {
70
+ "id": "fireworks-ai__accounts/fireworks/models/firellava-13b",
71
+ "name": "FireLLaVA-13B",
72
+ "integration": "fireworks-ai",
73
+ "input": {
74
+ "maxTokens": 4096
75
+ },
76
+ "output": {
77
+ "maxTokens": 4096
78
+ }
79
+ },
80
+ {
81
+ "id": "fireworks-ai__accounts/fireworks/models/firefunction-v2",
82
+ "name": "Firefunction V2",
83
+ "integration": "fireworks-ai",
84
+ "input": {
85
+ "maxTokens": 8192
86
+ },
87
+ "output": {
88
+ "maxTokens": 8192
89
+ }
90
+ },
91
+ {
92
+ "id": "fireworks-ai__accounts/fireworks/models/gemma2-9b-it",
93
+ "name": "Gemma 2 9B Instruct",
94
+ "integration": "fireworks-ai",
95
+ "input": {
96
+ "maxTokens": 8192
97
+ },
98
+ "output": {
99
+ "maxTokens": 8192
100
+ }
101
+ },
102
+ {
103
+ "id": "fireworks-ai__accounts/fireworks/models/llama-v3p1-405b-instruct",
104
+ "name": "Llama 3.1 405B Instruct",
105
+ "integration": "fireworks-ai",
106
+ "input": {
107
+ "maxTokens": 131072
108
+ },
109
+ "output": {
110
+ "maxTokens": 131072
111
+ }
112
+ },
113
+ {
114
+ "id": "fireworks-ai__accounts/fireworks/models/llama-v3p1-70b-instruct",
115
+ "name": "Llama 3.1 70B Instruct",
116
+ "integration": "fireworks-ai",
117
+ "input": {
118
+ "maxTokens": 131072
119
+ },
120
+ "output": {
121
+ "maxTokens": 131072
122
+ }
123
+ },
124
+ {
125
+ "id": "fireworks-ai__accounts/fireworks/models/llama-v3p1-8b-instruct",
126
+ "name": "Llama 3.1 8B Instruct",
127
+ "integration": "fireworks-ai",
128
+ "input": {
129
+ "maxTokens": 131072
130
+ },
131
+ "output": {
132
+ "maxTokens": 131072
133
+ }
134
+ },
135
+ {
136
+ "id": "fireworks-ai__accounts/fireworks/models/mixtral-8x22b-instruct",
137
+ "name": "Mixtral MoE 8x22B Instruct",
138
+ "integration": "fireworks-ai",
139
+ "input": {
140
+ "maxTokens": 65536
141
+ },
142
+ "output": {
143
+ "maxTokens": 65536
144
+ }
145
+ },
146
+ {
147
+ "id": "fireworks-ai__accounts/fireworks/models/mixtral-8x7b-instruct",
148
+ "name": "Mixtral MoE 8x7B Instruct",
149
+ "integration": "fireworks-ai",
150
+ "input": {
151
+ "maxTokens": 32768
152
+ },
153
+ "output": {
154
+ "maxTokens": 32768
155
+ }
156
+ },
157
+ {
158
+ "id": "fireworks-ai__accounts/fireworks/models/mythomax-l2-13b",
159
+ "name": "MythoMax L2 13b",
160
+ "integration": "fireworks-ai",
161
+ "input": {
162
+ "maxTokens": 4096
163
+ },
164
+ "output": {
165
+ "maxTokens": 4096
166
+ }
167
+ },
168
+ {
169
+ "id": "fireworks-ai__accounts/fireworks/models/qwen2-72b-instruct",
170
+ "name": "Qwen2 72b Instruct",
171
+ "integration": "fireworks-ai",
172
+ "input": {
173
+ "maxTokens": 32768
174
+ },
175
+ "output": {
176
+ "maxTokens": 32768
177
+ }
178
+ },
179
+ {
180
+ "id": "groq__gemma2-9b-it",
181
+ "name": "Gemma2 9B",
182
+ "integration": "groq",
183
+ "input": {
184
+ "maxTokens": 8192
185
+ },
186
+ "output": {
187
+ "maxTokens": 8192
188
+ }
189
+ },
190
+ {
191
+ "id": "groq__llama3-70b-8192",
192
+ "name": "LLaMA 3 70B",
193
+ "integration": "groq",
194
+ "input": {
195
+ "maxTokens": 8192
196
+ },
197
+ "output": {
198
+ "maxTokens": 8192
199
+ }
200
+ },
201
+ {
202
+ "id": "groq__llama3-8b-8192",
203
+ "name": "LLaMA 3 8B",
204
+ "integration": "groq",
205
+ "input": {
206
+ "maxTokens": 8192
207
+ },
208
+ "output": {
209
+ "maxTokens": 8192
210
+ }
211
+ },
212
+ {
213
+ "id": "groq__llama-3.1-70b-versatile",
214
+ "name": "LLaMA 3.1 70B",
215
+ "integration": "groq",
216
+ "input": {
217
+ "maxTokens": 128e3
218
+ },
219
+ "output": {
220
+ "maxTokens": 8192
221
+ }
222
+ },
223
+ {
224
+ "id": "groq__llama-3.1-8b-instant",
225
+ "name": "LLaMA 3.1 8B",
226
+ "integration": "groq",
227
+ "input": {
228
+ "maxTokens": 128e3
229
+ },
230
+ "output": {
231
+ "maxTokens": 8192
232
+ }
233
+ },
234
+ {
235
+ "id": "groq__llama-3.2-11b-vision-preview",
236
+ "name": "LLaMA 3.2 11B Vision",
237
+ "integration": "groq",
238
+ "input": {
239
+ "maxTokens": 128e3
240
+ },
241
+ "output": {
242
+ "maxTokens": 8192
243
+ }
244
+ },
245
+ {
246
+ "id": "groq__llama-3.2-1b-preview",
247
+ "name": "LLaMA 3.2 1B",
248
+ "integration": "groq",
249
+ "input": {
250
+ "maxTokens": 128e3
251
+ },
252
+ "output": {
253
+ "maxTokens": 8192
254
+ }
255
+ },
256
+ {
257
+ "id": "groq__llama-3.2-3b-preview",
258
+ "name": "LLaMA 3.2 3B",
259
+ "integration": "groq",
260
+ "input": {
261
+ "maxTokens": 128e3
262
+ },
263
+ "output": {
264
+ "maxTokens": 8192
265
+ }
266
+ },
267
+ {
268
+ "id": "groq__llama-3.2-90b-vision-preview",
269
+ "name": "LLaMA 3.2 90B Vision",
270
+ "integration": "groq",
271
+ "input": {
272
+ "maxTokens": 128e3
273
+ },
274
+ "output": {
275
+ "maxTokens": 8192
276
+ }
277
+ },
278
+ {
279
+ "id": "groq__llama-3.3-70b-versatile",
280
+ "name": "LLaMA 3.3 70B",
281
+ "integration": "groq",
282
+ "input": {
283
+ "maxTokens": 128e3
284
+ },
285
+ "output": {
286
+ "maxTokens": 32768
287
+ }
288
+ },
289
+ {
290
+ "id": "groq__mixtral-8x7b-32768",
291
+ "name": "Mixtral 8x7B",
292
+ "integration": "groq",
293
+ "input": {
294
+ "maxTokens": 32768
295
+ },
296
+ "output": {
297
+ "maxTokens": 32768
298
+ }
299
+ },
300
+ {
301
+ "id": "openai__o1-2024-12-17",
302
+ "name": "GPT o1",
303
+ "integration": "openai",
304
+ "input": {
305
+ "maxTokens": 2e5
306
+ },
307
+ "output": {
308
+ "maxTokens": 1e5
309
+ }
310
+ },
311
+ {
312
+ "id": "openai__o1-mini-2024-09-12",
313
+ "name": "GPT o1-mini",
314
+ "integration": "openai",
315
+ "input": {
316
+ "maxTokens": 128e3
317
+ },
318
+ "output": {
319
+ "maxTokens": 65536
320
+ }
321
+ },
322
+ {
323
+ "id": "openai__gpt-3.5-turbo-0125",
324
+ "name": "GPT-3.5 Turbo",
325
+ "integration": "openai",
326
+ "input": {
327
+ "maxTokens": 128e3
328
+ },
329
+ "output": {
330
+ "maxTokens": 4096
331
+ }
332
+ },
333
+ {
334
+ "id": "openai__gpt-4-turbo-2024-04-09",
335
+ "name": "GPT-4 Turbo",
336
+ "integration": "openai",
337
+ "input": {
338
+ "maxTokens": 128e3
339
+ },
340
+ "output": {
341
+ "maxTokens": 4096
342
+ }
343
+ },
344
+ {
345
+ "id": "openai__gpt-4o-2024-08-06",
346
+ "name": "GPT-4o (August 2024)",
347
+ "integration": "openai",
348
+ "input": {
349
+ "maxTokens": 128e3
350
+ },
351
+ "output": {
352
+ "maxTokens": 16384
353
+ }
354
+ },
355
+ {
356
+ "id": "openai__gpt-4o-2024-05-13",
357
+ "name": "GPT-4o (May 2024)",
358
+ "integration": "openai",
359
+ "input": {
360
+ "maxTokens": 128e3
361
+ },
362
+ "output": {
363
+ "maxTokens": 4096
364
+ }
365
+ },
366
+ {
367
+ "id": "openai__gpt-4o-2024-11-20",
368
+ "name": "GPT-4o (November 2024)",
369
+ "integration": "openai",
370
+ "input": {
371
+ "maxTokens": 128e3
372
+ },
373
+ "output": {
374
+ "maxTokens": 16384
375
+ }
376
+ },
377
+ {
378
+ "id": "openai__gpt-4o-mini-2024-07-18",
379
+ "name": "GPT-4o Mini",
380
+ "integration": "openai",
381
+ "input": {
382
+ "maxTokens": 128e3
383
+ },
384
+ "output": {
385
+ "maxTokens": 16384
386
+ }
387
+ }
388
+ ];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ import { Client } from "@botpress/client";
3
+ import _ from "lodash";
4
+ import fs from "node:fs";
5
+ const LLM_LIST_MODELS = "listLanguageModels";
6
+ const client = new Client({
7
+ apiUrl: process.env.CLOUD_API_ENDPOINT,
8
+ botId: process.env.CLOUD_BOT_ID,
9
+ token: process.env.CLOUD_PAT
10
+ });
11
+ const { bot } = await client.getBot({
12
+ id: process.env.CLOUD_BOT_ID
13
+ });
14
+ const models = [];
15
+ for (const integrationId in bot.integrations) {
16
+ const botIntegration = bot.integrations[integrationId];
17
+ if (botIntegration?.public && botIntegration?.enabled && botIntegration?.status === "registered") {
18
+ try {
19
+ const { integration } = await client.getPublicIntegrationById({
20
+ id: botIntegration.id
21
+ });
22
+ const canListModels = Object.keys(integration.actions).includes(LLM_LIST_MODELS);
23
+ if (!canListModels) {
24
+ continue;
25
+ }
26
+ const { output } = await client.callAction({
27
+ type: `${integration.name}:${LLM_LIST_MODELS}`,
28
+ input: {}
29
+ });
30
+ if (_.isArray(output?.models)) {
31
+ for (const model of output.models) {
32
+ models.push({
33
+ id: `${integration.name}__${model.id}`,
34
+ name: model.name,
35
+ integration: integration.name,
36
+ input: { maxTokens: model.input.maxTokens },
37
+ output: { maxTokens: model.output.maxTokens }
38
+ });
39
+ }
40
+ }
41
+ } catch (err) {
42
+ console.error("Error fetching integration:", err instanceof Error ? err.message : `${err}`);
43
+ }
44
+ }
45
+ }
46
+ const content = JSON.stringify(_.orderBy(models, ["integration", "name"]), null, 2);
47
+ fs.writeFileSync(
48
+ "./src/models.ts",
49
+ `
50
+ // This file is generated. Do not edit it manually.
51
+ // See 'scripts/update-models.ts'
52
+
53
+ /* eslint-disable */
54
+ /* tslint:disable */
55
+
56
+ export const Models = ${content} as const`,
57
+ "utf-8"
58
+ );
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ import { Client } from "@botpress/client";
3
+ import { z } from "@bpinternal/zui";
4
+ import _ from "lodash";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ const Interfaces = ["llm"];
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
+ for (const name of Interfaces) {
14
+ const { interfaces } = await client.listInterfaces({
15
+ name
16
+ });
17
+ const { interface: latest } = await client.getInterface({
18
+ id: _.maxBy(interfaces, "version").id
19
+ });
20
+ for (const action of Object.keys(latest.actions)) {
21
+ const references = Object.keys(latest.entities).reduce((acc, key) => {
22
+ return { ...acc, [key]: z.fromJsonSchema(latest.entities?.[key]?.schema) };
23
+ }, {});
24
+ const input = latest.actions[action]?.input.schema;
25
+ const output = latest.actions[action]?.output.schema;
26
+ const types = `
27
+ // This file is generated. Do not edit it manually.
28
+ // See 'scripts/update-models.ts'
29
+
30
+ /* eslint-disable */
31
+ /* tslint:disable */
32
+
33
+ export namespace ${name} {
34
+ export namespace ${action} {
35
+ export ${z.fromJsonSchema(input).title("Input").dereference(references).toTypescript({ declaration: "type" })};
36
+ export ${z.fromJsonSchema(output).title("Output").dereference(references).toTypescript({ declaration: "type" })};
37
+ }
38
+ }`;
39
+ fs.mkdirSync(path.resolve(`./src/sdk-interfaces/${name}`), { recursive: true });
40
+ fs.writeFileSync(path.resolve(`./src/sdk-interfaces/${name}/${action}.ts`), types);
41
+ }
42
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ import { z } from "@bpinternal/zui";
3
+ import { createTaskCollector, getCurrentSuite } from "vitest/suite";
4
+ import { Deferred } from "../utils/deferred";
5
+ const scenarioId = z.string().trim().min(1, "Scenario ID/name must not be empty").max(50, "Scenario ID/name is too long");
6
+ const ScenarioLike = z.union([
7
+ scenarioId,
8
+ z.object({ name: scenarioId }).passthrough(),
9
+ z.object({ id: scenarioId }).passthrough()
10
+ ]);
11
+ const getScenarioName = (scenario) => typeof scenario === "string" ? scenario : "name" in scenario ? scenario?.name : scenario?.id;
12
+ const scenarioArgs = z.array(ScenarioLike).min(2, "You need at least two scenarios to compare").max(10, "You can only compare up to 10 scenarios").refine((scenarios) => {
13
+ const set = /* @__PURE__ */ new Set();
14
+ scenarios.forEach((scenario) => set.add(getScenarioName(scenario)));
15
+ return set.size === scenarios.length;
16
+ }, "Scenarios names must be unique");
17
+ export function compare(name, scenarios, fn) {
18
+ scenarios = scenarioArgs.parse(scenarios);
19
+ return createTaskCollector((_name, fn2, timeout) => {
20
+ const currentSuite = getCurrentSuite();
21
+ let completedCount = 0;
22
+ const finished = new Deferred();
23
+ for (const scenario of scenarios) {
24
+ const key = getScenarioName(scenario);
25
+ currentSuite.task(key, {
26
+ meta: {
27
+ scenario: key,
28
+ isVaiTest: true
29
+ },
30
+ handler: async (context) => {
31
+ const extendedContext = Object.freeze({
32
+ scenario
33
+ });
34
+ context.onTestFinished(() => {
35
+ if (++completedCount === scenarios.length) {
36
+ finished.resolve();
37
+ }
38
+ });
39
+ await fn2({ ...context, ...extendedContext });
40
+ },
41
+ timeout: timeout ?? 1e4
42
+ });
43
+ }
44
+ })(name, fn);
45
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ import { expect } from "vitest";
3
+ import { getCurrentTest } from "vitest/suite";
4
+ import { Context } from "../context";
5
+ export class AsyncExpectError extends Error {
6
+ constructor(message, output) {
7
+ super(message);
8
+ this.output = output;
9
+ this.name = "AsyncExpectError";
10
+ }
11
+ }
12
+ const getErrorMessages = (e) => {
13
+ if (e instanceof Error) {
14
+ return e.message;
15
+ } else if (typeof e === "string") {
16
+ return e;
17
+ } else if (typeof e === "object" && e !== null) {
18
+ return JSON.stringify(e);
19
+ }
20
+ return `Unknown error: ${e}`;
21
+ };
22
+ export const asyncExpect = (output, assertion) => {
23
+ const promise = output.then((x) => {
24
+ try {
25
+ assertion(expect(x.result, x.reason));
26
+ } catch (e) {
27
+ if (Context.wrapError) {
28
+ return new AsyncExpectError(getErrorMessages(e), x);
29
+ }
30
+ throw e;
31
+ }
32
+ return x;
33
+ });
34
+ getCurrentTest().promises ??= [];
35
+ getCurrentTest().promises.push(promise);
36
+ return promise;
37
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ export class Deferred {
3
+ constructor() {
4
+ this.promise = new Promise((resolve, reject) => {
5
+ this._resolve = resolve;
6
+ this._reject = reject;
7
+ });
8
+ }
9
+ resolve(value) {
10
+ this._resolve(value);
11
+ }
12
+ reject(reason) {
13
+ this._reject(reason);
14
+ }
15
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ import { z } from "@bpinternal/zui";
3
+ import JSON5 from "json5";
4
+ import { Context } from "../context";
5
+ const nonEmptyString = z.string().trim().min(1);
6
+ const nonEmptyObject = z.object({}).passthrough().refine((value) => Object.keys(value).length > 0, {
7
+ message: "Expected a non-empty object"
8
+ });
9
+ const Input = nonEmptyString.or(nonEmptyObject).or(z.array(z.any()));
10
+ const Output = z.object({
11
+ reason: nonEmptyString.describe("A human-readable explanation of the result"),
12
+ result: z.any().describe(
13
+ "Your best guess at the output according to the instructions provided, rooted in the context of the input and the reason above"
14
+ )
15
+ });
16
+ const Example = z.object({
17
+ input: Input,
18
+ output: Output
19
+ });
20
+ const Options = z.object({
21
+ systemMessage: z.string(),
22
+ examples: z.array(Example).default([]),
23
+ input: Input,
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ outputSchema: z.custom((value) => typeof value === "object" && value !== null && "_def" in value),
26
+ model: z.string()
27
+ });
28
+ const isValidExample = (outputSchema) => (example) => Input.safeParse(example.input).success && Output.safeParse(example.output).success && outputSchema.safeParse(example.output.result).success;
29
+ export async function predictJson(_options) {
30
+ const options = Options.parse(_options);
31
+ const [integration, model] = options.model.split("__");
32
+ if (!model?.length) {
33
+ throw new Error("Invalid model");
34
+ }
35
+ const exampleMessages = options.examples.filter(isValidExample(options.outputSchema)).flatMap(({ input, output: output2 }) => [
36
+ { role: "user", content: JSON.stringify(input, null, 2) },
37
+ { role: "assistant", content: JSON.stringify(output2, null, 2) }
38
+ ]);
39
+ const outputSchema = Output.extend({
40
+ result: options.outputSchema.describe(Output.shape.result.description)
41
+ });
42
+ const result = await Context.client.callAction({
43
+ type: `${integration}:generateContent`,
44
+ input: {
45
+ systemPrompt: `
46
+ ${options.systemMessage}
47
+
48
+ ---
49
+ Please generate a JSON response with the following format:
50
+ \`\`\`typescript
51
+ ${await outputSchema.toTypescriptAsync()}
52
+ \`\`\`
53
+ `.trim(),
54
+ messages: [
55
+ ...exampleMessages,
56
+ {
57
+ role: "user",
58
+ content: JSON.stringify(options.input, null, 2)
59
+ }
60
+ ],
61
+ temperature: 0,
62
+ responseFormat: "json_object",
63
+ model: { id: model }
64
+ }
65
+ });
66
+ const output = result.output;
67
+ if (!output.choices.length || typeof output.choices?.[0]?.content !== "string") {
68
+ throw new Error("Invalid response from the model");
69
+ }
70
+ const json = output.choices[0].content.trim();
71
+ if (!json.length) {
72
+ throw new Error("No response from the model");
73
+ }
74
+ return outputSchema.parse(JSON5.parse(json));
75
+ }
package/package.json CHANGED
@@ -1,17 +1,18 @@
1
1
  {
2
2
  "name": "@botpress/vai",
3
- "version": "0.0.1",
4
- "type": "module",
3
+ "version": "0.0.2",
5
4
  "description": "Vitest AI (vai) – a vitest extension for testing with LLMs",
6
5
  "exports": {
7
6
  ".": {
8
7
  "types": "./dist/index.d.ts",
9
8
  "import": "./dist/index.js",
10
- "require": "./dist/index.cjs"
9
+ "require": "./dist/index.js"
11
10
  }
12
11
  },
13
12
  "scripts": {
14
- "build": "tsup",
13
+ "build": "npm run build:types && npm run build:neutral",
14
+ "build:neutral": "esbuild src/**/*.ts src/*.ts --platform=neutral --outdir=dist",
15
+ "build:types": "tsup",
15
16
  "watch": "tsup --watch",
16
17
  "test": "vitest run --config vitest.config.ts",
17
18
  "test:update": "vitest -u run --config vitest.config.ts",
@@ -30,15 +31,16 @@
30
31
  "devDependencies": {
31
32
  "@types/lodash": "^4.17.0",
32
33
  "dotenv": "^16.3.1",
34
+ "esbuild": "^0.24.2",
33
35
  "ts-node": "^10.9.2",
34
36
  "tsup": "^8.3.5",
35
37
  "typescript": "^5.7.2"
36
38
  },
37
39
  "peerDependencies": {
40
+ "@botpress/client": "^0.40.0",
41
+ "@botpress/wasm": "^1.0.1",
42
+ "@bpinternal/zui": "^0.13.4",
38
43
  "lodash": "^4.17.21",
39
- "@botpress/client": "^0.36.2",
40
- "@botpress/sdk": "^1.6.1",
41
- "@botpress/wasm": "^1.0.0",
42
44
  "vitest": "^2 || ^3 || ^4 || ^5"
43
45
  }
44
46
  }