@mmmbuto/nexuscli 0.7.0 → 0.7.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/frontend/dist/assets/{index-DuqGKSR-.js → index-DgHku52j.js} +1704 -1704
- package/frontend/dist/index.html +1 -1
- package/lib/cli/model.js +38 -17
- package/lib/config/models.js +157 -0
- package/lib/server/routes/config.js +18 -3
- package/lib/server/routes/models.js +5 -152
- package/package.json +1 -1
package/frontend/dist/index.html
CHANGED
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
|
|
60
60
|
<!-- Prevent Scaling on iOS -->
|
|
61
61
|
<meta name="format-detection" content="telephone=no" />
|
|
62
|
-
<script type="module" crossorigin src="/assets/index-
|
|
62
|
+
<script type="module" crossorigin src="/assets/index-DgHku52j.js"></script>
|
|
63
63
|
<link rel="stylesheet" crossorigin href="/assets/index-Bn_l1e6e.css">
|
|
64
64
|
</head>
|
|
65
65
|
<body>
|
package/lib/cli/model.js
CHANGED
|
@@ -4,9 +4,38 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const chalk = require('chalk');
|
|
7
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
getConfig,
|
|
9
|
+
setConfigValue,
|
|
10
|
+
isInitialized
|
|
11
|
+
} = require('../config/manager');
|
|
12
|
+
const {
|
|
13
|
+
getCliTools,
|
|
14
|
+
isValidModelId,
|
|
15
|
+
getAllModels
|
|
16
|
+
} = require('../config/models');
|
|
8
17
|
|
|
9
18
|
async function modelCommand(modelId) {
|
|
19
|
+
if (!isInitialized()) {
|
|
20
|
+
console.log(chalk.red('NexusCLI non è inizializzato.'));
|
|
21
|
+
console.log(chalk.yellow('Esegui prima: nexuscli init'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cliTools = getCliTools();
|
|
26
|
+
const allModels = getAllModels();
|
|
27
|
+
|
|
28
|
+
const printAvailableModels = () => {
|
|
29
|
+
console.log(chalk.bold('\nModelli disponibili:'));
|
|
30
|
+
for (const [key, cli] of Object.entries(cliTools)) {
|
|
31
|
+
console.log(chalk.dim(`${cli.name}:`));
|
|
32
|
+
for (const model of cli.models || []) {
|
|
33
|
+
const label = model.label || model.name;
|
|
34
|
+
const defaultTag = model.default ? chalk.green(' (default)') : '';
|
|
35
|
+
console.log(` ${model.id} ${chalk.gray(`- ${label}`)}${defaultTag}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
10
39
|
|
|
11
40
|
// If no model specified, show current default
|
|
12
41
|
if (!modelId) {
|
|
@@ -21,23 +50,15 @@ async function modelCommand(modelId) {
|
|
|
21
50
|
console.log(chalk.dim('Usage: nexuscli model <model-id>'));
|
|
22
51
|
}
|
|
23
52
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log(' claude-opus-4-5-20250514');
|
|
29
|
-
console.log(' claude-3-7-sonnet-20250219');
|
|
30
|
-
console.log(' claude-haiku-4-5-20250514');
|
|
31
|
-
console.log(chalk.dim('OpenAI (Codex):'));
|
|
32
|
-
console.log(' gpt-5.1-codex-max');
|
|
33
|
-
console.log(' gpt-5.1');
|
|
34
|
-
console.log(' o1-preview');
|
|
35
|
-
console.log(' o1-mini');
|
|
36
|
-
console.log(chalk.dim('Google (Gemini):'));
|
|
37
|
-
console.log(' gemini-3-pro-preview');
|
|
38
|
-
console.log(' gemini-2-5-pro-exp-0827');
|
|
39
|
-
console.log(' gemini-2-0-flash-exp');
|
|
53
|
+
printAvailableModels();
|
|
54
|
+
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
40
57
|
|
|
58
|
+
if (!isValidModelId(modelId)) {
|
|
59
|
+
console.log(chalk.red(`✗ Modello non valido: ${modelId}`));
|
|
60
|
+
printAvailableModels();
|
|
61
|
+
process.exitCode = 1;
|
|
41
62
|
return;
|
|
42
63
|
}
|
|
43
64
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared model catalog for NexusCLI (backend + CLI)
|
|
3
|
+
* Keep this as the single source of truth for available engines/models.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns the available CLI tools and their models.
|
|
8
|
+
* Shape is consumed by API, frontend, and CLI commands.
|
|
9
|
+
*/
|
|
10
|
+
function getCliTools() {
|
|
11
|
+
return {
|
|
12
|
+
// ============================================================
|
|
13
|
+
// CLAUDE - Anthropic Claude Code CLI
|
|
14
|
+
// ============================================================
|
|
15
|
+
'claude': {
|
|
16
|
+
name: 'Claude Code',
|
|
17
|
+
icon: 'Terminal',
|
|
18
|
+
enabled: true,
|
|
19
|
+
endpoint: '/api/v1/chat',
|
|
20
|
+
thinkModes: ['think', 'no-think'],
|
|
21
|
+
defaultThinkMode: 'think',
|
|
22
|
+
models: [
|
|
23
|
+
// === Claude Opus 4.5 (Most Intelligent) ===
|
|
24
|
+
{
|
|
25
|
+
id: 'claude-opus-4-5-20251101',
|
|
26
|
+
name: 'claude-opus-4-5-20251101',
|
|
27
|
+
label: 'Opus 4.5',
|
|
28
|
+
description: '🧠 Most Intelligent',
|
|
29
|
+
category: 'claude'
|
|
30
|
+
},
|
|
31
|
+
// === Claude Sonnet 4.5 (Best Balance) ===
|
|
32
|
+
{
|
|
33
|
+
id: 'claude-sonnet-4-5-20250929',
|
|
34
|
+
name: 'claude-sonnet-4-5-20250929',
|
|
35
|
+
label: 'Sonnet 4.5',
|
|
36
|
+
description: '🧠 Extended Thinking (default)',
|
|
37
|
+
category: 'claude',
|
|
38
|
+
default: true
|
|
39
|
+
},
|
|
40
|
+
// === Claude Haiku 4.5 (Fastest) ===
|
|
41
|
+
{
|
|
42
|
+
id: 'claude-haiku-4-5-20251001',
|
|
43
|
+
name: 'claude-haiku-4-5-20251001',
|
|
44
|
+
label: 'Haiku 4.5',
|
|
45
|
+
description: '⚡ Fast & Efficient',
|
|
46
|
+
category: 'claude'
|
|
47
|
+
},
|
|
48
|
+
// === DeepSeek (Alternative Models) ===
|
|
49
|
+
{
|
|
50
|
+
id: 'deepseek-reasoner',
|
|
51
|
+
name: 'deepseek-reasoner',
|
|
52
|
+
label: 'DeepSeek Reasoner',
|
|
53
|
+
description: '🧠 Deep Reasoning',
|
|
54
|
+
category: 'claude'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'deepseek-chat',
|
|
58
|
+
name: 'deepseek-chat',
|
|
59
|
+
label: 'DeepSeek Chat',
|
|
60
|
+
description: '💬 Fast Chat',
|
|
61
|
+
category: 'claude'
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
// ============================================================
|
|
67
|
+
// CODEX - OpenAI Codex CLI
|
|
68
|
+
// ============================================================
|
|
69
|
+
'codex': {
|
|
70
|
+
name: 'Codex',
|
|
71
|
+
icon: 'Code2',
|
|
72
|
+
enabled: true,
|
|
73
|
+
endpoint: '/api/v1/codex',
|
|
74
|
+
models: [
|
|
75
|
+
{
|
|
76
|
+
id: 'gpt-5.1-codex-max',
|
|
77
|
+
name: 'gpt-5.1-codex-max',
|
|
78
|
+
label: 'GPT-5.1 Codex Max',
|
|
79
|
+
description: '💎 Extra High reasoning (best)',
|
|
80
|
+
category: 'codex',
|
|
81
|
+
reasoningEfforts: ['low', 'medium', 'high', 'xhigh'],
|
|
82
|
+
defaultReasoning: 'xhigh',
|
|
83
|
+
default: true
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'gpt-5.1-codex',
|
|
87
|
+
name: 'gpt-5.1-codex',
|
|
88
|
+
label: 'GPT-5.1 Codex',
|
|
89
|
+
description: '🧠 High reasoning',
|
|
90
|
+
category: 'codex',
|
|
91
|
+
reasoningEfforts: ['low', 'medium', 'high'],
|
|
92
|
+
defaultReasoning: 'high'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 'gpt-5.1-codex-mini',
|
|
96
|
+
name: 'gpt-5.1-codex-mini',
|
|
97
|
+
label: 'GPT-5.1 Codex Mini',
|
|
98
|
+
description: '⚡ Compact & Fast',
|
|
99
|
+
category: 'codex',
|
|
100
|
+
reasoningEfforts: ['medium', 'high'],
|
|
101
|
+
defaultReasoning: 'high'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'gpt-5.1',
|
|
105
|
+
name: 'gpt-5.1',
|
|
106
|
+
label: 'GPT-5.1',
|
|
107
|
+
description: '🧠 General Purpose',
|
|
108
|
+
category: 'codex',
|
|
109
|
+
reasoningEfforts: ['low', 'medium', 'high'],
|
|
110
|
+
defaultReasoning: 'high'
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
// ============================================================
|
|
116
|
+
// GEMINI - Google Gemini CLI
|
|
117
|
+
// ============================================================
|
|
118
|
+
'gemini': {
|
|
119
|
+
name: 'Gemini',
|
|
120
|
+
icon: 'Sparkles',
|
|
121
|
+
enabled: true,
|
|
122
|
+
endpoint: '/api/v1/gemini',
|
|
123
|
+
models: [
|
|
124
|
+
{
|
|
125
|
+
id: 'gemini-3-pro-preview',
|
|
126
|
+
name: 'gemini-3-pro-preview',
|
|
127
|
+
label: 'Gemini 3 Pro',
|
|
128
|
+
description: '🚀 Latest Preview',
|
|
129
|
+
category: 'gemini',
|
|
130
|
+
default: true
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function getAllModels() {
|
|
138
|
+
return Object.values(getCliTools()).flatMap(cli => cli.models || []);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function isValidModelId(modelId) {
|
|
142
|
+
if (!modelId) return false;
|
|
143
|
+
return getAllModels().some(m => m.id === modelId);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function getDefaultModelId() {
|
|
147
|
+
const models = getAllModels();
|
|
148
|
+
const withDefault = models.find(m => m.default);
|
|
149
|
+
return withDefault ? withDefault.id : (models[0]?.id || null);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
module.exports = {
|
|
153
|
+
getCliTools,
|
|
154
|
+
getAllModels,
|
|
155
|
+
isValidModelId,
|
|
156
|
+
getDefaultModelId
|
|
157
|
+
};
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
const express = require('express');
|
|
7
7
|
const router = express.Router();
|
|
8
8
|
const { getConfig } = require('../../config/manager');
|
|
9
|
+
const {
|
|
10
|
+
isValidModelId,
|
|
11
|
+
getDefaultModelId
|
|
12
|
+
} = require('../../config/models');
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* GET /api/v1/config
|
|
@@ -15,10 +19,21 @@ router.get('/', (req, res) => {
|
|
|
15
19
|
try {
|
|
16
20
|
const config = getConfig();
|
|
17
21
|
|
|
22
|
+
const preferred = config.preferences?.defaultModel || null;
|
|
23
|
+
let defaultModel = preferred;
|
|
24
|
+
|
|
25
|
+
// Sanitize preferred model; fallback to catalog default to avoid broken UI
|
|
26
|
+
if (defaultModel && !isValidModelId(defaultModel)) {
|
|
27
|
+
console.warn('[Config API] Invalid defaultModel in config:', defaultModel);
|
|
28
|
+
defaultModel = null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!defaultModel) {
|
|
32
|
+
defaultModel = getDefaultModelId();
|
|
33
|
+
}
|
|
34
|
+
|
|
18
35
|
// Return only preferences (not sensitive data like auth)
|
|
19
|
-
const preferences = {
|
|
20
|
-
defaultModel: config.preferences?.defaultModel || null
|
|
21
|
-
};
|
|
36
|
+
const preferences = { defaultModel };
|
|
22
37
|
|
|
23
38
|
res.json(preferences);
|
|
24
39
|
} catch (error) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const router = express.Router();
|
|
3
|
+
const { getCliTools } = require('../../config/models');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* GET /api/v1/models
|
|
@@ -12,131 +13,7 @@ const router = express.Router();
|
|
|
12
13
|
*/
|
|
13
14
|
router.get('/', (req, res) => {
|
|
14
15
|
try {
|
|
15
|
-
const cliTools =
|
|
16
|
-
// ============================================================
|
|
17
|
-
// CLAUDE - Anthropic Claude Code CLI
|
|
18
|
-
// ============================================================
|
|
19
|
-
'claude': {
|
|
20
|
-
name: 'Claude Code',
|
|
21
|
-
icon: 'Terminal',
|
|
22
|
-
enabled: true,
|
|
23
|
-
endpoint: '/api/v1/chat',
|
|
24
|
-
thinkModes: ['think', 'no-think'],
|
|
25
|
-
defaultThinkMode: 'think',
|
|
26
|
-
models: [
|
|
27
|
-
// === Claude Opus 4.5 (Most Intelligent) ===
|
|
28
|
-
{
|
|
29
|
-
id: 'claude-opus-4-5-20251101',
|
|
30
|
-
name: 'claude-opus-4-5-20251101',
|
|
31
|
-
label: 'Opus 4.5',
|
|
32
|
-
description: '🧠 Most Intelligent',
|
|
33
|
-
category: 'claude'
|
|
34
|
-
},
|
|
35
|
-
// === Claude Sonnet 4.5 (Best Balance) ===
|
|
36
|
-
{
|
|
37
|
-
id: 'claude-sonnet-4-5-20250929',
|
|
38
|
-
name: 'claude-sonnet-4-5-20250929',
|
|
39
|
-
label: 'Sonnet 4.5',
|
|
40
|
-
description: '🧠 Extended Thinking (default)',
|
|
41
|
-
category: 'claude',
|
|
42
|
-
default: true
|
|
43
|
-
},
|
|
44
|
-
// === Claude Haiku 4.5 (Fastest) ===
|
|
45
|
-
{
|
|
46
|
-
id: 'claude-haiku-4-5-20251001',
|
|
47
|
-
name: 'claude-haiku-4-5-20251001',
|
|
48
|
-
label: 'Haiku 4.5',
|
|
49
|
-
description: '⚡ Fast & Efficient',
|
|
50
|
-
category: 'claude'
|
|
51
|
-
},
|
|
52
|
-
// === DeepSeek (Alternative Models) ===
|
|
53
|
-
{
|
|
54
|
-
id: 'deepseek-reasoner',
|
|
55
|
-
name: 'deepseek-reasoner',
|
|
56
|
-
label: 'DeepSeek Reasoner',
|
|
57
|
-
description: '🧠 Deep Reasoning',
|
|
58
|
-
category: 'claude'
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
id: 'deepseek-chat',
|
|
62
|
-
name: 'deepseek-chat',
|
|
63
|
-
label: 'DeepSeek Chat',
|
|
64
|
-
description: '💬 Fast Chat',
|
|
65
|
-
category: 'claude'
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
// ============================================================
|
|
71
|
-
// CODEX - OpenAI Codex CLI
|
|
72
|
-
// ============================================================
|
|
73
|
-
'codex': {
|
|
74
|
-
name: 'Codex',
|
|
75
|
-
icon: 'Code2',
|
|
76
|
-
enabled: true,
|
|
77
|
-
endpoint: '/api/v1/codex',
|
|
78
|
-
models: [
|
|
79
|
-
{
|
|
80
|
-
id: 'gpt-5.1-codex-max',
|
|
81
|
-
name: 'gpt-5.1-codex-max',
|
|
82
|
-
label: 'GPT-5.1 Codex Max',
|
|
83
|
-
description: '💎 Extra High reasoning (best)',
|
|
84
|
-
category: 'codex',
|
|
85
|
-
reasoningEfforts: ['low', 'medium', 'high', 'xhigh'],
|
|
86
|
-
defaultReasoning: 'xhigh',
|
|
87
|
-
default: true
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
id: 'gpt-5.1-codex',
|
|
91
|
-
name: 'gpt-5.1-codex',
|
|
92
|
-
label: 'GPT-5.1 Codex',
|
|
93
|
-
description: '🧠 High reasoning',
|
|
94
|
-
category: 'codex',
|
|
95
|
-
reasoningEfforts: ['low', 'medium', 'high'],
|
|
96
|
-
defaultReasoning: 'high'
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
id: 'gpt-5.1-codex-mini',
|
|
100
|
-
name: 'gpt-5.1-codex-mini',
|
|
101
|
-
label: 'GPT-5.1 Codex Mini',
|
|
102
|
-
description: '⚡ Compact & Fast',
|
|
103
|
-
category: 'codex',
|
|
104
|
-
reasoningEfforts: ['medium', 'high'],
|
|
105
|
-
defaultReasoning: 'high'
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id: 'gpt-5.1',
|
|
109
|
-
name: 'gpt-5.1',
|
|
110
|
-
label: 'GPT-5.1',
|
|
111
|
-
description: '🧠 General Purpose',
|
|
112
|
-
category: 'codex',
|
|
113
|
-
reasoningEfforts: ['low', 'medium', 'high'],
|
|
114
|
-
defaultReasoning: 'high'
|
|
115
|
-
}
|
|
116
|
-
]
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
// ============================================================
|
|
120
|
-
// GEMINI - Google Gemini CLI
|
|
121
|
-
// ============================================================
|
|
122
|
-
'gemini': {
|
|
123
|
-
name: 'Gemini',
|
|
124
|
-
icon: 'Sparkles',
|
|
125
|
-
enabled: true,
|
|
126
|
-
endpoint: '/api/v1/gemini',
|
|
127
|
-
models: [
|
|
128
|
-
{
|
|
129
|
-
id: 'gemini-3-pro-preview',
|
|
130
|
-
name: 'gemini-3-pro-preview',
|
|
131
|
-
label: 'Gemini 3 Pro',
|
|
132
|
-
description: '🚀 Latest Preview',
|
|
133
|
-
category: 'gemini',
|
|
134
|
-
default: true
|
|
135
|
-
}
|
|
136
|
-
]
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
16
|
+
const cliTools = getCliTools();
|
|
140
17
|
res.json(cliTools);
|
|
141
18
|
} catch (error) {
|
|
142
19
|
console.error('[Models] Error fetching models:', error);
|
|
@@ -151,6 +28,7 @@ router.get('/', (req, res) => {
|
|
|
151
28
|
router.get('/:engine', (req, res) => {
|
|
152
29
|
try {
|
|
153
30
|
const { engine } = req.params;
|
|
31
|
+
const cliTools = getCliTools();
|
|
154
32
|
|
|
155
33
|
// Normalize engine name
|
|
156
34
|
let normalizedEngine = engine.toLowerCase();
|
|
@@ -158,37 +36,12 @@ router.get('/:engine', (req, res) => {
|
|
|
158
36
|
if (normalizedEngine.includes('codex') || normalizedEngine.includes('openai')) normalizedEngine = 'codex';
|
|
159
37
|
if (normalizedEngine.includes('gemini') || normalizedEngine.includes('google')) normalizedEngine = 'gemini';
|
|
160
38
|
|
|
161
|
-
const cliTools = {
|
|
162
|
-
'claude': {
|
|
163
|
-
name: 'Claude Code',
|
|
164
|
-
models: [
|
|
165
|
-
{ id: 'claude-opus-4-5-20251101', label: 'Opus 4.5', description: '🧠 Most Intelligent' },
|
|
166
|
-
{ id: 'claude-sonnet-4-5-20250929', label: 'Sonnet 4.5', description: '🧠 Extended Thinking', default: true },
|
|
167
|
-
{ id: 'claude-haiku-4-5-20251001', label: 'Haiku 4.5', description: '⚡ Fast & Efficient' },
|
|
168
|
-
]
|
|
169
|
-
},
|
|
170
|
-
'codex': {
|
|
171
|
-
name: 'Codex',
|
|
172
|
-
models: [
|
|
173
|
-
{ id: 'gpt-5.1-codex-max', label: 'GPT-5.1 Codex Max', description: '💎 Best Quality', default: true },
|
|
174
|
-
{ id: 'gpt-5.1-codex', label: 'GPT-5.1 Codex', description: '🧠 High reasoning' },
|
|
175
|
-
{ id: 'gpt-5.1-codex-mini', label: 'GPT-5.1 Codex Mini', description: '⚡ Fast' },
|
|
176
|
-
{ id: 'gpt-5.1', label: 'GPT-5.1', description: '🧠 General Purpose' },
|
|
177
|
-
]
|
|
178
|
-
},
|
|
179
|
-
'gemini': {
|
|
180
|
-
name: 'Gemini',
|
|
181
|
-
models: [
|
|
182
|
-
{ id: 'gemini-3-pro-preview', label: 'Gemini 3 Pro', description: '🚀 Latest', default: true },
|
|
183
|
-
]
|
|
184
|
-
}
|
|
185
|
-
};
|
|
186
|
-
|
|
187
39
|
if (!cliTools[normalizedEngine]) {
|
|
188
40
|
return res.status(404).json({ error: `Engine not found: ${engine}` });
|
|
189
41
|
}
|
|
190
42
|
|
|
191
|
-
|
|
43
|
+
const { name, models } = cliTools[normalizedEngine];
|
|
44
|
+
res.json({ name, models });
|
|
192
45
|
} catch (error) {
|
|
193
46
|
console.error('[Models] Error fetching engine models:', error);
|
|
194
47
|
res.status(500).json({ error: 'Failed to fetch models' });
|