mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 16:04:03 +00:00
Add /models command for enabling/disabling Ctrl+P model cycling
- New /models command with toggle UI for each available model - Changes persist to enabledModels in settings.json - Updates take effect immediately for Ctrl+P cycling
This commit is contained in:
parent
42ed0129ed
commit
49acd8e648
7 changed files with 241 additions and 0 deletions
|
|
@ -45,6 +45,7 @@ import type {
|
|||
import { FooterDataProvider, type ReadonlyFooterDataProvider } from "../../core/footer-data-provider.js";
|
||||
import { KeybindingsManager } from "../../core/keybindings.js";
|
||||
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
||||
import { resolveModelScope } from "../../core/model-resolver.js";
|
||||
import { type SessionContext, SessionManager } from "../../core/session-manager.js";
|
||||
import { loadProjectContextFiles } from "../../core/system-prompt.js";
|
||||
import type { TruncationResult } from "../../core/tools/truncate.js";
|
||||
|
|
@ -68,6 +69,7 @@ import { ExtensionSelectorComponent } from "./components/extension-selector.js";
|
|||
import { FooterComponent } from "./components/footer.js";
|
||||
import { LoginDialogComponent } from "./components/login-dialog.js";
|
||||
import { ModelSelectorComponent } from "./components/model-selector.js";
|
||||
import { ModelsSelectorComponent } from "./components/models-selector.js";
|
||||
import { OAuthSelectorComponent } from "./components/oauth-selector.js";
|
||||
import { SessionSelectorComponent } from "./components/session-selector.js";
|
||||
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
||||
|
|
@ -280,6 +282,7 @@ export class InteractiveMode {
|
|||
}));
|
||||
},
|
||||
},
|
||||
{ name: "models", description: "Enable/disable models for Ctrl+P cycling" },
|
||||
{ name: "export", description: "Export session to HTML file" },
|
||||
{ name: "share", description: "Share session as a secret GitHub gist" },
|
||||
{ name: "copy", description: "Copy last agent message to clipboard" },
|
||||
|
|
@ -1412,6 +1415,11 @@ export class InteractiveMode {
|
|||
this.editor.setText("");
|
||||
return;
|
||||
}
|
||||
if (text === "/models") {
|
||||
this.editor.setText("");
|
||||
await this.showModelsSelector();
|
||||
return;
|
||||
}
|
||||
if (text === "/model" || text.startsWith("/model ")) {
|
||||
const searchTerm = text.startsWith("/model ") ? text.slice(7).trim() : undefined;
|
||||
this.editor.setText("");
|
||||
|
|
@ -2655,6 +2663,80 @@ export class InteractiveMode {
|
|||
});
|
||||
}
|
||||
|
||||
private async showModelsSelector(): Promise<void> {
|
||||
// Get all available models
|
||||
this.session.modelRegistry.refresh();
|
||||
const allModels = this.session.modelRegistry.getAvailable();
|
||||
|
||||
if (allModels.length === 0) {
|
||||
this.showStatus("No models available");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current enabledModels patterns
|
||||
const patterns = this.settingsManager.getEnabledModels();
|
||||
const hasFilter = patterns !== undefined && patterns.length > 0;
|
||||
|
||||
// Resolve patterns to get currently enabled model IDs
|
||||
const enabledModelIds = new Set<string>();
|
||||
if (hasFilter) {
|
||||
const scopedModels = await resolveModelScope(patterns, this.session.modelRegistry);
|
||||
for (const sm of scopedModels) {
|
||||
enabledModelIds.add(`${sm.model.provider}/${sm.model.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Track current enabled state
|
||||
const currentEnabledIds = new Set(enabledModelIds);
|
||||
let currentHasFilter = hasFilter;
|
||||
|
||||
this.showSelector((done) => {
|
||||
const selector = new ModelsSelectorComponent(
|
||||
{
|
||||
allModels,
|
||||
enabledModelIds: currentEnabledIds,
|
||||
hasEnabledModelsFilter: currentHasFilter,
|
||||
},
|
||||
{
|
||||
onModelToggle: async (modelId, enabled) => {
|
||||
if (enabled) {
|
||||
currentEnabledIds.add(modelId);
|
||||
} else {
|
||||
currentEnabledIds.delete(modelId);
|
||||
}
|
||||
currentHasFilter = true;
|
||||
|
||||
// Save to settings
|
||||
const newPatterns =
|
||||
currentEnabledIds.size === allModels.length
|
||||
? undefined // All enabled = clear filter
|
||||
: Array.from(currentEnabledIds);
|
||||
this.settingsManager.setEnabledModels(newPatterns);
|
||||
|
||||
// Update session's scoped models
|
||||
if (newPatterns && newPatterns.length > 0) {
|
||||
const defaultThinkingLevel = this.settingsManager.getDefaultThinkingLevel() ?? "off";
|
||||
const newScopedModels = await resolveModelScope(newPatterns, this.session.modelRegistry);
|
||||
this.session.setScopedModels(
|
||||
newScopedModels.map((sm) => ({
|
||||
model: sm.model,
|
||||
thinkingLevel: sm.thinkingLevel ?? defaultThinkingLevel,
|
||||
})),
|
||||
);
|
||||
} else {
|
||||
this.session.setScopedModels([]);
|
||||
}
|
||||
},
|
||||
onCancel: () => {
|
||||
done();
|
||||
this.ui.requestRender();
|
||||
},
|
||||
},
|
||||
);
|
||||
return { component: selector, focus: selector.getSettingsList() };
|
||||
});
|
||||
}
|
||||
|
||||
private showUserMessageSelector(): void {
|
||||
const userMessages = this.session.getUserMessagesForBranching();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue