diff --git a/v2/src/lib/components/Agent/AgentPane.svelte b/v2/src/lib/components/Agent/AgentPane.svelte index 3191e6a..277e1e8 100644 --- a/v2/src/lib/components/Agent/AgentPane.svelte +++ b/v2/src/lib/components/Agent/AgentPane.svelte @@ -58,6 +58,8 @@ useWorktrees?: boolean; /** Prepended to system_prompt for agent role instructions */ agentSystemPrompt?: string; + /** Model override (e.g. 'claude-sonnet-4-5-20250514'). Passed to sidecar. */ + model?: string; /** Extra env vars injected into agent process (e.g. BTMSG_AGENT_ID) */ extraEnv?: Record; /** Auto-triggered prompt (e.g. periodic context refresh). Picked up when agent is idle. */ @@ -67,7 +69,7 @@ onExit?: () => void; } - let { sessionId, projectId, prompt: initialPrompt = '', cwd: initialCwd, profile: profileName, provider: providerId = 'claude', capabilities = DEFAULT_CAPABILITIES, useWorktrees = false, agentSystemPrompt, extraEnv, autoPrompt, onautopromptconsumed, onExit }: Props = $props(); + let { sessionId, projectId, prompt: initialPrompt = '', cwd: initialCwd, profile: profileName, provider: providerId = 'claude', capabilities = DEFAULT_CAPABILITIES, useWorktrees = false, agentSystemPrompt, model: modelOverride, extraEnv, autoPrompt, onautopromptconsumed, onExit }: Props = $props(); let session = $derived(getAgentSession(sessionId)); let inputPrompt = $state(initialPrompt); @@ -209,6 +211,7 @@ setting_sources: ['user', 'project'], claude_config_dir: profile?.config_dir, system_prompt: systemPrompt, + model: modelOverride || undefined, worktree_name: useWorktrees ? sessionId : undefined, extra_env: extraEnv, }); diff --git a/v2/src/lib/components/Workspace/AgentSession.svelte b/v2/src/lib/components/Workspace/AgentSession.svelte index 69f7332..118e201 100644 --- a/v2/src/lib/components/Workspace/AgentSession.svelte +++ b/v2/src/lib/components/Workspace/AgentSession.svelte @@ -269,6 +269,7 @@ capabilities={providerMeta?.capabilities} useWorktrees={project.useWorktrees ?? false} agentSystemPrompt={agentPrompt} + model={project.model} extraEnv={agentEnv} autoPrompt={contextRefreshPrompt} onautopromptconsumed={handleAutoPromptConsumed} diff --git a/v2/src/lib/components/Workspace/SettingsTab.svelte b/v2/src/lib/components/Workspace/SettingsTab.svelte index 8acba3f..dfca0a8 100644 --- a/v2/src/lib/components/Workspace/SettingsTab.svelte +++ b/v2/src/lib/components/Workspace/SettingsTab.svelte @@ -12,6 +12,8 @@ addGroup, removeGroup, switchGroup, + emitAgentStop, + emitAgentStart, } from '../../stores/workspace.svelte'; import { deriveIdentifier, type GroupAgentRole, AGENT_ROLE_ICONS } from '../../types/groups'; import { ProjectId, GroupId } from '../../types/ids'; @@ -56,6 +58,7 @@ let expandedProvider = $state(null); let registeredProviders = $derived(getProviders()); let providerDropdownOpenFor = $state(null); + let modelDropdownOpenFor = $state(null); let activeGroupId = $derived(getActiveGroupId()); let activeGroup = $derived(getActiveGroup()); @@ -372,6 +375,7 @@ uiFontDropdownOpen = false; termFontDropdownOpen = false; providerDropdownOpenFor = null; + modelDropdownOpenFor = null; secretsKeyDropdownOpen = false; } if (!target.closest('.icon-field')) { @@ -389,6 +393,7 @@ termFontDropdownOpen = false; iconPickerOpenFor = null; profileDropdownOpenFor = null; + modelDropdownOpenFor = null; secretsKeyDropdownOpen = false; } } @@ -961,6 +966,7 @@
{#each activeGroup.agents ?? [] as agent (agent.id)} + {@const agentProvider = registeredProviders.find(p => p.id === (agent.provider ?? 'claude'))}
{AGENT_ROLE_ICONS[agent.role] ?? '🤖'} @@ -1000,17 +1006,89 @@
+ {#if registeredProviders.length > 1} +
+ + + Provider + +
+ + {#if providerDropdownOpenFor === agent.id} + + {/if} +
+
+ {/if} +
Model - updateAgent(activeGroupId, agent.id, { model: (e.target as HTMLInputElement).value || undefined })} - /> +
+ + {#if modelDropdownOpenFor === agent.id} + + {/if} +
{#if agent.role === 'manager'} @@ -1086,6 +1164,17 @@ >
+
+ +
+
@@ -1111,6 +1200,7 @@
{#each activeGroup.projects as project} + {@const projProvider = registeredProviders.find(p => p.id === (project.provider ?? 'claude'))}
@@ -1239,7 +1329,7 @@ role="option" aria-selected={(project.provider ?? 'claude') === prov.id} onclick={() => { - updateProject(activeGroupId, project.id, { provider: prov.id }); + updateProject(activeGroupId, project.id, { provider: prov.id, model: undefined }); providerDropdownOpenFor = null; }} > @@ -1252,6 +1342,53 @@
{/if} +
+ + + Model + +
+ + {#if modelDropdownOpenFor === project.id} + + {/if} +
+
+
@@ -1337,6 +1474,17 @@ >
+
+ +
+