diff --git a/src/__tests__/pieceExecution-session-loading.test.ts b/src/__tests__/pieceExecution-session-loading.test.ts index bcc952c..5664378 100644 --- a/src/__tests__/pieceExecution-session-loading.test.ts +++ b/src/__tests__/pieceExecution-session-loading.test.ts @@ -155,8 +155,20 @@ vi.mock('../shared/exitCodes.js', () => ({ })); import { executePiece } from '../features/tasks/execute/pieceExecution.js'; +import { resolvePieceConfigValues } from '../infra/config/index.js'; import { info } from '../shared/ui/index.js'; +const defaultResolvedConfigValues = { + notificationSound: true, + notificationSoundEvents: {}, + provider: 'claude', + runtime: undefined, + preventSleep: false, + model: undefined, + observability: undefined, + analytics: undefined, +}; + function makeConfig(): PieceConfig { return { name: 'test-piece', @@ -178,6 +190,7 @@ function makeConfig(): PieceConfig { describe('executePiece session loading', () => { beforeEach(() => { vi.clearAllMocks(); + vi.mocked(resolvePieceConfigValues).mockReturnValue({ ...defaultResolvedConfigValues }); mockLoadPersonaSessions.mockReturnValue({ coder: 'saved-session-id' }); mockLoadWorktreeSessions.mockReturnValue({ coder: 'worktree-session-id' }); }); @@ -261,6 +274,20 @@ describe('executePiece session loading', () => { expect(mockInfo).toHaveBeenCalledWith('Model: (default)'); }); + it('should log configured model from global/project settings when movement model is unresolved', async () => { + vi.mocked(resolvePieceConfigValues).mockReturnValue({ + ...defaultResolvedConfigValues, + model: 'gpt-4.1', + }); + + await executePiece(makeConfig(), 'task', '/tmp/project', { + projectCwd: '/tmp/project', + }); + + const mockInfo = vi.mocked(info); + expect(mockInfo).toHaveBeenCalledWith('Model: gpt-4.1'); + }); + it('should log provider and model per movement with overrides', async () => { await executePiece(makeConfig(), 'task', '/tmp/project', { projectCwd: '/tmp/project', diff --git a/src/features/tasks/execute/pieceExecution.ts b/src/features/tasks/execute/pieceExecution.ts index b7a33d6..b386169 100644 --- a/src/features/tasks/execute/pieceExecution.ts +++ b/src/features/tasks/execute/pieceExecution.ts @@ -339,6 +339,7 @@ export async function executePiece( const shouldNotifyPieceComplete = shouldNotify && notificationSoundEvents?.pieceComplete !== false; const shouldNotifyPieceAbort = shouldNotify && notificationSoundEvents?.pieceAbort !== false; const currentProvider = globalConfig.provider; + const configuredModel = options.model ?? globalConfig.model; if (!currentProvider) { throw new Error('No provider configured. Set "provider" in ~/.takt/config.yaml'); } @@ -453,7 +454,7 @@ export async function executePiece( let lastMovementName: string | undefined; let currentIteration = 0; let currentMovementProvider = currentProvider; - let currentMovementModel = globalConfig.model ?? '(default)'; + let currentMovementModel = configuredModel ?? '(default)'; const phasePrompts = new Map(); const movementIterations = new Map(); let engine: PieceEngine | null = null; @@ -552,7 +553,9 @@ export async function executePiece( }); out.info(`[${iteration}/${pieceConfig.maxMovements}] ${step.name} (${step.personaDisplayName})`); const movementProvider = providerInfo.provider ?? currentProvider; - const movementModel = providerInfo.model ?? '(default)'; + const movementModel = providerInfo.model + ?? (movementProvider === currentProvider ? configuredModel : undefined) + ?? '(default)'; currentMovementProvider = movementProvider; currentMovementModel = movementModel; providerEventLogger.setMovement(step.name);