intentiai 0.1.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 +156 -0
- package/bin/intentiai.js +39 -0
- package/commands/auth.js +242 -0
- package/commands/deploy.js +153 -0
- package/commands/docs.js +164 -0
- package/commands/intent.js +251 -0
- package/commands/project.js +193 -0
- package/commands/prompt.js +164 -0
- package/commands/route.js +187 -0
- package/commands/test.js +88 -0
- package/commands/train.js +135 -0
- package/lib/api.js +233 -0
- package/lib/config.js +94 -0
- package/package.json +47 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const ora = require('ora');
|
|
4
|
+
const Table = require('cli-table3');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const api = require('../lib/api');
|
|
8
|
+
const config = require('../lib/config');
|
|
9
|
+
|
|
10
|
+
function requireProject() {
|
|
11
|
+
const projectKey = config.getCurrentProject();
|
|
12
|
+
if (!projectKey) {
|
|
13
|
+
console.error(chalk.red('No project selected'));
|
|
14
|
+
console.log(chalk.gray('Select a project with:'), chalk.cyan('gatellm project select'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
return projectKey;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = (program) => {
|
|
21
|
+
const prompt = program.command('prompt').description('System prompt management');
|
|
22
|
+
|
|
23
|
+
// Set prompt
|
|
24
|
+
prompt
|
|
25
|
+
.command('set')
|
|
26
|
+
.description('Set system prompt for an intent')
|
|
27
|
+
.option('-i, --intent <intent>', 'Intent name')
|
|
28
|
+
.option('-s, --system <message>', 'System message')
|
|
29
|
+
.option('-f, --file <file>', 'Load system message from file')
|
|
30
|
+
.option('-m, --modifier <modifier>', 'High difficulty modifier')
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
requireProject();
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
let { intent, system, file, modifier } = options;
|
|
36
|
+
|
|
37
|
+
// Get intents
|
|
38
|
+
const intents = await api.listIntents();
|
|
39
|
+
|
|
40
|
+
if (intents.length === 0) {
|
|
41
|
+
console.error(chalk.red('No intents found'));
|
|
42
|
+
console.log(chalk.gray('Create an intent first:'), chalk.cyan('gatellm intent add <name>'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Prompt for intent if not provided
|
|
47
|
+
if (!intent) {
|
|
48
|
+
const answers = await inquirer.prompt([
|
|
49
|
+
{
|
|
50
|
+
type: 'list',
|
|
51
|
+
name: 'intent',
|
|
52
|
+
message: 'Select intent:',
|
|
53
|
+
choices: intents.map(i => i.name)
|
|
54
|
+
}
|
|
55
|
+
]);
|
|
56
|
+
intent = answers.intent;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Load from file if specified
|
|
60
|
+
if (file) {
|
|
61
|
+
const filePath = path.resolve(file);
|
|
62
|
+
if (!fs.existsSync(filePath)) {
|
|
63
|
+
console.error(chalk.red('File not found:'), filePath);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
system = fs.readFileSync(filePath, 'utf8');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Prompt for system message if not provided
|
|
70
|
+
if (!system) {
|
|
71
|
+
const answers = await inquirer.prompt([
|
|
72
|
+
{
|
|
73
|
+
type: 'editor',
|
|
74
|
+
name: 'system',
|
|
75
|
+
message: 'Enter system prompt (opens in editor):',
|
|
76
|
+
default: 'You are a helpful AI assistant.'
|
|
77
|
+
}
|
|
78
|
+
]);
|
|
79
|
+
system = answers.system;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const spinner = ora('Setting prompt...').start();
|
|
83
|
+
|
|
84
|
+
await api.setPrompt(intent, system, modifier);
|
|
85
|
+
|
|
86
|
+
spinner.succeed(chalk.green('Prompt set successfully!'));
|
|
87
|
+
console.log(chalk.gray('Intent:'), intent);
|
|
88
|
+
console.log(chalk.gray('System message:'), system.substring(0, 100) + (system.length > 100 ? '...' : ''));
|
|
89
|
+
if (modifier) {
|
|
90
|
+
console.log(chalk.gray('Difficulty modifier:'), modifier);
|
|
91
|
+
}
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error(chalk.red('Failed to set prompt:'), error.message);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Get prompt
|
|
99
|
+
prompt
|
|
100
|
+
.command('get <intent>')
|
|
101
|
+
.description('Get system prompt for an intent')
|
|
102
|
+
.action(async (intent) => {
|
|
103
|
+
requireProject();
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const spinner = ora('Fetching prompt...').start();
|
|
107
|
+
const promptData = await api.getPrompt(intent);
|
|
108
|
+
spinner.stop();
|
|
109
|
+
|
|
110
|
+
console.log(chalk.green('System Prompt:'));
|
|
111
|
+
console.log(chalk.gray('Intent:'), intent);
|
|
112
|
+
console.log(chalk.gray('Message:'));
|
|
113
|
+
console.log(chalk.cyan(promptData.system_message));
|
|
114
|
+
|
|
115
|
+
if (promptData.high_difficulty_modifier) {
|
|
116
|
+
console.log(chalk.gray('\nHigh Difficulty Modifier:'));
|
|
117
|
+
console.log(chalk.yellow(promptData.high_difficulty_modifier));
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error(chalk.red('Failed to get prompt:'), error.message);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// List all prompts
|
|
126
|
+
prompt
|
|
127
|
+
.command('list')
|
|
128
|
+
.alias('ls')
|
|
129
|
+
.description('List all prompts')
|
|
130
|
+
.action(async () => {
|
|
131
|
+
requireProject();
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
const spinner = ora('Fetching prompts...').start();
|
|
135
|
+
const prompts = await api.listPrompts();
|
|
136
|
+
spinner.stop();
|
|
137
|
+
|
|
138
|
+
if (prompts.length === 0) {
|
|
139
|
+
console.log(chalk.yellow('No prompts configured'));
|
|
140
|
+
console.log(chalk.gray('Set one with:'), chalk.cyan('gatellm prompt set'));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const table = new Table({
|
|
145
|
+
head: [chalk.cyan('Intent'), chalk.cyan('System Message'), chalk.cyan('Has Modifier')],
|
|
146
|
+
colWidths: [25, 50, 15]
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
prompts.forEach(p => {
|
|
150
|
+
table.push([
|
|
151
|
+
p.intent_name,
|
|
152
|
+
p.system_message.substring(0, 45) + (p.system_message.length > 45 ? '...' : ''),
|
|
153
|
+
p.high_difficulty_modifier ? chalk.green('Yes') : chalk.gray('No')
|
|
154
|
+
]);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
console.log(table.toString());
|
|
158
|
+
console.log(chalk.gray(`\nTotal: ${prompts.length} prompt(s)`));
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error(chalk.red('Failed to list prompts:'), error.message);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const ora = require('ora');
|
|
4
|
+
const Table = require('cli-table3');
|
|
5
|
+
const api = require('../lib/api');
|
|
6
|
+
const config = require('../lib/config');
|
|
7
|
+
|
|
8
|
+
function requireProject() {
|
|
9
|
+
const projectKey = config.getCurrentProject();
|
|
10
|
+
if (!projectKey) {
|
|
11
|
+
console.error(chalk.red('No project selected'));
|
|
12
|
+
console.log(chalk.gray('Select a project with:'), chalk.cyan('gatellm project select'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
return projectKey;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DIFFICULTY_LEVELS = ['easy', 'medium', 'hard'];
|
|
19
|
+
const PROVIDERS = {
|
|
20
|
+
openai: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-3.5-turbo'],
|
|
21
|
+
groq: ['llama-3.1-8b-instant', 'llama-3.3-70b-versatile', 'mixtral-8x7b-32768'],
|
|
22
|
+
anthropic: ['claude-3-5-sonnet-20241022', 'claude-3-haiku-20240307'],
|
|
23
|
+
gemini: ['gemini-2.0-flash-exp', 'gemini-1.5-flash']
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = (program) => {
|
|
27
|
+
const route = program.command('route').description('Routing rule management');
|
|
28
|
+
|
|
29
|
+
// Add route
|
|
30
|
+
route
|
|
31
|
+
.command('add')
|
|
32
|
+
.description('Add a routing rule')
|
|
33
|
+
.option('-i, --intent <intent>', 'Intent name')
|
|
34
|
+
.option('-d, --difficulty <level>', 'Difficulty level (easy/medium/hard)')
|
|
35
|
+
.option('-m, --model <model>', 'Model name')
|
|
36
|
+
.option('-p, --provider <provider>', 'Provider (openai/groq/anthropic/gemini)')
|
|
37
|
+
.action(async (options) => {
|
|
38
|
+
requireProject();
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
let { intent, difficulty, model, provider } = options;
|
|
42
|
+
|
|
43
|
+
// Interactive prompts for missing options
|
|
44
|
+
const intents = await api.listIntents();
|
|
45
|
+
|
|
46
|
+
if (intents.length === 0) {
|
|
47
|
+
console.error(chalk.red('No intents found'));
|
|
48
|
+
console.log(chalk.gray('Create an intent first:'), chalk.cyan('gatellm intent add <name>'));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!intent || !difficulty || !model || !provider) {
|
|
53
|
+
const answers = await inquirer.prompt([
|
|
54
|
+
{
|
|
55
|
+
type: 'list',
|
|
56
|
+
name: 'intent',
|
|
57
|
+
message: 'Select intent:',
|
|
58
|
+
choices: intents.map(i => i.name),
|
|
59
|
+
when: !intent
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'list',
|
|
63
|
+
name: 'difficulty',
|
|
64
|
+
message: 'Difficulty level:',
|
|
65
|
+
choices: DIFFICULTY_LEVELS,
|
|
66
|
+
when: !difficulty
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'list',
|
|
70
|
+
name: 'provider',
|
|
71
|
+
message: 'Select provider:',
|
|
72
|
+
choices: Object.keys(PROVIDERS),
|
|
73
|
+
when: !provider
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
type: 'list',
|
|
77
|
+
name: 'model',
|
|
78
|
+
message: 'Select model:',
|
|
79
|
+
choices: (answers) => PROVIDERS[answers.provider || provider],
|
|
80
|
+
when: !model
|
|
81
|
+
}
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
intent = intent || answers.intent;
|
|
85
|
+
difficulty = difficulty || answers.difficulty;
|
|
86
|
+
provider = provider || answers.provider;
|
|
87
|
+
model = model || answers.model;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const spinner = ora('Creating routing rule...').start();
|
|
91
|
+
|
|
92
|
+
await api.createRoute(intent, difficulty, model, provider);
|
|
93
|
+
|
|
94
|
+
spinner.succeed(chalk.green('Routing rule created successfully!'));
|
|
95
|
+
console.log(chalk.gray('Intent:'), intent);
|
|
96
|
+
console.log(chalk.gray('Difficulty:'), difficulty);
|
|
97
|
+
console.log(chalk.gray('Model:'), `${provider}/${model}`);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error(chalk.red('Failed to create route:'), error.message);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// List routes
|
|
105
|
+
route
|
|
106
|
+
.command('list')
|
|
107
|
+
.alias('ls')
|
|
108
|
+
.description('List all routing rules')
|
|
109
|
+
.action(async () => {
|
|
110
|
+
requireProject();
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const spinner = ora('Fetching routes...').start();
|
|
114
|
+
|
|
115
|
+
const routes = await api.listRoutes();
|
|
116
|
+
|
|
117
|
+
spinner.stop();
|
|
118
|
+
|
|
119
|
+
if (routes.length === 0) {
|
|
120
|
+
console.log(chalk.yellow('No routing rules found'));
|
|
121
|
+
console.log(chalk.gray('Create one with:'), chalk.cyan('gatellm route add'));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const table = new Table({
|
|
126
|
+
head: [chalk.cyan('ID'), chalk.cyan('Intent'), chalk.cyan('Difficulty'), chalk.cyan('Provider'), chalk.cyan('Model')],
|
|
127
|
+
colWidths: [8, 25, 15, 15, 35]
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
routes.forEach(route => {
|
|
131
|
+
const difficultyColor =
|
|
132
|
+
route.difficulty_level === 'easy' ? chalk.green :
|
|
133
|
+
route.difficulty_level === 'medium' ? chalk.yellow :
|
|
134
|
+
chalk.red;
|
|
135
|
+
|
|
136
|
+
table.push([
|
|
137
|
+
route.id,
|
|
138
|
+
route.intent_name,
|
|
139
|
+
difficultyColor(route.difficulty_level),
|
|
140
|
+
route.provider,
|
|
141
|
+
route.model_name
|
|
142
|
+
]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
console.log(table.toString());
|
|
146
|
+
console.log(chalk.gray(`\nTotal: ${routes.length} route(s)`));
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(chalk.red('Failed to list routes:'), error.message);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Delete route
|
|
154
|
+
route
|
|
155
|
+
.command('delete <id>')
|
|
156
|
+
.alias('rm')
|
|
157
|
+
.description('Delete a routing rule')
|
|
158
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
159
|
+
.action(async (id, options) => {
|
|
160
|
+
requireProject();
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
if (!options.yes) {
|
|
164
|
+
const answers = await inquirer.prompt([
|
|
165
|
+
{
|
|
166
|
+
type: 'confirm',
|
|
167
|
+
name: 'confirm',
|
|
168
|
+
message: `Are you sure you want to delete route ${id}?`,
|
|
169
|
+
default: false
|
|
170
|
+
}
|
|
171
|
+
]);
|
|
172
|
+
|
|
173
|
+
if (!answers.confirm) {
|
|
174
|
+
console.log(chalk.yellow('Cancelled'));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const spinner = ora('Deleting route...').start();
|
|
180
|
+
await api.deleteRoute(id);
|
|
181
|
+
spinner.succeed(chalk.green('Route deleted successfully'));
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error(chalk.red('Failed to delete route:'), error.message);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
package/commands/test.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const ora = require('ora');
|
|
3
|
+
const api = require('../lib/api');
|
|
4
|
+
const config = require('../lib/config');
|
|
5
|
+
|
|
6
|
+
function requireProject() {
|
|
7
|
+
const projectKey = config.getCurrentProject();
|
|
8
|
+
if (!projectKey) {
|
|
9
|
+
console.error(chalk.red('No project selected'));
|
|
10
|
+
console.log(chalk.gray('Select a project with:'), chalk.cyan('gatellm project select'));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
return projectKey;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = (program) => {
|
|
17
|
+
// Test command
|
|
18
|
+
program
|
|
19
|
+
.command('test <query>')
|
|
20
|
+
.description('Test a query against your chatbot')
|
|
21
|
+
.option('-s, --stream', 'Stream the response')
|
|
22
|
+
.action(async (query, options) => {
|
|
23
|
+
requireProject();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const spinner = ora('Processing query...').start();
|
|
27
|
+
|
|
28
|
+
const response = await api.testQuery(query, options.stream);
|
|
29
|
+
|
|
30
|
+
spinner.stop();
|
|
31
|
+
|
|
32
|
+
console.log(chalk.green('\n=== Response ===\n'));
|
|
33
|
+
|
|
34
|
+
if (response.choices && response.choices.length > 0) {
|
|
35
|
+
const message = response.choices[0].message;
|
|
36
|
+
console.log(chalk.cyan(message.content));
|
|
37
|
+
|
|
38
|
+
console.log(chalk.gray('\n=== Metadata ==='));
|
|
39
|
+
|
|
40
|
+
if (response.usage) {
|
|
41
|
+
console.log(chalk.gray('Tokens:'),
|
|
42
|
+
`${response.usage.prompt_tokens} prompt + ${response.usage.completion_tokens} completion = ${response.usage.total_tokens} total`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (response.model) {
|
|
47
|
+
console.log(chalk.gray('Model:'), response.model);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// GateLLM specific metadata
|
|
51
|
+
if (response.gatellm_metadata) {
|
|
52
|
+
console.log(chalk.gray('\n=== GateLLM Routing ==='));
|
|
53
|
+
const meta = response.gatellm_metadata;
|
|
54
|
+
|
|
55
|
+
if (meta.intent) {
|
|
56
|
+
console.log(chalk.gray('Intent:'), chalk.green(meta.intent.name));
|
|
57
|
+
console.log(chalk.gray('Confidence:'), `${(meta.intent.confidence * 100).toFixed(2)}%`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (meta.difficulty) {
|
|
61
|
+
const diffColor =
|
|
62
|
+
meta.difficulty.level === 'easy' ? chalk.green :
|
|
63
|
+
meta.difficulty.level === 'medium' ? chalk.yellow :
|
|
64
|
+
chalk.red;
|
|
65
|
+
|
|
66
|
+
console.log(chalk.gray('Difficulty:'), diffColor(meta.difficulty.level));
|
|
67
|
+
console.log(chalk.gray('Difficulty Score:'), meta.difficulty.score?.toFixed(4) || 'N/A');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (meta.routing) {
|
|
71
|
+
console.log(chalk.gray('Selected Model:'), meta.routing.model);
|
|
72
|
+
console.log(chalk.gray('Provider:'), meta.routing.provider);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (meta.rag_used) {
|
|
76
|
+
console.log(chalk.gray('RAG Context:'), chalk.green('Used'));
|
|
77
|
+
console.log(chalk.gray('Documents Retrieved:'), meta.rag_docs_count || 0);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
console.log(chalk.yellow('No response generated'));
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error(chalk.red('Test failed:'), error.message);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const inquirer = require('inquirer');
|
|
2
|
+
const chalk = require('chalk');
|
|
3
|
+
const ora = require('ora');
|
|
4
|
+
const api = require('../lib/api');
|
|
5
|
+
const config = require('../lib/config');
|
|
6
|
+
|
|
7
|
+
function requireProject() {
|
|
8
|
+
const projectKey = config.getCurrentProject();
|
|
9
|
+
if (!projectKey) {
|
|
10
|
+
console.error(chalk.red('No project selected'));
|
|
11
|
+
console.log(chalk.gray('Select a project with:'), chalk.cyan('gatellm project select'));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
return projectKey;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function sleep(ms) {
|
|
18
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = (program) => {
|
|
22
|
+
const train = program.command('train').description('Model training commands');
|
|
23
|
+
|
|
24
|
+
// Start training
|
|
25
|
+
train
|
|
26
|
+
.command('start')
|
|
27
|
+
.description('Start training the model')
|
|
28
|
+
.option('-i, --intents <intents...>', 'Specific intents to train (default: all)')
|
|
29
|
+
.option('-n, --samples <number>', 'Number of samples per intent', '100')
|
|
30
|
+
.option('-w, --watch', 'Watch training progress')
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
requireProject();
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const numSamples = parseInt(options.samples);
|
|
36
|
+
|
|
37
|
+
const spinner = ora('Starting training...').start();
|
|
38
|
+
|
|
39
|
+
const response = await api.startTraining(options.intents, numSamples);
|
|
40
|
+
|
|
41
|
+
spinner.succeed(chalk.green('Training started!'));
|
|
42
|
+
console.log(chalk.gray('Task ID:'), chalk.cyan(response.task_id));
|
|
43
|
+
console.log(chalk.gray('Status:'), response.status);
|
|
44
|
+
|
|
45
|
+
if (options.watch) {
|
|
46
|
+
console.log(chalk.gray('\nWatching training progress... (Ctrl+C to stop watching)\n'));
|
|
47
|
+
|
|
48
|
+
const progressSpinner = ora('Training in progress...').start();
|
|
49
|
+
|
|
50
|
+
let completed = false;
|
|
51
|
+
|
|
52
|
+
while (!completed) {
|
|
53
|
+
await sleep(3000); // Poll every 3 seconds
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const status = await api.getTrainingStatus(response.task_id);
|
|
57
|
+
|
|
58
|
+
if (status.status === 'completed') {
|
|
59
|
+
progressSpinner.succeed(chalk.green('Training completed!'));
|
|
60
|
+
completed = true;
|
|
61
|
+
|
|
62
|
+
if (status.result) {
|
|
63
|
+
console.log(chalk.gray('\nResults:'));
|
|
64
|
+
console.log(chalk.gray(' Intents trained:'), status.result.intents_trained || 'N/A');
|
|
65
|
+
console.log(chalk.gray(' Samples generated:'), status.result.samples_generated || 'N/A');
|
|
66
|
+
console.log(chalk.gray(' Model path:'), status.result.model_path || 'N/A');
|
|
67
|
+
}
|
|
68
|
+
} else if (status.status === 'failed') {
|
|
69
|
+
progressSpinner.fail(chalk.red('Training failed'));
|
|
70
|
+
completed = true;
|
|
71
|
+
|
|
72
|
+
if (status.error) {
|
|
73
|
+
console.error(chalk.red('Error:'), status.error);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
// Update progress message
|
|
77
|
+
progressSpinner.text = `Training in progress... (${status.status})`;
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
progressSpinner.warn(chalk.yellow('Could not fetch status'));
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
console.log(chalk.gray('\nCheck training status with:'));
|
|
86
|
+
console.log(chalk.cyan(` gatellm train status ${response.task_id}`));
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(chalk.red('Failed to start training:'), error.message);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Check training status
|
|
95
|
+
train
|
|
96
|
+
.command('status <taskId>')
|
|
97
|
+
.description('Check training status')
|
|
98
|
+
.action(async (taskId) => {
|
|
99
|
+
requireProject();
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
const spinner = ora('Fetching training status...').start();
|
|
103
|
+
|
|
104
|
+
const status = await api.getTrainingStatus(taskId);
|
|
105
|
+
|
|
106
|
+
spinner.stop();
|
|
107
|
+
|
|
108
|
+
console.log(chalk.green('Training Status:'));
|
|
109
|
+
console.log(chalk.gray(' Task ID:'), taskId);
|
|
110
|
+
console.log(chalk.gray(' Status:'),
|
|
111
|
+
status.status === 'completed' ? chalk.green(status.status) :
|
|
112
|
+
status.status === 'failed' ? chalk.red(status.status) :
|
|
113
|
+
chalk.yellow(status.status)
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
if (status.status === 'completed' && status.result) {
|
|
117
|
+
console.log(chalk.gray('\nResults:'));
|
|
118
|
+
console.log(chalk.gray(' Intents trained:'), status.result.intents_trained || 'N/A');
|
|
119
|
+
console.log(chalk.gray(' Samples generated:'), status.result.samples_generated || 'N/A');
|
|
120
|
+
console.log(chalk.gray(' Model path:'), status.result.model_path || 'N/A');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (status.status === 'failed' && status.error) {
|
|
124
|
+
console.log(chalk.red('\nError:'), status.error);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (status.progress) {
|
|
128
|
+
console.log(chalk.gray('\nProgress:'), `${status.progress}%`);
|
|
129
|
+
}
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(chalk.red('Failed to get training status:'), error.message);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
};
|