diff --git a/src/main/ai/InferenceProvider.ts b/src/main/ai/InferenceProvider.ts index 2ef7773..f3aa2ef 100644 --- a/src/main/ai/InferenceProvider.ts +++ b/src/main/ai/InferenceProvider.ts @@ -5,6 +5,7 @@ export interface GenerateInput { text: string; todayKst: string; // ISO YYYY-MM-DD in KST dueDateCandidates: ParseResult[]; + vocab?: string[]; // v0.2.3 #3 — top-N kebab-case 태그. 미전달 시 빈 배열로 처리. } export interface HealthResult { ok: boolean; model?: string; reason?: string; } diff --git a/src/main/ai/LocalOllamaProvider.ts b/src/main/ai/LocalOllamaProvider.ts index 36239c3..d326ad8 100644 --- a/src/main/ai/LocalOllamaProvider.ts +++ b/src/main/ai/LocalOllamaProvider.ts @@ -37,7 +37,7 @@ export class LocalOllamaProvider implements InferenceProvider { headers: { 'content-type': 'application/json' }, body: JSON.stringify({ model: this.model, - prompt: buildPrompt(input.text, input.todayKst, input.dueDateCandidates), + prompt: buildPrompt(input.text, input.todayKst, input.dueDateCandidates, input.vocab ?? []), format: 'json', stream: false, options: { temperature: this.temperature, num_predict: this.numPredict } diff --git a/tests/unit/LocalOllamaProvider.test.ts b/tests/unit/LocalOllamaProvider.test.ts index 2d1155e..a9d60fb 100644 --- a/tests/unit/LocalOllamaProvider.test.ts +++ b/tests/unit/LocalOllamaProvider.test.ts @@ -26,6 +26,25 @@ describe('LocalOllamaProvider', () => { expect(r.title).toBe('회의'); }); + it('generate passes vocab into prompt body', async () => { + let capturedBody: string = ''; + mock.get('http://localhost:11434').intercept({ + path: '/api/generate', method: 'POST' + }).reply((opts) => { + capturedBody = opts.body as string; + return { statusCode: 200, data: JSON.stringify({ + response: JSON.stringify({ title: '회의', summary: 'a\nb\nc', tags: ['design'] }) + }) }; + }); + await new LocalOllamaProvider().generate({ + text: 'x', todayKst: '2026-05-02', dueDateCandidates: [], + vocab: ['design', 'meeting'] + }); + const parsed = JSON.parse(capturedBody) as { prompt: string }; + expect(parsed.prompt).toContain('design, meeting'); + expect(parsed.prompt).toContain('Prefer reusing'); + }); + it('generate throws on non-JSON', async () => { mock.get('http://localhost:11434').intercept({ path: '/api/generate', method: 'POST' }).reply(200, { response: 'not json'