File size: 2,544 Bytes
102dd4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cf6d08c
102dd4f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import hashlib
from pathlib import Path

from app.config import Settings
from app.database.supabase import SupabaseRepository
from app.services.embedding_service import JinaEmbeddingService
from app.services.trip_indexing import build_trip_embedding_record


class AdminService:
    def __init__(
        self,
        *,
        repository: SupabaseRepository,
        embeddings: JinaEmbeddingService,
        settings: Settings,
        info_path: Path | None = None,
    ) -> None:
        self.repository = repository
        self.embeddings = embeddings
        self.settings = settings
        self.info_path = info_path or Path("prompts/falzh_info.md")

    async def seed_info(self) -> int:
        text = self.info_path.read_text(encoding="utf-8")
        chunk_texts = _chunk_markdown(text)
        embeddings = await self.embeddings.embed_passages(chunk_texts)
        chunks = []
        for chunk, embedding in zip(chunk_texts, embeddings, strict=True):
            digest = hashlib.sha256(chunk.encode("utf-8")).hexdigest()[:24]
            chunks.append(
                {
                    "id": f"info-{digest}",
                    "chunk_text": chunk,
                    "source": str(self.info_path),
                    "embedding": embedding,
                    "embedding_model": self.settings.jina_embedding_model,
                }
            )
        return await self.repository.upsert_info_chunks(chunks)

    async def sync_trips(self) -> int:
        trips = await self.repository.list_active_trips()
        trip_records = [
            build_trip_embedding_record(trip, self.settings.jina_embedding_model)
            for trip in trips
        ]
        embeddings = await self.embeddings.embed_passages(
            [record["chunk_text"] for record in trip_records]
        )
        for record, embedding in zip(trip_records, embeddings, strict=True):
            record["embedding"] = embedding
        return await self.repository.upsert_trip_embeddings(trip_records)


def _chunk_markdown(text: str, *, max_chars: int = 1200) -> list[str]:
    sections = [section.strip() for section in text.split("\n## ") if section.strip()]
    chunks: list[str] = []
    for index, section in enumerate(sections):
        content = section if index == 0 else f"## {section}"
        if len(content) <= max_chars:
            chunks.append(content)
            continue
        for start in range(0, len(content), max_chars):
            chunks.append(content[start : start + max_chars].strip())
    return chunks