feat(ai): integrate local Ollama AI for in-context sentence translation and caching (Task 13)

This commit is contained in:
Antigravity committed 2026-10-06 15:05:24 +03:00
1 parent 0c5951df8d
commit 37a1f1ab35
12 files changed
+605 -15

No files matched your search

+69
View File
@@ -1,5 +1,6 @@
import sqlite3
import contextlib
import hashlib
from pathlib import Path
from typing import Generator
from app import config
@@ -186,6 +187,21 @@ def _migrate(conn: sqlite3.Connection):
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_offline_dict_term ON offline_dictionary(term COLLATE NOCASE);")
# Ensure sentence_translations table exists
conn.execute("""
CREATE TABLE IF NOT EXISTS sentence_translations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sentence_hash TEXT NOT NULL,
original_text TEXT NOT NULL,
translated_text TEXT NOT NULL,
target_word TEXT DEFAULT '',
word_meaning TEXT DEFAULT '',
source TEXT DEFAULT 'local_llm',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
""")
conn.execute("CREATE INDEX IF NOT EXISTS idx_sentence_trans_hash ON sentence_translations(sentence_hash);")
# Auto-seed offline dictionary if empty
_seed_offline_dictionary(conn)
@@ -333,6 +349,59 @@ def init_db():
pos TEXT DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_offline_dict_term ON offline_dictionary(term COLLATE NOCASE);
CREATE TABLE IF NOT EXISTS sentence_translations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sentence_hash TEXT NOT NULL,
original_text TEXT NOT NULL,
translated_text TEXT NOT NULL,
target_word TEXT DEFAULT '',
word_meaning TEXT DEFAULT '',
source TEXT DEFAULT 'local_llm',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_sentence_trans_hash ON sentence_translations(sentence_hash);
""")
# Apply migrations for pre-existing databases
_migrate(conn)
def compute_sentence_hash(sentence: str, target_word: str = "") -> str:
norm = f"{sentence.strip().lower()}||{target_word.strip().lower()}"
return hashlib.sha256(norm.encode("utf-8")).hexdigest()
def get_cached_sentence_translation(sentence: str, target_word: str = "") -> dict | None:
s_hash = compute_sentence_hash(sentence, target_word)
with get_db() as conn:
row = conn.execute(
"""
SELECT original_text, translated_text, target_word, word_meaning, source, created_at
FROM sentence_translations
WHERE sentence_hash = ?
ORDER BY id DESC LIMIT 1
""",
(s_hash,),
).fetchone()
if row:
return dict(row)
return None
def save_sentence_translation(
sentence: str,
translated_text: str,
target_word: str = "",
word_meaning: str = "",
source: str = "local_llm",
) -> None:
s_hash = compute_sentence_hash(sentence, target_word)
with get_db() as conn:
conn.execute(
"""
INSERT INTO sentence_translations (sentence_hash, original_text, translated_text, target_word, word_meaning, source)
VALUES (?, ?, ?, ?, ?, ?)
""",
(s_hash, sentence.strip(), translated_text.strip(), target_word.strip(), word_meaning.strip(), source),
)