Opt-in typed dictation-companion results and captured-target delivery #963
michaelaperez-byte
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Proposal
Would you be open to an opt-in, typed dictation-companion provider contract on macOS? I am integrating a fully local writing companion, Ryu, with FluidVoice and would like it to work with stock, updateable releases rather than require a maintained custom build. This is a design discussion first, following CONTRIBUTING.md; the wire names and implementation split below are proposals, not assumed upstream decisions.
The workflow keeps FluidVoice's live streaming Parakeet preview. After recording stops, the companion processes that completed recording once, applying spelling, grammar, and Dragon-style spoken commands. FluidVoice remains responsible for delivering the accepted result to the captured destination. Grammar rules and dictionaries stay outside FluidVoice.
Related: #406 (voice-command triggers), discussion #875 (raw transcription after enhancement failure), and #962 (delayed redelivery). This proposes a provider integration contract rather than claiming to establish the cause of #962 or replacing those reports.
Why an ordinary final-string response is insufficient
Checked on 11 September 2026 against main
42e33e68ec473129ad090521e56c22c912a16db3, latest stock release v1.6.9, and PR #955 head38730e98cef244a81d3f2173021cc448d45c0723.LLMClienttrims the ordinary streamed content result. A dictatednew paragraphneeds a successful whitespace-only result, including boundary newlines.DictationPostProcessingServicerejects empty content and applies another formatting pass. Successful no-output commands and exact companion formatting need distinct semantics.These requirements would apply only to providers that explicitly opt in. Existing providers retain their current behaviour.
Suggested contract
A locally tested candidate uses a versioned capability (
FluidVoiceDictationCompanionProtocolVersion=2in the app anddictationCompanionProtocolVersion: 2on the provider). Naming and negotiation are open for review.Requests carry explicit
request_kind: "dictation", a recording transaction ID, frozen session mode/dialect, and bounded pre-cleanup command evidence. An optional captured selection includes its UTF-16 range, text, and UTF-8 SHA-256 for selection-rewrite commands.One OpenAI-compatible tool,
submit_dictation_result, returns exactly one typed result, bound to that transaction:{ "version": 2, "kind": "exact_text", "text": "Alpha, beta.\n\nGamma?", "transaction_id": "recording-pipeline-uuid" }Result kinds distinguish:
exact_text: non-empty content preserved code point for code point;layout: non-empty whitespace-only content;no_output: successful intentional empty output;control: one bounded, validated intent executed by FluidVoice, not the provider.The candidate controls cover undo, previous-word/sentence casing, vocabulary additions, mode/dialect changes, and selection rewrites. They have closed argument shapes and explicit size/count bounds. These could be reviewed separately from the simpler text/layout contract.
The evidence collector bounds revision history and final text. Exceeding a bound explicitly marks the evidence incomplete; it does not silently discard early speech. Only the recogniser final authorises commands—intermediate hypotheses are diagnostic history, not votes.
Delivery and retry semantics
FluidVoice owns a once-only execution ledger independent of the companion's bounded response cache. Provider acceptance, dispatch, callback success/failure, and unknown outcomes are separate states. New recordings invalidate pending delivery state, and stale callbacks cannot act on a newer transaction.
The strict candidate revalidates the captured Accessibility element and UTF-16 range before mutation. Selection rewrites additionally check the current text's exact UTF-8 digest; they replace only that selection. A changed target fails instead of redirecting output to current focus. Unsupported editors must be reported as unsupported rather than silently weakening that guarantee.
There is no automatic redelivery. A definite callback failure may allow an explicit retry of the immutable accepted result; an unknown outcome must not be treated as definitely safe to repeat. A successful Accessibility call is not itself proof that the destination retained the text.
Candidate evidence and limits
A local three-patch implementation applies to the pinned main and PR #955 heads. Recorded code-signing-disabled tests passed 24/24 focused cases on main; on PR #955, 66/66 companion/direct-audio cases, 19/19 adjacent cases, and the full 495/495 target. These are local candidate results, not upstream CI or signed-release acceptance. The patch series can be supplied for review after agreement on direction; it has not been published as a PR.
Real streaming Parakeet-to-editor delivery, cancellation, field changes, selection replacement, text retention, send, and empty-composer behaviour still require signed-build/live verification. No compatible stock capability is claimed, and the installed app has not been replaced.
Questions for maintainers
The aim is a small, maintainable upstream integration surface that lets independent local writing tools evolve without putting their language engines into FluidVoice.
All reactions