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
package/lib/api.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
const FormData = require('form-data');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const config = require('./config');
|
|
5
|
+
|
|
6
|
+
// Create axios instance
|
|
7
|
+
function createClient() {
|
|
8
|
+
const client = axios.create({
|
|
9
|
+
baseURL: config.getApiUrl(),
|
|
10
|
+
timeout: 30000,
|
|
11
|
+
headers: {
|
|
12
|
+
'Content-Type': 'application/json'
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Add auth header if available
|
|
17
|
+
const apiKey = config.getApiKey();
|
|
18
|
+
if (apiKey) {
|
|
19
|
+
client.defaults.headers.common['Authorization'] = `Bearer ${apiKey}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return client;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Auth endpoints
|
|
26
|
+
async function login(username, password) {
|
|
27
|
+
const client = createClient();
|
|
28
|
+
const formData = new URLSearchParams();
|
|
29
|
+
formData.append('username', username);
|
|
30
|
+
formData.append('password', password);
|
|
31
|
+
|
|
32
|
+
const response = await client.post('/auth/login', formData, {
|
|
33
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
|
34
|
+
});
|
|
35
|
+
return response.data;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function register(username, email, password) {
|
|
39
|
+
const client = createClient();
|
|
40
|
+
const response = await client.post('/auth/register', {
|
|
41
|
+
username,
|
|
42
|
+
email,
|
|
43
|
+
password
|
|
44
|
+
});
|
|
45
|
+
return response.data;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Project endpoints
|
|
49
|
+
async function createProject(name, description = '') {
|
|
50
|
+
const client = createClient();
|
|
51
|
+
const response = await client.post('/projects', { name, description });
|
|
52
|
+
return response.data;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function listProjects() {
|
|
56
|
+
const client = createClient();
|
|
57
|
+
const response = await client.get('/projects');
|
|
58
|
+
return response.data;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function getProject(projectId) {
|
|
62
|
+
const client = createClient();
|
|
63
|
+
const response = await client.get(`/projects/${projectId}`);
|
|
64
|
+
return response.data;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function deleteProject(projectId) {
|
|
68
|
+
const client = createClient();
|
|
69
|
+
const response = await client.delete(`/projects/${projectId}`);
|
|
70
|
+
return response.data;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Intent endpoints
|
|
74
|
+
async function addIntent(projectId, name, description, examples = []) {
|
|
75
|
+
const client = createClient();
|
|
76
|
+
const response = await client.post(`/projects/${projectId}/intents`, {
|
|
77
|
+
name,
|
|
78
|
+
description,
|
|
79
|
+
examples
|
|
80
|
+
});
|
|
81
|
+
return response.data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function listIntents(projectId) {
|
|
85
|
+
const client = createClient();
|
|
86
|
+
const response = await client.get(`/projects/${projectId}/intents`);
|
|
87
|
+
return response.data;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function deleteIntent(projectId, intentId) {
|
|
91
|
+
const client = createClient();
|
|
92
|
+
const response = await client.delete(`/projects/${projectId}/intents/${intentId}`);
|
|
93
|
+
return response.data;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Routing endpoints
|
|
97
|
+
async function addRoute(projectId, intentName, difficulty, provider, model) {
|
|
98
|
+
const client = createClient();
|
|
99
|
+
const response = await client.post(`/projects/${projectId}/routing-rules`, {
|
|
100
|
+
intent_name: intentName,
|
|
101
|
+
difficulty,
|
|
102
|
+
provider,
|
|
103
|
+
model
|
|
104
|
+
});
|
|
105
|
+
return response.data;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function listRoutes(projectId) {
|
|
109
|
+
const client = createClient();
|
|
110
|
+
const response = await client.get(`/projects/${projectId}/routing-rules`);
|
|
111
|
+
return response.data;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function deleteRoute(routeId) {
|
|
115
|
+
const client = createClient();
|
|
116
|
+
const response = await client.delete(`/routing-rules/${routeId}`);
|
|
117
|
+
return response.data;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Prompt endpoints
|
|
121
|
+
async function setPrompt(projectId, intentId, systemPrompt, difficulty = null) {
|
|
122
|
+
const client = createClient();
|
|
123
|
+
const response = await client.post(`/projects/${projectId}/intents/${intentId}/prompts`, {
|
|
124
|
+
system_prompt: systemPrompt,
|
|
125
|
+
difficulty
|
|
126
|
+
});
|
|
127
|
+
return response.data;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function getPrompts(projectId, intentId) {
|
|
131
|
+
const client = createClient();
|
|
132
|
+
const response = await client.get(`/projects/${projectId}/intents/${intentId}/prompts`);
|
|
133
|
+
return response.data;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Document endpoints
|
|
137
|
+
async function uploadDocument(projectId, filePath) {
|
|
138
|
+
const client = createClient();
|
|
139
|
+
const formData = new FormData();
|
|
140
|
+
formData.append('file', fs.createReadStream(filePath));
|
|
141
|
+
|
|
142
|
+
const response = await client.post(`/projects/${projectId}/documents`, formData, {
|
|
143
|
+
headers: formData.getHeaders()
|
|
144
|
+
});
|
|
145
|
+
return response.data;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function listDocuments(projectId) {
|
|
149
|
+
const client = createClient();
|
|
150
|
+
const response = await client.get(`/projects/${projectId}/documents`);
|
|
151
|
+
return response.data;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function deleteDocument(documentId) {
|
|
155
|
+
const client = createClient();
|
|
156
|
+
const response = await client.delete(`/documents/${documentId}`);
|
|
157
|
+
return response.data;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Training endpoints
|
|
161
|
+
async function startTraining(projectId) {
|
|
162
|
+
const client = createClient();
|
|
163
|
+
const response = await client.post(`/projects/${projectId}/train`);
|
|
164
|
+
return response.data;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function getTrainingStatus(projectId) {
|
|
168
|
+
const client = createClient();
|
|
169
|
+
const response = await client.get(`/projects/${projectId}/train/status`);
|
|
170
|
+
return response.data;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Test/Chat endpoints
|
|
174
|
+
async function testQuery(projectKey, message, sessionId = null) {
|
|
175
|
+
const client = createClient();
|
|
176
|
+
const response = await client.post('/v1/chat/completions', {
|
|
177
|
+
messages: [{ role: 'user', content: message }],
|
|
178
|
+
session_id: sessionId
|
|
179
|
+
}, {
|
|
180
|
+
headers: { 'X-Project-Key': projectKey }
|
|
181
|
+
});
|
|
182
|
+
return response.data;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Deploy endpoint
|
|
186
|
+
async function getProjectKey(projectId) {
|
|
187
|
+
const client = createClient();
|
|
188
|
+
const response = await client.get(`/projects/${projectId}`);
|
|
189
|
+
return response.data.project_key;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Device auth endpoints (for browser-based login)
|
|
193
|
+
async function checkDeviceAuth(deviceCode) {
|
|
194
|
+
const client = createClient();
|
|
195
|
+
const response = await client.get(`/auth/device/${deviceCode}`);
|
|
196
|
+
return response.data;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function completeDeviceAuth(deviceCode, accessToken, username, email) {
|
|
200
|
+
const client = createClient();
|
|
201
|
+
const response = await client.post(`/auth/device/${deviceCode}`, {
|
|
202
|
+
access_token: accessToken,
|
|
203
|
+
username,
|
|
204
|
+
email
|
|
205
|
+
});
|
|
206
|
+
return response.data;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
module.exports = {
|
|
210
|
+
login,
|
|
211
|
+
register,
|
|
212
|
+
createProject,
|
|
213
|
+
listProjects,
|
|
214
|
+
getProject,
|
|
215
|
+
deleteProject,
|
|
216
|
+
addIntent,
|
|
217
|
+
listIntents,
|
|
218
|
+
deleteIntent,
|
|
219
|
+
addRoute,
|
|
220
|
+
listRoutes,
|
|
221
|
+
deleteRoute,
|
|
222
|
+
setPrompt,
|
|
223
|
+
getPrompts,
|
|
224
|
+
uploadDocument,
|
|
225
|
+
listDocuments,
|
|
226
|
+
deleteDocument,
|
|
227
|
+
startTraining,
|
|
228
|
+
getTrainingStatus,
|
|
229
|
+
testQuery,
|
|
230
|
+
getProjectKey,
|
|
231
|
+
checkDeviceAuth,
|
|
232
|
+
completeDeviceAuth
|
|
233
|
+
};
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), '.intentiai');
|
|
6
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
7
|
+
|
|
8
|
+
// Ensure config directory exists
|
|
9
|
+
function ensureConfigDir() {
|
|
10
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
11
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Load config
|
|
16
|
+
function loadConfig() {
|
|
17
|
+
ensureConfigDir();
|
|
18
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
21
|
+
} catch (e) {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Save config
|
|
29
|
+
function saveConfig(config) {
|
|
30
|
+
ensureConfigDir();
|
|
31
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Get API URL
|
|
35
|
+
function getApiUrl() {
|
|
36
|
+
return process.env.INTENTIAI_API_URL || 'https://api.intentiai.com';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get Web URL (frontend)
|
|
40
|
+
function getWebUrl() {
|
|
41
|
+
return process.env.INTENTIAI_WEB_URL || 'https://www.intentiai.com';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Auth functions
|
|
45
|
+
function setAuth(username, apiKey) {
|
|
46
|
+
const config = loadConfig();
|
|
47
|
+
config.username = username;
|
|
48
|
+
config.apiKey = apiKey;
|
|
49
|
+
saveConfig(config);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getUsername() {
|
|
53
|
+
return loadConfig().username;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getApiKey() {
|
|
57
|
+
return loadConfig().apiKey;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function clearAuth() {
|
|
61
|
+
const config = loadConfig();
|
|
62
|
+
delete config.username;
|
|
63
|
+
delete config.apiKey;
|
|
64
|
+
saveConfig(config);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Project functions
|
|
68
|
+
function setCurrentProject(projectId, projectName) {
|
|
69
|
+
const config = loadConfig();
|
|
70
|
+
config.currentProject = { id: projectId, name: projectName };
|
|
71
|
+
saveConfig(config);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getCurrentProject() {
|
|
75
|
+
return loadConfig().currentProject;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function clearCurrentProject() {
|
|
79
|
+
const config = loadConfig();
|
|
80
|
+
delete config.currentProject;
|
|
81
|
+
saveConfig(config);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = {
|
|
85
|
+
getApiUrl,
|
|
86
|
+
getWebUrl,
|
|
87
|
+
setAuth,
|
|
88
|
+
getUsername,
|
|
89
|
+
getApiKey,
|
|
90
|
+
clearAuth,
|
|
91
|
+
setCurrentProject,
|
|
92
|
+
getCurrentProject,
|
|
93
|
+
clearCurrentProject
|
|
94
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "intentiai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "IntentiAI CLI - Intent-aware LLM routing that saves 60-90% on API costs",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"intentiai": "./bin/intentiai.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"llm",
|
|
14
|
+
"ai",
|
|
15
|
+
"chatbot",
|
|
16
|
+
"routing",
|
|
17
|
+
"openai",
|
|
18
|
+
"claude",
|
|
19
|
+
"groq",
|
|
20
|
+
"gpt-4",
|
|
21
|
+
"intent-classification",
|
|
22
|
+
"cost-optimization"
|
|
23
|
+
],
|
|
24
|
+
"author": "Nishan Poudel <happynishan30@gmail.com>",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"homepage": "https://www.intentiai.com",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/intentiai/intentiai"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/intentiai/intentiai/issues"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"commander": "^11.1.0",
|
|
36
|
+
"axios": "^1.6.2",
|
|
37
|
+
"chalk": "^4.1.2",
|
|
38
|
+
"ora": "^5.4.1",
|
|
39
|
+
"inquirer": "^8.2.5",
|
|
40
|
+
"dotenv": "^16.3.1",
|
|
41
|
+
"cli-table3": "^0.6.3",
|
|
42
|
+
"form-data": "^4.0.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=14.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|