fix: Project-level model config ignored — getLocalLayerValue missing model case
This commit is contained in:
parent
e57612d703
commit
753deb6539
@ -501,6 +501,60 @@ describe('analytics config resolution', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('model config resolution', () => {
|
||||||
|
let testDir: string;
|
||||||
|
let originalTaktConfigDir: string | undefined;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
testDir = join(tmpdir(), `takt-test-${randomUUID()}`);
|
||||||
|
mkdirSync(testDir, { recursive: true });
|
||||||
|
originalTaktConfigDir = process.env.TAKT_CONFIG_DIR;
|
||||||
|
process.env.TAKT_CONFIG_DIR = join(testDir, 'global-takt');
|
||||||
|
invalidateGlobalConfigCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
if (originalTaktConfigDir === undefined) {
|
||||||
|
delete process.env.TAKT_CONFIG_DIR;
|
||||||
|
} else {
|
||||||
|
process.env.TAKT_CONFIG_DIR = originalTaktConfigDir;
|
||||||
|
}
|
||||||
|
invalidateGlobalConfigCache();
|
||||||
|
|
||||||
|
if (existsSync(testDir)) {
|
||||||
|
rmSync(testDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve project model over global model', () => {
|
||||||
|
const projectConfigDir = getProjectConfigDir(testDir);
|
||||||
|
mkdirSync(projectConfigDir, { recursive: true });
|
||||||
|
writeFileSync(join(projectConfigDir, 'config.yaml'), 'piece: default\nmodel: project-model\n');
|
||||||
|
|
||||||
|
const globalConfigDir = process.env.TAKT_CONFIG_DIR!;
|
||||||
|
mkdirSync(globalConfigDir, { recursive: true });
|
||||||
|
writeFileSync(join(globalConfigDir, 'config.yaml'), 'model: global-model\n');
|
||||||
|
|
||||||
|
expect(resolveConfigValue(testDir, 'model')).toBe('project-model');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to global model when project model is not set', () => {
|
||||||
|
const projectConfigDir = getProjectConfigDir(testDir);
|
||||||
|
mkdirSync(projectConfigDir, { recursive: true });
|
||||||
|
writeFileSync(join(projectConfigDir, 'config.yaml'), 'piece: default\n');
|
||||||
|
|
||||||
|
const globalConfigDir = process.env.TAKT_CONFIG_DIR!;
|
||||||
|
mkdirSync(globalConfigDir, { recursive: true });
|
||||||
|
writeFileSync(join(globalConfigDir, 'config.yaml'), 'model: global-model\n');
|
||||||
|
|
||||||
|
expect(resolveConfigValue(testDir, 'model')).toBe('global-model');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined when neither project nor global model is set', () => {
|
||||||
|
expect(resolveConfigValue(testDir, 'model')).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('isVerboseMode', () => {
|
describe('isVerboseMode', () => {
|
||||||
let testDir: string;
|
let testDir: string;
|
||||||
let originalTaktConfigDir: string | undefined;
|
let originalTaktConfigDir: string | undefined;
|
||||||
|
|||||||
@ -129,6 +129,7 @@ export interface PersistedGlobalConfig {
|
|||||||
export interface ProjectConfig {
|
export interface ProjectConfig {
|
||||||
piece?: string;
|
piece?: string;
|
||||||
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
||||||
|
model?: string;
|
||||||
providerOptions?: MovementProviderOptions;
|
providerOptions?: MovementProviderOptions;
|
||||||
/** Provider-specific permission profiles */
|
/** Provider-specific permission profiles */
|
||||||
providerProfiles?: ProviderPermissionProfiles;
|
providerProfiles?: ProviderPermissionProfiles;
|
||||||
|
|||||||
@ -487,6 +487,7 @@ export const GlobalConfigSchema = z.object({
|
|||||||
export const ProjectConfigSchema = z.object({
|
export const ProjectConfigSchema = z.object({
|
||||||
piece: z.string().optional(),
|
piece: z.string().optional(),
|
||||||
provider: z.enum(['claude', 'codex', 'opencode', 'mock']).optional(),
|
provider: z.enum(['claude', 'codex', 'opencode', 'mock']).optional(),
|
||||||
|
model: z.string().optional(),
|
||||||
provider_options: MovementProviderOptionsSchema,
|
provider_options: MovementProviderOptionsSchema,
|
||||||
provider_profiles: ProviderPermissionProfilesSchema,
|
provider_profiles: ProviderPermissionProfilesSchema,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -116,6 +116,8 @@ function getLocalLayerValue<K extends ConfigParameterKey>(
|
|||||||
return project.piece as LoadedConfig[K] | undefined;
|
return project.piece as LoadedConfig[K] | undefined;
|
||||||
case 'provider':
|
case 'provider':
|
||||||
return project.provider as LoadedConfig[K] | undefined;
|
return project.provider as LoadedConfig[K] | undefined;
|
||||||
|
case 'model':
|
||||||
|
return project.model as LoadedConfig[K] | undefined;
|
||||||
case 'autoPr':
|
case 'autoPr':
|
||||||
return project.auto_pr as LoadedConfig[K] | undefined;
|
return project.auto_pr as LoadedConfig[K] | undefined;
|
||||||
case 'draftPr':
|
case 'draftPr':
|
||||||
|
|||||||
@ -12,6 +12,8 @@ export interface ProjectLocalConfig {
|
|||||||
piece?: string;
|
piece?: string;
|
||||||
/** Provider selection for agent runtime */
|
/** Provider selection for agent runtime */
|
||||||
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
provider?: 'claude' | 'codex' | 'opencode' | 'mock';
|
||||||
|
/** Model selection for agent runtime */
|
||||||
|
model?: string;
|
||||||
/** Auto-create PR after worktree execution */
|
/** Auto-create PR after worktree execution */
|
||||||
auto_pr?: boolean;
|
auto_pr?: boolean;
|
||||||
/** Create PR as draft */
|
/** Create PR as draft */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user