@botpress/zai 1.0.1-beta.3 → 1.0.1-beta.5

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 (66) hide show
  1. package/dist/browser/index.js +1 -4
  2. package/dist/index.d.ts +917 -0
  3. package/dist/index.js +1743 -0
  4. package/dist/node/adapters/adapter.d.js +0 -0
  5. package/dist/node/adapters/botpress-table.d.js +1 -0
  6. package/dist/node/adapters/botpress-table.js +1 -4
  7. package/dist/node/adapters/memory.d.js +0 -0
  8. package/dist/node/index.d.js +9 -0
  9. package/dist/node/models.d.js +0 -0
  10. package/dist/node/operations/check.d.js +1 -0
  11. package/dist/node/operations/check.test.d.js +1 -0
  12. package/dist/node/operations/constants.d.js +0 -0
  13. package/dist/node/operations/errors.d.js +0 -0
  14. package/dist/node/operations/extract.d.js +1 -0
  15. package/dist/node/operations/extract.test.d.js +1 -0
  16. package/dist/node/operations/filter.d.js +1 -0
  17. package/dist/node/operations/filter.test.d.js +1 -0
  18. package/dist/node/operations/label.d.js +1 -0
  19. package/dist/node/operations/label.test.d.js +1 -0
  20. package/dist/node/operations/rewrite.d.js +1 -0
  21. package/dist/node/operations/rewrite.test.d.js +1 -0
  22. package/dist/node/operations/summarize.d.js +1 -0
  23. package/dist/node/operations/summarize.test.d.js +1 -0
  24. package/dist/node/operations/text.d.js +1 -0
  25. package/dist/node/operations/text.test.d.js +1 -0
  26. package/dist/node/operations/zai-learn.test.d.js +1 -0
  27. package/dist/node/operations/zai-retry.test.d.js +1 -0
  28. package/dist/node/utils.d.js +0 -0
  29. package/dist/node/zai.d.js +1 -0
  30. package/package.json +5 -14
  31. package/src/adapters/adapter.d.ts +27 -0
  32. package/src/adapters/botpress-table.d.ts +153 -0
  33. package/src/adapters/botpress-table.ts +1 -4
  34. package/src/adapters/memory.d.ts +7 -0
  35. package/src/index.d.ts +9 -0
  36. package/src/models.d.ts +351 -0
  37. package/src/operations/__tests/index.d.ts +20 -0
  38. package/src/operations/check.d.ts +36 -0
  39. package/src/operations/check.test.d.ts +1 -0
  40. package/src/operations/constants.d.ts +2 -0
  41. package/src/operations/errors.d.ts +5 -0
  42. package/src/operations/extract.d.ts +20 -0
  43. package/src/operations/extract.test.d.ts +1 -0
  44. package/src/operations/filter.d.ts +39 -0
  45. package/src/operations/filter.test.d.ts +1 -0
  46. package/src/operations/label.d.ts +79 -0
  47. package/src/operations/label.test.d.ts +1 -0
  48. package/src/operations/rewrite.d.ts +34 -0
  49. package/src/operations/rewrite.test.d.ts +1 -0
  50. package/src/operations/summarize.d.ts +46 -0
  51. package/src/operations/summarize.test.d.ts +1 -0
  52. package/src/operations/text.d.ts +16 -0
  53. package/src/operations/text.test.d.ts +1 -0
  54. package/src/operations/zai-learn.test.d.ts +1 -0
  55. package/src/operations/zai-retry.test.d.ts +1 -0
  56. package/src/sdk-interfaces/llm/generateContent.d.ts +128 -0
  57. package/src/sdk-interfaces/llm/listLanguageModels.d.ts +25 -0
  58. package/src/utils.d.ts +52 -0
  59. package/src/utils.ts +1 -1
  60. package/src/zai.d.ts +99 -0
  61. package/tsconfig.json +2 -2
  62. package/scripts/update-models.mts +0 -76
  63. package/scripts/update-types.mts +0 -49
  64. package/tsup.config.ts +0 -16
  65. package/vitest.config.ts +0 -9
  66. package/vitest.setup.ts +0 -24
