@chatbotkit/cli 1.29.0 → 1.30.0

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/README.md CHANGED
@@ -11,13 +11,13 @@ A powerful command-line interface for ChatBotKit that provides both API manageme
11
11
 
12
12
  ## Why ChatBotKit?
13
13
 
14
- **Build lighter, future-proof AI agents.** When you build with ChatBotKit, the heavy lifting happens on our servers—not in your application. This architectural advantage delivers:
14
+ **Build lighter, future-proof AI agents.** When you build with ChatBotKit, the heavy lifting happens on our servers-not in your application. This architectural advantage delivers:
15
15
 
16
16
  - 🪶 **Lightweight Agents**: Your agents stay lean because complex AI processing, model orchestration, and tool execution happen server-side. Less code in your app means faster load times and simpler maintenance.
17
17
 
18
18
  - šŸ›”ļø **Robust & Streamlined**: Server-side processing provides a more reliable experience with built-in error handling, automatic retries, and consistent behavior across all platforms.
19
19
 
20
- - šŸ”„ **Backward & Forward Compatible**: As AI technology evolves—new models, new capabilities, new paradigms—your agents automatically benefit. No code changes required on your end.
20
+ - šŸ”„ **Backward & Forward Compatible**: As AI technology evolves-new models, new capabilities, new paradigms-your agents automatically benefit. No code changes required on your end.
21
21
 
22
22
  - šŸ”® **Future-Proof**: Agents you build today will remain capable tomorrow. When we add support for new AI models or capabilities, your existing agents gain those powers without any updates to your codebase.
23
23
 
@@ -80,15 +80,24 @@ function getClient() {
80
80
  exports.command = new commander_1.Command()
81
81
  .name('agent')
82
82
  .description('Run an agent as a background worker with a prompt')
83
+ .addOption(new commander_1.Option('-a, --agent <agent>', 'Path to an agent markdown file'))
83
84
  .addOption(new commander_1.Option('-b, --bot <bot>', 'Bot id'))
84
85
  .addOption(new commander_1.Option('-m, --model <model>', 'Model name'))
86
+ .addOption(new commander_1.Option('--skillset <skillset>', 'Skillset id'))
87
+ .addOption(new commander_1.Option('--dataset <dataset>', 'Dataset id'))
85
88
  .addOption(new commander_1.Option('-p, --prompt <prompt>', 'The prompt to execute (or path to a file containing the prompt)').makeOptionMandatory())
86
89
  .addOption(new commander_1.Option('-t, --tools <tools...>', 'Specific tools to enable').choices((0, tools_js_1.getToolNames)()))
90
+ .addOption(new commander_1.Option('-s, --skills <dirs...>', 'Directories to load skills from'))
87
91
  .addOption(new commander_1.Option('-i, --max-iterations <maxIterations>', 'Maximum number of iterations')
88
- .default(50)
92
+ .default(100)
89
93
  .argParser((value) => parseInt(value, 10)))
94
+ .addOption(new commander_1.Option('-d, --debug', 'Print raw stream items to stderr'))
90
95
  .action(async (options) => {
91
96
  const client = getClient();
97
+ const agentDef = options.agent ? await (0, agent_1.loadAgent)(options.agent) : null;
98
+ const { skills, close: closeSkills } = options.skills
99
+ ? await (0, agent_1.loadSkills)(options.skills, { watch: false })
100
+ : { skills: [], close: () => { } };
92
101
  const tools = (0, tools_js_1.getTools)(options.tools);
93
102
  let prompt = options.prompt;
94
103
  {
@@ -109,16 +118,33 @@ exports.command = new commander_1.Command()
109
118
  let hasOutput = false;
110
119
  for await (const { type, data } of (0, agent_1.execute)({
111
120
  client,
112
- ...(options.bot ? { botId: options.bot } : { model: options.model }),
121
+ ...(options.bot
122
+ ? { botId: options.bot }
123
+ : agentDef?.botId
124
+ ? { botId: agentDef.botId }
125
+ : { model: options.model ?? agentDef?.model }),
126
+ ...(agentDef?.backstory ? { backstory: agentDef.backstory } : {}),
127
+ ...(options.skillset ?? agentDef?.skillsetId
128
+ ? { skillsetId: options.skillset ?? agentDef?.skillsetId }
129
+ : {}),
130
+ ...(options.dataset ?? agentDef?.datasetId
131
+ ? { datasetId: options.dataset ?? agentDef?.datasetId }
132
+ : {}),
113
133
  messages: [{ type: 'user', text: prompt }],
114
134
  tools,
115
135
  maxIterations: options.maxIterations,
136
+ ...(skills.length > 0
137
+ ? { extensions: { features: [(0, agent_1.createSkillsFeature)(skills)] } }
138
+ : {}),
116
139
  })) {
140
+ if (options.debug) {
141
+ process.stderr.write(`[debug] ${JSON.stringify({ type, data })}\n`);
142
+ }
117
143
  if (type === 'iteration') {
118
144
  if (isInteractive) {
119
145
  const iterationNum = data.iteration - 1;
120
146
  output.writeLine((0, color_js_1.formatBlue)(`\n╭─ Iteration ${iterationNum} ─╮`));
121
- if (spinner) {
147
+ if (spinner && !options.debug) {
122
148
  spinner.start();
123
149
  }
124
150
  }
@@ -134,7 +160,7 @@ exports.command = new commander_1.Command()
134
160
  status: 'running',
135
161
  args: data.args,
136
162
  });
137
- if (spinner) {
163
+ if (spinner && !options.debug) {
138
164
  spinner.start();
139
165
  }
140
166
  }
@@ -144,7 +170,7 @@ exports.command = new commander_1.Command()
144
170
  status: 'completed',
145
171
  result: data.result,
146
172
  });
147
- if (spinner) {
173
+ if (spinner && !options.debug) {
148
174
  spinner.start();
149
175
  }
150
176
  }
@@ -154,7 +180,7 @@ exports.command = new commander_1.Command()
154
180
  status: 'error',
155
181
  error: data.error,
156
182
  });
157
- if (spinner) {
183
+ if (spinner && !options.debug) {
158
184
  spinner.start();
159
185
  }
160
186
  }
@@ -180,6 +206,7 @@ exports.command = new commander_1.Command()
180
206
  }
181
207
  }
182
208
  }
