feat(ai): integrate local Ollama AI for in-context sentence translation and caching (Task 13)
This commit is contained in:
@@ -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),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user