Skip to content

[feature] dictation polish rewrites the sentence instead of tidying it - #324

Merged
Lanznx merged 1 commit into
mainfrom
feature/polish-rewrites
Sep 2, 2026
Merged

[feature] dictation polish rewrites the sentence instead of tidying it#324
Lanznx merged 1 commit into
mainfrom
feature/polish-rewrites

Conversation

@YJack0000

Copy link
Copy Markdown
Contributor

Why

The AI polish felt like it barely did anything, on the desktop and on the phone alike. The prompt is why. It asked for filler removal, punctuation and paragraph breaks, and then said:

Keep the meaning and the speaker's own wording as much as possible.

That clause forbade everything else people actually wanted from the pass. Speech comes out with the qualifier before the claim and the self-correction three clauses after the mistake; the recogniser mishears a homophone; someone counts off "第一點…第二點…第三點…" and gets back a wall of prose. Repairing any of that means changing the wording — so the model didn't. It was doing what it was told.

What changed

The prompt now licenses a rewrite (identical text in polish.ts and TranscriptPolisher.swift):

  • reorder, merge and split clauses so the result reads in a writer's order
  • cut filler, false starts and repetition; on a self-correction, keep only what it corrected to
  • repair words the recogniser clearly misheard when context makes the intended word obvious
  • repunctuate from scratch
  • lay a spoken enumeration out as a numbered list, one item per line; bullets for unordered lists; paragraph breaks between topics — but prose said as prose stays prose

The limits move to where they belong. A free hand is one step from "improve this", and an improved transcript says things the speaker did not, under their name, in their document. So the prompt now forbids explicitly: adding or inferring content, summarising or dropping anything said, answering a question inside the transcript, changing the language or script, and trading the speaker's register for grander words.

Desktop round-trip budget 2s → 4s (POLISH_TIMEOUT_MS). Two seconds was sized for an edit whose output is as long as its input. A rewrite emits more than it was given, and the longest transcripts — the ones with the most to gain — are the slowest ones. A timeout pastes the raw text, which the user cannot tell apart from the polish having done nothing, so the tight budget would have shipped the feature only to the short dictations that barely needed it. iOS already allowed 6s (DictationCoordinator.polishBudget), which is part of why the desktop felt worse.

Settings copy updated on both platforms (zh-TW + en) to describe what it now does, including the "nothing is added or summarised away" promise.

What deliberately did not change

acceptPolish / accept keep the 0.3–2.0 length band. It is the guard that catches the model ignoring "do not summarise", and it is doing more work now than it was before, so it stays where it is — a list-formatted rewrite of a rambling utterance lands around 0.8, well inside. A rejected polish still silently pastes the raw transcript and logs at info.

Tests

  • desktop: the reordered/list-formatted rewrite is accepted (guard written for the old pass must not reject the new success case); the prompt licenses a rewrite and still carries every limit; the prompt is asserted word-for-word against the Swift literal — drift between platforms reaches the user as "it behaves differently on my phone", which is near-impossible to report or diagnose
  • iOS: the same accept case and the same two prompt assertions

bunx tsc --noEmit clean, bunx vitest run 291/291. The Swift tests could not be run locally — this machine has Command Line Tools but no full Xcode, so XCTest will not resolve; swift build on ParleyKit passes, the test file passes swiftc -parse, and the new assertions were checked by evaluating the same conditions against the built prompt. CI (ios-release.yml) runs swift test properly.

Worth a look in review

The prompt is the whole PR — if a limit reads as too loose or too tight, that's the thing to argue about.

🤖 Generated with Claude Code

The prompt asked for filler removal, punctuation and paragraph breaks, and
then told the model to "keep the speaker's own wording as much as possible".
That last clause forbade everything else the pass was wanted for. Speech comes
out with the qualifier before the claim and the correction three clauses after
the mistake; the recogniser mishears a homophone; someone counts off "第一點…
第二點…" and gets back a wall of prose. Repairing any of that means changing
the wording, so the model left it alone, and the feature read as barely doing
anything on either platform.

So the licence is broad now — reorder, merge, split, repair misheard words,
lay a spoken enumeration out as a numbered list — and the limits move
somewhere safer: nothing may be added, nothing said may be dropped, and the
transcript is never a request to the model. "Rewrite freely" is one step from
"improve", and an improved transcript says things the speaker did not, under
their name, in their document.

Desktop's round-trip budget goes 2s → 4s. Two was sized for an edit whose
output is as long as its input; a rewrite emits more than it was given, and
the longest transcripts — the ones with the most to gain — are the slowest.
A timeout pastes the raw text, which is indistinguishable from the polish
doing nothing, so the tight budget would have delivered the feature only to
the short dictations that barely needed it. iOS already allowed six.

Both copies of the prompt are word-for-word identical, and a test now reads
the Swift literal and asserts it: drift reaches the user as "it behaves
differently on my phone", which is close to impossible to report.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

✅ SonarQube Quality Gate passed — pathorsAI_parley

0 open issues on this PR.

@Lanznx
Lanznx merged commit 2ef9cf3 into main Sep 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants