feat: OpenAI-compatible transcriber provider (#5) #6
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/5-openai-transcriber"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #5.
Что сделано
Провайдер распознавания
OpenAiTranscriberдля OpenAI-совместимого/v1/audio/transcriptions(по умолчанию AITUNNEL,gpt-4o-transcribe); другой сервис — тот же код с другим base URL.src/core/— портHttpClient, побайтовый multipart-билдер, чтение иtrimнастроек, классификация ответов вtemporary/permanent, очистка секретов (redact), транскрайбер с предпроверками, таймаутом 5 мин и отменой; логика команды проверки (pickCheckAudio,checkNotice,mimeFromExt).src/obsidian/— адаптерrequestUrl, вкладка настроек (4 поля, ключ скрыт), команда «Проверить провайдер распознавания» (только Notice, без записи в заметки и очередь).tests/integration/aitunnel.test.ts— живой тест, запускается только при заданномAITUNNEL_API_KEY.openspec/changes/openai-transcriber/(proposal, specs, design.md с решениями 1–19).Проверка
npm test(безAITUNNEL_API_KEY): 18 файлов passed | 1 skipped; 243 tests passed | 1 skipped.npm run typecheck— чисто (оба прохода);npm run build— exit 0.1 passedtest-01.m4a→voice/source/20260927-000000-0000.m4adata.json{openai:{baseUrl, model, apiKey, language}},data.jsonне в gitrequestUrlФактические тексты уведомлений человек не приводил — подтверждено «все ок».
Rulings I made
redact()вtranscribe()обёрнут в отдельныйtry/catchс фиксированной строкой-заглушкой; отступление от буквального кода плана, который нарушал собственный инвариант «никогда не бросает».overrideу поляsettingsвVoiceNotePlugin: obsidian 1.13.1 объявляетPlugin.settings, аnoImplicitOverrideбез модификатора не даёт скомпилировать.rejectedпо оценке финального ревью «acceptable as-is»; исправлена формулировка #18.Находки
redact(): индекс срезаContent-Dispositionсчитался по строке в нижнем регистреab698d0ab698d0transcribe()(недостижимо)saveSettingsсохраняет только{openai}— сотрёт другие ключиdata.json, когда они появятся"/CRLF в name/filenametests/fakes.ts formPartsдекодирует бинарное тело как UTF-8removeEventListenerотдельноfinally(R-4)not.toContain(KEY)в e2e-тесте эха тела вакууменerrorText → redact(R-4)makeBoundaryвызывается до предпроверокerrorText()мог бросить на патологическом значенииab698d0NO_CHECK_AUDIOAITUNNEL_API_KEYв окружении → обычныйnpm testделает живой запрос(unset AITUNNEL_API_KEY; npm test)echo $AITUNNEL_API_KEY)Deferred
M-3, M-4, M-5, O-5, O-6 — попадут в follow-up issue при закрытии.
🤖 Generated with Claude Code