209
+ closeSkills();
183
210
  if (exitResult) {
184
211
  output.printStructured({
185
212
  status: exitResult.code === 0 ? 'success' : 'failed',
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = exports.conversationList = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const env_js_1 = require("../../../env.cjs");
6
8
  const output_js_1 = require("../../../output.cjs");
7
- const index_js_1 = tslib_1.__importDefault(require("./message/index.cjs"));
9
+ const index_js_1 = __importDefault(require("./message/index.cjs"));
8
10
  const index_js_2 = require("@chatbotkit/sdk/conversation/index.js");
9
11
  const commander_1 = require("commander");
10
12
  function getClient() {
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = exports.datasetDelete = exports.datasetFetch = exports.datasetList = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const env_js_1 = require("../../../env.cjs");
6
8
  const output_js_1 = require("../../../output.cjs");
7
- const index_js_1 = tslib_1.__importDefault(require("./file/index.cjs"));
8
- const index_js_2 = tslib_1.__importDefault(require("./record/index.cjs"));
9
+ const index_js_1 = __importDefault(require("./file/index.cjs"));
10
+ const index_js_2 = __importDefault(require("./record/index.cjs"));
9
11
  const index_js_3 = require("@chatbotkit/sdk/dataset/index.js");
10
12
  const commander_1 = require("commander");
11
13
  function getClient() {
@@ -1,20 +1,23 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const output_js_1 = require("../../output.cjs");
6
- const index_js_1 = tslib_1.__importDefault(require("./blueprint/index.cjs"));
7
- const index_js_2 = tslib_1.__importDefault(require("./bot/index.cjs"));
8
- const index_js_3 = tslib_1.__importDefault(require("./contact/index.cjs"));
9
- const index_js_4 = tslib_1.__importDefault(require("./conversation/index.cjs"));
10
- const index_js_5 = tslib_1.__importDefault(require("./dataset/index.cjs"));
11
- const index_js_6 = tslib_1.__importDefault(require("./file/index.cjs"));
12
- const index_js_7 = tslib_1.__importDefault(require("./integration/index.cjs"));
13
- const index_js_8 = tslib_1.__importDefault(require("./memory/index.cjs"));
14
- const index_js_9 = tslib_1.__importDefault(require("./partner/index.cjs"));
15
- const index_js_10 = tslib_1.__importDefault(require("./secret/index.cjs"));
16
- const index_js_11 = tslib_1.__importDefault(require("./skillset/index.cjs"));
17
- const index_js_12 = tslib_1.__importDefault(require("./team/index.cjs"));
8
+ const index_js_1 = __importDefault(require("./blueprint/index.cjs"));
9
+ const index_js_2 = __importDefault(require("./bot/index.cjs"));
10
+ const index_js_3 = __importDefault(require("./contact/index.cjs"));
11
+ const index_js_4 = __importDefault(require("./conversation/index.cjs"));
12
+ const index_js_5 = __importDefault(require("./dataset/index.cjs"));
13
+ const index_js_6 = __importDefault(require("./file/index.cjs"));
14
+ const index_js_7 = __importDefault(require("./integration/index.cjs"));
15
+ const index_js_8 = __importDefault(require("./memory/index.cjs"));
16
+ const index_js_9 = __importDefault(require("./partner/index.cjs"));
17
+ const index_js_10 = __importDefault(require("./platform/index.cjs"));
18
+ const index_js_11 = __importDefault(require("./secret/index.cjs"));
19
+ const index_js_12 = __importDefault(require("./skillset/index.cjs"));
20
+ const index_js_13 = __importDefault(require("./team/index.cjs"));
18
21
  const commander_1 = require("commander");
19
22
  const commands = {
20
23
  blueprint: index_js_1.default,
@@ -26,9 +29,10 @@ const commands = {
26
29
  integration: index_js_7.default,
27
30
  memory: index_js_8.default,
28
31
  partner: index_js_9.default,
29
- secret: index_js_10.default,
30
- skillset: index_js_11.default,
31
- team: index_js_12.default,
32
+ platform: index_js_10.default,
33
+ secret: index_js_11.default,
34
+ skillset: index_js_12.default,
35
+ team: index_js_13.default,
32
36
  };
33
37
  exports.command = new commander_1.Command()
34
38
  .name('api')
@@ -1,22 +1,24 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = void 0;
4
- const tslib_1 = require("tslib");
5
- const index_js_1 = tslib_1.__importDefault(require("./discord/index.cjs"));
6
- const index_js_2 = tslib_1.__importDefault(require("./email/index.cjs"));
7
- const index_js_3 = tslib_1.__importDefault(require("./extract/index.cjs"));
8
- const index_js_4 = tslib_1.__importDefault(require("./instagram/index.cjs"));
9
- const index_js_5 = tslib_1.__importDefault(require("./mcpserver/index.cjs"));
10
- const index_js_6 = tslib_1.__importDefault(require("./messenger/index.cjs"));
11
- const index_js_7 = tslib_1.__importDefault(require("./notion/index.cjs"));
12
- const index_js_8 = tslib_1.__importDefault(require("./sitemap/index.cjs"));
13
- const index_js_9 = tslib_1.__importDefault(require("./slack/index.cjs"));
14
- const index_js_10 = tslib_1.__importDefault(require("./support/index.cjs"));
15
- const index_js_11 = tslib_1.__importDefault(require("./telegram/index.cjs"));
16
- const index_js_12 = tslib_1.__importDefault(require("./trigger/index.cjs"));
17
- const index_js_13 = tslib_1.__importDefault(require("./twilio/index.cjs"));
18
- const index_js_14 = tslib_1.__importDefault(require("./whatsapp/index.cjs"));
19
- const index_js_15 = tslib_1.__importDefault(require("./widget/index.cjs"));
7
+ const index_js_1 = __importDefault(require("./discord/index.cjs"));
8
+ const index_js_2 = __importDefault(require("./email/index.cjs"));
9
+ const index_js_3 = __importDefault(require("./extract/index.cjs"));
10
+ const index_js_4 = __importDefault(require("./instagram/index.cjs"));
11
+ const index_js_5 = __importDefault(require("./mcpserver/index.cjs"));
12
+ const index_js_6 = __importDefault(require("./messenger/index.cjs"));
13
+ const index_js_7 = __importDefault(require("./notion/index.cjs"));
14
+ const index_js_8 = __importDefault(require("./sitemap/index.cjs"));
15
+ const index_js_9 = __importDefault(require("./slack/index.cjs"));
16
+ const index_js_10 = __importDefault(require("./support/index.cjs"));
17
+ const index_js_11 = __importDefault(require("./telegram/index.cjs"));
18
+ const index_js_12 = __importDefault(require("./trigger/index.cjs"));
19
+ const index_js_13 = __importDefault(require("./twilio/index.cjs"));
20
+ const index_js_14 = __importDefault(require("./whatsapp/index.cjs"));
21
+ const index_js_15 = __importDefault(require("./widget/index.cjs"));
20
22
  const commander_1 = require("commander");
21
23
  const commands = {
22
24
  widget: index_js_15.default,
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = void 0;
4
- const tslib_1 = require("tslib");
5
- const index_js_1 = tslib_1.__importDefault(require("./user/index.cjs"));
7
+ const index_js_1 = __importDefault(require("./user/index.cjs"));
6
8
  const commander_1 = require("commander");
7
9
  const commands = {
8
10
  user: index_js_1.default,
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.command = void 0;
7
+ const index_js_1 = __importDefault(require("./model/index.cjs"));
8
+ const commander_1 = require("commander");
9
+ const commands = {
10
+ model: index_js_1.default,
11
+ };
12
+ exports.command = new commander_1.Command()
13
+ .name('platform')
14
+ .description('Platform tools for ChatBotKit');
15
+ for (const cmd of Object.values(commands)) {
16
+ exports.command.addCommand(cmd);
17
+ }
18
+ exports.default = exports.command;
@@ -0,0 +1,3 @@
1
+ export const command: Command;
2
+ export default command;
3
+ import { Command } from 'commander';
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.command = exports.modelList = void 0;
4
+ const env_js_1 = require("../../../../env.cjs");
5
+ const output_js_1 = require("../../../../output.cjs");
6
+ const index_js_1 = require("@chatbotkit/sdk/platform/model/index.js");
7
+ const commander_1 = require("commander");
8
+ function getClient() {
9
+ return new index_js_1.PlatformModelClient({
10
+ secret: (0, env_js_1.getSECRET)(),
11
+ runAsUserId: (0, env_js_1.getRUNAS_USERID)(),
12
+ });
13
+ }
14
+ exports.modelList = new commander_1.Command()
15
+ .name('list')
16
+ .description('List platform models')
17
+ .option('-s, --stream', 'Stream models')
18
+ .action(async (str, options) => {
19
+ const { stream } = options;
20
+ const client = getClient();
21
+ if (stream) {
22
+ for await (const model of client.list().stream()) {
23
+ (0, output_js_1.print)(model);
24
+ }
25
+ }
26
+ else {
27
+ const { items } = await client.list();
28
+ for (const model of items) {
29
+ (0, output_js_1.print)(model);
30
+ }
31
+ }
32
+ });
33
+ const commands = {
34
+ list: exports.modelList,
35
+ };
36
+ exports.command = new commander_1.Command()
37
+ .name('model')
38
+ .description('Model tools for ChatBotKit platform');
39
+ for (const cmd of Object.values(commands)) {
40
+ exports.command.addCommand(cmd);
41
+ }
42
+ exports.default = exports.command;
@@ -0,0 +1,4 @@
1
+ export const modelList: Command;
2
+ export const command: Command;
3
+ export default command;
4
+ import { Command } from 'commander';
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = exports.skillsetDelete = exports.skillsetFetch = exports.skillsetList = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const env_js_1 = require("../../../env.cjs");
6
8
  const output_js_1 = require("../../../output.cjs");
7
- const index_js_1 = tslib_1.__importDefault(require("./ability/index.cjs"));
9
+ const index_js_1 = __importDefault(require("./ability/index.cjs"));
8
10
  const index_js_2 = require("@chatbotkit/sdk/skillset/index.js");
9
11
  const commander_1 = require("commander");
10
12
  function getClient() {
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const env_js_1 = require("../../env.cjs");
6
8
  const spinner_js_1 = require("../../spinner.cjs");
7
9
  const tools_js_1 = require("../../tools.cjs");
8
10
  const agent_1 = require("@chatbotkit/agent");
9
11
  const sdk_1 = require("@chatbotkit/sdk");
10
12
  const commander_1 = require("commander");
11
- const promises_1 = tslib_1.__importDefault(require("readline/promises"));
13
+ const promises_1 = __importDefault(require("readline/promises"));
12
14
  function getClient() {
13
15
  return new sdk_1.ChatBotKit({
14
16
  secret: (0, env_js_1.getSECRET)(),
@@ -18,15 +20,29 @@ function getClient() {
18
20
  exports.command = new commander_1.Command()
19
21
  .name('chat')
20
22
  .description('Start a chat session')
23
+ .addOption(new commander_1.Option('-a, --agent <agent>', 'Path to an agent markdown file'))
21
24
  .addOption(new commander_1.Option('-b, --bot <bot>', 'Bot id'))
22
25
  .addOption(new commander_1.Option('-m, --model <model>', 'Model name'))
26
+ .addOption(new commander_1.Option('--skillset <skillset>', 'Skillset id'))
27
+ .addOption(new commander_1.Option('--dataset <dataset>', 'Dataset id'))
23
28
  .addOption(new commander_1.Option('-t, --tools <tools...>', 'Specific tools to enable').choices((0, tools_js_1.getToolNames)()))
29
+ .addOption(new commander_1.Option('-s, --skills <dirs...>', 'Directories to load skills from'))
30
+ .addOption(new commander_1.Option('-d, --debug', 'Print raw stream items to stderr'))
24
31
  .action(async (options) => {
25
32
  const client = getClient();
33
+ const agent = options.agent ? await (0, agent_1.loadAgent)(options.agent) : null;
34
+ const { skills, close: closeSkills } = options.skills
35
+ ? await (0, agent_1.loadSkills)(options.skills, { watch: true })
36
+ : { skills: [], close: () => { } };
26
37
  const rl = promises_1.default.createInterface({
27
38
  input: process.stdin,
28
39
  output: process.stdout,
29
40
  });
41
+ rl.on('close', () => {
42
+ process.stdout.write('\n');
43
+ closeSkills();
44
+ process.exit(0);
45
+ });
30
46
  const messages = [];
31
47
  const tools = (0, tools_js_1.getTools)(options.tools);
32
48
  const colors = {
@@ -34,33 +50,131 @@ exports.command = new commander_1.Command()
34
50
  bold: '\x1b[1m',
35
51
  cyan: '\x1b[36m',
36
52
  green: '\x1b[32m',
53
+ dim: '\x1b[2m',
54
+ gray: '\x1b[90m',
37
55
  };
56
+ const effectiveBot = options.bot || agent?.botId;
57
+ const effectiveModel = options.model ?? agent?.model;
58
+ const effectiveSkillset = options.skillset ?? agent?.skillsetId;
59
+ const effectiveDataset = options.dataset ?? agent?.datasetId;
60
+ const effectiveSkills = options.skills;
61
+ const metaLines = [];
62
+ if (agent?.name) {
63
+ metaLines.push(`agent ${agent.name}`);
64
+ }
65
+ if (effectiveBot) {
66
+ metaLines.push(`bot ${effectiveBot}`);
67
+ }
68
+ if (effectiveModel) {
69
+ metaLines.push(`model ${effectiveModel}`);
70
+ }
71
+ if (effectiveSkillset) {
72
+ metaLines.push(`skillset ${effectiveSkillset}`);
73
+ }
74
+ if (effectiveDataset) {
75
+ metaLines.push(`dataset ${effectiveDataset}`);
76
+ }
77
+ if (effectiveSkills) {
78
+ metaLines.push(`skills ${effectiveSkills.join(', ')}`);
79
+ }
80
+ if (metaLines.length > 0) {
81
+ process.stdout.write('\n');
82
+ for (const line of metaLines) {
83
+ process.stdout.write(`${colors.gray} ${line}${colors.reset}\n`);
84
+ }
85
+ }
86
+ process.stdout.write(`\n${colors.gray} shortcuts Ctrl+C re-prompt Ā· Ctrl+CƗ2 abort response Ā· Ctrl+D exit${colors.reset}\n`);
87
+ let agentAbort = null;
88
+ let promptAbort = null;
89
+ let sigintCount = 0;
90
+ rl.on('SIGINT', () => {
91
+ if (agentAbort) {
92
+ sigintCount++;
93
+ if (sigintCount === 1) {
94
+ process.stdout.write(`\n ${colors.dim}(Press Ctrl+C again to cancel)${colors.reset}\n`);
95
+ }
96
+ else {
97
+ sigintCount = 0;
98
+ agentAbort.abort();
99
+ }
100
+ }
101
+ else {
102
+ process.stdout.write('^C\n');
103
+ promptAbort?.abort();
104
+ }
105
+ });
38
106
  for (;;) {
39
107
  process.stdout.write('\n');
40
- const user = await rl.question(`${colors.cyan}ā—${colors.reset} ${colors.bold}You${colors.reset}\n\n> `);
41
- messages.push({ type: 'user', text: user });
108
+ promptAbort = new AbortController();
109
+ let text;
110
+ try {
111
+ text = await rl.question(`${colors.cyan}ā—${colors.reset} ${colors.bold}You${colors.reset}\n\n> `, { signal: promptAbort.signal });
112
+ }
113
+ catch {
114
+ continue;
115
+ }
116
+ finally {
117
+ promptAbort = null;
118
+ }
119
+ text = text?.trim();
120
+ if (!text) {
121
+ continue;
122
+ }
123
+ messages.push({ type: 'user', text: text });
42
124
  process.stdout.write(`\n${colors.green}ā—${colors.reset} ${colors.bold}Assistant${colors.reset}\n\n `);
43
125
  const spinner = new spinner_js_1.Spinner('');
44
- spinner.start();
126
+ if (!options.debug) {
127
+ spinner.start();
128
+ }
45
129
  let firstToken = true;
46
- for await (const { type, data } of (0, agent_1.complete)({
47
- client,
48
- ...(options.bot ? { botId: options.bot } : { model: options.model }),
49
- messages,
50
- tools,
51
- })) {
52
- if (type === 'token') {
53
- if (firstToken) {
54
- spinner.stop();
55
- firstToken = false;
130
+ sigintCount = 0;
131
+ agentAbort = new AbortController();
132
+ try {
133
+ for await (const item of (0, agent_1.execute)({
134
+ client,
135
+ ...(options.bot
136
+ ? { botId: options.bot }
137
+ : agent?.botId
138
+ ? { botId: agent.botId }
139
+ : { model: options.model ?? agent?.model }),
140
+ ...(agent?.backstory ? { backstory: agent.backstory } : {}),
141
+ ...(options.skillset ?? agent?.skillsetId
142
+ ? { skillsetId: options.skillset ?? agent?.skillsetId }
143
+ : {}),
144
+ ...(options.dataset ?? agent?.datasetId
145
+ ? { datasetId: options.dataset ?? agent?.datasetId }
146
+ : {}),
147
+ messages,
148
+ tools,
149
+ abortSignal: agentAbort.signal,
150
+ ...(skills.length > 0
151
+ ? { extensions: { features: [(0, agent_1.createSkillsFeature)(skills)] } }
152
+ : {}),
153
+ })) {
154
+ const { type, data } = item;
155
+ if (options.debug) {
156
+ process.stderr.write(`${colors.dim}[debug] ${JSON.stringify(item)}${colors.reset}\n`);
157
+ }
158
+ else if (type === 'token') {
159
+ if (firstToken) {
160
+ spinner.stop();
161
+ firstToken = false;
162
+ }
163
+ process.stdout.write(data.token);
164
+ }
165
+ if (type === 'message') {
166
+ messages.push(data);
56
167
  }
57
- process.stdout.write(data.token);
58
- }
59
- else if (type === 'result') {
60
- messages.push({ type: 'bot', text: data.text });
61
168
  }
62
169
  }
63
- spinner.stop();
170
+ catch {
171
+ }
172
+ finally {
173
+ agentAbort = null;
174
+ }
175
+ if (!options.debug) {
176
+ spinner.stop();
177
+ }
64
178
  process.stdout.write('\n');
65
179
  }
66
180
  });
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = exports.solutionSync = exports.solutionDelete = exports.solutionCreate = exports.solutionList = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const input_js_1 = require("../../input.cjs");
6
8
  const output_js_1 = require("../../output.cjs");
7
9
  const index_js_1 = require("../../solution/index.cjs");
8
- const index_js_2 = tslib_1.__importDefault(require("./resource/index.cjs"));
10
+ const index_js_2 = __importDefault(require("./resource/index.cjs"));
9
11
  const commander_1 = require("commander");
10
12
  exports.solutionList = new commander_1.Command()
11
13
  .name('list')
@@ -1,13 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.command = exports.resourceDelete = exports.resourceCreate = void 0;
4
- const tslib_1 = require("tslib");
5
7
  const input_js_1 = require("../../../input.cjs");
6
8
  const output_js_1 = require("../../../output.cjs");
7
9
  const index_js_1 = require("../../../solution/index.cjs");
8
10
  const commander_1 = require("commander");
9
- const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
10
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
11
+ const promises_1 = __importDefault(require("node:fs/promises"));
12
+ const node_path_1 = __importDefault(require("node:path"));
11
13
  exports.resourceCreate = new commander_1.Command()
12
14
  .name('create')
13
15
  .description('Create a new resource')
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Argument = exports.Option = exports.Command = void 0;
4
7
  exports.default = cbk;
5
- const tslib_1 = require("tslib");
6
8
  const color_js_1 = require("./color.cjs");
7
- const index_js_1 = tslib_1.__importDefault(require("./command/agent/index.cjs"));
8
- const index_js_2 = tslib_1.__importDefault(require("./command/api/index.cjs"));
9
- const index_js_3 = tslib_1.__importDefault(require("./command/chat/index.cjs"));
10
- const index_js_4 = tslib_1.__importDefault(require("./command/run/index.cjs"));
11
- const index_js_5 = tslib_1.__importDefault(require("./command/solution/index.cjs"));
9
+ const index_js_1 = __importDefault(require("./command/agent/index.cjs"));
10
+ const index_js_2 = __importDefault(require("./command/api/index.cjs"));
11
+ const index_js_3 = __importDefault(require("./command/chat/index.cjs"));
12
+ const index_js_4 = __importDefault(require("./command/run/index.cjs"));
13
+ const index_js_5 = __importDefault(require("./command/solution/index.cjs"));
12
14
  const commander_1 = require("commander");
13
15
  Object.defineProperty(exports, "Argument", { enumerable: true, get: function () { return commander_1.Argument; } });
14
16
  Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return commander_1.Command; } });
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.confirm = confirm;
4
7
  exports.prompt = prompt;
5
8
  exports.select = select;
6
- const tslib_1 = require("tslib");
7
- const readline_1 = tslib_1.__importDefault(require("readline"));
9
+ const readline_1 = __importDefault(require("readline"));
8
10
  async function confirm(question) {
9
11
  const rl = readline_1.default.createInterface({
10
12
  input: process.stdin,
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.CommandError = exports.config = void 0;
4
7
  exports.print = print;
5
8
  exports.printError = printError;
6
- const tslib_1 = require("tslib");
7
- const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
8
- const util_1 = tslib_1.__importDefault(require("util"));
9
+ const js_yaml_1 = __importDefault(require("js-yaml"));
10
+ const util_1 = __importDefault(require("util"));
9
11
  exports.config = {
10
12
  output: 'yaml',
11
13
  };
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.ArrayBackedObject = exports.Solution = exports.TwilioIntegrationResource = exports.McpServerIntegrationResource = exports.ExtractIntegrationResource = exports.SupportIntegrationResource = exports.TriggerIntegrationResource = exports.EmailIntegrationResource = exports.NotionIntegrationResource = exports.MessengerIntegrationResource = exports.WhatsAppIntegrationResource = exports.TelegramIntegrationResource = exports.DiscordIntegrationResource = exports.SlackIntegrationResource = exports.SitemapIntegrationResource = exports.WidgetIntegrationResource = exports.SkillsetResource = exports.SecretResource = exports.FileResource = exports.DatasetResource = exports.BotResource = exports.BlueprintResource = exports.Resource = exports.SolutionConfigSchema = exports.ResourceConfigSchema = exports.TwilioIntegrationResourceConfigSchema = exports.McpServerIntegrationResourceConfigSchema = exports.ExtractIntegrationResourceConfigSchema = exports.SupportIntegrationResourceConfigSchema = exports.TriggerIntegrationResourceConfigSchema = exports.EmailIntegrationResourceConfigSchema = exports.NotionIntegrationResourceConfigSchema = exports.MessengerIntegrationResourceConfigSchema = exports.WhatsAppIntegrationResourceConfigSchema = exports.TelegramIntegrationResourceConfigSchema = exports.DiscordIntegrationResourceConfigSchema = exports.SlackIntegrationResourceConfigSchema = exports.SitemapIntegrationResourceConfigSchema = exports.WidgetIntegrationResourceConfigSchema = exports.SkillsetResourceConfigSchema = exports.SecretResourceConfigSchema = exports.FileResourceConfigSchema = exports.DatasetResourceConfigSchema = exports.BotResourceConfigSchema = exports.BlueprintResourceConfigSchema = exports.BasicResourceConfigSchema = void 0;
4
7
  exports.getSolutionFolderPath = getSolutionFolderPath;
@@ -7,12 +10,11 @@ exports.getSolutionFilePath = getSolutionFilePath;
7
10
  exports.getSolutionFileNameAndPath = getSolutionFileNameAndPath;
8
11
  exports.replaceEnvVars = replaceEnvVars;
9
12
  exports.getArrayBackedObject = getArrayBackedObject;
10
- const tslib_1 = require("tslib");
11
13
  const env_js_1 = require("../env.cjs");
12
14
  const output_js_1 = require("../output.cjs");
13
- const sdk_1 = tslib_1.__importDefault(require("@chatbotkit/sdk"));
14
- const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
15
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
15
+ const sdk_1 = __importDefault(require("@chatbotkit/sdk"));
16
+ const promises_1 = __importDefault(require("node:fs/promises"));
17
+ const node_path_1 = __importDefault(require("node:path"));
16
18
  const zod_1 = require("zod");
17
19
  function getSolutionFolderPath() {
18
20
  const folderPath = node_path_1.default.join('.chatbotkit', 'solutions');
@@ -368,6 +370,7 @@ exports.McpServerIntegrationResourceConfigSchema = exports.BasicResourceConfigSc
368
370
  meta: zod_1.z.record(zod_1.z.unknown()).optional(),
369
371
  blueprintId: zod_1.z.string().optional(),
370
372
  skillsetId: zod_1.z.string().optional(),
373
+ oAuthConnectionId: zod_1.z.string().optional(),
371
374
  }),
372
375
  });
373
376
  exports.TwilioIntegrationResourceConfigSchema = exports.BasicResourceConfigSchema.extend({
@@ -3,7 +3,7 @@ import { getRUNAS_USERID, getSECRET } from '../../env.js';
3
3
  import { print, printError } from '../../output.js';
4
4
  import { Spinner } from '../../spinner.js';
5
5
  import { getToolNames, getTools } from '../../tools.js';
6
- import { execute } from '@chatbotkit/agent';
6
+ import { createSkillsFeature, execute, loadAgent, loadSkills, } from '@chatbotkit/agent';
7
7
  import { ChatBotKit } from '@chatbotkit/sdk';
8
8
  import { Command, Option } from 'commander';
9
9
  import { existsSync, readFileSync } from 'fs';
@@ -77,15 +77,24 @@ function getClient() {
77
77
  export const command = new Command()
78
78
  .name('agent')
79
79
  .description('Run an agent as a background worker with a prompt')
80
+ .addOption(new Option('-a, --agent <agent>', 'Path to an agent markdown file'))
80
81
  .addOption(new Option('-b, --bot <bot>', 'Bot id'))
81
82
  .addOption(new Option('-m, --model <model>', 'Model name'))
83
+ .addOption(new Option('--skillset <skillset>', 'Skillset id'))
84
+ .addOption(new Option('--dataset <dataset>', 'Dataset id'))
82
85
  .addOption(new Option('-p, --prompt <prompt>', 'The prompt to execute (or path to a file containing the prompt)').makeOptionMandatory())
83
86
  .addOption(new Option('-t, --tools <tools...>', 'Specific tools to enable').choices(getToolNames()))
87
+ .addOption(new Option('-s, --skills <dirs...>', 'Directories to load skills from'))
84
88
  .addOption(new Option('-i, --max-iterations <maxIterations>', 'Maximum number of iterations')
85
- .default(50)
89
+ .default(100)
86
90
  .argParser((value) => parseInt(value, 10)))
91
+ .addOption(new Option('-d, --debug', 'Print raw stream items to stderr'))
87
92
  .action(async (options) => {
88
93
  const client = getClient();
94
+ const agentDef = options.agent ? await loadAgent(options.agent) : null;
95
+ const { skills, close: closeSkills } = options.skills
96
+ ? await loadSkills(options.skills, { watch: false })
97
+ : { skills: [], close: () => { } };
89
98
  const tools = getTools(options.tools);
90
99
  let prompt = options.prompt;
91
100
  {
@@ -106,16 +115,33 @@ export const command = new Command()
106
115
  let hasOutput = false;
107
116
  for await (const { type, data } of execute({
108
117
  client,
109
- ...(options.bot ? { botId: options.bot } : { model: options.model }),
118
+ ...(options.bot
119
+ ? { botId: options.bot }
120
+ : agentDef?.botId
121
+ ? { botId: agentDef.botId }
122
+ : { model: options.model ?? agentDef?.model }),
123
+ ...(agentDef?.backstory ? { backstory: agentDef.backstory } : {}),
124
+ ...(options.skillset ?? agentDef?.skillsetId
125
+ ? { skillsetId: options.skillset ?? agentDef?.skillsetId }
126
+ : {}),
127
+ ...(options.dataset ?? agentDef?.datasetId
128
+ ? { datasetId: options.dataset ?? agentDef?.datasetId }
129
+ : {}),
110
130
  messages: [{ type: 'user', text: prompt }],
111
131
  tools,
112
132
  maxIterations: options.maxIterations,
133
+ ...(skills.length > 0
134
+ ? { extensions: { features: [createSkillsFeature(skills)] } }
135
+ : {}),
113
136
  })) {
137
+ if (options.debug) {
138
+ process.stderr.write(`[debug] ${JSON.stringify({ type, data })}\n`);
139
+ }
114
140
  if (type === 'iteration') {
115
141
  if (isInteractive) {
116
142
  const iterationNum = data.iteration - 1;
117
143
  output.writeLine(formatBlue(`\n╭─ Iteration ${iterationNum} ─╮`));
118
- if (spinner) {
144
+ if (spinner && !options.debug) {
119
145
  spinner.start();
120
146
  }
121
147
  }
@@ -131,7 +157,7 @@ export const command = new Command()
131
157
  status: 'running',
132
158
  args: data.args,
133
159
  });
134
- if (spinner) {
160
+ if (spinner && !options.debug) {
135
161
  spinner.start();
136
162
  }
137
163
  }
@@ -141,7 +167,7 @@ export const command = new Command()
141
167
  status: 'completed',
142
168
  result: data.result,
143
169
  });
144
- if (spinner) {
170
+ if (spinner && !options.debug) {
145
171
  spinner.start();
146
172
  }
147
173
  }
@@ -151,7 +177,7 @@ export const command = new Command()
151
177
  status: 'error',
152
178
  error: data.error,
153
179
  });
154
- if (spinner) {
180
+ if (spinner && !options.debug) {
155
181
  spinner.start();
156
182
  }
157
183
  }
@@ -177,6 +203,7 @@ export const command = new Command()
177
203
  }
178
204
  }
179
205
  }
206
+ closeSkills();
180
207
  if (exitResult) {
181
208
  output.printStructured({
182
209
  status: exitResult.code === 0 ? 'success' : 'failed',
@@ -8,6 +8,7 @@ import file from './file/index.js';
8
8
  import integration from './integration/index.js';
9
9
  import memory from './memory/index.js';
10
10
  import partner from './partner/index.js';
11
+ import platform from './platform/index.js';
11
12
  import secret from './secret/index.js';
12
13
  import skillset from './skillset/index.js';
13
14
  import team from './team/index.js';
@@ -22,6 +23,7 @@ const commands = {
22
23
  integration,
23
24
  memory,
24
25
  partner,
26
+ platform,
25
27
  secret,
26
28
  skillset,
27
29
  team,
@@ -0,0 +1,3 @@
1
+ export const command: Command;
2
+ export default command;
3
+ import { Command } from 'commander';
@@ -0,0 +1,12 @@
1
+ import model from './model/index.js';
2
+ import { Command } from 'commander';
3
+ const commands = {
4
+ model,
5
+ };
6
+ export const command = new Command()
7
+ .name('platform')
8
+ .description('Platform tools for ChatBotKit');
9
+ for (const cmd of Object.values(commands)) {
10
+ command.addCommand(cmd);
11
+ }
12
+ export default command;
@@ -0,0 +1,4 @@
1
+ export const modelList: Command;
2
+ export const command: Command;
3
+ export default command;
4
+ import { Command } from 'commander';
@@ -0,0 +1,39 @@
1
+ import { getRUNAS_USERID, getSECRET } from '../../../../env.js';
2
+ import { print } from '../../../../output.js';
3
+ import { PlatformModelClient } from '@chatbotkit/sdk/platform/model/index.js';
4
+ import { Command } from 'commander';
5
+ function getClient() {
6
+ return new PlatformModelClient({
7
+ secret: getSECRET(),
8
+ runAsUserId: getRUNAS_USERID(),
9
+ });
10
+ }
11
+ export const modelList = new Command()
12
+ .name('list')
13
+ .description('List platform models')
14
+ .option('-s, --stream', 'Stream models')
15
+ .action(async (str, options) => {
16
+ const { stream } = options;
17
+ const client = getClient();
18
+ if (stream) {
19
+ for await (const model of client.list().stream()) {
20
+ print(model);
21
+ }
22
+ }
23
+ else {
24
+ const { items } = await client.list();
25
+ for (const model of items) {
26
+ print(model);
27
+ }
28
+ }
29
+ });
30
+ const commands = {
31
+ list: modelList,
32
+ };
33
+ export const command = new Command()
34
+ .name('model')
35
+ .description('Model tools for ChatBotKit platform');
36
+ for (const cmd of Object.values(commands)) {
37
+ command.addCommand(cmd);
38
+ }
39
+ export default command;
@@ -1,7 +1,7 @@
1
1
  import { getRUNAS_USERID, getSECRET } from '../../env.js';
2
2
  import { Spinner } from '../../spinner.js';
3
3
  import { getToolNames, getTools } from '../../tools.js';
4
- import { complete } from '@chatbotkit/agent';
4
+ import { createSkillsFeature, execute, loadAgent, loadSkills, } from '@chatbotkit/agent';
5
5
  import { ChatBotKit } from '@chatbotkit/sdk';
6
6
  import { Command, Option } from 'commander';
7
7
  import readline from 'readline/promises';
@@ -14,15 +14,29 @@ function getClient() {
14
14
  export const command = new Command()
15
15
  .name('chat')
16
16
  .description('Start a chat session')
17
+ .addOption(new Option('-a, --agent <agent>', 'Path to an agent markdown file'))
17
18
  .addOption(new Option('-b, --bot <bot>', 'Bot id'))
18
19
  .addOption(new Option('-m, --model <model>', 'Model name'))
20
+ .addOption(new Option('--skillset <skillset>', 'Skillset id'))
21
+ .addOption(new Option('--dataset <dataset>', 'Dataset id'))
19
22
  .addOption(new Option('-t, --tools <tools...>', 'Specific tools to enable').choices(getToolNames()))
23
+ .addOption(new Option('-s, --skills <dirs...>', 'Directories to load skills from'))
24
+ .addOption(new Option('-d, --debug', 'Print raw stream items to stderr'))
20
25
  .action(async (options) => {
21
26
  const client = getClient();
27
+ const agent = options.agent ? await loadAgent(options.agent) : null;
28
+ const { skills, close: closeSkills } = options.skills
29
+ ? await loadSkills(options.skills, { watch: true })
30
+ : { skills: [], close: () => { } };
22
31
  const rl = readline.createInterface({
23
32
  input: process.stdin,
24
33
  output: process.stdout,
25
34
  });
35
+ rl.on('close', () => {
36
+ process.stdout.write('\n');
37
+ closeSkills();
38
+ process.exit(0);
39
+ });
26
40
  const messages = [];
27
41
  const tools = getTools(options.tools);
28
42
  const colors = {
@@ -30,33 +44,131 @@ export const command = new Command()
30
44
  bold: '\x1b[1m',
31
45
  cyan: '\x1b[36m',
32
46
  green: '\x1b[32m',
47
+ dim: '\x1b[2m',
48
+ gray: '\x1b[90m',
33
49
  };
50
+ const effectiveBot = options.bot || agent?.botId;
51
+ const effectiveModel = options.model ?? agent?.model;
52
+ const effectiveSkillset = options.skillset ?? agent?.skillsetId;
53
+ const effectiveDataset = options.dataset ?? agent?.datasetId;
54
+ const effectiveSkills = options.skills;
55
+ const metaLines = [];
56
+ if (agent?.name) {
57
+ metaLines.push(`agent ${agent.name}`);
58
+ }
59
+ if (effectiveBot) {
60
+ metaLines.push(`bot ${effectiveBot}`);
61
+ }
62
+ if (effectiveModel) {
63
+ metaLines.push(`model ${effectiveModel}`);
64
+ }
65
+ if (effectiveSkillset) {
66
+ metaLines.push(`skillset ${effectiveSkillset}`);
67
+ }
68
+ if (effectiveDataset) {
69
+ metaLines.push(`dataset ${effectiveDataset}`);
70
+ }
71
+ if (effectiveSkills) {
72
+ metaLines.push(`skills ${effectiveSkills.join(', ')}`);
73
+ }
74
+ if (metaLines.length > 0) {
75
+ process.stdout.write('\n');
76
+ for (const line of metaLines) {
77
+ process.stdout.write(`${colors.gray} ${line}${colors.reset}\n`);
78
+ }
79
+ }
80
+ process.stdout.write(`\n${colors.gray} shortcuts Ctrl+C re-prompt Ā· Ctrl+CƗ2 abort response Ā· Ctrl+D exit${colors.reset}\n`);
81
+ let agentAbort = null;
82
+ let promptAbort = null;
83
+ let sigintCount = 0;
84
+ rl.on('SIGINT', () => {
85
+ if (agentAbort) {
86
+ sigintCount++;
87
+ if (sigintCount === 1) {
88
+ process.stdout.write(`\n ${colors.dim}(Press Ctrl+C again to cancel)${colors.reset}\n`);
89
+ }
90
+ else {
91
+ sigintCount = 0;
92
+ agentAbort.abort();
93
+ }
94
+ }
95
+ else {
96
+ process.stdout.write('^C\n');
97
+ promptAbort?.abort();
98
+ }
99
+ });
34
100
  for (;;) {
35
101
  process.stdout.write('\n');
36
- const user = await rl.question(`${colors.cyan}ā—${colors.reset} ${colors.bold}You${colors.reset}\n\n> `);
37
- messages.push({ type: 'user', text: user });
102
+ promptAbort = new AbortController();
103
+ let text;
104
+ try {
105
+ text = await rl.question(`${colors.cyan}ā—${colors.reset} ${colors.bold}You${colors.reset}\n\n> `, { signal: promptAbort.signal });
106
+ }
107
+ catch {
108
+ continue;
109
+ }
110
+ finally {
111
+ promptAbort = null;
112
+ }
113
+ text = text?.trim();
114
+ if (!text) {
115
+ continue;
116
+ }
117
+ messages.push({ type: 'user', text: text });
38
118
  process.stdout.write(`\n${colors.green}ā—${colors.reset} ${colors.bold}Assistant${colors.reset}\n\n `);
39
119
  const spinner = new Spinner('');
40
- spinner.start();
120
+ if (!options.debug) {
121
+ spinner.start();
122
+ }
41
123
  let firstToken = true;
42
- for await (const { type, data } of complete({
43
- client,
44
- ...(options.bot ? { botId: options.bot } : { model: options.model }),
45
- messages,
46
- tools,
47
- })) {
48
- if (type === 'token') {
49
- if (firstToken) {
50
- spinner.stop();
51
- firstToken = false;
124
+ sigintCount = 0;
125
+ agentAbort = new AbortController();
126
+ try {
127
+ for await (const item of execute({
128
+ client,
129
+ ...(options.bot
130
+ ? { botId: options.bot }
131
+ : agent?.botId
132
+ ? { botId: agent.botId }
133
+ : { model: options.model ?? agent?.model }),
134
+ ...(agent?.backstory ? { backstory: agent.backstory } : {}),
135
+ ...(options.skillset ?? agent?.skillsetId
136
+ ? { skillsetId: options.skillset ?? agent?.skillsetId }
137
+ : {}),
138
+ ...(options.dataset ?? agent?.datasetId
139
+ ? { datasetId: options.dataset ?? agent?.datasetId }
140
+ : {}),
141
+ messages,
142
+ tools,
143
+ abortSignal: agentAbort.signal,
144
+ ...(skills.length > 0
145
+ ? { extensions: { features: [createSkillsFeature(skills)] } }
146
+ : {}),
147
+ })) {
148
+ const { type, data } = item;
149
+ if (options.debug) {
150
+ process.stderr.write(`${colors.dim}[debug] ${JSON.stringify(item)}${colors.reset}\n`);
151
+ }
152
+ else if (type === 'token') {
153
+ if (firstToken) {
154
+ spinner.stop();
155
+ firstToken = false;
156
+ }
157
+ process.stdout.write(data.token);
158
+ }
159
+ if (type === 'message') {
160
+ messages.push(data);
52
161
  }
53
- process.stdout.write(data.token);
54
- }
55
- else if (type === 'result') {
56
- messages.push({ type: 'bot', text: data.text });
57
162
  }
58
163
  }
59
- spinner.stop();
164
+ catch {
165
+ }
166
+ finally {
167
+ agentAbort = null;
168
+ }
169
+ if (!options.debug) {
170
+ spinner.stop();
171
+ }
60
172
  process.stdout.write('\n');
61
173
  }
62
174
  });
@@ -252,7 +252,7 @@ export const ResourceConfigSchema: z.ZodUnion<[ResourceConfigSchemaFor<"blueprin
252
252
  blueprintId?: string;
253
253
  botId?: string;
254
254
  authenticate?: boolean;
255
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly";
255
+ triggerSchedule?: string | null;
256
256
  sessionDuration?: number;
257
257
  maxIterations?: number;
258
258
  maxTime?: number;
@@ -286,6 +286,7 @@ export const ResourceConfigSchema: z.ZodUnion<[ResourceConfigSchemaFor<"blueprin
286
286
  };
287
287
  blueprintId?: string;
288
288
  skillsetId?: string;
289
+ oAuthConnectionId?: string;
289
290
  }>, ResourceConfigSchemaFor<"twilioIntegration", {
290
291
  name?: string;
291
292
  description?: string;
@@ -512,7 +513,7 @@ export const SolutionConfigSchema: z.ZodObject<{
512
513
  blueprintId?: string;
513
514
  botId?: string;
514
515
  authenticate?: boolean;
515
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly";
516
+ triggerSchedule?: string | null;
516
517
  sessionDuration?: number;
517
518
  maxIterations?: number;
518
519
  maxTime?: number;
@@ -546,6 +547,7 @@ export const SolutionConfigSchema: z.ZodObject<{
546
547
  };
547
548
  blueprintId?: string;
548
549
  skillsetId?: string;
550
+ oAuthConnectionId?: string;
549
551
  }>, ResourceConfigSchemaFor<"twilioIntegration", {
550
552
  name?: string;
551
553
  description?: string;
@@ -866,7 +868,7 @@ export const SolutionConfigSchema: z.ZodObject<{
866
868
  blueprintId?: string | undefined;
867
869
  sessionDuration?: number | undefined;
868
870
  authenticate?: boolean | undefined;
869
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly" | undefined;
871
+ triggerSchedule?: string | null | undefined;
870
872
  maxTime?: number | undefined;
871
873
  };
872
874
  slug?: string | undefined;
@@ -913,6 +915,7 @@ export const SolutionConfigSchema: z.ZodObject<{
913
915
  [key: string]: unknown;
914
916
  } | undefined;
915
917
  blueprintId?: string | undefined;
918
+ oAuthConnectionId?: string | undefined;
916
919
  };
917
920
  slug?: string | undefined;
918
921
  id?: string | undefined;
@@ -1241,7 +1244,7 @@ export const SolutionConfigSchema: z.ZodObject<{
1241
1244
  blueprintId?: string | undefined;
1242
1245
  sessionDuration?: number | undefined;
1243
1246
  authenticate?: boolean | undefined;
1244
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly" | undefined;
1247
+ triggerSchedule?: string | null | undefined;
1245
1248
  maxTime?: number | undefined;
1246
1249
  };
1247
1250
  slug?: string | undefined;
@@ -1288,6 +1291,7 @@ export const SolutionConfigSchema: z.ZodObject<{
1288
1291
  [key: string]: unknown;
1289
1292
  } | undefined;
1290
1293
  blueprintId?: string | undefined;
1294
+ oAuthConnectionId?: string | undefined;
1291
1295
  };
1292
1296
  slug?: string | undefined;
1293
1297
  id?: string | undefined;
@@ -1617,7 +1621,7 @@ export class Resource {
1617
1621
  blueprintId?: string | undefined;
1618
1622
  sessionDuration?: number | undefined;
1619
1623
  authenticate?: boolean | undefined;
1620
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly" | undefined;
1624
+ triggerSchedule?: string | null | undefined;
1621
1625
  maxTime?: number | undefined;
1622
1626
  };
1623
1627
  slug?: string | undefined;
@@ -1664,6 +1668,7 @@ export class Resource {
1664
1668
  [key: string]: unknown;
1665
1669
  } | undefined;
1666
1670
  blueprintId?: string | undefined;
1671
+ oAuthConnectionId?: string | undefined;
1667
1672
  };
1668
1673
  slug?: string | undefined;
1669
1674
  id?: string | undefined;
@@ -2073,7 +2078,7 @@ export class Solution {
2073
2078
  blueprintId?: string | undefined;
2074
2079
  sessionDuration?: number | undefined;
2075
2080
  authenticate?: boolean | undefined;
2076
- triggerSchedule?: "never" | "quarterhourly" | "halfhourly" | "hourly" | "daily" | "weekly" | "monthly" | undefined;
2081
+ triggerSchedule?: string | null | undefined;
2077
2082
  maxTime?: number | undefined;
2078
2083
  };
2079
2084
  slug?: string | undefined;
@@ -2120,6 +2125,7 @@ export class Solution {
2120
2125
  [key: string]: unknown;
2121
2126
  } | undefined;
2122
2127
  blueprintId?: string | undefined;
2128
+ oAuthConnectionId?: string | undefined;
2123
2129
  };
2124
2130
  slug?: string | undefined;
2125
2131
  id?: string | undefined;
@@ -358,6 +358,7 @@ export const McpServerIntegrationResourceConfigSchema = BasicResourceConfigSchem
358
358
  meta: z.record(z.unknown()).optional(),
359
359
  blueprintId: z.string().optional(),
360
360
  skillsetId: z.string().optional(),
361
+ oAuthConnectionId: z.string().optional(),
361
362
  }),
362
363
  });
363
364
  export const TwilioIntegrationResourceConfigSchema = BasicResourceConfigSchema.extend({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chatbotkit/cli",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
4
4
  "description": "ChatBotKit command line tools",
5
5
  "license": "ISC",
6
6
  "engines": {
@@ -945,6 +945,66 @@
945
945
  "default": "./dist/cjs/command/api/partner/user/index.cjs"
946
946
  }
947
947
  },
948
+ "./command/api/platform": {
949
+ "import": {
950
+ "types": "./dist/esm/command/api/platform/index.d.ts",
951
+ "default": "./dist/esm/command/api/platform/index.js"
952
+ },
953
+ "require": {
954
+ "types": "./dist/cjs/command/api/platform/index.d.ts",
955
+ "default": "./dist/cjs/command/api/platform/index.cjs"
956
+ }
957
+ },
958
+ "./command/api/platform/index": {
959
+ "import": {
960
+ "types": "./dist/esm/command/api/platform/index.d.ts",
961
+ "default": "./dist/esm/command/api/platform/index.js"
962
+ },
963
+ "require": {
964
+ "types": "./dist/cjs/command/api/platform/index.d.ts",
965
+ "default": "./dist/cjs/command/api/platform/index.cjs"
966
+ }
967
+ },
968
+ "./command/api/platform/index.js": {
969
+ "import": {
970
+ "types": "./dist/esm/command/api/platform/index.d.ts",
971
+ "default": "./dist/esm/command/api/platform/index.js"
972
+ },
973
+ "require": {
974
+ "types": "./dist/cjs/command/api/platform/index.d.ts",
975
+ "default": "./dist/cjs/command/api/platform/index.cjs"
976
+ }
977
+ },
978
+ "./command/api/platform/model": {
979
+ "import": {
980
+ "types": "./dist/esm/command/api/platform/model/index.d.ts",
981
+ "default": "./dist/esm/command/api/platform/model/index.js"
982
+ },
983
+ "require": {
984
+ "types": "./dist/cjs/command/api/platform/model/index.d.ts",
985
+ "default": "./dist/cjs/command/api/platform/model/index.cjs"
986
+ }
987
+ },
988
+ "./command/api/platform/model/index": {
989
+ "import": {
990
+ "types": "./dist/esm/command/api/platform/model/index.d.ts",
991
+ "default": "./dist/esm/command/api/platform/model/index.js"
992
+ },
993
+ "require": {
994
+ "types": "./dist/cjs/command/api/platform/model/index.d.ts",
995
+ "default": "./dist/cjs/command/api/platform/model/index.cjs"
996
+ }
997
+ },
998
+ "./command/api/platform/model/index.js": {
999
+ "import": {
1000
+ "types": "./dist/esm/command/api/platform/model/index.d.ts",
1001
+ "default": "./dist/esm/command/api/platform/model/index.js"
1002
+ },
1003
+ "require": {
1004
+ "types": "./dist/cjs/command/api/platform/model/index.d.ts",
1005
+ "default": "./dist/cjs/command/api/platform/model/index.cjs"
1006
+ }
1007
+ },
948
1008
  "./command/api/secret": {
949
1009
  "import": {
950
1010
  "types": "./dist/esm/command/api/secret/index.d.ts",
@@ -1402,10 +1462,9 @@
1402
1462
  "commander": "^11.1.0",
1403
1463
  "dotenv": "^16.4.5",
1404
1464
  "js-yaml": "^4.1.0",
1405
- "tslib": "^2.6.2",
1406
1465
  "zod": "^3.25.76",
1407
- "@chatbotkit/agent": "1.29.0",
1408
- "@chatbotkit/sdk": "1.29.0"
1466
+ "@chatbotkit/agent": "1.30.0",
1467
+ "@chatbotkit/sdk": "1.30.0"
1409
1468
  },
1410
1469
  "devDependencies": {
1411
1470
  "@types/js-yaml": "^4.0.9",