feat(v031): SettingsService.{getVisionModel,setVisionModel,getVisionCapableCache,setVisionCapableCache}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
altair823
2026-05-10 04:42:52 +09:00
parent 7a56184ad2
commit 463be7cf26
2 changed files with 56 additions and 1 deletions

View File

@@ -17,7 +17,11 @@ const SettingsSchema = z.object({
// v0.3.0 Cut E — 양방향 git sync 설정. 모두 optional — 미구성 시 sync 비활성.
sync_repo_url: z.string().nullable().optional(),
sync_auto_enabled: z.boolean().optional(),
sync_interval_min: z.number().int().min(5).optional()
sync_interval_min: z.number().int().min(5).optional(),
// v0.3.1 Cut F
vision_model: z.string().nullable().optional(),
vision_capable_cache: z.array(z.string()).optional(),
vision_cache_at: z.string().optional()
}).strict();
export type Settings = z.infer<typeof SettingsSchema>;
@@ -127,6 +131,30 @@ export class SettingsService {
await this.persist(next);
}
/** v0.3.1 Cut F — 선택된 vision model. null = 미선택. */
async getVisionModel(): Promise<string | null> {
const s = await this.load();
return s.vision_model ?? null;
}
async setVisionModel(value: string | null): Promise<void> {
const current = await this.load();
const next: Settings = { ...current, vision_model: value };
await this.persist(next);
}
/** v0.3.1 Cut F — /api/tags 조회 결과 캐시. 기본 빈 배열 + null timestamp. */
async getVisionCapableCache(): Promise<{ models: string[]; at: string | null }> {
const s = await this.load();
return { models: s.vision_capable_cache ?? [], at: s.vision_cache_at ?? null };
}
async setVisionCapableCache(models: string[], now: Date): Promise<void> {
const current = await this.load();
const next: Settings = { ...current, vision_capable_cache: models, vision_cache_at: now.toISOString() };
await this.persist(next);
}
private async persist(next: Settings): Promise<void> {
await mkdir(dirname(this.filePath), { recursive: true });
const tmpPath = this.filePath + '.tmp';