feat: OpenAI-compatible transcriber provider (#5) #6

Merged
aep merged 15 commits from feat/5-openai-transcriber into main 2026-10-10 17:43:23 +03:00

15 Commits

Author SHA1 Message Date
Andrey Epifancev
17a5156cc6 docs(openspec): decision #19 (R-4) — final statuses for task-review minors; fix #18 wording (#5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:10:07 +04:00
Andrey Epifancev
ab698d00f3 fix(core): redact() Content-Disposition cut index; errorText never throws; design.md accuracy
M-1: redact()'s Content-Disposition cut computed its index against a
lowercased copy but sliced the original string — some Unicode characters
change length under toLowerCase(), which could let a fragment of
"Content-Disposition" survive the cut. Now uses a case-insensitive regex
matched directly against the original string.

T3.5: errorText() could itself throw on a pathological thrown value (a
null-prototype object with no toString/valueOf/Symbol.toPrimitive),
defeating transcribe()'s "never throws" guarantee in an already-caught
branch. Now wrapped defensively with a generic fallback message.

Also corrects two stale descriptions in design.md (classify/redact
signatures, and the post-promise rejection handling) so the archived
design document matches the shipped code.

Refs #5

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 01:24:58 +04:00
Andrey Epifancev
a948a80e7a docs: record decision #18 (R-3) — final review fix scope
Fixing M-1 (redact() Content-Disposition cut index), T3.5 (errorText
defensive wrap), and M-2 (design.md stale signatures) per the final
whole-branch reviewer's own bundling recommendation. Deferring M-3, M-4,
M-5 as cosmetic/unreachable/forward-looking with no current impact.

Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 01:20:17 +04:00
Andrey Epifancev
6f6df01cbd docs: record decisions #16-17 for Task 3/6 deviations from plan's literal code
R-1 (design #16): OpenAiTranscriber.transcribe's redact() call moved out of
the plan's literal post-try/catch position into a single guarded call site,
closing a never-throws gap the plan's own code left open (Task 3 fix loop).

R-2 (design #17): main.ts's settings field needed an override modifier to
satisfy noImplicitOverride against obsidian 1.13.1's new base Plugin.settings
field; the plan's literal code did not compile without it (Task 6).

Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 01:11:03 +04:00
Andrey Epifancev
4f6f202eda feat(obsidian): requestUrl adapter, settings tab, provider check command
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 01:08:50 +04:00
Andrey Epifancev
129e7c0b40 feat(core): provider check helpers — pick latest audio, format notice
Refs #5

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 01:01:29 +04:00
Andrey Epifancev
87826bc427 test: live AITUNNEL integration test, skipped without AITUNNEL_API_KEY
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:54:20 +04:00
Andrey Epifancev
812ace7f3c fix(core): guard the only redact() call in transcribe() so it truly cannot throw
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:49:12 +04:00
Andrey Epifancev
b38e160073 fix(core): wrap redact() in transcribe()'s try/catch so it never throws
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:46:02 +04:00
Andrey Epifancev
06d3528efd feat(core): OpenAI-compatible transcriber with prechecks, timeout and abort
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:31:01 +04:00
Andrey Epifancev
bfe44fa648 feat(core): provider settings, response classification, secret redaction
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:18:33 +04:00
Andrey Epifancev
3f6debc18b feat(core): HttpClient port and byte-exact multipart builder
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-28 00:00:08 +04:00
Andrey Epifancev
4059b72178 docs: implementation plan for openai-transcriber; plan-level decisions 13-15 (#5)
Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-27 23:52:39 +04:00
Andrey Epifancev
a7902222db docs(openspec): trim model setting too (#5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-27 23:44:18 +04:00
Andrey Epifancev
75b9b5e471 docs(openspec): propose openai-transcriber (#5)
Spec delta transcription-provider, proposal and design with decisions
made without discussion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
2026-09-27 23:39:58 +04:00