@gotcos/glasses-server 6.27.3 → 6.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ ## 6.27.4
2
+
3
+ ### Fuzzy name corrections reach phone dictation
4
+
5
+ - `applyFuzzyCorrections` is now called inside `cleanOutboundDictation`, so text
6
+ arriving at `POST /dictation/finalize` gets the same Levenshtein pass the
7
+ server-transcription route has always had. It previously had exactly ONE call site
8
+ (`transcribe-audio.ts:252`), which meant phone Moonshine dictation — which sends
9
+ text, never audio — never received it. Verified by call-site enumeration, not by
10
+ reading a single file.
11
+ - Runs BEFORE the autoclean LLM, so the model sees corrected proper nouns instead of
12
+ being asked to guess at them, and it still helps on every path where autoclean is
13
+ off, over the character cap, or breaker-open.
14
+ - Same target construction (`getAllSpeakerNames()` + `getVocabulary()`) and the same
15
+ non-fatal posture as the existing call site: a correction pass is quality
16
+ enhancement, never a durability dependency.
17
+
18
+ **Measured reach, so callers do not assume more than it delivers.** The distance
19
+ budget is 1 edit for 5-8 character words, so it catches single-edit misses
20
+ (`Austen` → Austin, `Nyala` → Niala) but NOT `Miyala` → Niala (2 edits) or
21
+ `Yukoma` → Ukaoma (3). Wiring it does **not** remove the need for explicit
22
+ `whisper_corrections` entries on multi-edit misses; the new test asserts both
23
+ directions so that is not re-derived later.
24
+
25
+ `Austin` deliberately untouched — `correctAustinJustin()` already owns that pair.
26
+
27
+ Pairs with app 6.8.346, which breadcrumbs the finalize call so a missing correction
28
+ can be told apart from a finalize step that never ran.
29
+
1
30
  ## 6.27.3
2
31
 
3
32
  ### Durable, resumable video transport (private canary)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotcos/glasses-server",
3
- "version": "6.27.3",
3
+ "version": "6.27.4",
4
4
  "description": "COS Glasses \u2014 self-hosted AI heads-up-display server for Even G2 smart glasses, powered by Claude Code, Codex, or Cursor Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -35,6 +35,8 @@ import {
35
35
  applyNegativeRules,
36
36
  } from '../lib/hallucination-filter.js'
37
37
  import { applyCorrections } from '../lib/whisper-local.js'
38
+ import { applyFuzzyCorrections } from '../lib/fuzzy-correct.js'
39
+ import { getAllSpeakerNames } from '../lib/speaker-embeddings.js'
38
40
  import { transcribeWhisperPreview } from '../lib/whisper-preview.js'
39
41
  import { autoCleanDictation, AUTOCLEAN_MAX_CHARS } from '../lib/dictation-clean.js'
40
42
  import { getVocabulary } from '../lib/profile.js'
@@ -104,6 +106,27 @@ function routeAutoClean(req: { body?: any; query?: any }): AutoCleanRequest {
104
106
 
105
107
  async function cleanOutboundDictation(text: string, opts: AutoCleanRequest & { signal?: AbortSignal }): Promise<string> {
106
108
  let cleaned = applyNegativeRules(applyCorrections(text)).replace(/\s+/g, ' ').trim() || text
109
+ // applyCorrections above is an EXACT string map, so it only fixes misspellings someone
110
+ // already hand-authored. A novel miss ("Miyala" for Niala, "Yukoma" for Ukaoma) sails
111
+ // through it. The Levenshtein pass is what catches those, and until now it had exactly
112
+ // ONE call site — transcribe-audio.ts:252, the server-transcription route — so phone
113
+ // Moonshine dictation, which arrives here as text, never got it. Same construction and
114
+ // same non-fatal posture as that site, deliberately: targets are speaker names plus
115
+ // vocabulary, and a throw must never cost the user their transcript.
116
+ //
117
+ // Runs BEFORE the autoclean LLM so the model sees corrected proper nouns rather than
118
+ // being asked to guess at them, and it still helps on every path where autoclean is
119
+ // off, over the char cap, or breaker-open.
120
+ try {
121
+ const fuzzyTargets = [...getAllSpeakerNames(), ...getVocabulary()]
122
+ const { text: corrected, replacements } = applyFuzzyCorrections(cleaned, fuzzyTargets)
123
+ if (replacements > 0) {
124
+ console.log(`[prompt-draft] Fuzzy corrected ${replacements} word(s)`)
125
+ cleaned = corrected
126
+ }
127
+ } catch (fuzzyErr: any) {
128
+ console.warn(`[prompt-draft] Fuzzy correction failed (non-fatal): ${fuzzyErr?.message ?? fuzzyErr}`)
129
+ }
107
130
  if (!(opts.enabled ?? autoCleanDefaultEnabled())) return cleaned
108
131
  if (cleaned.length > AUTOCLEAN_MAX_CHARS || autoCleanBreaker.isOpen() || autoCleanCountToday() >= autoCleanDailyCap()) return cleaned
109
132
  const startedAt = Date.now()