erosolar-cli 1.1.7 → 1.2.2
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 +175 -296
- package/dist/contracts/agent-schemas.json +15 -0
- package/dist/providers/openaiChatCompletionsProvider.js +66 -3
- package/dist/providers/openaiChatCompletionsProvider.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +20 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +206 -0
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/tools/code-quality-dashboard.d.ts +57 -0
- package/dist/tools/code-quality-dashboard.d.ts.map +1 -0
- package/dist/tools/code-quality-dashboard.js +218 -0
- package/dist/tools/code-quality-dashboard.js.map +1 -0
- package/package.json +9 -6
- package/scripts/code-quality-dashboard.js +239 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/shell/interactiveShell.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/shell/interactiveShell.ts"],"names":[],"mappings":"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"}
|
|
@@ -678,6 +678,15 @@ export class InteractiveShell {
|
|
|
678
678
|
case '/plugins':
|
|
679
679
|
this.showPluginStatus();
|
|
680
680
|
break;
|
|
681
|
+
case '/provider':
|
|
682
|
+
await this.handleProviderCommand(input);
|
|
683
|
+
break;
|
|
684
|
+
case '/providers':
|
|
685
|
+
this.showConfiguredProviders();
|
|
686
|
+
break;
|
|
687
|
+
case '/local':
|
|
688
|
+
await this.handleLocalCommand(input);
|
|
689
|
+
break;
|
|
681
690
|
default:
|
|
682
691
|
if (!(await this.tryCustomSlashCommand(command, input))) {
|
|
683
692
|
display.showWarning(`Unknown command "${command}".`);
|
|
@@ -2197,6 +2206,203 @@ export class InteractiveShell {
|
|
|
2197
2206
|
reasoningEffort: this.sessionState.reasoningEffort,
|
|
2198
2207
|
});
|
|
2199
2208
|
}
|
|
2209
|
+
/**
|
|
2210
|
+
* Handle the /provider command to switch AI providers.
|
|
2211
|
+
*/
|
|
2212
|
+
async handleProviderCommand(input) {
|
|
2213
|
+
const tokens = input.trim().split(/\s+/).slice(1);
|
|
2214
|
+
const targetProvider = tokens[0]?.toLowerCase();
|
|
2215
|
+
if (!targetProvider) {
|
|
2216
|
+
this.showConfiguredProviders();
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
// Find matching provider
|
|
2220
|
+
const providerOptions = this.buildProviderOptions();
|
|
2221
|
+
const match = providerOptions.find((opt) => opt.provider.toLowerCase() === targetProvider || opt.label.toLowerCase() === targetProvider);
|
|
2222
|
+
if (!match) {
|
|
2223
|
+
display.showWarning(`Unknown provider "${targetProvider}".`);
|
|
2224
|
+
const available = providerOptions.map((opt) => opt.provider).join(', ');
|
|
2225
|
+
display.showInfo(`Available providers: ${available}`);
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
if (match.provider === this.sessionState.provider) {
|
|
2229
|
+
display.showInfo(`Already using ${match.label}.`);
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
// Get default model for the provider
|
|
2233
|
+
const models = MODEL_PRESETS.filter((preset) => preset.provider === match.provider);
|
|
2234
|
+
if (!models.length) {
|
|
2235
|
+
display.showWarning(`No models available for ${match.label}.`);
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
const defaultModel = models[0];
|
|
2239
|
+
const oldProvider = this.sessionState.provider;
|
|
2240
|
+
const oldModel = this.sessionState.model;
|
|
2241
|
+
// Update session state
|
|
2242
|
+
this.sessionState = {
|
|
2243
|
+
provider: match.provider,
|
|
2244
|
+
model: defaultModel.id,
|
|
2245
|
+
temperature: defaultModel.temperature,
|
|
2246
|
+
maxTokens: defaultModel.maxTokens,
|
|
2247
|
+
reasoningEffort: defaultModel.reasoningEffort,
|
|
2248
|
+
};
|
|
2249
|
+
// Rebuild agent with new provider
|
|
2250
|
+
if (this.rebuildAgent()) {
|
|
2251
|
+
this.persistSessionPreference();
|
|
2252
|
+
this.refreshBannerSessionInfo();
|
|
2253
|
+
display.showInfo(`Switched from ${this.providerLabel(oldProvider)}/${oldModel} to ${match.label}/${defaultModel.id}`);
|
|
2254
|
+
}
|
|
2255
|
+
else {
|
|
2256
|
+
// Revert on failure
|
|
2257
|
+
this.sessionState.provider = oldProvider;
|
|
2258
|
+
this.sessionState.model = oldModel;
|
|
2259
|
+
display.showError(`Failed to switch to ${match.label}. Reverted to ${this.providerLabel(oldProvider)}.`);
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
/**
|
|
2263
|
+
* Show all configured providers and their status.
|
|
2264
|
+
*/
|
|
2265
|
+
showConfiguredProviders() {
|
|
2266
|
+
const providerOptions = this.buildProviderOptions();
|
|
2267
|
+
if (!providerOptions.length) {
|
|
2268
|
+
display.showWarning('No providers are configured.');
|
|
2269
|
+
display.showInfo('Set an API key: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, etc.');
|
|
2270
|
+
return;
|
|
2271
|
+
}
|
|
2272
|
+
const lines = [
|
|
2273
|
+
theme.bold('Configured Providers:'),
|
|
2274
|
+
'',
|
|
2275
|
+
...providerOptions.map((option) => {
|
|
2276
|
+
const isCurrent = option.provider === this.sessionState.provider;
|
|
2277
|
+
const marker = isCurrent ? theme.primary(' ← active') : '';
|
|
2278
|
+
const countLabel = `${option.modelCount} model${option.modelCount === 1 ? '' : 's'}`;
|
|
2279
|
+
return ` ${theme.success('✓')} ${option.label} (${option.provider}) — ${countLabel}${marker}`;
|
|
2280
|
+
}),
|
|
2281
|
+
'',
|
|
2282
|
+
'Switch with: /provider <name>',
|
|
2283
|
+
'Example: /provider xai',
|
|
2284
|
+
];
|
|
2285
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* Handle the /local command for local/air-gapped LLM management.
|
|
2289
|
+
*/
|
|
2290
|
+
async handleLocalCommand(input) {
|
|
2291
|
+
const tokens = input.trim().split(/\s+/).slice(1);
|
|
2292
|
+
const subcommand = (tokens[0] ?? '').toLowerCase();
|
|
2293
|
+
switch (subcommand) {
|
|
2294
|
+
case '':
|
|
2295
|
+
case 'scan':
|
|
2296
|
+
case 'status':
|
|
2297
|
+
await this.scanLocalProviders();
|
|
2298
|
+
break;
|
|
2299
|
+
case 'use':
|
|
2300
|
+
const provider = tokens[1]?.toLowerCase();
|
|
2301
|
+
if (!provider) {
|
|
2302
|
+
display.showWarning('Usage: /local use <provider>');
|
|
2303
|
+
display.showInfo('Example: /local use ollama');
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
await this.handleProviderCommand(`/provider ${provider}`);
|
|
2307
|
+
break;
|
|
2308
|
+
default:
|
|
2309
|
+
this.showLocalHelp();
|
|
2310
|
+
break;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
/**
|
|
2314
|
+
* Scan for running local LLM servers.
|
|
2315
|
+
*/
|
|
2316
|
+
async scanLocalProviders() {
|
|
2317
|
+
const localProviders = [
|
|
2318
|
+
{ id: 'ollama', label: 'Ollama', url: 'http://localhost:11434', envVar: 'OLLAMA_BASE_URL' },
|
|
2319
|
+
{ id: 'lmstudio', label: 'LM Studio', url: 'http://localhost:1234', envVar: 'LMSTUDIO_BASE_URL' },
|
|
2320
|
+
{ id: 'vllm', label: 'vLLM', url: 'http://localhost:8000', envVar: 'VLLM_BASE_URL' },
|
|
2321
|
+
{ id: 'llamacpp', label: 'llama.cpp', url: 'http://localhost:8080', envVar: 'LLAMACPP_BASE_URL' },
|
|
2322
|
+
];
|
|
2323
|
+
display.showInfo('Scanning for local LLM servers...');
|
|
2324
|
+
const results = [];
|
|
2325
|
+
for (const provider of localProviders) {
|
|
2326
|
+
const baseUrl = process.env[provider.envVar] || provider.url;
|
|
2327
|
+
try {
|
|
2328
|
+
const controller = new AbortController();
|
|
2329
|
+
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
2330
|
+
const response = await fetch(`${baseUrl}/api/tags`, {
|
|
2331
|
+
signal: controller.signal,
|
|
2332
|
+
}).catch(() => fetch(`${baseUrl}/v1/models`, { signal: controller.signal }));
|
|
2333
|
+
clearTimeout(timeout);
|
|
2334
|
+
if (response.ok) {
|
|
2335
|
+
const data = await response.json();
|
|
2336
|
+
const models = data.models?.map((m) => m.name) ?? [];
|
|
2337
|
+
results.push({ provider, running: true, models });
|
|
2338
|
+
}
|
|
2339
|
+
else {
|
|
2340
|
+
results.push({ provider, running: false });
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
catch {
|
|
2344
|
+
results.push({ provider, running: false });
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
const running = results.filter((r) => r.running);
|
|
2348
|
+
const stopped = results.filter((r) => !r.running);
|
|
2349
|
+
const lines = [theme.bold('Local LLM Servers:'), ''];
|
|
2350
|
+
if (running.length) {
|
|
2351
|
+
lines.push(theme.success('Running:'));
|
|
2352
|
+
for (const r of running) {
|
|
2353
|
+
const modelCount = r.models?.length ?? 0;
|
|
2354
|
+
const modelInfo = modelCount ? ` (${modelCount} model${modelCount === 1 ? '' : 's'})` : '';
|
|
2355
|
+
lines.push(` ${theme.success('●')} ${r.provider.label}${modelInfo}`);
|
|
2356
|
+
if (r.models?.length) {
|
|
2357
|
+
for (const model of r.models.slice(0, 5)) {
|
|
2358
|
+
lines.push(` • ${model}`);
|
|
2359
|
+
}
|
|
2360
|
+
if (r.models.length > 5) {
|
|
2361
|
+
lines.push(` • ... and ${r.models.length - 5} more`);
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
lines.push('');
|
|
2366
|
+
}
|
|
2367
|
+
if (stopped.length) {
|
|
2368
|
+
lines.push(theme.secondary('Not detected:'));
|
|
2369
|
+
for (const r of stopped) {
|
|
2370
|
+
lines.push(` ${theme.ui.muted('○')} ${r.provider.label}`);
|
|
2371
|
+
}
|
|
2372
|
+
lines.push('');
|
|
2373
|
+
}
|
|
2374
|
+
if (running.length) {
|
|
2375
|
+
lines.push(`Switch with: /local use ${running[0].provider.id}`);
|
|
2376
|
+
}
|
|
2377
|
+
else {
|
|
2378
|
+
lines.push('No local servers running.');
|
|
2379
|
+
lines.push('Install Ollama: https://ollama.ai');
|
|
2380
|
+
}
|
|
2381
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Show help for /local commands.
|
|
2385
|
+
*/
|
|
2386
|
+
showLocalHelp() {
|
|
2387
|
+
const lines = [
|
|
2388
|
+
theme.bold('/local Commands:'),
|
|
2389
|
+
'',
|
|
2390
|
+
' /local Scan for running local LLM servers',
|
|
2391
|
+
' /local status Same as /local (scan for servers)',
|
|
2392
|
+
' /local use <name> Switch to a local provider',
|
|
2393
|
+
'',
|
|
2394
|
+
'Supported Local Providers:',
|
|
2395
|
+
' ollama - Easy-to-use local LLM runner (recommended)',
|
|
2396
|
+
' lmstudio - GUI-based local model serving',
|
|
2397
|
+
' vllm - High-throughput production serving',
|
|
2398
|
+
' llamacpp - Lightweight llama.cpp server',
|
|
2399
|
+
'',
|
|
2400
|
+
'Example:',
|
|
2401
|
+
' /local # Scan for running servers',
|
|
2402
|
+
' /local use ollama # Switch to Ollama',
|
|
2403
|
+
];
|
|
2404
|
+
display.showSystemMessage(lines.join('\n'));
|
|
2405
|
+
}
|
|
2200
2406
|
enableBracketedPasteMode() {
|
|
2201
2407
|
if (!input.isTTY || !output.isTTY) {
|
|
2202
2408
|
return false;
|