@chatbotkit/cli 1.29.0 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/command/agent/index.cjs +33 -6
- package/dist/cjs/command/api/index.cjs +8 -6
- package/dist/cjs/command/api/platform/index.cjs +16 -0
- package/dist/cjs/command/api/platform/index.d.ts +3 -0
- package/dist/cjs/command/api/platform/model/index.cjs +42 -0
- package/dist/cjs/command/api/platform/model/index.d.ts +4 -0
- package/dist/cjs/command/chat/index.cjs +130 -18
- package/dist/esm/command/agent/index.js +34 -7
- package/dist/esm/command/api/index.js +2 -0
- package/dist/esm/command/api/platform/index.d.ts +3 -0
- package/dist/esm/command/api/platform/index.js +12 -0
- package/dist/esm/command/api/platform/model/index.d.ts +4 -0
- package/dist/esm/command/api/platform/model/index.js +39 -0
- package/dist/esm/command/chat/index.js +131 -19
- package/package.json +62 -2
|
@@ -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(
|
|
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
|
|
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',
|
|
@@ -12,9 +12,10 @@ const index_js_6 = tslib_1.__importDefault(require("./file/index.cjs"));
|
|
|
12
12
|
const index_js_7 = tslib_1.__importDefault(require("./integration/index.cjs"));
|
|
13
13
|
const index_js_8 = tslib_1.__importDefault(require("./memory/index.cjs"));
|
|
14
14
|
const index_js_9 = tslib_1.__importDefault(require("./partner/index.cjs"));
|
|
15
|
-
const index_js_10 = tslib_1.__importDefault(require("./
|
|
16
|
-
const index_js_11 = tslib_1.__importDefault(require("./
|
|
17
|
-
const index_js_12 = tslib_1.__importDefault(require("./
|
|
15
|
+
const index_js_10 = tslib_1.__importDefault(require("./platform/index.cjs"));
|
|
16
|
+
const index_js_11 = tslib_1.__importDefault(require("./secret/index.cjs"));
|
|
17
|
+
const index_js_12 = tslib_1.__importDefault(require("./skillset/index.cjs"));
|
|
18
|
+
const index_js_13 = tslib_1.__importDefault(require("./team/index.cjs"));
|
|
18
19
|
const commander_1 = require("commander");
|
|
19
20
|
const commands = {
|
|
20
21
|
blueprint: index_js_1.default,
|
|
@@ -26,9 +27,10 @@ const commands = {
|
|
|
26
27
|
integration: index_js_7.default,
|
|
27
28
|
memory: index_js_8.default,
|
|
28
29
|
partner: index_js_9.default,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
platform: index_js_10.default,
|
|
31
|
+
secret: index_js_11.default,
|
|
32
|
+
skillset: index_js_12.default,
|
|
33
|
+
team: index_js_13.default,
|
|
32
34
|
};
|
|
33
35
|
exports.command = new commander_1.Command()
|
|
34
36
|
.name('api')
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const index_js_1 = tslib_1.__importDefault(require("./model/index.cjs"));
|
|
6
|
+
const commander_1 = require("commander");
|
|
7
|
+
const commands = {
|
|
8
|
+
model: index_js_1.default,
|
|
9
|
+
};
|
|
10
|
+
exports.command = new commander_1.Command()
|
|
11
|
+
.name('platform')
|
|
12
|
+
.description('Platform tools for ChatBotKit');
|
|
13
|
+
for (const cmd of Object.values(commands)) {
|
|
14
|
+
exports.command.addCommand(cmd);
|
|
15
|
+
}
|
|
16
|
+
exports.default = exports.command;
|
|
@@ -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;
|
|
@@ -18,15 +18,29 @@ function getClient() {
|
|
|
18
18
|
exports.command = new commander_1.Command()
|
|
19
19
|
.name('chat')
|
|
20
20
|
.description('Start a chat session')
|
|
21
|
+
.addOption(new commander_1.Option('-a, --agent <agent>', 'Path to an agent markdown file'))
|
|
21
22
|
.addOption(new commander_1.Option('-b, --bot <bot>', 'Bot id'))
|
|
22
23
|
.addOption(new commander_1.Option('-m, --model <model>', 'Model name'))
|
|
24
|
+
.addOption(new commander_1.Option('--skillset <skillset>', 'Skillset id'))
|
|
25
|
+
.addOption(new commander_1.Option('--dataset <dataset>', 'Dataset id'))
|
|
23
26
|
.addOption(new commander_1.Option('-t, --tools <tools...>', 'Specific tools to enable').choices((0, tools_js_1.getToolNames)()))
|
|
27
|
+
.addOption(new commander_1.Option('-s, --skills <dirs...>', 'Directories to load skills from'))
|
|
28
|
+
.addOption(new commander_1.Option('-d, --debug', 'Print raw stream items to stderr'))
|
|
24
29
|
.action(async (options) => {
|
|
25
30
|
const client = getClient();
|
|
31
|
+
const agent = options.agent ? await (0, agent_1.loadAgent)(options.agent) : null;
|
|
32
|
+
const { skills, close: closeSkills } = options.skills
|
|
33
|
+
? await (0, agent_1.loadSkills)(options.skills, { watch: true })
|
|
34
|
+
: { skills: [], close: () => { } };
|
|
26
35
|
const rl = promises_1.default.createInterface({
|
|
27
36
|
input: process.stdin,
|
|
28
37
|
output: process.stdout,
|
|
29
38
|
});
|
|
39
|
+
rl.on('close', () => {
|
|
40
|
+
process.stdout.write('\n');
|
|
41
|
+
closeSkills();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
});
|
|
30
44
|
const messages = [];
|
|
31
45
|
const tools = (0, tools_js_1.getTools)(options.tools);
|
|
32
46
|
const colors = {
|
|
@@ -34,33 +48,131 @@ exports.command = new commander_1.Command()
|
|
|
34
48
|
bold: '\x1b[1m',
|
|
35
49
|
cyan: '\x1b[36m',
|
|
36
50
|
green: '\x1b[32m',
|
|
51
|
+
dim: '\x1b[2m',
|
|
52
|
+
gray: '\x1b[90m',
|
|
37
53
|
};
|
|
54
|
+
const effectiveBot = options.bot || agent?.botId;
|
|
55
|
+
const effectiveModel = options.model ?? agent?.model;
|
|
56
|
+
const effectiveSkillset = options.skillset ?? agent?.skillsetId;
|
|
57
|
+
const effectiveDataset = options.dataset ?? agent?.datasetId;
|
|
58
|
+
const effectiveSkills = options.skills;
|
|
59
|
+
const metaLines = [];
|
|
60
|
+
if (agent?.name) {
|
|
61
|
+
metaLines.push(`agent ${agent.name}`);
|
|
62
|
+
}
|
|
63
|
+
if (effectiveBot) {
|
|
64
|
+
metaLines.push(`bot ${effectiveBot}`);
|
|
65
|
+
}
|
|
66
|
+
if (effectiveModel) {
|
|
67
|
+
metaLines.push(`model ${effectiveModel}`);
|
|
68
|
+
}
|
|
69
|
+
if (effectiveSkillset) {
|
|
70
|
+
metaLines.push(`skillset ${effectiveSkillset}`);
|
|
71
|
+
}
|
|
72
|
+
if (effectiveDataset) {
|
|
73
|
+
metaLines.push(`dataset ${effectiveDataset}`);
|
|
74
|
+
}
|
|
75
|
+
if (effectiveSkills) {
|
|
76
|
+
metaLines.push(`skills ${effectiveSkills.join(', ')}`);
|
|
77
|
+
}
|
|
78
|
+
if (metaLines.length > 0) {
|
|
79
|
+
process.stdout.write('\n');
|
|
80
|
+
for (const line of metaLines) {
|
|
81
|
+
process.stdout.write(`${colors.gray} ${line}${colors.reset}\n`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
process.stdout.write(`\n${colors.gray} shortcuts Ctrl+C re-prompt · Ctrl+C×2 abort response · Ctrl+D exit${colors.reset}\n`);
|
|
85
|
+
let agentAbort = null;
|
|
86
|
+
let promptAbort = null;
|
|
87
|
+
let sigintCount = 0;
|
|
88
|
+
rl.on('SIGINT', () => {
|
|
89
|
+
if (agentAbort) {
|
|
90
|
+
sigintCount++;
|
|
91
|
+
if (sigintCount === 1) {
|
|
92
|
+
process.stdout.write(`\n ${colors.dim}(Press Ctrl+C again to cancel)${colors.reset}\n`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
sigintCount = 0;
|
|
96
|
+
agentAbort.abort();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
process.stdout.write('^C\n');
|
|
101
|
+
promptAbort?.abort();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
38
104
|
for (;;) {
|
|
39
105
|
process.stdout.write('\n');
|
|
40
|
-
|
|
41
|
-
|
|
106
|
+
promptAbort = new AbortController();
|
|
107
|
+
let text;
|
|
108
|
+
try {
|
|
109
|
+
text = await rl.question(`${colors.cyan}●${colors.reset} ${colors.bold}You${colors.reset}\n\n> `, { signal: promptAbort.signal });
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
promptAbort = null;
|
|
116
|
+
}
|
|
117
|
+
text = text?.trim();
|
|
118
|
+
if (!text) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
messages.push({ type: 'user', text: text });
|
|
42
122
|
process.stdout.write(`\n${colors.green}●${colors.reset} ${colors.bold}Assistant${colors.reset}\n\n `);
|
|
43
123
|
const spinner = new spinner_js_1.Spinner('');
|
|
44
|
-
|
|
124
|
+
if (!options.debug) {
|
|
125
|
+
spinner.start();
|
|
126
|
+
}
|
|
45
127
|
let firstToken = true;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
128
|
+
sigintCount = 0;
|
|
129
|
+
agentAbort = new AbortController();
|
|
130
|
+
try {
|
|
131
|
+
for await (const item of (0, agent_1.execute)({
|
|
132
|
+
client,
|
|
133
|
+
...(options.bot
|
|
134
|
+
? { botId: options.bot }
|
|
135
|
+
: agent?.botId
|
|
136
|
+
? { botId: agent.botId }
|
|
137
|
+
: { model: options.model ?? agent?.model }),
|
|
138
|
+
...(agent?.backstory ? { backstory: agent.backstory } : {}),
|
|
139
|
+
...(options.skillset ?? agent?.skillsetId
|
|
140
|
+
? { skillsetId: options.skillset ?? agent?.skillsetId }
|
|
141
|
+
: {}),
|
|
142
|
+
...(options.dataset ?? agent?.datasetId
|
|
143
|
+
? { datasetId: options.dataset ?? agent?.datasetId }
|
|
144
|
+
: {}),
|
|
145
|
+
messages,
|
|
146
|
+
tools,
|
|
147
|
+
abortSignal: agentAbort.signal,
|
|
148
|
+
...(skills.length > 0
|
|
149
|
+
? { extensions: { features: [(0, agent_1.createSkillsFeature)(skills)] } }
|
|
150
|
+
: {}),
|
|
151
|
+
})) {
|
|
152
|
+
const { type, data } = item;
|
|
153
|
+
if (options.debug) {
|
|
154
|
+
process.stderr.write(`${colors.dim}[debug] ${JSON.stringify(item)}${colors.reset}\n`);
|
|
155
|
+
}
|
|
156
|
+
else if (type === 'token') {
|
|
157
|
+
if (firstToken) {
|
|
158
|
+
spinner.stop();
|
|
159
|
+
firstToken = false;
|
|
160
|
+
}
|
|
161
|
+
process.stdout.write(data.token);
|
|
162
|
+
}
|
|
163
|
+
if (type === 'message') {
|
|
164
|
+
messages.push(data);
|
|
56
165
|
}
|
|
57
|
-
process.stdout.write(data.token);
|
|
58
|
-
}
|
|
59
|
-
else if (type === 'result') {
|
|
60
|
-
messages.push({ type: 'bot', text: data.text });
|
|
61
166
|
}
|
|
62
167
|
}
|
|
63
|
-
|
|
168
|
+
catch {
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
agentAbort = null;
|
|
172
|
+
}
|
|
173
|
+
if (!options.debug) {
|
|
174
|
+
spinner.stop();
|
|
175
|
+
}
|
|
64
176
|
process.stdout.write('\n');
|
|
65
177
|
}
|
|
66
178
|
});
|
|
@@ -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(
|
|
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
|
|
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,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,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 {
|
|
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
|
-
|
|
37
|
-
|
|
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
|
-
|
|
120
|
+
if (!options.debug) {
|
|
121
|
+
spinner.start();
|
|
122
|
+
}
|
|
41
123
|
let firstToken = true;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatbotkit/cli",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.1",
|
|
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",
|
|
@@ -1404,7 +1464,7 @@
|
|
|
1404
1464
|
"js-yaml": "^4.1.0",
|
|
1405
1465
|
"tslib": "^2.6.2",
|
|
1406
1466
|
"zod": "^3.25.76",
|
|
1407
|
-
"@chatbotkit/agent": "1.29.
|
|
1467
|
+
"@chatbotkit/agent": "1.29.1",
|
|
1408
1468
|
"@chatbotkit/sdk": "1.29.0"
|
|
1409
1469
|
},
|
|
1410
1470
|
"devDependencies": {
|