agent: lumotia-rebrand — rust workspace crates magnotia-* -> lumotia-*
Phase 2 of the rebrand cascade. Renames all 9 workspace crates from magnotia-* to lumotia-* plus the src-tauri binary crate name: - magnotia-ai-formatting -> lumotia-ai-formatting - magnotia-audio -> lumotia-audio - magnotia-cloud-providers -> lumotia-cloud-providers - magnotia-core -> lumotia-core - magnotia-hotkey -> lumotia-hotkey - magnotia-llm -> lumotia-llm - magnotia-mcp -> lumotia-mcp - magnotia-storage -> lumotia-storage - magnotia-transcription -> lumotia-transcription - magnotia -> lumotia (src-tauri binary) - magnotia_lib -> lumotia_lib (src-tauri lib target) Crate directories (crates/audio/ etc.) stay as-is; only the Cargo.toml [package] name field changes plus all consumer module imports (magnotia_core -> lumotia_core, etc.). Remaining magnotia_* references at this point are intentional and scoped to later phases: tracing targets (Phase 4), DB setting keys magnotia_preferences/magnotia_history (Phase 5). cargo build --workspace passes. cargo test --workspace: 330 pass, 0 fail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
326
Cargo.lock
generated
326
Cargo.lock
generated
@@ -2752,6 +2752,169 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||
|
||||
[[package]]
|
||||
name = "lumotia"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"base64 0.22.1",
|
||||
"gdk",
|
||||
"gtk",
|
||||
"lumotia-ai-formatting",
|
||||
"lumotia-audio",
|
||||
"lumotia-cloud-providers",
|
||||
"lumotia-core",
|
||||
"lumotia-hotkey",
|
||||
"lumotia-llm",
|
||||
"lumotia-storage",
|
||||
"lumotia-transcription",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-global-shortcut",
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-window-state",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
"webkit2gtk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-ai-formatting"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lumotia-core",
|
||||
"lumotia-llm",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-audio"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cpal",
|
||||
"hound",
|
||||
"lumotia-core",
|
||||
"regex",
|
||||
"rubato",
|
||||
"serde",
|
||||
"symphonia",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-cloud-providers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"lumotia-core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"libloading 0.8.9",
|
||||
"num_cpus",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-hotkey"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"evdev",
|
||||
"lumotia-core",
|
||||
"nix 0.29.0",
|
||||
"notify",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-llm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"llama-cpp-2",
|
||||
"lumotia-core",
|
||||
"reqwest 0.12.28",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-mcp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lumotia-storage",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-storage"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"lumotia-core",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lumotia-transcription"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures-util",
|
||||
"lumotia-cloud-providers",
|
||||
"lumotia-core",
|
||||
"num_cpus",
|
||||
"reqwest 0.12.28",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"transcribe-rs",
|
||||
"whisper-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzma-rust2"
|
||||
version = "0.15.7"
|
||||
@@ -2785,169 +2948,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"base64 0.22.1",
|
||||
"gdk",
|
||||
"gtk",
|
||||
"magnotia-ai-formatting",
|
||||
"magnotia-audio",
|
||||
"magnotia-cloud-providers",
|
||||
"magnotia-core",
|
||||
"magnotia-hotkey",
|
||||
"magnotia-llm",
|
||||
"magnotia-storage",
|
||||
"magnotia-transcription",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-global-shortcut",
|
||||
"tauri-plugin-notification",
|
||||
"tauri-plugin-opener",
|
||||
"tauri-plugin-window-state",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
"webkit2gtk",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-ai-formatting"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"magnotia-core",
|
||||
"magnotia-llm",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-audio"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cpal",
|
||||
"hound",
|
||||
"magnotia-core",
|
||||
"regex",
|
||||
"rubato",
|
||||
"serde",
|
||||
"symphonia",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-cloud-providers"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"magnotia-core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"libloading 0.8.9",
|
||||
"num_cpus",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-hotkey"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"evdev",
|
||||
"magnotia-core",
|
||||
"nix 0.29.0",
|
||||
"notify",
|
||||
"serde",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-llm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"llama-cpp-2",
|
||||
"magnotia-core",
|
||||
"reqwest 0.12.28",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-mcp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"magnotia-storage",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-storage"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"magnotia-core",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magnotia-transcription"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures-util",
|
||||
"magnotia-cloud-providers",
|
||||
"magnotia-core",
|
||||
"num_cpus",
|
||||
"reqwest 0.12.28",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"transcribe-rs",
|
||||
"whisper-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markup5ever"
|
||||
version = "0.14.1"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "magnotia-ai-formatting"
|
||||
name = "lumotia-ai-formatting"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Text post-processing pipeline: filler removal, British English conversion, formatting for Magnotia"
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
magnotia-llm = { path = "../llm" }
|
||||
lumotia-core = { path = "../core" }
|
||||
lumotia-llm = { path = "../llm" }
|
||||
regex-lite = "0.1"
|
||||
tracing = "0.1"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! The llm_client is not yet wired to a running model. This module defines
|
||||
//! the prompt contract so that wiring it produces correct, hardened output.
|
||||
|
||||
use magnotia_llm::{EngineError, LlmEngine};
|
||||
use lumotia_llm::{EngineError, LlmEngine};
|
||||
|
||||
/// System prompt sent before every cleanup call.
|
||||
///
|
||||
@@ -161,7 +161,7 @@ pub fn cleanup_text(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use magnotia_llm::EngineError;
|
||||
use lumotia_llm::EngineError;
|
||||
|
||||
#[test]
|
||||
fn empty_terms_returns_empty_string() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use magnotia_core::constants::SMART_PARAGRAPH_GAP_SECS;
|
||||
use magnotia_core::types::Segment;
|
||||
use magnotia_llm::LlmEngine;
|
||||
use lumotia_core::constants::SMART_PARAGRAPH_GAP_SECS;
|
||||
use lumotia_core::types::Segment;
|
||||
use lumotia_llm::LlmEngine;
|
||||
|
||||
use crate::{llm_client, rule_based, to_plain_text::to_plain_text};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
//! is the whitespace pass and empty-segment filter, plus a single
|
||||
//! public function the pipeline can depend on.
|
||||
|
||||
use magnotia_core::types::Segment;
|
||||
use lumotia_core::types::Segment;
|
||||
|
||||
/// Join transcription segments into a single plain-text string
|
||||
/// suitable for feeding to an LLM cleanup prompt.
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "magnotia-audio"
|
||||
name = "lumotia-audio"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Audio capture (cpal), VAD, resampling (rubato), file decoding (symphonia), WAV I/O (hound) for Magnotia"
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
|
||||
# Microphone capture
|
||||
cpal = "0.17"
|
||||
|
||||
@@ -8,7 +8,7 @@ use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
|
||||
const AUDIO_CHANNEL_CAPACITY: usize = 32;
|
||||
|
||||
@@ -149,7 +149,7 @@ impl MicrophoneCapture {
|
||||
for device in devices {
|
||||
let name = device_display_name(&device).unwrap_or_default();
|
||||
if name == device_name {
|
||||
tracing::info!(target: "magnotia_audio", "start_with_device: opening explicit device '{name}'");
|
||||
tracing::info!(target: "lumotia_audio", "start_with_device: opening explicit device '{name}'");
|
||||
return open_and_validate(device, &name, /* require_audio = */ true);
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ impl MicrophoneCapture {
|
||||
});
|
||||
|
||||
tracing::info!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
device_count = all_devices.len(),
|
||||
default = %default_name,
|
||||
"enumerated input devices"
|
||||
@@ -211,7 +211,7 @@ impl MicrophoneCapture {
|
||||
match open_and_validate(device.clone(), &name, true) {
|
||||
Ok(result) => return Ok(result),
|
||||
Err(e) => {
|
||||
tracing::warn!(target: "magnotia_audio", device = %name, error = %e, "candidate device rejected");
|
||||
tracing::warn!(target: "lumotia_audio", device = %name, error = %e, "candidate device rejected");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +219,7 @@ impl MicrophoneCapture {
|
||||
// Second pass: accept anything that delivers bytes (monitor sources
|
||||
// included). Better to capture from a monitor than fail entirely.
|
||||
tracing::warn!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
"no non-monitor mic produced audio; falling back to monitor/loopback sources"
|
||||
);
|
||||
for device in &all_devices {
|
||||
@@ -227,7 +227,7 @@ impl MicrophoneCapture {
|
||||
match open_and_validate(device.clone(), &name, false) {
|
||||
Ok(result) => {
|
||||
tracing::warn!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
device = %name,
|
||||
"capturing from likely monitor source; recordings may be silent or contain system audio"
|
||||
);
|
||||
@@ -367,7 +367,7 @@ fn open_and_validate(
|
||||
let format = config.sample_format();
|
||||
|
||||
tracing::info!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
device = %name,
|
||||
sample_rate,
|
||||
channels,
|
||||
@@ -467,7 +467,7 @@ fn open_and_validate(
|
||||
|
||||
let rms = (sum_sq / total_samples as f64).sqrt() as f32;
|
||||
tracing::info!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
device = %name,
|
||||
samples = total_samples,
|
||||
rms,
|
||||
@@ -499,7 +499,7 @@ fn open_and_validate(
|
||||
}
|
||||
}
|
||||
|
||||
tracing::info!(target: "magnotia_audio", device = %name, "selected microphone");
|
||||
tracing::info!(target: "lumotia_audio", device = %name, "selected microphone");
|
||||
Ok((
|
||||
MicrophoneCapture {
|
||||
stream: Some(stream),
|
||||
@@ -547,7 +547,7 @@ where
|
||||
move |err| {
|
||||
// Surface stream errors to the live session via err_tx so the
|
||||
// frontend can show a toast.
|
||||
tracing::error!(target: "magnotia_audio", error = %err, "capture stream error");
|
||||
tracing::error!(target: "lumotia_audio", error = %err, "capture stream error");
|
||||
if err_tx
|
||||
.try_send(CaptureRuntimeError {
|
||||
device_name: err_device_name.clone(),
|
||||
@@ -560,7 +560,7 @@ where
|
||||
// even if the frontend never received the typed event.
|
||||
let prior = dropped_errors.fetch_add(1, Ordering::Relaxed);
|
||||
tracing::warn!(
|
||||
target: "magnotia_audio",
|
||||
target: "lumotia_audio",
|
||||
device = %err_device_name,
|
||||
dropped_error = prior + 1,
|
||||
"capture error channel full; dropping runtime error"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use magnotia_core::error::Result;
|
||||
use magnotia_core::types::AudioSamples;
|
||||
use lumotia_core::error::Result;
|
||||
use lumotia_core::types::AudioSamples;
|
||||
|
||||
use crate::decode::decode_audio_file;
|
||||
use crate::resample::resample_to_16khz;
|
||||
@@ -16,6 +16,6 @@ pub async fn decode_and_resample(path: &Path) -> Result<AudioSamples> {
|
||||
})
|
||||
.await
|
||||
.map_err(|e| {
|
||||
magnotia_core::error::MagnotiaError::AudioDecodeFailed(format!("Task join error: {e}"))
|
||||
lumotia_core::error::MagnotiaError::AudioDecodeFailed(format!("Task join error: {e}"))
|
||||
})?
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ use symphonia::core::io::MediaSourceStream;
|
||||
use symphonia::core::meta::MetadataOptions;
|
||||
use symphonia::core::probe::Hint;
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::AudioSamples;
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::AudioSamples;
|
||||
|
||||
/// Decode an audio file to mono f32 PCM samples.
|
||||
/// Supports all formats symphonia handles: mp3, aac, flac, wav, ogg, etc.
|
||||
|
||||
@@ -2,9 +2,9 @@ use rubato::{
|
||||
Resampler, SincFixedIn, SincInterpolationParameters, SincInterpolationType, WindowFunction,
|
||||
};
|
||||
|
||||
use magnotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::AudioSamples;
|
||||
use lumotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::AudioSamples;
|
||||
|
||||
/// Resample audio to 16kHz mono using sinc interpolation (rubato).
|
||||
/// Returns a new AudioSamples at the target sample rate.
|
||||
|
||||
@@ -27,8 +27,8 @@ use rubato::{
|
||||
Resampler, SincFixedIn, SincInterpolationParameters, SincInterpolationType, WindowFunction,
|
||||
};
|
||||
|
||||
use magnotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
|
||||
/// Number of input samples the rubato resampler consumes per `process()`
|
||||
/// call. Matches the chunk size used in `resample::resample_to_16khz`.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// For now, all audio is treated as speech. This matches v0.2 behaviour
|
||||
// (no VAD) and doesn't affect core functionality.
|
||||
|
||||
use magnotia_core::constants::VAD_SPEECH_THRESHOLD;
|
||||
use lumotia_core::constants::VAD_SPEECH_THRESHOLD;
|
||||
|
||||
/// Stub speech detector. Treats all audio as speech.
|
||||
#[derive(Default)]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::io::BufWriter;
|
||||
use std::path::Path;
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::AudioSamples;
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::AudioSamples;
|
||||
|
||||
/// Append-friendly WAV writer for long-running captures.
|
||||
///
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "magnotia-cloud-providers"
|
||||
name = "lumotia-cloud-providers"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Provider trait and BYOK cloud STT scaffolding for Magnotia (Wyrdnote pending rebrand)"
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
|
||||
# Async-native trait. async_trait converts async fn into Pin<Box<dyn
|
||||
# Future>> at the trait surface so TranscriptionProvider stays
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
use std::fmt;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use magnotia_core::error::Result;
|
||||
use magnotia_core::types::{AudioSamples, ModelId, Transcript, TranscriptionOptions};
|
||||
use lumotia_core::error::Result;
|
||||
use lumotia_core::types::{AudioSamples, ModelId, Transcript, TranscriptionOptions};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Stable, lower-kebab-case identifier for a provider. Used in user
|
||||
@@ -70,7 +70,7 @@ pub enum CostClass {
|
||||
}
|
||||
|
||||
/// Capabilities a provider advertises to the orchestrator and the UI.
|
||||
/// Superset of `magnotia_transcription::TranscriberCapabilities` for
|
||||
/// Superset of `lumotia_transcription::TranscriberCapabilities` for
|
||||
/// local providers, with extra fields cloud providers populate.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ProviderCapabilities {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "magnotia-core"
|
||||
name = "lumotia-core"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Core types, constants, traits, hardware detection, and model registry for Magnotia"
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
//! exactly one INFO line; subsequent calls with the same tuple are
|
||||
//! silenced by the per-process log-once cache.
|
||||
|
||||
use magnotia_core::tuning::{inference_thread_count, Workload};
|
||||
use lumotia_core::tuning::{inference_thread_count, Workload};
|
||||
|
||||
fn main() {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter("magnotia_core=info")
|
||||
.with_env_filter("lumotia_core=info")
|
||||
.with_target(true)
|
||||
.with_writer(std::io::stderr)
|
||||
.init();
|
||||
|
||||
@@ -34,7 +34,7 @@ pub enum MagnotiaError {
|
||||
#[error("file not found: '{}'", .0.display())]
|
||||
FileNotFound(PathBuf),
|
||||
|
||||
/// Structured storage failure flowed up from `magnotia_storage::Error` via
|
||||
/// Structured storage failure flowed up from `lumotia_storage::Error` via
|
||||
/// its `From` impl. Display reads through to `detail` so the operation +
|
||||
/// source context produced by the storage crate isn't double-prefixed.
|
||||
#[error("{detail}")]
|
||||
@@ -58,7 +58,7 @@ pub enum MagnotiaError {
|
||||
/// Coarse discriminator for `MagnotiaError::Storage`. The storage crate maps
|
||||
/// its full typed error onto one of these kinds at the boundary. Backend code
|
||||
/// that wants finer-grained branching pattern-matches on
|
||||
/// `magnotia_storage::Error` directly.
|
||||
/// `lumotia_storage::Error` directly.
|
||||
#[derive(Debug, Clone, Copy, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum StorageKind {
|
||||
|
||||
@@ -89,7 +89,7 @@ pub fn inference_thread_count(workload: Workload, gpu_offloaded: bool) -> usize
|
||||
if let Ok(mut seen) = log_seen().lock() {
|
||||
if seen.insert(key) {
|
||||
tracing::info!(
|
||||
target: "magnotia_core::tuning",
|
||||
target: "lumotia_core::tuning",
|
||||
threads = final_value,
|
||||
workload = ?workload,
|
||||
gpu_offloaded,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "magnotia-hotkey"
|
||||
name = "lumotia-hotkey"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Wayland-compatible global hotkey listener for Magnotia — evdev backend with device hotplug"
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
tokio = { version = "1", features = ["rt", "sync", "macros", "time"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tracing = "0.1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "magnotia-llm"
|
||||
name = "lumotia-llm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Local LLM engine for Magnotia (Qwen3.5 / Qwen3.6 via llama-cpp-2): transcript cleanup, task extraction, micro-step decomposition"
|
||||
@@ -7,7 +7,7 @@ description = "Local LLM engine for Magnotia (Qwen3.5 / Qwen3.6 via llama-cpp-2)
|
||||
[features]
|
||||
# Default desktop build keeps the existing openmp + vulkan acceleration.
|
||||
# Mobile / CPU-only targets can drop one or both via:
|
||||
# cargo build -p magnotia-llm --no-default-features
|
||||
# cargo build -p lumotia-llm --no-default-features
|
||||
# These are independent so an Android Vulkan build can opt into vulkan
|
||||
# without openmp (the NDK ships OpenMP libs but the toolchain configuration
|
||||
# is fragile across NDK versions).
|
||||
@@ -16,7 +16,7 @@ gpu-vulkan = ["llama-cpp-2/vulkan"]
|
||||
openmp = ["llama-cpp-2/openmp"]
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
encoding_rs = "0.8"
|
||||
futures-util = "0.3"
|
||||
llama-cpp-2 = { version = "0.1.146", default-features = false }
|
||||
|
||||
@@ -9,7 +9,7 @@ use llama_cpp_2::llama_batch::LlamaBatch;
|
||||
use llama_cpp_2::model::params::LlamaModelParams;
|
||||
use llama_cpp_2::model::{AddBos, LlamaChatMessage, LlamaChatTemplate, LlamaModel};
|
||||
use llama_cpp_2::sampling::LlamaSampler;
|
||||
use magnotia_core::tuning::{inference_thread_count, Workload};
|
||||
use lumotia_core::tuning::{inference_thread_count, Workload};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod grammars;
|
||||
|
||||
@@ -240,7 +240,7 @@ pub fn recommend_tier(total_ram_bytes: u64, total_vram_bytes: Option<u64>) -> Ll
|
||||
}
|
||||
|
||||
pub fn model_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().llm_models_dir()
|
||||
lumotia_core::paths::app_paths().llm_models_dir()
|
||||
}
|
||||
|
||||
pub fn model_path(id: LlmModelId) -> PathBuf {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use magnotia_llm::{is_valid_intent, LlmEngine, LlmModelId};
|
||||
use lumotia_llm::{is_valid_intent, LlmEngine, LlmModelId};
|
||||
|
||||
#[test]
|
||||
fn extract_content_tags_returns_valid_pair() {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use magnotia_llm::LlmEngine;
|
||||
use magnotia_llm::LlmModelId;
|
||||
use lumotia_llm::LlmEngine;
|
||||
use lumotia_llm::LlmModelId;
|
||||
|
||||
#[test]
|
||||
fn llama_cpp_2_smoke_generates_and_wraps() {
|
||||
@@ -32,7 +32,7 @@ fn llama_cpp_2_smoke_generates_and_wraps() {
|
||||
let completion = engine
|
||||
.generate(
|
||||
"Write exactly one short greeting.",
|
||||
&magnotia_llm::GenerationConfig {
|
||||
&lumotia_llm::GenerationConfig {
|
||||
max_tokens: 32,
|
||||
temperature: 0.0,
|
||||
stop_sequences: vec!["\n".to_string()],
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
[package]
|
||||
name = "magnotia-mcp"
|
||||
name = "lumotia-mcp"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Read-only MCP stdio server exposing Magnotia transcripts and tasks to external agents"
|
||||
|
||||
[[bin]]
|
||||
name = "magnotia-mcp"
|
||||
name = "lumotia-mcp"
|
||||
path = "src/main.rs"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
magnotia-storage = { path = "../storage" }
|
||||
lumotia-storage = { path = "../storage" }
|
||||
sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "sqlite"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
@@ -206,7 +206,7 @@ async fn list_transcripts_tool(pool: &SqlitePool, args: Value) -> Result<Value,
|
||||
};
|
||||
let limit = args.limit.unwrap_or(20).clamp(1, 200);
|
||||
|
||||
let rows = magnotia_storage::list_transcripts(pool, limit)
|
||||
let rows = lumotia_storage::list_transcripts(pool, limit)
|
||||
.await
|
||||
.map_err(|e| error(-32603, format!("DB error: {e}")))?;
|
||||
|
||||
@@ -239,7 +239,7 @@ async fn get_transcript_tool(pool: &SqlitePool, args: Value) -> Result<Value, Js
|
||||
let args: Args = serde_json::from_value(args)
|
||||
.map_err(|e| error(-32602, format!("Invalid arguments: {e}")))?;
|
||||
|
||||
let row = magnotia_storage::get_transcript(pool, &args.id)
|
||||
let row = lumotia_storage::get_transcript(pool, &args.id)
|
||||
.await
|
||||
.map_err(|e| error(-32603, format!("DB error: {e}")))?
|
||||
.ok_or_else(|| error(-32000, format!("Transcript {} not found", args.id)))?;
|
||||
@@ -273,7 +273,7 @@ async fn search_transcripts_tool(pool: &SqlitePool, args: Value) -> Result<Value
|
||||
.map_err(|e| error(-32602, format!("Invalid arguments: {e}")))?;
|
||||
let limit = args.limit.unwrap_or(20).clamp(1, 100);
|
||||
|
||||
let rows = magnotia_storage::search_transcripts(pool, &args.query, limit)
|
||||
let rows = lumotia_storage::search_transcripts(pool, &args.query, limit)
|
||||
.await
|
||||
.map_err(|e| error(-32603, format!("DB error: {e}")))?;
|
||||
|
||||
@@ -296,7 +296,7 @@ async fn search_transcripts_tool(pool: &SqlitePool, args: Value) -> Result<Value
|
||||
}
|
||||
|
||||
async fn list_tasks_tool(pool: &SqlitePool) -> Result<Value, JsonRpcError> {
|
||||
let rows = magnotia_storage::list_tasks(pool)
|
||||
let rows = lumotia_storage::list_tasks(pool)
|
||||
.await
|
||||
.map_err(|e| error(-32603, format!("DB error: {e}")))?;
|
||||
|
||||
@@ -460,7 +460,7 @@ mod tests {
|
||||
});
|
||||
|
||||
let pool = sqlx::SqlitePool::connect("sqlite::memory:").await.unwrap();
|
||||
magnotia_storage::migrations::run_migrations(&pool)
|
||||
lumotia_storage::migrations::run_migrations(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
let response = handle_message(&pool, request).await.expect("has response");
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//! Stdio entry point for magnotia-mcp. Reads newline-delimited JSON-RPC messages
|
||||
//! from stdin, dispatches via `magnotia_mcp::handle_message`, writes responses to
|
||||
//! from stdin, dispatches via `lumotia_mcp::handle_message`, writes responses to
|
||||
//! stdout. Logs land on stderr so they don't collide with the JSON-RPC stream.
|
||||
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let db_path = magnotia_storage::database_path();
|
||||
let db_path = lumotia_storage::database_path();
|
||||
eprintln!(
|
||||
"[magnotia-mcp] opening Magnotia database at {} (read-only)",
|
||||
db_path.display()
|
||||
@@ -15,7 +15,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
// to the user's database, regardless of which tools the dispatcher
|
||||
// exposes. Migrations are deliberately skipped — this binary never owns
|
||||
// the schema; the main app is the single migration writer.
|
||||
let pool = magnotia_storage::init_readonly(&db_path).await?;
|
||||
let pool = lumotia_storage::init_readonly(&db_path).await?;
|
||||
eprintln!("[magnotia-mcp] ready, waiting for JSON-RPC on stdin");
|
||||
|
||||
let mut lines = BufReader::new(tokio::io::stdin()).lines();
|
||||
@@ -28,7 +28,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
|
||||
let response = match serde_json::from_str::<serde_json::Value>(trimmed) {
|
||||
Ok(raw) => match magnotia_mcp::handle_message(&pool, raw).await {
|
||||
Ok(raw) => match lumotia_mcp::handle_message(&pool, raw).await {
|
||||
Some(response) => response,
|
||||
None => continue, // notification — no reply
|
||||
},
|
||||
@@ -39,7 +39,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
// clients saw silence instead of a structured error
|
||||
// (2026-04-22 review MAJOR).
|
||||
eprintln!("[magnotia-mcp] parse error: {err}");
|
||||
magnotia_mcp::parse_error_response(&err.to_string())
|
||||
lumotia_mcp::parse_error_response(&err.to_string())
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "magnotia-storage"
|
||||
name = "lumotia-storage"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "SQLite persistence, BM25 search, and file storage for Magnotia"
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
|
||||
# SQLite with compile-time checked queries
|
||||
# default-features = false strips sqlx's `any`, `macros`, `migrate`, `json` —
|
||||
@@ -24,7 +24,7 @@ serde = { version = "1", features = ["derive"] }
|
||||
# Logging
|
||||
log = "0.4"
|
||||
|
||||
# Structured error derivation for magnotia_storage::Error.
|
||||
# Structured error derivation for lumotia_storage::Error.
|
||||
thiserror = "1"
|
||||
|
||||
# UUIDs for profile + profile_terms ids (v7 random).
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Storage-local typed error.
|
||||
//!
|
||||
//! Backend code that wants to branch on storage failure modes pattern-matches
|
||||
//! on [`Error`] directly. The crate boundary into [`magnotia_core::error::MagnotiaError`]
|
||||
//! on [`Error`] directly. The crate boundary into [`lumotia_core::error::MagnotiaError`]
|
||||
//! flattens this into a [`MagnotiaError::Storage`] variant carrying a serde-friendly
|
||||
//! `kind`, an `operation` label, and the Display output as `detail` — so the
|
||||
//! frontend (which still receives stringified errors from Tauri commands today)
|
||||
@@ -14,7 +14,7 @@
|
||||
use std::borrow::Cow;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, StorageKind};
|
||||
use lumotia_core::error::{MagnotiaError, StorageKind};
|
||||
|
||||
/// Kinds of database-open operation that can fail before the pool is ready.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn app_data_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().app_data_dir()
|
||||
lumotia_core::paths::app_paths().app_data_dir()
|
||||
}
|
||||
|
||||
/// Path to the SQLite database file.
|
||||
pub fn database_path() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().database_path()
|
||||
lumotia_core::paths::app_paths().database_path()
|
||||
}
|
||||
|
||||
/// Directory for saved audio recordings.
|
||||
pub fn recordings_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().recordings_dir()
|
||||
lumotia_core::paths::app_paths().recordings_dir()
|
||||
}
|
||||
|
||||
/// Directory for crash dumps written by the Rust panic hook.
|
||||
/// Each crash is a single text file: `<unix-ts>-<short-id>.crash`.
|
||||
/// Used by the diagnostic-report bundler in Settings → About.
|
||||
pub fn crashes_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().crashes_dir()
|
||||
lumotia_core::paths::app_paths().crashes_dir()
|
||||
}
|
||||
|
||||
/// Directory for the rolling Rust log file (magnotia.log + rotated magnotia.log.1, etc).
|
||||
/// Subscribers configured in src-tauri/src/lib.rs at startup.
|
||||
pub fn logs_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().logs_dir()
|
||||
lumotia_core::paths::app_paths().logs_dir()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "magnotia-transcription"
|
||||
name = "lumotia-transcription"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Speech-to-text engine wrappers, model management, and inference concurrency for Magnotia"
|
||||
@@ -15,18 +15,18 @@ build = "build.rs"
|
||||
# `whisper-vulkan` is a separate feature so a non-Vulkan target (Android
|
||||
# without GPU drivers, a CPU-only Windows build) can pull in whisper-rs
|
||||
# but skip the Vulkan backend. Build CPU-only with:
|
||||
# cargo build -p magnotia-transcription --no-default-features --features whisper
|
||||
# cargo build -p lumotia-transcription --no-default-features --features whisper
|
||||
default = ["whisper", "whisper-vulkan"]
|
||||
whisper = ["dep:whisper-rs"]
|
||||
whisper-vulkan = ["whisper-rs?/vulkan"]
|
||||
|
||||
[dependencies]
|
||||
magnotia-core = { path = "../core" }
|
||||
lumotia-core = { path = "../core" }
|
||||
|
||||
# TranscriptionProvider async trait + EngineProfile + ProviderId. The
|
||||
# trait lives in cloud-providers so an OEM licensee can implement it
|
||||
# without depending on transcription internals.
|
||||
magnotia-cloud-providers = { path = "../cloud-providers" }
|
||||
lumotia-cloud-providers = { path = "../cloud-providers" }
|
||||
|
||||
# Async-trait for the LocalProviderAdapter impl.
|
||||
async-trait = "0.1"
|
||||
@@ -57,12 +57,12 @@ thiserror = "2"
|
||||
tracing = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
# TcpListener fixture for the download resume tests (mirrors magnotia-llm).
|
||||
# TcpListener fixture for the download resume tests (mirrors lumotia-llm).
|
||||
# `macros` and `rt-multi-thread` enable #[tokio::test] and the multi-threaded
|
||||
# scheduler used by the orchestrator tests.
|
||||
tokio = { version = "1", features = ["rt", "rt-multi-thread", "sync", "net", "io-util", "macros"] }
|
||||
tempfile = "3"
|
||||
# Test-only — used by tests/thread_sweep.rs to label physical vs logical
|
||||
# core counts in the scaling table. Production code uses the
|
||||
# `magnotia_core::constants::inference_thread_count` helper instead.
|
||||
# `lumotia_core::constants::inference_thread_count` helper instead.
|
||||
num_cpus = "1"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
//! workspace ever pulls `tokenizers` into the dependency graph on a
|
||||
//! Windows target. If we ever legitimately need it we can reintroduce
|
||||
//! it via a sidecar (isolated process, separate CRT) rather than
|
||||
//! linking it into `magnotia_lib`.
|
||||
//! linking it into `lumotia_lib`.
|
||||
//!
|
||||
//! The check is advisory on non-Windows targets — it still prints a
|
||||
//! cargo:warning if `tokenizers` appears, so the Windows failure isn't
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::{AudioSamples, TranscriptionOptions};
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::{AudioSamples, TranscriptionOptions};
|
||||
|
||||
use crate::local_engine::{LocalEngine, TimedTranscript};
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ pub use transcribe_rs::SpeechModel;
|
||||
pub use transcriber::{Transcriber, TranscriberCapabilities};
|
||||
|
||||
// Re-export the trait surface so downstream crates depend only on
|
||||
// `magnotia_transcription` to access both local engines and the
|
||||
// provider trait without a separate `magnotia_cloud_providers`
|
||||
// `lumotia_transcription` to access both local engines and the
|
||||
// provider trait without a separate `lumotia_cloud_providers`
|
||||
// dependency. This is the seam an OEM licensee uses when they swap
|
||||
// providers.
|
||||
pub use magnotia_cloud_providers::{
|
||||
pub use lumotia_cloud_providers::{
|
||||
CostClass, EngineProfile, NetworkRequirement, ProviderCapabilities, ProviderId, ProviderKind,
|
||||
ProviderTranscript, TranscriptionProvider,
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@ use std::time::Instant;
|
||||
|
||||
use transcribe_rs::{SpeechModel, TranscribeOptions, TranscriptionResult};
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::{
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::{
|
||||
AudioSamples, EngineName, ModelId, Segment, Transcript, TranscriptionOptions,
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ pub struct SpeechModelAdapter(pub Box<dyn SpeechModel + Send>);
|
||||
impl Transcriber for SpeechModelAdapter {
|
||||
fn capabilities(&self) -> TranscriberCapabilities {
|
||||
TranscriberCapabilities {
|
||||
sample_rate: magnotia_core::constants::WHISPER_SAMPLE_RATE,
|
||||
sample_rate: lumotia_core::constants::WHISPER_SAMPLE_RATE,
|
||||
channels: 1,
|
||||
supports_initial_prompt: false,
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ use std::collections::HashSet;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::model_registry::{find_model, ModelFile};
|
||||
use magnotia_core::types::{DownloadProgress, ModelId};
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::model_registry::{find_model, ModelFile};
|
||||
use lumotia_core::types::{DownloadProgress, ModelId};
|
||||
|
||||
static ACTIVE_DOWNLOADS: LazyLock<Mutex<HashSet<String>>> =
|
||||
LazyLock::new(|| Mutex::new(HashSet::new()));
|
||||
@@ -40,12 +40,12 @@ impl Drop for DownloadReservation {
|
||||
/// Windows: %LOCALAPPDATA%/magnotia/models
|
||||
/// Unix: ~/.magnotia/models
|
||||
pub fn models_dir() -> PathBuf {
|
||||
magnotia_core::paths::app_paths().models_dir()
|
||||
lumotia_core::paths::app_paths().models_dir()
|
||||
}
|
||||
|
||||
/// Get the directory path where a specific model's files are stored.
|
||||
pub fn model_dir(id: &ModelId) -> PathBuf {
|
||||
magnotia_core::paths::app_paths().speech_model_dir(id)
|
||||
lumotia_core::paths::app_paths().speech_model_dir(id)
|
||||
}
|
||||
|
||||
/// Check whether all files for a model have been downloaded.
|
||||
@@ -61,7 +61,7 @@ pub fn is_downloaded(id: &ModelId) -> bool {
|
||||
|
||||
/// List all downloaded model IDs.
|
||||
pub fn list_downloaded() -> Vec<ModelId> {
|
||||
magnotia_core::model_registry::all_models()
|
||||
lumotia_core::model_registry::all_models()
|
||||
.iter()
|
||||
.filter(|m| is_downloaded(&m.id))
|
||||
.map(|m| m.id.clone())
|
||||
@@ -117,7 +117,7 @@ fn verified_manifest_path(dir: &Path) -> PathBuf {
|
||||
}
|
||||
|
||||
fn verified_manifest_matches(
|
||||
entry: &magnotia_core::model_registry::ModelEntry,
|
||||
entry: &lumotia_core::model_registry::ModelEntry,
|
||||
dir: &Path,
|
||||
) -> bool {
|
||||
let manifest = match std::fs::read_to_string(verified_manifest_path(dir)) {
|
||||
@@ -140,7 +140,7 @@ fn verified_manifest_matches(
|
||||
}
|
||||
|
||||
fn write_verified_manifest(
|
||||
entry: &magnotia_core::model_registry::ModelEntry,
|
||||
entry: &lumotia_core::model_registry::ModelEntry,
|
||||
dir: &Path,
|
||||
) -> std::io::Result<()> {
|
||||
let mut lines = Vec::with_capacity(entry.files.len() + 1);
|
||||
@@ -357,7 +357,7 @@ mod tests {
|
||||
let list = list_downloaded();
|
||||
// In test environment, no models are downloaded
|
||||
// This just verifies the function doesn't panic
|
||||
assert!(list.len() <= magnotia_core::model_registry::all_models().len());
|
||||
assert!(list.len() <= lumotia_core::model_registry::all_models().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -481,7 +481,7 @@ mod tests {
|
||||
let file = ModelFile {
|
||||
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
|
||||
url: leak(format!("http://{addr}/fixture.bin")),
|
||||
size: magnotia_core::types::Megabytes(0),
|
||||
size: lumotia_core::types::Megabytes(0),
|
||||
sha256: leak(expected_sha.clone()),
|
||||
};
|
||||
let id = ModelId::new("test-fixture");
|
||||
@@ -516,7 +516,7 @@ mod tests {
|
||||
let file = ModelFile {
|
||||
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
|
||||
url: leak(format!("http://{addr}/fixture.bin")),
|
||||
size: magnotia_core::types::Megabytes(0),
|
||||
size: lumotia_core::types::Megabytes(0),
|
||||
sha256: leak(expected_sha),
|
||||
};
|
||||
let id = ModelId::new("test-fixture");
|
||||
@@ -571,7 +571,7 @@ mod tests {
|
||||
let file = ModelFile {
|
||||
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
|
||||
url: leak(format!("http://{addr}/fixture.bin")),
|
||||
size: magnotia_core::types::Megabytes(0),
|
||||
size: lumotia_core::types::Megabytes(0),
|
||||
sha256: leak("0".repeat(64)),
|
||||
};
|
||||
let id = ModelId::new("test-fixture");
|
||||
@@ -599,7 +599,7 @@ mod tests {
|
||||
let file = ModelFile {
|
||||
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
|
||||
url: leak(format!("http://{addr}/fixture.bin")),
|
||||
size: magnotia_core::types::Megabytes(0),
|
||||
size: lumotia_core::types::Megabytes(0),
|
||||
sha256: leak("deadbeef".repeat(8)),
|
||||
};
|
||||
let id = ModelId::new("test-fixture");
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use magnotia_cloud_providers::{
|
||||
use lumotia_cloud_providers::{
|
||||
CostClass, EngineProfile, ProviderCapabilities, ProviderId, ProviderKind, ProviderTranscript,
|
||||
TranscriptionProvider,
|
||||
};
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::types::{AudioSamples, TranscriptionOptions};
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::types::{AudioSamples, TranscriptionOptions};
|
||||
|
||||
use crate::local_engine::LocalEngine;
|
||||
use crate::registry::EngineRegistry;
|
||||
@@ -68,7 +68,7 @@ impl TranscriptionProvider for LocalProviderAdapter {
|
||||
ProviderCapabilities {
|
||||
sample_rate: local
|
||||
.map(|c| c.sample_rate)
|
||||
.unwrap_or(magnotia_core::constants::WHISPER_SAMPLE_RATE),
|
||||
.unwrap_or(lumotia_core::constants::WHISPER_SAMPLE_RATE),
|
||||
channels: local.map(|c| c.channels).unwrap_or(1),
|
||||
initial_prompt_supported: local.map(|c| c.supports_initial_prompt).unwrap_or(false),
|
||||
language_hint_supported: true,
|
||||
@@ -153,7 +153,7 @@ mod tests {
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use magnotia_core::types::{Segment, Transcript};
|
||||
use lumotia_core::types::{Segment, Transcript};
|
||||
|
||||
/// Mock provider that returns a canned transcript and counts
|
||||
/// invocations. Used to validate the orchestrator's dispatch logic
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use magnotia_cloud_providers::{ProviderId, TranscriptionProvider};
|
||||
use lumotia_cloud_providers::{ProviderId, TranscriptionProvider};
|
||||
|
||||
/// Catalogue of providers known to the orchestrator.
|
||||
pub struct EngineRegistry {
|
||||
@@ -82,11 +82,11 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use magnotia_cloud_providers::{
|
||||
use lumotia_cloud_providers::{
|
||||
CostClass, EngineProfile, ProviderCapabilities, ProviderKind, ProviderTranscript,
|
||||
};
|
||||
use magnotia_core::error::Result;
|
||||
use magnotia_core::types::{AudioSamples, Transcript, TranscriptionOptions};
|
||||
use lumotia_core::error::Result;
|
||||
use lumotia_core::types::{AudioSamples, Transcript, TranscriptionOptions};
|
||||
|
||||
struct DummyProvider {
|
||||
id: ProviderId,
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
//! `whisper` feature — `WhisperRsBackend` (direct whisper-rs, the only
|
||||
//! path that pipes `initial_prompt`).
|
||||
|
||||
use magnotia_core::error::Result;
|
||||
use magnotia_core::types::{Segment, TranscriptionOptions};
|
||||
use lumotia_core::error::Result;
|
||||
use lumotia_core::types::{Segment, TranscriptionOptions};
|
||||
|
||||
/// Static capabilities a `Transcriber` advertises to callers.
|
||||
///
|
||||
|
||||
@@ -10,10 +10,10 @@ use std::path::Path;
|
||||
|
||||
use whisper_rs::{FullParams, SamplingStrategy, WhisperContext, WhisperContextParameters};
|
||||
|
||||
use magnotia_core::error::{MagnotiaError, Result};
|
||||
use magnotia_core::hardware::vulkan_loader_available;
|
||||
use magnotia_core::tuning::{inference_thread_count, Workload};
|
||||
use magnotia_core::types::{Segment, TranscriptionOptions};
|
||||
use lumotia_core::error::{MagnotiaError, Result};
|
||||
use lumotia_core::hardware::vulkan_loader_available;
|
||||
use lumotia_core::tuning::{inference_thread_count, Workload};
|
||||
use lumotia_core::types::{Segment, TranscriptionOptions};
|
||||
|
||||
use crate::transcriber::{Transcriber, TranscriberCapabilities};
|
||||
|
||||
@@ -42,7 +42,7 @@ impl WhisperRsBackend {
|
||||
impl Transcriber for WhisperRsBackend {
|
||||
fn capabilities(&self) -> TranscriberCapabilities {
|
||||
TranscriberCapabilities {
|
||||
sample_rate: magnotia_core::constants::WHISPER_SAMPLE_RATE,
|
||||
sample_rate: lumotia_core::constants::WHISPER_SAMPLE_RATE,
|
||||
channels: 1,
|
||||
supports_initial_prompt: true,
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
use std::env;
|
||||
use std::time::Instant;
|
||||
|
||||
use magnotia_core::hardware::vulkan_loader_available;
|
||||
use magnotia_core::tuning::{inference_thread_count, Workload};
|
||||
use lumotia_core::hardware::vulkan_loader_available;
|
||||
use lumotia_core::tuning::{inference_thread_count, Workload};
|
||||
use whisper_rs::{FullParams, SamplingStrategy, WhisperContext, WhisperContextParameters};
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
[package]
|
||||
name = "magnotia"
|
||||
name = "lumotia"
|
||||
version = "0.1.0"
|
||||
description = "Magnotia — Think out loud"
|
||||
description = "Lumotia — Think out loud"
|
||||
authors = ["CORBEL Ltd"]
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "magnotia_lib"
|
||||
name = "lumotia_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
# Default build includes the Whisper backend. Disabling this feature
|
||||
# also drops it from magnotia-transcription (see Cargo.toml in that crate)
|
||||
# also drops it from lumotia-transcription (see Cargo.toml in that crate)
|
||||
# so a --no-default-features workspace build does not pull whisper-rs-sys.
|
||||
# load_model_from_disk returns a runtime error for Engine::Whisper when
|
||||
# this feature is off; Parakeet continues to work.
|
||||
default = ["whisper"]
|
||||
whisper = ["magnotia-transcription/whisper"]
|
||||
whisper = ["lumotia-transcription/whisper"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
@@ -28,14 +28,14 @@ serde_json = "1"
|
||||
|
||||
[dependencies]
|
||||
# Workspace crates
|
||||
magnotia-core = { path = "../crates/core" }
|
||||
magnotia-audio = { path = "../crates/audio" }
|
||||
magnotia-transcription = { path = "../crates/transcription", default-features = false }
|
||||
magnotia-ai-formatting = { path = "../crates/ai-formatting" }
|
||||
magnotia-storage = { path = "../crates/storage" }
|
||||
magnotia-cloud-providers = { path = "../crates/cloud-providers" }
|
||||
magnotia-hotkey = { path = "../crates/hotkey" }
|
||||
magnotia-llm = { path = "../crates/llm" }
|
||||
lumotia-core = { path = "../crates/core" }
|
||||
lumotia-audio = { path = "../crates/audio" }
|
||||
lumotia-transcription = { path = "../crates/transcription", default-features = false }
|
||||
lumotia-ai-formatting = { path = "../crates/ai-formatting" }
|
||||
lumotia-storage = { path = "../crates/storage" }
|
||||
lumotia-cloud-providers = { path = "../crates/cloud-providers" }
|
||||
lumotia-hotkey = { path = "../crates/hotkey" }
|
||||
lumotia-llm = { path = "../crates/llm" }
|
||||
|
||||
# Tauri. The `tray-icon` feature, the global-shortcut/window-state/
|
||||
# autostart plugins are desktop-only — gated below under
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use tauri::Manager;
|
||||
|
||||
use crate::commands::security::ensure_main_window;
|
||||
use magnotia_audio::{DeviceInfo, MicrophoneCapture};
|
||||
use lumotia_audio::{DeviceInfo, MicrophoneCapture};
|
||||
|
||||
/// Enumerate every input device available to cpal, with metadata for the
|
||||
/// Settings device-picker UI. Includes a flag for likely PulseAudio /
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use magnotia_storage::{
|
||||
use lumotia_storage::{
|
||||
app_data_dir, crashes_dir, list_recent_errors, log_error, logs_dir, ErrorLogRow,
|
||||
};
|
||||
|
||||
@@ -335,7 +335,7 @@ async fn generate_diagnostic_report_inner(
|
||||
|
||||
if opts.include_settings {
|
||||
out.push_str("## Settings (sanitised)\n\n");
|
||||
match magnotia_storage::get_setting(&state.db, "magnotia_preferences").await {
|
||||
match lumotia_storage::get_setting(&state.db, "magnotia_preferences").await {
|
||||
Ok(Some(json)) => {
|
||||
out.push_str("```json\n");
|
||||
out.push_str(&sanitise_preferences_json(&json));
|
||||
@@ -520,7 +520,7 @@ pub async fn save_diagnostic_report(
|
||||
let _ = app; // reserved for future dialog integration
|
||||
let report = generate_diagnostic_report_inner(&state, options).await?;
|
||||
|
||||
let dir = magnotia_storage::app_data_dir().join("diagnostic-reports");
|
||||
let dir = lumotia_storage::app_data_dir().join("diagnostic-reports");
|
||||
fs::create_dir_all(&dir).map_err(|e| format!("create dir: {e}"))?;
|
||||
|
||||
let ts = SystemTime::now()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use magnotia_storage::{
|
||||
use lumotia_storage::{
|
||||
record_feedback as db_record_feedback, FeedbackTargetType, RecordFeedbackParams,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use magnotia_core::hardware::{self, Os};
|
||||
use magnotia_core::recommendation;
|
||||
use lumotia_core::hardware::{self, Os};
|
||||
use lumotia_core::recommendation;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SystemInfo {
|
||||
@@ -53,7 +53,7 @@ pub fn rank_models() -> Result<Vec<ModelRecommendation>, String> {
|
||||
Ok(ranked
|
||||
.into_iter()
|
||||
.map(|scored| {
|
||||
let downloaded = magnotia_transcription::is_downloaded(&scored.entry.id);
|
||||
let downloaded = lumotia_transcription::is_downloaded(&scored.entry.id);
|
||||
ModelRecommendation {
|
||||
id: scored.entry.id.as_str().to_string(),
|
||||
display_name: scored.entry.display_name,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||
use tauri::Emitter;
|
||||
use tokio::sync::{mpsc, Mutex};
|
||||
|
||||
use magnotia_hotkey::{EvdevHotkeyListener, HotkeyCombo, HotkeyEvent};
|
||||
use lumotia_hotkey::{EvdevHotkeyListener, HotkeyCombo, HotkeyEvent};
|
||||
|
||||
/// Managed state for the evdev hotkey listener.
|
||||
pub struct HotkeyState {
|
||||
@@ -30,7 +30,7 @@ pub fn is_wayland_session() -> bool {
|
||||
/// Check whether evdev hotkey capture is available (user in `input` group, etc.).
|
||||
#[tauri::command]
|
||||
pub fn check_hotkey_access() -> Result<(), String> {
|
||||
magnotia_hotkey::check_evdev_access()
|
||||
lumotia_hotkey::check_evdev_access()
|
||||
}
|
||||
|
||||
/// Start the evdev global hotkey listener. Emits "magnotia:hotkey-pressed" and
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use magnotia_storage::{
|
||||
use lumotia_storage::{
|
||||
delete_implementation_rule as db_delete_rule, get_task_by_id,
|
||||
insert_implementation_rule as db_insert_rule, list_implementation_rules as db_list_rules,
|
||||
mark_implementation_rule_fired as db_mark_rule_fired,
|
||||
|
||||
@@ -19,13 +19,13 @@ use crate::commands::models::{default_model_id_for_engine, ensure_model_loaded};
|
||||
use crate::commands::power::PowerAssertion;
|
||||
use crate::commands::security::ensure_main_window;
|
||||
use crate::AppState;
|
||||
use magnotia_ai_formatting::{post_process_segments, FormatMode, PostProcessOptions};
|
||||
use magnotia_audio::{
|
||||
use lumotia_ai_formatting::{post_process_segments, FormatMode, PostProcessOptions};
|
||||
use lumotia_audio::{
|
||||
AudioChunk, CaptureRuntimeError, MicrophoneCapture, StreamingResampler, WavWriter,
|
||||
};
|
||||
use magnotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use magnotia_core::types::{AudioSamples, Segment, TranscriptionOptions};
|
||||
use magnotia_transcription::LocalEngine;
|
||||
use lumotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use lumotia_core::types::{AudioSamples, Segment, TranscriptionOptions};
|
||||
use lumotia_transcription::LocalEngine;
|
||||
|
||||
const CHUNK_SAMPLES: usize = 32_000; // 2s at 16kHz
|
||||
const OVERLAP_SAMPLES: usize = 4_000; // 0.25s at 16kHz
|
||||
@@ -450,7 +450,7 @@ struct InferenceTask {
|
||||
chunk_start_sample: u64,
|
||||
trim_before_secs: f64,
|
||||
duration_secs: f64,
|
||||
rx: std::sync::mpsc::Receiver<Result<magnotia_transcription::TimedTranscript, String>>,
|
||||
rx: std::sync::mpsc::Receiver<Result<lumotia_transcription::TimedTranscript, String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -503,15 +503,15 @@ pub async fn start_live_transcription_session(
|
||||
let resolved_profile_id = config
|
||||
.profile_id
|
||||
.clone()
|
||||
.unwrap_or_else(|| magnotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
.unwrap_or_else(|| lumotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
|
||||
let profile = magnotia_storage::database::get_profile(&state.db, &resolved_profile_id)
|
||||
let profile = lumotia_storage::database::get_profile(&state.db, &resolved_profile_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?
|
||||
.ok_or_else(|| format!("Profile {resolved_profile_id} not found"))?;
|
||||
|
||||
let profile_terms: Vec<String> =
|
||||
magnotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
lumotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?
|
||||
.into_iter()
|
||||
@@ -1555,8 +1555,8 @@ mod tests {
|
||||
let stop_flag = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let (tx1, rx1) = std::sync::mpsc::channel();
|
||||
tx1.send(Ok(magnotia_transcription::TimedTranscript {
|
||||
transcript: magnotia_core::types::Transcript::new(
|
||||
tx1.send(Ok(lumotia_transcription::TimedTranscript {
|
||||
transcript: lumotia_core::types::Transcript::new(
|
||||
vec![segment(0.0, 0.8, "first chunk")],
|
||||
"en".into(),
|
||||
0.8,
|
||||
@@ -1597,8 +1597,8 @@ mod tests {
|
||||
);
|
||||
|
||||
let (tx2, rx2) = std::sync::mpsc::channel();
|
||||
tx2.send(Ok(magnotia_transcription::TimedTranscript {
|
||||
transcript: magnotia_core::types::Transcript::new(
|
||||
tx2.send(Ok(lumotia_transcription::TimedTranscript {
|
||||
transcript: lumotia_core::types::Transcript::new(
|
||||
vec![segment(0.0, 0.9, "second chunk")],
|
||||
"en".into(),
|
||||
0.9,
|
||||
|
||||
@@ -3,10 +3,10 @@ use tauri::{Emitter, State};
|
||||
use crate::commands::power::PowerAssertion;
|
||||
use crate::commands::security::ensure_main_window;
|
||||
use crate::AppState;
|
||||
use magnotia_ai_formatting::{llm_cleanup_text, LlmPromptPreset};
|
||||
use magnotia_core::hardware;
|
||||
use magnotia_llm::model_manager::{self, model_info};
|
||||
use magnotia_llm::{ContentTags, LlmModelId};
|
||||
use lumotia_ai_formatting::{llm_cleanup_text, LlmPromptPreset};
|
||||
use lumotia_core::hardware;
|
||||
use lumotia_llm::model_manager::{self, model_info};
|
||||
use lumotia_llm::{ContentTags, LlmModelId};
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -369,9 +369,9 @@ pub async fn cleanup_transcript_text_cmd(
|
||||
) -> Result<String, String> {
|
||||
ensure_main_window(&window)?;
|
||||
let resolved_profile_id =
|
||||
profile_id.unwrap_or_else(|| magnotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
profile_id.unwrap_or_else(|| lumotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
let profile_terms: Vec<String> =
|
||||
magnotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
lumotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?
|
||||
.into_iter()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
use magnotia_core::process_watch::{self, ProcessLister};
|
||||
use lumotia_core::process_watch::{self, ProcessLister};
|
||||
|
||||
/// Tauri-managed state for the meeting poller. Holds a long-lived
|
||||
/// `ProcessLister` so each poll refreshes the existing `sysinfo::System`
|
||||
|
||||
@@ -5,14 +5,14 @@ use tauri::Emitter;
|
||||
|
||||
use crate::commands::security::ensure_main_window;
|
||||
use crate::AppState;
|
||||
use magnotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use magnotia_core::hardware::{self, vulkan_loader_available, CpuFeatures};
|
||||
use magnotia_core::model_registry::{self, Engine, LanguageSupport, ModelEntry};
|
||||
use magnotia_core::types::{AudioSamples, ModelId, TranscriptionOptions};
|
||||
use lumotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use lumotia_core::hardware::{self, vulkan_loader_available, CpuFeatures};
|
||||
use lumotia_core::model_registry::{self, Engine, LanguageSupport, ModelEntry};
|
||||
use lumotia_core::types::{AudioSamples, ModelId, TranscriptionOptions};
|
||||
#[cfg(feature = "whisper")]
|
||||
use magnotia_transcription::load_whisper;
|
||||
use magnotia_transcription::model_manager;
|
||||
use magnotia_transcription::{load_parakeet, LocalEngine, Transcriber};
|
||||
use lumotia_transcription::load_whisper;
|
||||
use lumotia_transcription::model_manager;
|
||||
use lumotia_transcription::{load_parakeet, LocalEngine, Transcriber};
|
||||
|
||||
/// Map legacy size strings to ModelId.
|
||||
fn whisper_model_id(size: &str) -> ModelId {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Tauri commands wrapping magnotia_storage profile + profile_term CRUD.
|
||||
// Pattern mirrors tasks.rs — flat imports from `magnotia_storage` with a `db_`
|
||||
// Tauri commands wrapping lumotia_storage profile + profile_term CRUD.
|
||||
// Pattern mirrors tasks.rs — flat imports from `lumotia_storage` with a `db_`
|
||||
// alias prefix to avoid name collisions with the command functions, plain
|
||||
// snake_case parameters (Tauri 2.x auto-converts camelCase JS keys),
|
||||
// `.map_err(|e| e.to_string())` for error conversion, and camelCase DTOs
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use magnotia_ai_formatting::extract_corrections;
|
||||
use magnotia_storage::{
|
||||
use lumotia_ai_formatting::extract_corrections;
|
||||
use lumotia_storage::{
|
||||
add_profile_term as db_add_profile_term, create_profile as db_create_profile,
|
||||
delete_profile as db_delete_profile, delete_profile_term as db_delete_profile_term,
|
||||
list_profile_terms as db_list_profile_terms, list_profiles as db_list_profiles,
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
//! filtering rather than adding a second query path.
|
||||
//!
|
||||
//! Stored under the existing SQLite settings table via
|
||||
//! `magnotia_storage::{get_setting, set_setting}` — same bag as
|
||||
//! `lumotia_storage::{get_setting, set_setting}` — same bag as
|
||||
//! `magnotia_preferences`.
|
||||
|
||||
use magnotia_storage::{get_setting, set_setting};
|
||||
use lumotia_storage::{get_setting, set_setting};
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Tauri commands wrapping magnotia_storage task CRUD.
|
||||
// Tauri commands wrapping lumotia_storage task CRUD.
|
||||
// Pattern mirrors transcripts.rs — TaskDto is the camelCase frontend shape,
|
||||
// storage functions are aliased with db_ prefix to avoid name collisions.
|
||||
|
||||
@@ -6,8 +6,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
use magnotia_llm::prompts::FeedbackExample as LlmFeedbackExample;
|
||||
use magnotia_storage::{
|
||||
use lumotia_llm::prompts::FeedbackExample as LlmFeedbackExample;
|
||||
use lumotia_storage::{
|
||||
complete_subtask_and_check_parent as db_complete_subtask, complete_task as db_complete_task,
|
||||
delete_task as db_delete_task, get_task_by_id as db_get_task,
|
||||
insert_subtask as db_insert_subtask, insert_task as db_insert_task,
|
||||
@@ -228,7 +228,7 @@ fn to_llm_examples(rows: Vec<FeedbackRow>) -> Vec<LlmFeedbackExample> {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
target: "magnotia_lib::feedback",
|
||||
target: "lumotia_lib::feedback",
|
||||
row_id = r.id,
|
||||
error = %e,
|
||||
"skipping feedback row with malformed context_json"
|
||||
|
||||
@@ -9,9 +9,9 @@ use crate::commands::build_initial_prompt;
|
||||
use crate::commands::models::{default_model_id_for_engine, ensure_model_loaded};
|
||||
use crate::commands::security::ensure_main_window;
|
||||
use crate::AppState;
|
||||
use magnotia_ai_formatting::{post_process_segments, FormatMode, PostProcessOptions};
|
||||
use magnotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use magnotia_core::types::{AudioSamples, Segment, Transcript, TranscriptionOptions};
|
||||
use lumotia_ai_formatting::{post_process_segments, FormatMode, PostProcessOptions};
|
||||
use lumotia_core::constants::WHISPER_SAMPLE_RATE;
|
||||
use lumotia_core::types::{AudioSamples, Segment, Transcript, TranscriptionOptions};
|
||||
|
||||
const PARAKEET_CHUNK_THRESHOLD_SECS: usize = 18;
|
||||
const PARAKEET_CHUNK_SECS: usize = 15;
|
||||
@@ -29,7 +29,7 @@ struct ChunkingStrategy {
|
||||
fn pick_engine(
|
||||
state: &AppState,
|
||||
engine: &str,
|
||||
) -> Result<Arc<magnotia_transcription::LocalEngine>, String> {
|
||||
) -> Result<Arc<lumotia_transcription::LocalEngine>, String> {
|
||||
match engine {
|
||||
"whisper" => Ok(state.whisper_engine.clone()),
|
||||
"parakeet" => Ok(state.parakeet_engine.clone()),
|
||||
@@ -70,11 +70,11 @@ fn trim_overlap_segments(segments: &mut Vec<Segment>, trim_before_secs: f64) {
|
||||
}
|
||||
|
||||
fn transcribe_samples_sync(
|
||||
engine: Arc<magnotia_transcription::LocalEngine>,
|
||||
engine: Arc<lumotia_transcription::LocalEngine>,
|
||||
engine_name: &str,
|
||||
samples: Vec<f32>,
|
||||
options: TranscriptionOptions,
|
||||
) -> Result<magnotia_transcription::TimedTranscript, String> {
|
||||
) -> Result<lumotia_transcription::TimedTranscript, String> {
|
||||
let Some(strategy) = pick_chunking_strategy(engine_name, samples.len()) else {
|
||||
let audio = AudioSamples::mono_16khz(samples);
|
||||
return engine
|
||||
@@ -128,7 +128,7 @@ fn transcribe_samples_sync(
|
||||
chunk_start = chunk_end.saturating_sub(strategy.overlap_samples);
|
||||
}
|
||||
|
||||
Ok(magnotia_transcription::TimedTranscript {
|
||||
Ok(lumotia_transcription::TimedTranscript {
|
||||
transcript: Transcript::new(
|
||||
all_segments,
|
||||
options.language.clone().unwrap_or_else(|| "en".to_string()),
|
||||
@@ -165,15 +165,15 @@ pub async fn transcribe_file(
|
||||
) -> Result<serde_json::Value, String> {
|
||||
ensure_main_window(&window)?;
|
||||
let resolved_profile_id =
|
||||
profile_id.unwrap_or_else(|| magnotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
profile_id.unwrap_or_else(|| lumotia_storage::DEFAULT_PROFILE_ID.to_string());
|
||||
|
||||
let profile = magnotia_storage::database::get_profile(&state.db, &resolved_profile_id)
|
||||
let profile = lumotia_storage::database::get_profile(&state.db, &resolved_profile_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?
|
||||
.ok_or_else(|| format!("Profile {resolved_profile_id} not found"))?;
|
||||
|
||||
let profile_terms: Vec<String> =
|
||||
magnotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
lumotia_storage::database::list_profile_terms(&state.db, &resolved_profile_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())?
|
||||
.into_iter()
|
||||
@@ -199,7 +199,7 @@ pub async fn transcribe_file(
|
||||
let engine_name_for_worker = engine_name.clone();
|
||||
let path_for_probe = Path::new(&path);
|
||||
if let Some(duration_secs) =
|
||||
magnotia_audio::probe_audio_duration_secs(path_for_probe).map_err(|e| e.to_string())?
|
||||
lumotia_audio::probe_audio_duration_secs(path_for_probe).map_err(|e| e.to_string())?
|
||||
{
|
||||
if duration_secs > MAX_FILE_TRANSCRIPTION_SECS {
|
||||
return Err(format!(
|
||||
@@ -210,12 +210,12 @@ pub async fn transcribe_file(
|
||||
}
|
||||
|
||||
let timed = tokio::task::spawn_blocking(move || {
|
||||
let audio = magnotia_audio::decode_audio_file_limited(
|
||||
let audio = lumotia_audio::decode_audio_file_limited(
|
||||
Path::new(&path),
|
||||
Some(MAX_FILE_TRANSCRIPTION_SECS),
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let resampled = magnotia_audio::resample_to_16khz(&audio).map_err(|e| e.to_string())?;
|
||||
let resampled = lumotia_audio::resample_to_16khz(&audio).map_err(|e| e.to_string())?;
|
||||
transcribe_samples_sync(
|
||||
engine,
|
||||
&engine_name_for_worker,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Tauri commands wrapping the magnotia_storage transcript CRUD.
|
||||
// Tauri commands wrapping the lumotia_storage transcript CRUD.
|
||||
// These are the bridge that lets the Svelte frontend treat SQLite as the
|
||||
// canonical store rather than localStorage.
|
||||
//
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use magnotia_storage::{
|
||||
use lumotia_storage::{
|
||||
delete_transcript as db_delete_transcript, get_transcript as db_get_transcript,
|
||||
insert_transcript as db_insert_transcript, list_transcripts_paged,
|
||||
search_transcripts as db_search_transcripts, update_transcript as db_update_transcript,
|
||||
@@ -110,7 +110,7 @@ pub async fn add_transcript(
|
||||
profile_id: transcript
|
||||
.profile_id
|
||||
.as_deref()
|
||||
.unwrap_or(magnotia_storage::DEFAULT_PROFILE_ID),
|
||||
.unwrap_or(lumotia_storage::DEFAULT_PROFILE_ID),
|
||||
title: transcript.title.as_deref(),
|
||||
audio_path: transcript.audio_path.as_deref(),
|
||||
duration: transcript.duration,
|
||||
|
||||
@@ -12,15 +12,15 @@ use sqlx::SqlitePool;
|
||||
use tauri::Manager;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use magnotia_core::types::EngineName;
|
||||
use magnotia_llm::LlmEngine;
|
||||
use magnotia_storage::{database_path, get_setting, init as init_db, prune_error_log, set_setting};
|
||||
use lumotia_core::types::EngineName;
|
||||
use lumotia_llm::LlmEngine;
|
||||
use lumotia_storage::{database_path, get_setting, init as init_db, prune_error_log, set_setting};
|
||||
|
||||
/// How long to retain `error_log` rows. Pruned once on startup.
|
||||
/// 90 days is long enough to triage "this happened a few weeks ago"
|
||||
/// reports and short enough that the table stays kilobyte-scale.
|
||||
const ERROR_LOG_RETENTION_DAYS: i64 = 90;
|
||||
use magnotia_transcription::LocalEngine;
|
||||
use lumotia_transcription::LocalEngine;
|
||||
|
||||
static TRACING_INIT: Once = Once::new();
|
||||
|
||||
@@ -162,7 +162,7 @@ fn init_tracing() {
|
||||
TRACING_INIT.call_once(|| {
|
||||
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
||||
EnvFilter::new(
|
||||
"warn,magnotia=info,magnotia_lib=info,magnotia_audio=info,magnotia_startup=info,magnotia_hotkey=info,magnotia_ai_formatting=info",
|
||||
"warn,magnotia=info,lumotia_lib=info,lumotia_audio=info,magnotia_startup=info,lumotia_hotkey=info,lumotia_ai_formatting=info",
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
magnotia_lib::run()
|
||||
lumotia_lib::run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user