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.
@@ -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
+ };
@@ -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
+ };