centaurus-cli 2.9.2 → 2.9.3
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/dist/cli-adapter.d.ts +6 -3
- package/dist/cli-adapter.d.ts.map +1 -1
- package/dist/cli-adapter.js +244 -74
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +2 -0
- package/dist/config/models.js.map +1 -1
- package/dist/config/slash-commands.d.ts +3 -0
- package/dist/config/slash-commands.d.ts.map +1 -1
- package/dist/config/slash-commands.js +35 -1
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/config/types.d.ts +2 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +1 -0
- package/dist/config/types.js.map +1 -1
- package/dist/services/ai-autocomplete-agent.d.ts +39 -0
- package/dist/services/ai-autocomplete-agent.d.ts.map +1 -0
- package/dist/services/ai-autocomplete-agent.js +189 -0
- package/dist/services/ai-autocomplete-agent.js.map +1 -0
- package/dist/services/ai-service-client.d.ts +25 -0
- package/dist/services/ai-service-client.d.ts.map +1 -1
- package/dist/services/ai-service-client.js +162 -1
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/auth-handler.js +1 -1
- package/dist/services/auth-handler.js.map +1 -1
- package/dist/services/local-chat-storage.d.ts +21 -0
- package/dist/services/local-chat-storage.d.ts.map +1 -1
- package/dist/services/local-chat-storage.js +138 -43
- package/dist/services/local-chat-storage.js.map +1 -1
- package/dist/services/ollama-service.d.ts +197 -0
- package/dist/services/ollama-service.d.ts.map +1 -0
- package/dist/services/ollama-service.js +324 -0
- package/dist/services/ollama-service.js.map +1 -0
- package/dist/ui/components/App.d.ts +2 -2
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +45 -2
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/InputBox.d.ts +2 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +321 -19
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/MultiLineInput.d.ts.map +1 -1
- package/dist/ui/components/MultiLineInput.js +68 -2
- package/dist/ui/components/MultiLineInput.js.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.d.ts.map +1 -1
- package/dist/ui/components/ToolExecutionMessage.js +5 -1
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/utils/command-history.d.ts +12 -2
- package/dist/utils/command-history.d.ts.map +1 -1
- package/dist/utils/command-history.js +57 -13
- package/dist/utils/command-history.js.map +1 -1
- package/dist/utils/input-classifier.js +1 -1
- package/dist/utils/input-classifier.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-adapter.d.ts
CHANGED
|
@@ -203,7 +203,7 @@ export declare class CentaurusCLI {
|
|
|
203
203
|
* Get the current conversation ID for file uploads
|
|
204
204
|
*/
|
|
205
205
|
getCurrentConversationId(): string | null;
|
|
206
|
-
handlePickerSelection(selection: string, pickerType: 'model'): Promise<void>;
|
|
206
|
+
handlePickerSelection(selection: string, pickerType: 'model' | 'local-model'): Promise<void>;
|
|
207
207
|
private sshHandler?;
|
|
208
208
|
/**
|
|
209
209
|
* Notify UI about tool execution status
|
|
@@ -242,8 +242,11 @@ export declare class CentaurusCLI {
|
|
|
242
242
|
cancelCurrentRequest(): void;
|
|
243
243
|
/**
|
|
244
244
|
* Clean up orphaned tool_calls from conversation history.
|
|
245
|
-
* This
|
|
246
|
-
*
|
|
245
|
+
* This validates the ENTIRE history and removes any assistant messages
|
|
246
|
+
* where tool_calls don't have matching tool result messages.
|
|
247
|
+
*
|
|
248
|
+
* Vertex AI / Claude APIs require that every assistant message with tool_calls
|
|
249
|
+
* has matching tool result messages immediately following it.
|
|
247
250
|
*/
|
|
248
251
|
private cleanupOrphanedToolCalls;
|
|
249
252
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-adapter.d.ts","sourceRoot":"","sources":["../src/cli-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAY/C,OAAO,EAA6L,IAAI,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAWjP,OAAO,EAAmB,OAAO,IAAI,SAAS,EAAe,MAAM,iCAAiC,CAAC;AAQrG,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQrD,OAAO,EAAmC,aAAa,EAAwC,MAAM,kCAAkC,CAAC;AACxI,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAyB,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-adapter.d.ts","sourceRoot":"","sources":["../src/cli-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-adapter.js
CHANGED
|
@@ -42,6 +42,7 @@ import { localChatStorage } from './services/local-chat-storage.js';
|
|
|
42
42
|
import { logWarning } from './utils/logger.js';
|
|
43
43
|
import { BackgroundTaskManager } from './services/background-task-manager.js';
|
|
44
44
|
import { sessionQuotaManager } from './services/session-quota-manager.js';
|
|
45
|
+
import { ollamaService, OllamaService } from './services/ollama-service.js';
|
|
45
46
|
export class CentaurusCLI {
|
|
46
47
|
configManager;
|
|
47
48
|
toolRegistry;
|
|
@@ -441,25 +442,48 @@ export class CentaurusCLI {
|
|
|
441
442
|
}
|
|
442
443
|
async handlePickerSelection(selection, pickerType) {
|
|
443
444
|
try {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
445
|
+
if (pickerType === 'local-model') {
|
|
446
|
+
// Local Ollama model selection
|
|
447
|
+
// Selection is the model name (e.g., "llama3:latest")
|
|
448
|
+
const modelName = selection;
|
|
449
|
+
// Store the local model configuration
|
|
450
|
+
this.configManager.set('model', modelName);
|
|
451
|
+
this.configManager.set('modelName', modelName);
|
|
452
|
+
this.configManager.set('isLocalModel', true);
|
|
453
|
+
// Notify UI of model name change
|
|
454
|
+
// Local models don't have a fixed context window, use a reasonable default
|
|
455
|
+
if (this.onModelChange) {
|
|
456
|
+
this.onModelChange(modelName, 128000); // Most local models have 128k context
|
|
457
|
+
}
|
|
458
|
+
const responseMessage = `✅ Switched to local Ollama model: ${modelName}`;
|
|
459
|
+
// Send response back to UI
|
|
460
|
+
if (this.onResponseCallback) {
|
|
461
|
+
this.onResponseCallback(responseMessage);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
// Cloud model selection (existing behavior)
|
|
466
|
+
// Selection is the index of the model in models array from backend
|
|
467
|
+
const modelsConfig = await fetchModelsConfig();
|
|
468
|
+
const modelIndex = parseInt(selection, 10);
|
|
469
|
+
if (isNaN(modelIndex) || modelIndex < 0 || modelIndex >= modelsConfig.models.length) {
|
|
470
|
+
throw new Error('Invalid model selection');
|
|
471
|
+
}
|
|
472
|
+
const selectedModel = modelsConfig.models[modelIndex];
|
|
473
|
+
// Store only the model ID and name (not the full config with thinkingConfig)
|
|
474
|
+
// This prevents caching issues when we update model configs
|
|
475
|
+
this.configManager.set('model', selectedModel.id);
|
|
476
|
+
this.configManager.set('modelName', selectedModel.name);
|
|
477
|
+
this.configManager.set('isLocalModel', false);
|
|
478
|
+
// Notify UI of model name change and contextWindow
|
|
479
|
+
if (this.onModelChange) {
|
|
480
|
+
this.onModelChange(selectedModel.name, selectedModel.contextWindow);
|
|
481
|
+
}
|
|
482
|
+
const responseMessage = `✅ Switched to cloud model: ${selectedModel.name}`;
|
|
483
|
+
// Send response back to UI
|
|
484
|
+
if (this.onResponseCallback) {
|
|
485
|
+
this.onResponseCallback(responseMessage);
|
|
486
|
+
}
|
|
463
487
|
}
|
|
464
488
|
}
|
|
465
489
|
catch (error) {
|
|
@@ -659,41 +683,69 @@ Press Enter to continue...
|
|
|
659
683
|
}
|
|
660
684
|
/**
|
|
661
685
|
* Clean up orphaned tool_calls from conversation history.
|
|
662
|
-
* This
|
|
663
|
-
*
|
|
686
|
+
* This validates the ENTIRE history and removes any assistant messages
|
|
687
|
+
* where tool_calls don't have matching tool result messages.
|
|
688
|
+
*
|
|
689
|
+
* Vertex AI / Claude APIs require that every assistant message with tool_calls
|
|
690
|
+
* has matching tool result messages immediately following it.
|
|
664
691
|
*/
|
|
665
692
|
cleanupOrphanedToolCalls() {
|
|
666
693
|
if (this.conversationHistory.length === 0)
|
|
667
694
|
return;
|
|
668
|
-
|
|
669
|
-
let
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
695
|
+
let cleanedAny = false;
|
|
696
|
+
let iterations = 0;
|
|
697
|
+
const maxIterations = 20; // Safety limit to prevent infinite loops
|
|
698
|
+
// Keep cleaning until no more orphans are found
|
|
699
|
+
// (removing one orphan may expose another)
|
|
700
|
+
while (iterations < maxIterations) {
|
|
701
|
+
iterations++;
|
|
702
|
+
let foundOrphan = false;
|
|
703
|
+
// Scan through history to find ALL assistant messages with tool_calls
|
|
704
|
+
for (let i = 0; i < this.conversationHistory.length; i++) {
|
|
705
|
+
const msg = this.conversationHistory[i];
|
|
706
|
+
if (msg.role !== 'assistant' || !msg.tool_calls || msg.tool_calls.length === 0) {
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
// Collect all tool_call IDs from this assistant message
|
|
710
|
+
const expectedToolCallIds = new Set(msg.tool_calls.map((tc) => tc.id));
|
|
711
|
+
// Check if ALL tool_calls have matching tool result messages after this message
|
|
712
|
+
// Tool results must come AFTER the assistant message, before the next user/assistant message
|
|
713
|
+
let j = i + 1;
|
|
714
|
+
while (j < this.conversationHistory.length) {
|
|
715
|
+
const nextMsg = this.conversationHistory[j];
|
|
716
|
+
// If we hit a user or assistant message, stop looking for tool results
|
|
717
|
+
if (nextMsg.role === 'user' || nextMsg.role === 'assistant') {
|
|
718
|
+
break;
|
|
719
|
+
}
|
|
720
|
+
// If it's a tool result, check if it matches one of our expected IDs
|
|
721
|
+
if (nextMsg.role === 'tool' && nextMsg.tool_call_id) {
|
|
722
|
+
expectedToolCallIds.delete(nextMsg.tool_call_id);
|
|
723
|
+
}
|
|
724
|
+
j++;
|
|
725
|
+
}
|
|
726
|
+
// If there are still unmatched tool_calls, this is an orphan
|
|
727
|
+
if (expectedToolCallIds.size > 0) {
|
|
728
|
+
try {
|
|
729
|
+
quickLog(`[${new Date().toISOString()}] [CLI] Found orphaned tool_calls at index ${i}: ${Array.from(expectedToolCallIds).join(', ')}\n`);
|
|
730
|
+
}
|
|
731
|
+
catch (e) { }
|
|
732
|
+
// Remove this assistant message and all tool results up to (but not including) the next user/assistant message
|
|
733
|
+
const removeCount = j - i;
|
|
734
|
+
this.conversationHistory.splice(i, removeCount);
|
|
735
|
+
foundOrphan = true;
|
|
736
|
+
cleanedAny = true;
|
|
737
|
+
break; // Restart scan from beginning since indices changed
|
|
738
|
+
}
|
|
675
739
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
return; // No assistant messages with tool_calls
|
|
679
|
-
const assistantMsg = this.conversationHistory[lastAssistantWithToolCallsIndex];
|
|
680
|
-
const toolCallIds = new Set(assistantMsg.tool_calls.map((tc) => tc.id));
|
|
681
|
-
// Check if all tool_calls have matching tool result messages after this assistant message
|
|
682
|
-
for (let i = lastAssistantWithToolCallsIndex + 1; i < this.conversationHistory.length; i++) {
|
|
683
|
-
const msg = this.conversationHistory[i];
|
|
684
|
-
if (msg.role === 'tool' && msg.tool_call_id) {
|
|
685
|
-
toolCallIds.delete(msg.tool_call_id);
|
|
740
|
+
if (!foundOrphan) {
|
|
741
|
+
break; // No more orphans found, we're done
|
|
686
742
|
}
|
|
687
743
|
}
|
|
688
|
-
|
|
689
|
-
if (toolCallIds.size > 0) {
|
|
690
|
-
// Log the cleanup for debugging
|
|
744
|
+
if (cleanedAny) {
|
|
691
745
|
try {
|
|
692
|
-
quickLog(`[${new Date().toISOString()}] [CLI]
|
|
746
|
+
quickLog(`[${new Date().toISOString()}] [CLI] Completed history cleanup after ${iterations} iteration(s), ${this.conversationHistory.length} messages remaining\n`);
|
|
693
747
|
}
|
|
694
748
|
catch (e) { }
|
|
695
|
-
// Remove the orphaned assistant message and any partial tool results after it
|
|
696
|
-
this.conversationHistory.splice(lastAssistantWithToolCallsIndex);
|
|
697
749
|
}
|
|
698
750
|
}
|
|
699
751
|
/**
|
|
@@ -780,8 +832,27 @@ Press Enter to continue...
|
|
|
780
832
|
// Cancel any active request when a new message comes in
|
|
781
833
|
// This enables "interrupt and replace" - new message takes priority
|
|
782
834
|
if (this.currentAbortController) {
|
|
783
|
-
|
|
784
|
-
this.
|
|
835
|
+
// Mark as intentionally aborted so error handling knows not to throw or show message
|
|
836
|
+
this.requestIntentionallyAborted = true;
|
|
837
|
+
const oldController = this.currentAbortController;
|
|
838
|
+
// Create new controller BEFORE aborting old one to avoid race condition
|
|
839
|
+
// where new request tries to access undefined controller
|
|
840
|
+
this.currentAbortController = new AbortController();
|
|
841
|
+
oldController.abort();
|
|
842
|
+
// Clean up orphaned tool calls from the interrupted turn
|
|
843
|
+
this.cleanupOrphanedToolCalls();
|
|
844
|
+
// Remove the last user message from history (it's being replaced by the new message)
|
|
845
|
+
// Walk backwards and remove messages until we find and remove a user message
|
|
846
|
+
while (this.conversationHistory.length > 0) {
|
|
847
|
+
const lastMsg = this.conversationHistory[this.conversationHistory.length - 1];
|
|
848
|
+
this.conversationHistory.pop();
|
|
849
|
+
if (lastMsg.role === 'user') {
|
|
850
|
+
// Found and removed the interrupted user message, stop here
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
// Continue removing assistant/tool messages that were part of the interrupted turn
|
|
854
|
+
}
|
|
855
|
+
quickLog(`[${new Date().toISOString()}] [handleMessage] Interrupted active request - cleaned up history for replacement\n`);
|
|
785
856
|
}
|
|
786
857
|
// Store original request if in planning mode (for execution phase after approval)
|
|
787
858
|
if (this.planMode && !this.pendingPlanRequest) {
|
|
@@ -857,6 +928,9 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
|
|
|
857
928
|
// Build messages array WITHOUT system prompt - backend will inject it
|
|
858
929
|
// The backend uses cli-system-prompt.md for CLI clients
|
|
859
930
|
// We pass environmentContext and mode separately so backend can inject them
|
|
931
|
+
// SAFETY: Clean up any orphaned tool calls before making AI request
|
|
932
|
+
// This prevents "improperly formed request" errors from corrupted history
|
|
933
|
+
this.cleanupOrphanedToolCalls();
|
|
860
934
|
let messages = [...this.conversationHistory];
|
|
861
935
|
// Inject subshell context if in a subshell environment
|
|
862
936
|
const currentContext = this.contextManager.getCurrentContext();
|
|
@@ -879,9 +953,12 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
|
|
|
879
953
|
// ANTI-LOOP: Track ALL duplicate tool calls (not just file ops)
|
|
880
954
|
const toolCallTracker = new Map(); // Hash -> count
|
|
881
955
|
const MAX_IDENTICAL_TOOL_CALLS = 3; // Max times exact same tool call allowed
|
|
882
|
-
// Create AbortController for this request
|
|
883
|
-
this.currentAbortController
|
|
884
|
-
|
|
956
|
+
// Create AbortController for this request (if not already created during interruption handling)
|
|
957
|
+
if (!this.currentAbortController) {
|
|
958
|
+
this.currentAbortController = new AbortController();
|
|
959
|
+
}
|
|
960
|
+
// Note: Don't reset requestIntentionallyAborted here - let the error handler reset it
|
|
961
|
+
// to avoid race condition where old request's error handler sees false
|
|
885
962
|
// Clean up any orphaned tool_calls from a previous aborted request
|
|
886
963
|
// This prevents 400 Bad Request errors when sending to the backend
|
|
887
964
|
this.cleanupOrphanedToolCalls();
|
|
@@ -960,7 +1037,7 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
|
|
|
960
1037
|
});
|
|
961
1038
|
// Stream AI response from backend
|
|
962
1039
|
// Backend will inject system prompt automatically with environment context
|
|
963
|
-
for await (const chunk of aiServiceClient.streamChat(selectedModel, messages, tools, environmentContext, mode, selectedModelThinkingConfig, this.currentAbortController
|
|
1040
|
+
for await (const chunk of aiServiceClient.streamChat(selectedModel, messages, tools, environmentContext, mode, selectedModelThinkingConfig, this.currentAbortController?.signal)) {
|
|
964
1041
|
// Handle error chunks
|
|
965
1042
|
if (chunk.type === 'error') {
|
|
966
1043
|
// Check if this is an abort situation (user cancelled or sent new message)
|
|
@@ -1910,8 +1987,14 @@ DO NOT use write_to_file, edit_file, or execute_command until the plan is approv
|
|
|
1910
1987
|
catch (error) {
|
|
1911
1988
|
// Log the error
|
|
1912
1989
|
conversationLogger.logError('handleMessage', error);
|
|
1913
|
-
// Check if this was an abort/cancellation
|
|
1914
|
-
if (error.name === 'AbortError' || error.message?.includes('aborted')) {
|
|
1990
|
+
// Check if this was an abort/cancellation (including timeout errors from aborted requests)
|
|
1991
|
+
if (error.name === 'AbortError' || error.message?.includes('aborted') || error.message?.includes('timed out') || this.requestIntentionallyAborted) {
|
|
1992
|
+
// If intentionally aborted for replacement by new message, return silently
|
|
1993
|
+
// The new message will take over - no need to show cancellation message
|
|
1994
|
+
if (this.requestIntentionallyAborted) {
|
|
1995
|
+
this.requestIntentionallyAborted = false;
|
|
1996
|
+
return;
|
|
1997
|
+
}
|
|
1915
1998
|
conversationLogger.logError('handleMessage', new Error('Request cancelled by user'));
|
|
1916
1999
|
if (this.onResponseCallback) {
|
|
1917
2000
|
this.onResponseCallback('⚠️ Request cancelled by user.');
|
|
@@ -2323,43 +2406,126 @@ Start by listing the directory structure to understand what you're working with.
|
|
|
2323
2406
|
`Model: ${config.model || 'gemini-2.5-flash (default)'}\n` +
|
|
2324
2407
|
`Enhanced Quality: ${config.enhancedQuality !== false ? '✅ Enabled' : '❌ Disabled'}\n` +
|
|
2325
2408
|
`Autonomous Mode: ${config.autonomousMode === true ? '✅ Enabled' : '❌ Disabled'}\n` +
|
|
2409
|
+
`AI Auto-Suggest: ${config.aiAutoSuggest === true ? '✅ Enabled' : '❌ Disabled'}\n` +
|
|
2326
2410
|
`Authentication: ${apiClient.isAuthenticated() ? '✅ Signed in' : '❌ Not signed in'}`;
|
|
2327
2411
|
}
|
|
2328
2412
|
break;
|
|
2413
|
+
case 'settings':
|
|
2414
|
+
if (args.length >= 2 && args[0].toLowerCase() === 'auto-suggest') {
|
|
2415
|
+
// Handle /settings auto-suggest <on/off>
|
|
2416
|
+
const value = args[1].toLowerCase();
|
|
2417
|
+
if (value === 'on') {
|
|
2418
|
+
this.configManager.set('aiAutoSuggest', true);
|
|
2419
|
+
responseMessage = '✅ **AI Auto-Suggestions Enabled**\n\n' +
|
|
2420
|
+
'From now on, I will suggest commands after 5 seconds of inactivity.\n' +
|
|
2421
|
+
'Suggestions will appear in grey text. Use the **Right Arrow** key to accept them.';
|
|
2422
|
+
}
|
|
2423
|
+
else if (value === 'off') {
|
|
2424
|
+
this.configManager.set('aiAutoSuggest', false);
|
|
2425
|
+
responseMessage = '✅ **AI Auto-Suggestions Disabled**\n\n' +
|
|
2426
|
+
'I will no longer provide AI-powered command suggestions.';
|
|
2427
|
+
}
|
|
2428
|
+
else {
|
|
2429
|
+
responseMessage = '❌ Invalid option. Usage: `/settings auto-suggest on` or `/settings auto-suggest off`';
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
else {
|
|
2433
|
+
responseMessage = '❌ Invalid command format.\n\nUsage:\n- `/settings auto-suggest on`\n- `/settings auto-suggest off`';
|
|
2434
|
+
}
|
|
2435
|
+
break;
|
|
2329
2436
|
case 'model':
|
|
2330
|
-
|
|
2331
|
-
|
|
2437
|
+
case 'models':
|
|
2438
|
+
// Handle subcommands: local, cloud
|
|
2439
|
+
const modelSubCommand = args[0]?.toLowerCase();
|
|
2440
|
+
if (modelSubCommand === 'local') {
|
|
2441
|
+
// Local Ollama models
|
|
2442
|
+
try {
|
|
2443
|
+
// Check if Ollama is running
|
|
2444
|
+
const status = await ollamaService.isOllamaRunning();
|
|
2445
|
+
if (!status.available) {
|
|
2446
|
+
responseMessage = `❌ Cannot connect to Ollama
|
|
2447
|
+
|
|
2448
|
+
${status.error || 'Ollama is not running.'}
|
|
2449
|
+
|
|
2450
|
+
To use local models:
|
|
2451
|
+
1. Install Ollama from: https://ollama.ai
|
|
2452
|
+
2. Start Ollama by running: ollama serve
|
|
2453
|
+
3. Pull a model: ollama pull llama3
|
|
2454
|
+
|
|
2455
|
+
Then try /models local again.`;
|
|
2456
|
+
break;
|
|
2457
|
+
}
|
|
2458
|
+
// Get available local models
|
|
2459
|
+
const localModels = await ollamaService.getLocalModels();
|
|
2460
|
+
if (localModels.length === 0) {
|
|
2461
|
+
responseMessage = `📭 No local models found
|
|
2462
|
+
|
|
2463
|
+
Ollama is running (v${status.version}) but no models are downloaded.
|
|
2464
|
+
|
|
2465
|
+
To download models, run:
|
|
2466
|
+
ollama pull llama3
|
|
2467
|
+
ollama pull codellama
|
|
2468
|
+
ollama pull mistral
|
|
2469
|
+
|
|
2470
|
+
Then try /models local again.`;
|
|
2471
|
+
break;
|
|
2472
|
+
}
|
|
2473
|
+
// Show picker for local model selection
|
|
2474
|
+
if (this.onShowPickerCallback) {
|
|
2475
|
+
const config = this.configManager.load();
|
|
2476
|
+
const currentModelName = config.modelName || '';
|
|
2477
|
+
const isCurrentLocal = config.isLocalModel === true;
|
|
2478
|
+
this.onShowPickerCallback({
|
|
2479
|
+
message: 'Select Local Model (Ollama)',
|
|
2480
|
+
type: 'local-model', // Cast to bypass type check, will be handled in handlePickerSelection
|
|
2481
|
+
choices: localModels.map((model) => {
|
|
2482
|
+
const size = OllamaService.formatModelSize(model.size);
|
|
2483
|
+
const isCurrent = isCurrentLocal && currentModelName === model.name;
|
|
2484
|
+
const supportsTools = OllamaService.modelSupportsTools(model.name);
|
|
2485
|
+
const toolsBadge = supportsTools ? ' [Tools]' : '';
|
|
2486
|
+
return {
|
|
2487
|
+
label: `${model.name} (${size})${toolsBadge}${isCurrent ? ' [CURRENT]' : ''}`,
|
|
2488
|
+
value: model.name
|
|
2489
|
+
};
|
|
2490
|
+
})
|
|
2491
|
+
});
|
|
2492
|
+
return; // Don't send a text response, picker will handle it
|
|
2493
|
+
}
|
|
2494
|
+
}
|
|
2495
|
+
catch (error) {
|
|
2496
|
+
responseMessage = OllamaService.getHelpfulErrorMessage(error);
|
|
2497
|
+
}
|
|
2498
|
+
break;
|
|
2499
|
+
}
|
|
2500
|
+
if (modelSubCommand === 'cloud' || args.length === 0) {
|
|
2501
|
+
// Cloud models (default behavior when no subcommand or 'cloud' specified)
|
|
2332
2502
|
if (this.onShowPickerCallback) {
|
|
2333
2503
|
const config = this.configManager.load();
|
|
2334
2504
|
const currentModelName = config.modelName || '';
|
|
2505
|
+
const isCurrentCloud = config.isLocalModel !== true;
|
|
2335
2506
|
// Fetch models from backend
|
|
2336
2507
|
const modelsConfig = await fetchModelsConfig();
|
|
2337
2508
|
this.onShowPickerCallback({
|
|
2338
|
-
message: 'Select Model',
|
|
2509
|
+
message: '☁️ Select Cloud Model',
|
|
2339
2510
|
type: 'model',
|
|
2340
|
-
choices: modelsConfig.models.map((modelConfig, index) =>
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2511
|
+
choices: modelsConfig.models.map((modelConfig, index) => {
|
|
2512
|
+
const isCurrent = isCurrentCloud && currentModelName === modelConfig.name;
|
|
2513
|
+
return {
|
|
2514
|
+
label: `${modelConfig.name} - ${modelConfig.description}${isCurrent ? ' [CURRENT]' : ''}`,
|
|
2515
|
+
value: `${index}` // Use index as unique identifier
|
|
2516
|
+
};
|
|
2517
|
+
})
|
|
2344
2518
|
});
|
|
2345
2519
|
return; // Don't send a text response, picker will handle it
|
|
2346
2520
|
}
|
|
2347
2521
|
}
|
|
2348
2522
|
else {
|
|
2349
|
-
//
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
}
|
|
2356
|
-
try {
|
|
2357
|
-
this.configManager.set('model', newModel);
|
|
2358
|
-
responseMessage = `✅ Model changed to: ${newModel}`;
|
|
2359
|
-
}
|
|
2360
|
-
catch (error) {
|
|
2361
|
-
responseMessage = `❌ Failed to set model: ${error.message}`;
|
|
2362
|
-
}
|
|
2523
|
+
// Unrecognized subcommand - show help
|
|
2524
|
+
responseMessage = `Usage: /models [local|cloud]
|
|
2525
|
+
|
|
2526
|
+
/models local - Select from locally installed Ollama models
|
|
2527
|
+
/models cloud - Select from cloud models (Centaurus backend)
|
|
2528
|
+
/models - Default: show cloud models`;
|
|
2363
2529
|
}
|
|
2364
2530
|
break;
|
|
2365
2531
|
case 'mcp':
|
|
@@ -2372,7 +2538,7 @@ Start by listing the directory structure to understand what you're working with.
|
|
|
2372
2538
|
break;
|
|
2373
2539
|
case 'docs':
|
|
2374
2540
|
// Open documentation URL in default browser
|
|
2375
|
-
const docsUrl = 'https://
|
|
2541
|
+
const docsUrl = 'https://centauruslabs.in/docs';
|
|
2376
2542
|
const { exec } = await import('child_process');
|
|
2377
2543
|
const platform = process.platform;
|
|
2378
2544
|
if (platform === 'win32') {
|
|
@@ -3216,6 +3382,10 @@ Start by listing the directory structure to understand what you're working with.
|
|
|
3216
3382
|
this.updateTokenCount().catch(err => {
|
|
3217
3383
|
quickLog(`[${new Date().toISOString()}] [loadChatFromPicker] Failed to update token count: ${err}\n`);
|
|
3218
3384
|
});
|
|
3385
|
+
// Clean up any orphaned tool calls from previous interrupted sessions
|
|
3386
|
+
// This prevents "improperly formed request" errors when continuing conversations
|
|
3387
|
+
this.cleanupOrphanedToolCalls();
|
|
3388
|
+
quickLog(`[${new Date().toISOString()}] [loadChat] Cleaned up conversation history after load\n`);
|
|
3219
3389
|
return true;
|
|
3220
3390
|
}
|
|
3221
3391
|
/**
|