uttrflow / uttrflow/uttrflow-swift
The AI suggestion prompt tells the model a Hindi writer "writes casually, without sentence punctuation", and gives Devanagari lines a smaller token allowance than the line needs
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
`Register` describes the person's writing to the local model. Two parts of it read Devanagari as if it were broken English.
**1. Sentence punctuation.** `Register.sentenceCaseShare` (`Sources/UttrflowPredict/Register.swift:234-240`) counts a line as a sentence only if it opens with an uppercase letter and ends in `.`, `!` or `?`:
```swift
return first.isUppercase && ".!?".contains(last)
```
Devanagari has no case, and a Hindi sentence ends in "।". Three properly punctuated Hindi lines, each ending in "।", score 0.0 (English lines score 1.0). The prompt then carries the hint at `:137`: "this person writes casually, without sentence punctuation". Checked by running the function copied from `origin/main` 26d7bc1.
**2. Token allowance.** `maxTokens` (`Register.swift:104-113`) is `typicalLength / 2`, where `typicalLength` is measured in Characters. The comment says half the character count is "about twice the tokens the line needs". That holds for English, where a token is about four letters. Devanagari takes several tokens per word. For one Hindi and one English line, with `PromptBuilder`'s own token estimate:
| line | Characters | estimated tokens | `maxTokens` | allowance ÷ need |
|---|---|---|---|---|
| Hindi | 49 | 34 | 24 | 0.7× |
| English | 72 | 19 | 36 | 1.9× |
(#536 measured that the Devanagari tokenizer path is the slow one as well.) When the limit hits, `wholeWords` (`Sources/UttrflowLocalModel/MLXCandidateScorer.swift:288`) cuts back to the last space, so Hindi completions come back a word or two long rather than as the line.
**3. Script.** Nothing tells the model which script the typed line is in. The instructions and examples (`MLXCandidateScorer.swift:428-439`) are English only. No check requires a completion to stay in the typed script, so a romanised continuation after Devanagari (or the reverse) is accepted when it repeats the typed text.
The real tokenizer wasn't run; the estimate above is `PromptBuilder.estimatedTokens`.
## Why it matters
A Hindi typist who punctuates carefully is described to the model as careless, which pushes completions toward unpunctuated chat style. Their completions are also cut to a fraction of the English length. Both come from constants tuned on English.
## Acceptance criteria
- `sentenceCaseShare` treats a caseless script's first letter as a valid opening and accepts "।" as an ending, so the three Hindi lines score 1.0.
- `maxTokens` is derived from an estimated token count of the typical line (the `PromptBuilder` estimate, or the tokenizer when loaded), not from Characters / 2. The Hindi row above gets at least the same ratio as the English row.
- A completion whose letters are in a different script from the typed line's last word is dropped, or the prompt names the script. Pick one and test it.
- Tests: `Tests/UttrflowPredictTests/RegisterTests.swift` for 1 and 2, and `Tests/UttrflowLocalModelTests/PromptTests.swift` or `CompletionParsingTests.swift` for 3.
Contributor guide
Research direction
Start with Sources/UttrflowPredict/Register.swift and Tests/UttrflowPredictTests/RegisterTests.swift, then read PromptBuilder.estimatedTokens and the cited MLXCandidateScorer.swift prompt and completion paths. Run the Hindi and English examples through the named tests. Done means the acceptance criteria for sentence scoring, token allowance, and script handling are covered by tests and the existing suites pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- ai, internationalization, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100