@@ -0,0 +1,128 @@
1
+ export declare namespace llm {
2
+ namespace generateContent {
3
+ type Input = {
4
+ /** Model to use for content generation */
5
+ model?: {
6
+ id: string;
7
+ };
8
+ /** Optional system prompt to guide the model */
9
+ systemPrompt?: string;
10
+ /** Array of messages for the model to process */
11
+ messages: Array<{
12
+ role: 'user' | 'assistant';
13
+ type?: 'text' | 'tool_calls' | 'tool_result' | 'multipart';
14
+ /** Required if `type` is "tool_calls" */
15
+ toolCalls?: Array<{
16
+ id: string;
17
+ type: 'function';
18
+ function: {
19
+ name: string;
20
+ /** Some LLMs may generate invalid JSON for a tool call, so this will be `null` when it happens. */
21
+ arguments: {
22
+ [key: string]: any;
23
+ } | null;
24
+ };
25
+ }>;
26
+ /** Required if `type` is "tool_result" */
27
+ toolResultCallId?: string;
28
+ /** Required unless `type` is "tool_call". If `type` is "multipart", this field must be an array of content objects. If `type` is "tool_result" then this field should be the result of the tool call (a plain string or a JSON-encoded array or object). If `type` is "tool_call" then the `toolCalls` field should be used instead. */
29
+ content: string | Array<{
30
+ type: 'text' | 'image';
31
+ /** Indicates the MIME type of the content. If not provided it will be detected from the content-type header of the provided URL. */
32
+ mimeType?: string;
33
+ /** Required if part type is "text" */
34
+ text?: string;
35
+ /** Required if part type is "image" */
36
+ url?: string;
37
+ }> | null;
38
+ }>;
39
+ /** Response format expected from the model. If "json_object" is chosen, you must instruct the model to generate JSON either via the system prompt or a user message. */
40
+ responseFormat?: 'text' | 'json_object';
41
+ /** Maximum number of tokens allowed in the generated response */
42
+ maxTokens?: number;
43
+ /** Sampling temperature for the model. Higher values result in more random outputs. */
44
+ temperature?: number;
45
+ /** Top-p sampling parameter. Limits sampling to the smallest set of tokens with a cumulative probability above the threshold. */
46
+ topP?: number;
47
+ /** Sequences where the model should stop generating further tokens. */
48
+ stopSequences?: string[];
49
+ tools?: Array<{
50
+ type: 'function';
51
+ function: {
52
+ /** Function name */
53
+ name: string;
54
+ description?: string;
55
+ /** JSON schema of the function arguments */
56
+ argumentsSchema?: {};
57
+ };
58
+ }>;
59
+ toolChoice?: {
60
+ type?: 'auto' | 'specific' | 'any' | 'none' | '';
61
+ /** Required if `type` is "specific" */
62
+ functionName?: string;
63
+ };
64
+ userId?: string;
65
+ /** Set to `true` to output debug information to the bot logs */
66
+ debug?: boolean;
67
+ meta?: {
68
+ /** Source of the prompt, e.g. agent/:id/:version cards/ai-generate, cards/ai-task, nodes/autonomous, etc. */
69
+ promptSource?: string;
70
+ promptCategory?: string;
71
+ /** Name of the integration that originally received the message that initiated this action */
72
+ integrationName?: string;
73
+ };
74
+ };
75
+ type Output = {
76
+ /** Response ID from LLM provider */
77
+ id: string;
78
+ /** LLM provider name */
79
+ provider: string;
80
+ /** Model name */
81
+ model: string;
82
+ choices: Array<{
83
+ type?: 'text' | 'tool_calls' | 'tool_result' | 'multipart';
84
+ /** Required if `type` is "tool_calls" */
85
+ toolCalls?: Array<{
86
+ id: string;
87
+ type: 'function';
88
+ function: {
89
+ name: string;
90
+ /** Some LLMs may generate invalid JSON for a tool call, so this will be `null` when it happens. */
91
+ arguments: {
92
+ [key: string]: any;
93
+ } | null;
94
+ };
95
+ }>;
96
+ /** Required if `type` is "tool_result" */
97
+ toolResultCallId?: string;
98
+ /** Required unless `type` is "tool_call". If `type` is "multipart", this field must be an array of content objects. If `type` is "tool_result" then this field should be the result of the tool call (a plain string or a JSON-encoded array or object). If `type` is "tool_call" then the `toolCalls` field should be used instead. */
99
+ content: string | Array<{
100
+ type: 'text' | 'image';
101
+ /** Indicates the MIME type of the content. If not provided it will be detected from the content-type header of the provided URL. */
102
+ mimeType?: string;
103
+ /** Required if part type is "text" */
104
+ text?: string;
105
+ /** Required if part type is "image" */
106
+ url?: string;
107
+ }> | null;
108
+ role: 'assistant';
109
+ index: number;
110
+ stopReason: 'stop' | 'max_tokens' | 'tool_calls' | 'content_filter' | 'other';
111
+ }>;
112
+ usage: {
113
+ /** Number of input tokens used by the model */
114
+ inputTokens: number;
115
+ /** Cost of the input tokens received by the model, in U.S. dollars */
116
+ inputCost: number;
117
+ /** Number of output tokens used by the model */
118
+ outputTokens: number;
119
+ /** Cost of the output tokens generated by the model, in U.S. dollars */
120
+ outputCost: number;
121
+ };
122
+ botpress: {
123
+ /** Total cost of the content generation, in U.S. dollars */
124
+ cost: number;
125
+ };
126
+ };
127
+ }
128
+ }
@@ -0,0 +1,25 @@
1
+ export declare namespace llm {
2
+ namespace listLanguageModels {
3
+ type Input = {};
4
+ type Output = {
5
+ models: Array<{
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ tags: Array<'recommended' | 'deprecated' | 'general-purpose' | 'low-cost' | 'vision' | 'coding' | 'agents' | 'function-calling' | 'roleplay' | 'storytelling' | 'reasoning'>;
10
+ input: {
11
+ maxTokens: number;
12
+ /** Cost per 1 million tokens, in U.S. dollars */
13
+ costPer1MTokens: number;
14
+ };
15
+ output: {
16
+ maxTokens: number;
17
+ /** Cost per 1 million tokens, in U.S. dollars */
18
+ costPer1MTokens: number;
19
+ };
20
+ } & {
21
+ id: string;
22
+ }>;
23
+ };
24
+ }
25
+ }
package/src/utils.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ import { z } from '@bpinternal/zui';
2
+ export declare const stringify: (input: unknown, beautify?: boolean) => string;
3
+ export declare const BotpressClient: z.Schema<any, import("@bpinternal/zui").ZodTypeDef, any>;
4
+ export declare function fastHash(str: string): string;
5
+ export declare const takeUntilTokens: <T>(arr: T[], tokens: number, count: (el: T) => number) => T[];
6
+ export type GenerationMetadata = z.input<typeof GenerationMetadata>;
7
+ export declare const GenerationMetadata: import("@bpinternal/zui").ZodObject<{
8
+ model: import("@bpinternal/zui").ZodString;
9
+ cost: import("@bpinternal/zui").ZodObject<{
10
+ input: import("@bpinternal/zui").ZodNumber;
11
+ output: import("@bpinternal/zui").ZodNumber;
12
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
13
+ input?: number;
14
+ output?: number;
15
+ }, {
16
+ input?: number;
17
+ output?: number;
18
+ }>;
19
+ latency: import("@bpinternal/zui").ZodNumber;
20
+ tokens: import("@bpinternal/zui").ZodObject<{
21
+ input: import("@bpinternal/zui").ZodNumber;
22
+ output: import("@bpinternal/zui").ZodNumber;
23
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
24
+ input?: number;
25
+ output?: number;
26
+ }, {
27
+ input?: number;
28
+ output?: number;
29
+ }>;
30
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
31
+ model?: string;
32
+ cost?: {
33
+ input?: number;
34
+ output?: number;
35
+ };
36
+ latency?: number;
37
+ tokens?: {
38
+ input?: number;
39
+ output?: number;
40
+ };
41
+ }, {
42
+ model?: string;
43
+ cost?: {
44
+ input?: number;
45
+ output?: number;
46
+ };
47
+ latency?: number;
48
+ tokens?: {
49
+ input?: number;
50
+ output?: number;
51
+ };
52
+ }>;
package/src/utils.ts CHANGED
@@ -42,7 +42,7 @@ export const takeUntilTokens = <T>(arr: T[], tokens: number, count: (el: T) => n
42
42
  return result
43
43
  }
44
44
 
45
- export type GenerationMetadata = sdk.z.input<typeof GenerationMetadata>
45
+ export type GenerationMetadata = z.input<typeof GenerationMetadata>
46
46
  export const GenerationMetadata = z.object({
47
47
  model: z.string(),
48
48
  cost: z
package/src/zai.d.ts ADDED
@@ -0,0 +1,99 @@
1
+ import { Client } from '@botpress/client';
2
+ import { z } from '@bpinternal/zui';
3
+ import { type TextTokenizer } from '@botpress/wasm';
4
+ import { Adapter } from './adapters/adapter';
5
+ import { Models } from './models';
6
+ import { llm } from './sdk-interfaces/llm/generateContent';
7
+ import { GenerationMetadata } from './utils';
8
+ type ActiveLearning = z.input<typeof ActiveLearning>;
9
+ declare const ActiveLearning: import("@bpinternal/zui").ZodObject<{
10
+ enable: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodBoolean>;
11
+ tableName: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodString>;
12
+ taskId: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodString>;
13
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
14
+ tableName?: string;
15
+ taskId?: string;
16
+ enable?: boolean;
17
+ }, {
18
+ tableName?: string;
19
+ taskId?: string;
20
+ enable?: boolean;
21
+ }>;
22
+ type ZaiConfig = z.input<typeof ZaiConfig>;
23
+ declare const ZaiConfig: import("@bpinternal/zui").ZodObject<{
24
+ client: z.Schema<any, import("@bpinternal/zui").ZodTypeDef, any>;
25
+ userId: import("@bpinternal/zui").ZodOptional<import("@bpinternal/zui").ZodString>;
26
+ retry: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodObject<{
27
+ maxRetries: import("@bpinternal/zui").ZodNumber;
28
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
29
+ maxRetries?: number;
30
+ }, {
31
+ maxRetries?: number;
32
+ }>>;
33
+ modelId: import("@bpinternal/zui").ZodDefault<z.Schema<string, import("@bpinternal/zui").ZodTypeDef, string>>;
34
+ activeLearning: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodObject<{
35
+ enable: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodBoolean>;
36
+ tableName: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodString>;
37
+ taskId: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodString>;
38
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
39
+ tableName?: string;
40
+ taskId?: string;
41
+ enable?: boolean;
42
+ }, {
43
+ tableName?: string;
44
+ taskId?: string;
45
+ enable?: boolean;
46
+ }>>;
47
+ namespace: import("@bpinternal/zui").ZodDefault<import("@bpinternal/zui").ZodString>;
48
+ }, "strip", import("@bpinternal/zui").ZodTypeAny, {
49
+ client?: any;
50
+ userId?: string;
51
+ retry?: {
52
+ maxRetries?: number;
53
+ };
54
+ modelId?: string;
55
+ activeLearning?: {
56
+ tableName?: string;
57
+ taskId?: string;
58
+ enable?: boolean;
59
+ };
60
+ namespace?: string;
61
+ }, {
62
+ client?: any;
63
+ userId?: string;
64
+ retry?: {
65
+ maxRetries?: number;
66
+ };
67
+ modelId?: string;
68
+ activeLearning?: {
69
+ tableName?: string;
70
+ taskId?: string;
71
+ enable?: boolean;
72
+ };
73
+ namespace?: string;
74
+ }>;
75
+ export declare class Zai {
76
+ protected static tokenizer: TextTokenizer;
77
+ protected client: Client;
78
+ private originalConfig;
79
+ private userId;
80
+ private integration;
81
+ private model;
82
+ private retry;
83
+ protected Model: (typeof Models)[number];
84
+ protected namespace: string;
85
+ protected adapter: Adapter;
86
+ protected activeLearning: ActiveLearning;
87
+ constructor(config: ZaiConfig);
88
+ /** @internal */
89
+ protected callModel(props: Partial<llm.generateContent.Input>): Promise<llm.generateContent.Output & {
90
+ metadata: GenerationMetadata;
91
+ }>;
92
+ /** @internal */
93
+ private _callModel;
94
+ protected getTokenizer(): Promise<TextTokenizer>;
95
+ protected get taskId(): string;
96
+ with(options: Partial<ZaiConfig>): Zai;
97
+ learn(taskId: string): Zai;
98
+ }
99
+ export {};
package/tsconfig.json CHANGED
@@ -3,6 +3,7 @@
3
3
  "target": "ESNext",
4
4
  "module": "ESNext",
5
5
  "moduleResolution": "bundler",
6
+ "outDir": "dist",
6
7
  "allowJs": true,
7
8
  "skipLibCheck": true,
8
9
  "esModuleInterop": true,
@@ -16,7 +17,7 @@
16
17
  "noUnusedParameters": true,
17
18
  "noUncheckedIndexedAccess": true,
18
19
  "lib": ["dom", "ESNext", "dom.iterable"],
19
- "declaration": false,
20
+ "declaration": true,
20
21
  "noEmit": false,
21
22
  "paths": {
22
23
  "@botpress/zai": ["./src/zai.ts"]
@@ -24,7 +25,6 @@
24
25
  },
25
26
  "exclude": ["node_modules", "dist"],
26
27
  "include": ["src/**/*", "vitest.d.ts"],
27
-
28
28
  "ts-node": {
29
29
  "esm": true,
30
30
  "require": ["dotenv/config", "./ensure-env.cjs"]
@@ -1,76 +0,0 @@
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
- )
@@ -1,49 +0,0 @@
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
- }
package/tsup.config.ts DELETED
@@ -1,16 +0,0 @@
1
- import { defineConfig } from 'tsup'
2
-
3
- export default defineConfig({
4
- entry: ['src/index.ts'],
5
- splitting: false,
6
- format: ['esm', 'cjs'],
7
- sourcemap: true,
8
- keepNames: true,
9
- dts: true,
10
- platform: 'browser',
11
- clean: true,
12
- shims: true,
13
- external: ['react', 'react-dom'],
14
- bundle: true,
15
- plugins: []
16
- })
package/vitest.config.ts DELETED
@@ -1,9 +0,0 @@
1
- import 'dotenv/config'
2
- import { defineConfig } from 'vitest/config'
3
-
4
- export default defineConfig({
5
- test: {
6
- include: ['./src/**/*.test.ts'],
7
- setupFiles: './vitest.setup.ts'
8
- }
9
- })
package/vitest.setup.ts DELETED
@@ -1,24 +0,0 @@
1
- import { Client } from '@botpress/client'
2
- import { setupClient } from '@botpress/vai'
3
-
4
- import { beforeAll } from 'vitest'
5
-
6
- globalThis.STUDIO = false
7
-
8
- beforeAll(async () => {
9
- if (!process.env.CLOUD_PAT) {
10
- throw new Error('Missing CLOUD_PAT')
11
- }
12
-
13
- if (!process.env.CLOUD_BOT_ID) {
14
- throw new Error('Missing CLOUD_BOT_ID')
15
- }
16
-
17
- setupClient(
18
- new Client({
19
- apiUrl: process.env.CLOUD_API_ENDPOINT ?? 'https://api.botpress.dev',
20
- botId: process.env.CLOUD_BOT_ID,
21
- token: process.env.CLOUD_PAT
22
- })
23
- )
24
- })