fix: Global/ProjectのmodelがModelログに反映されない不具合を修正 (#417)

* test: add regression for movement model log fallback

* fix: use configured model for movement model logging
This commit is contained in:
Junichi Kato 2026-02-28 12:54:32 +09:00 committed by GitHub
parent 7494149e75
commit 252c337456
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 2 deletions

View File

@ -155,8 +155,20 @@ vi.mock('../shared/exitCodes.js', () => ({
})); }));
import { executePiece } from '../features/tasks/execute/pieceExecution.js'; import { executePiece } from '../features/tasks/execute/pieceExecution.js';
import { resolvePieceConfigValues } from '../infra/config/index.js';
import { info } from '../shared/ui/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 { function makeConfig(): PieceConfig {
return { return {
name: 'test-piece', name: 'test-piece',
@ -178,6 +190,7 @@ function makeConfig(): PieceConfig {
describe('executePiece session loading', () => { describe('executePiece session loading', () => {
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
vi.mocked(resolvePieceConfigValues).mockReturnValue({ ...defaultResolvedConfigValues });
mockLoadPersonaSessions.mockReturnValue({ coder: 'saved-session-id' }); mockLoadPersonaSessions.mockReturnValue({ coder: 'saved-session-id' });
mockLoadWorktreeSessions.mockReturnValue({ coder: 'worktree-session-id' }); mockLoadWorktreeSessions.mockReturnValue({ coder: 'worktree-session-id' });
}); });
@ -261,6 +274,20 @@ describe('executePiece session loading', () => {
expect(mockInfo).toHaveBeenCalledWith('Model: (default)'); 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 () => { it('should log provider and model per movement with overrides', async () => {
await executePiece(makeConfig(), 'task', '/tmp/project', { await executePiece(makeConfig(), 'task', '/tmp/project', {
projectCwd: '/tmp/project', projectCwd: '/tmp/project',

View File

@ -339,6 +339,7 @@ export async function executePiece(
const shouldNotifyPieceComplete = shouldNotify && notificationSoundEvents?.pieceComplete !== false; const shouldNotifyPieceComplete = shouldNotify && notificationSoundEvents?.pieceComplete !== false;
const shouldNotifyPieceAbort = shouldNotify && notificationSoundEvents?.pieceAbort !== false; const shouldNotifyPieceAbort = shouldNotify && notificationSoundEvents?.pieceAbort !== false;
const currentProvider = globalConfig.provider; const currentProvider = globalConfig.provider;
const configuredModel = options.model ?? globalConfig.model;
if (!currentProvider) { if (!currentProvider) {
throw new Error('No provider configured. Set "provider" in ~/.takt/config.yaml'); 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 lastMovementName: string | undefined;
let currentIteration = 0; let currentIteration = 0;
let currentMovementProvider = currentProvider; let currentMovementProvider = currentProvider;
let currentMovementModel = globalConfig.model ?? '(default)'; let currentMovementModel = configuredModel ?? '(default)';
const phasePrompts = new Map<string, string>(); const phasePrompts = new Map<string, string>();
const movementIterations = new Map<string, number>(); const movementIterations = new Map<string, number>();
let engine: PieceEngine | null = null; let engine: PieceEngine | null = null;
@ -552,7 +553,9 @@ export async function executePiece(
}); });
out.info(`[${iteration}/${pieceConfig.maxMovements}] ${step.name} (${step.personaDisplayName})`); out.info(`[${iteration}/${pieceConfig.maxMovements}] ${step.name} (${step.personaDisplayName})`);
const movementProvider = providerInfo.provider ?? currentProvider; const movementProvider = providerInfo.provider ?? currentProvider;
const movementModel = providerInfo.model ?? '(default)'; const movementModel = providerInfo.model
?? (movementProvider === currentProvider ? configuredModel : undefined)
?? '(default)';
currentMovementProvider = movementProvider; currentMovementProvider = movementProvider;
currentMovementModel = movementModel; currentMovementModel = movementModel;
providerEventLogger.setMovement(step.name); providerEventLogger.setMovement(step.name);