fix(ui): stop pinning inherited effort as a session choice on send
Sending recorded the effective variant - inherited settings/agent defaults included - as the session's explicit per-session choice, so the picker jumped from Default to the inherited effort right after the send and the session stopped following later default changes. Record only an explicit picker override when the send reflects the live selection; sends carrying a captured configuration for another session keep their captured variant.
This commit is contained in:
@@ -4,6 +4,7 @@ import { useProjectsStore } from '@/stores/useProjectsStore';
|
||||
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
||||
import { useSessionWorktreeStore } from './session-worktree-store';
|
||||
import { expandSlashCommandGoalObjective, routeMessage, useSessionUIStore } from './session-ui-store';
|
||||
import { useSelectionStore } from './selection-store';
|
||||
import { setActionRefs, setOptimisticRefs } from './session-actions';
|
||||
import { useSkillsStore } from '@/stores/useSkillsStore';
|
||||
import { useCommandsStore } from '@/stores/useCommandsStore';
|
||||
@@ -352,6 +353,100 @@ describe('sendMessage captured target', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendMessage effort recording', () => {
|
||||
let originalSendMessage;
|
||||
const calls = [];
|
||||
|
||||
beforeEach(() => {
|
||||
calls.length = 0;
|
||||
const childStore = {
|
||||
getState: () => ({ session: [], message: {}, part: {}, session_status: {} }),
|
||||
setState: () => {},
|
||||
};
|
||||
const childStores = {
|
||||
children: new Map(),
|
||||
ensureChild: () => childStore,
|
||||
getChild: () => childStore,
|
||||
};
|
||||
setActionRefs(opencodeClient, childStores, () => '/current/project');
|
||||
setOptimisticRefs(() => {}, () => {});
|
||||
useConfigStore.setState({ isConnected: true });
|
||||
useSessionUIStore.setState({
|
||||
currentSessionId: 'session-current',
|
||||
currentSessionDirectory: '/current/project',
|
||||
newSessionDraft: { open: false, directoryOverride: null, parentID: null },
|
||||
});
|
||||
|
||||
originalSendMessage = opencodeClient.sendMessage;
|
||||
opencodeClient.sendMessage = async (params) => {
|
||||
calls.push(params);
|
||||
return 'msg';
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
opencodeClient.sendMessage = originalSendMessage;
|
||||
});
|
||||
|
||||
const sendWithVariant = (variant, sessionId) => useSessionUIStore.getState().sendMessage(
|
||||
'hello',
|
||||
'provider-a',
|
||||
'model-a',
|
||||
'plan',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
variant,
|
||||
'normal',
|
||||
{ target: { runtimeKey: getRuntimeKey(), sessionId, directory: '/current/project' } },
|
||||
);
|
||||
|
||||
test('does not pin an inherited effort as the session choice', async () => {
|
||||
useConfigStore.setState({
|
||||
currentProviderId: 'provider-a',
|
||||
currentModelId: 'model-a',
|
||||
currentAgentName: 'plan',
|
||||
currentVariant: 'low',
|
||||
currentVariantSelection: { override: undefined, inherited: 'low' },
|
||||
});
|
||||
|
||||
await sendWithVariant('low', 'session-current');
|
||||
|
||||
// The send still carries the inherited effort; it is just not recorded
|
||||
// as this session's explicit choice.
|
||||
expect(calls[0].variant).toBe('low');
|
||||
expect(useSelectionStore.getState().getAgentModelVariantForSession('session-current', 'plan', 'provider-a', 'model-a')).toBe(undefined);
|
||||
});
|
||||
|
||||
test('records an explicit effort choice with the send', async () => {
|
||||
useConfigStore.setState({
|
||||
currentProviderId: 'provider-a',
|
||||
currentModelId: 'model-a',
|
||||
currentAgentName: 'plan',
|
||||
currentVariant: 'high',
|
||||
currentVariantSelection: { override: 'high', inherited: 'low' },
|
||||
});
|
||||
|
||||
await sendWithVariant('high', 'session-current');
|
||||
|
||||
expect(useSelectionStore.getState().getAgentModelVariantForSession('session-current', 'plan', 'provider-a', 'model-a')).toBe('high');
|
||||
});
|
||||
|
||||
test('keeps the captured variant for a send targeting another session', async () => {
|
||||
useConfigStore.setState({
|
||||
currentProviderId: 'provider-a',
|
||||
currentModelId: 'model-a',
|
||||
currentAgentName: 'plan',
|
||||
currentVariant: 'low',
|
||||
currentVariantSelection: { override: undefined, inherited: 'low' },
|
||||
});
|
||||
|
||||
await sendWithVariant('low', 'session-other');
|
||||
|
||||
expect(useSelectionStore.getState().getAgentModelVariantForSession('session-other', 'plan', 'provider-a', 'model-a')).toBe('low');
|
||||
});
|
||||
});
|
||||
|
||||
describe('slash-command goal objectives', () => {
|
||||
test('expands every $ARGUMENTS reference from the authoritative command template', () => {
|
||||
expect(expandSlashCommandGoalObjective('/issue--to-pr LIN-123 --draft', [{
|
||||
|
||||
@@ -1707,7 +1707,21 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
|
||||
if (targetSessionId && effectiveAgent) {
|
||||
useSelectionStore.getState().saveSessionAgentSelection(targetSessionId, effectiveAgent)
|
||||
useSelectionStore.getState().saveAgentModelForSession(targetSessionId, effectiveAgent, providerID, modelID)
|
||||
useSelectionStore.getState().saveAgentModelVariantForSession(targetSessionId, effectiveAgent, providerID, modelID, variant)
|
||||
// `variant` is the effective effort, inherited defaults included.
|
||||
// Recording it verbatim would pin the inherited default as this
|
||||
// session's explicit choice, so the picker jumps from "Default" to
|
||||
// that effort after the send. When the send reflects the live picker
|
||||
// selection, record only an explicit override; sends carrying a
|
||||
// captured configuration for another context keep their variant.
|
||||
const configState = useConfigStore.getState()
|
||||
const reflectsLiveSelection = targetSessionId === get().currentSessionId
|
||||
&& configState.currentProviderId === providerID
|
||||
&& configState.currentModelId === modelID
|
||||
&& configState.currentAgentName === effectiveAgent
|
||||
const variantToRecord = reflectsLiveSelection
|
||||
? configState.currentVariantSelection.override ?? undefined
|
||||
: variant
|
||||
useSelectionStore.getState().saveAgentModelVariantForSession(targetSessionId, effectiveAgent, providerID, modelID, variantToRecord)
|
||||
}
|
||||
|
||||
if (targetSessionId) {
|
||||
|
||||
Reference in New Issue
Block a user