Repository navigation
LiveLingo 2.0: composer rewrite, voice dictation, model warm-up and auto-update - #1
Merged
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Drop the 1.x translation stack (Gemma/Marian engines, routing and fallback chain, language detection, old speech engines, processors, overlay and settings UI, benchmark tool) and keep the platform layer, model download infrastructure, localization and update service. Desktop is reduced to a tray + global hotkey shell with a schema 3 settings model. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…commit snapshot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…check and retry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…archives Every asset now carries a SHA256 that is verified after download; a mismatch deletes the file and fails the install. Archives are unpacked with the .NET readers (tar.gz, zip) or SharpCompress (tar.bz2) into one flattened directory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A failed Hugging Face request is no longer re-sent to a third-party host. Only a mirror the user configured explicitly is used. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- verify existing asset files before trusting them; delete on hash failure - serialize LlamaServerHost disposal with per-role locks - fail all pending translations together on a service-level failure - mac window tracker returns no target instead of a pid posing as a window id Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e next start Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d draft Audio becomes units of a DraftSession; live hypotheses go to Draft.Pending. Sentence splitting reuses TextUnits (now also ends at ;, … and repeated terminators) instead of a second splitter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…he draft Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ry, parity probe The llama-server cleaner matches the POC cleaner on 93% of gate outcomes. Requests now close their connection after each call, which fixes sporadic connection errors against llama-server. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The composer can listen (tap = hands-free, hold = push-to-talk), show the live text, clean sentences while speaking and translate them as they finish. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…esults Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…yed text selectable Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…their wording Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…r and glossary The glossary feeds second-pass hotwords, cleanup, the fidelity gate and translation prompts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…tible endpoint Per-role consent switches in settings (off by default, text only), https endpoint validation, API key kept in the system secret store, routing read on every call with no local fallback after a cloud failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend the spike with --bench, --park and --headless; record the macOS results of S8a-S8g in the design (IME needs a keyCode 229 check, warm window is parked instead of hidden, headless adapter is unusable). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the Vite/TypeScript toolchain with vendored Preact and htm assembled at load time by the host, test with Playwright .NET, and record the Blazor WASM memory comparison that ruled out the C# UI option. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Vendor preact and htm, split the prototype stylesheet into tokens and base, assemble the embedded assets into one nonce-protected page in WebPage, and add LiveLingo.Web.Tests that check the page and drive it in WebKit and Chromium with Playwright. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- WebIntent: closed, strictly parsed intent set (size/range/version checks, no echo in rejection reasons) - ComposerViewState.From: pure snapshot of the composer view model, with golden JSON fixtures for 25 prototype states - WebBridge: ready handshake, 16 ms coalesced whole-state pushes, monotonic rev, strings message - ComposerIntents: maps intents onto the view model; source revision rule keeps IME input safe - WebSurface: NativeWebView host (no navigation, no new windows, non-persistent data) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preact/htm page that draws ComposerViewState and sends closed-set intents. Playwright tests replay the golden snapshots in WebKit and Chromium. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace ComposerWindow.axaml with a persistent, parked ComposerWindow that hosts a long-lived WebSurface; the page is reloaded on every park so each summon starts from a clean page. - ComposerWebSession wires one ComposerViewModel to the page per summon (strings, snapshots, toast, focus, openMenu, size, wide). - IWindowTracker.Activate returns the keyboard to the application the user came from when the composer closes; text injectors reuse it. - Remove the unused `reset` message from the page contract. - Delete the old XAML composer, its dialogs and tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The settings window is a thin Avalonia shell around the shared web bundle (entry "settings"). State stays in SettingsViewModel; the page draws whole snapshots and sends closed-set intents (setting, addTerm, removeTerm, cloudToggle, consent, saveKey, forgetKey, removeLegacyModels). The cloud consent dialog and the hotkey recorder moved to the page; the API key is never part of a snapshot and never printed. The old XAML window, the custom Avalonia controls, the Avalonia theme and the headless test host are deleted. style-src-attr is relaxed for WebKit's native select. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…kept-original reasons - Composer.CleanupEnabled (default on): off creates no CleanupScheduler, hides the "Clean" output, starts the composer on the original wording and stops the cloud chip claiming a cloud cleanup. The settings page gets the switch. - The models group gets a status dialog listing version, system and switch states; it never contains terms, endpoint, deployment, device name or key. - FidelityGate now returns a typed GateRejection instead of an English sentence, so the "original kept" note follows the interface language (composer.gate.* keys). - Modal helper shared by the consent and status dialogs. Recognition language and keeping recordings are intentionally not added: the speech engine has no language option and nothing records audio to disk. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…or the web UI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… window Avalonia 12 only shows a TrayIcon that is registered via TrayIcon.SetIcons. When our own app was frontmost, the window tracker returned the parked composer as the target and the composer was placed off screen. Co-authored-by: Cursor <cursoragent@cursor.com>
…screen Show the window before moving it to the parked position (a first position far off screen gives a 0 x 0 window on macOS), and move it on screen, still transparent, before the session starts: WebKit runs no animation frames for an off-screen page, so the page could never report its size. Co-authored-by: Cursor <cursoragent@cursor.com>
…th an in-margin shadow Typed text was sent to the cleaner on every key; each new request cancelled the previous one, which also killed the llama-server that was still loading (22 starts in one second). The last sentence is now cleaned after 400 ms without edits. The composer panel was see-through and its 88 px shadow was clipped to a visible rectangle by the 18 px window margin. Co-authored-by: Cursor <cursoragent@cursor.com>
…creen The window only placed itself on the first measurement, so a result that grew the page pushed the footer buttons below the screen. It is now re-placed on every size change, capped to the working area of its screen, and the page is told how tall its panel may get so it scrolls inside instead. The header starts the system's own window drag (an NSWindow drag on macOS, the caption move loop on Windows); the page only reports that the drag began, because pointer screen coordinates differ between web engines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s one click The last unwritten draft used to be put back into the composer on the next summon, so the previous session's text (often a voice input) had to be cleared by hand. The composer now starts empty; when the last draft was closed without being written, the empty state shows a Continue last draft button. Written drafts are never offered. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…r the other actions Dictation no longer needs a mouse button held down: Command/Ctrl+D (or a click on the microphone) starts it and the same key stops it, and it keeps running when the window loses focus. Hold-to-talk is removed. The other actions get shortcuts too (output 1-3, swap language, copy, new draft, recent drafts, import, export, settings). They are defined once in C#, travel with the snapshot, match on the physical key and are ignored during an input method composition and while a dialog is open. Menus, tooltips and hints show the key caps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t stays a default) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The composer begins with the output (clean up or translate) and translation direction last chosen for the target application. A note under the hint and a line in the output menu say where the choice came from, with one click back to the defaults. Original, cloud switches and the microphone are never remembered. - preferences.json (separate from settings): app id, two choices, last export format; LRU of 50 apps, no expiry; atomic write, corrupt file starts empty. - Target windows carry a stable app id (bundle id on macOS, exe name on Windows). - Settings: remember switch, default output, start dictating when summoned (global), and an app list with forget / clear all. - The export dialog marks and focuses the format exported last. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…irst A scan could read a draft that already had the first keystroke before the change notification recorded the edit, so the edit counted as made long ago and the typed sentence was cleaned at once. Edits are now observed in the same locked step that reads the draft. The settings session test now waits on the snapshot instead of a property that is set before it is announced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Dictation no longer stops after 4 s of silence. The microphone is closed only after 5 minutes without any sound, with a notice that what was heard is kept. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ures time-zone independent The product ships for Windows x64 and macOS arm64, the only pinned llama.cpp runtimes, so its tests cannot run on Linux. The release workflow also lacked the Playwright browsers that the web tests need. The resume-draft fixture held a local clock time; it is now normalized like the key caps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WiX v7 refuses to build until the OSMF EULA is accepted, which is a decision for the project owner. 6.0.2 is what the 1.4.x releases used. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- IModelManager loses model deletion, disk usage and storage relocation; the stub manager, null download coordinator and Hugging Face web-URL helper go. - HfGguf keeps only the resolve URL and downloader; repository listing, quantization choosing, repo id parsing and the HfGguf.Cli tool are removed. - Unused Win32 / Cocoa declarations, AudioBuffer.TrimBefore and the Input Monitoring probe are removed, together with tests that only checked record equality. - 1.x product design, proposals, roadmap, demo images, the WebView spike, duplicate icon sources and scratch files are removed; the architecture rule and CONTRIBUTING describe the 2.0 layout. - The update URL default no longer points at a placeholder repository. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mselves Releases only carried installers, so an installed app found nothing to update to. - Pack builds the Velopack package and feed (releases.<channel>.json) for both platforms. macOS now uses vpk pack instead of a hand-built .pkg, which the updater cannot manage; it gets an icon and a version-stamped Info.plist. The vpk environment now keeps PATH. - The release workflow uploads the packages and feeds, refuses to publish a release whose feed does not name a package that is in it, and marks versions with a suffix as pre-releases. - The app downloads a newer version in the background, offers Restart to Update in the tray menu and installs it on quit. UpdateChecks owns when to check and is tested; VelopackUpdateService is only the adapter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e suffix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Starting dictation reloaded three speech models every time (3-5 s), and the first cleanup waited ~10 s for llama-server. Models are now loaded ahead of use and kept while recently used. - ResidentModel<T>: one load however many ask, lent to a user, unloaded when idle. - SherpaSpeechEngine owns the speech models (dictation, import, warm-up); sessions borrow the large recognizers and make only the small detector. Replaces the per-session factory and the file transcriber's own load. - ModelWarmup decides when: speech 3 s after startup (setting, default on), after the speech models are downloaded, on every summon, then the model of the starting output; the new output's model when it changes. - LlamaServerHost.WarmAsync / IInferenceWarmup; no local load for roles routed to the cloud. InferenceModels is the one place that maps a role to its model. - The empty composer says "speech models are getting ready" while they load. Measured on an M3 Pro: dictation starts in 4-15 ms after warm-up; the first cleanup drops from ~10 s to ~1 s. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Checked end to end on macOS: an installed 2.0.1 downloaded 2.0.2 from a feed and was replaced by it on quit. That check found what blocked real users: - Every settings file of 1.x and 2.0.0 stores the placeholder update URL (github.com/user/LiveLingo), so the corrected default never reached them. It is replaced on load; a user-set address is kept and an empty one turns updates off (it used to be filled in again at every start). - VelopackApp.Run is now the first thing in Main, before the single-instance lock, so a running instance cannot turn the installer or updater hooks away. Also fixes a race in the composer: the slow-output countdown is now created before the "working" status is published, which made five tests flaky. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CleanupScheduler: the test read the timer after a fixed 50 ms, before the scheduler's worker had set it on a loaded runner; it now waits for the timer. - Web tests: a size report queued by a render could arrive after the intents were cleared and be taken for the reaction to a shortcut; clearing now lets the page's pending animation frames run first. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
LiveLingo 2.0: a rewrite around a single composer window. Summon it with a global hotkey, type, paste or dictate, pick Clean up, Translate or Original, and press Enter to write into the app you came from.
v2.0.0 is already tagged and released from this branch. Merging brings
mainup to the released code; it does not publish anything.Contents (70 commits, see
CHANGELOG.md)llama-server. Optional, per-feature cloud routing (text only, off by default).docs/superpowers/specs/2026-11-02-model-warmup-design.md.HfGguf.Clitool.Checked before merging
./build.sh Testv2.0.0, and av2.0.1-rc.1dry run)winandosxchannelsInfo.plistandsq.version2.0.2), and the updated app starts and no longer downloadsVelopackApp.Runis now first inMain, before the single-instance lockTheSlowNotice_...(countdown is created before "working" is published)Not verified
win; installing the downloaded update on Windows has not been run (no Windows machine). The logic is the same Velopack path.Known issues, not part of this PR
%LocalAppData%\LiveLingo, which is also where settings, logs and the models (several GB) live. Uninstalling deletes the whole folder. The data should move out of the install root (needs a migration)..msiand development builds never self-update.