forked from ChelseaKR/sprout
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconftest.py
More file actions
125 lines (105 loc) · 3.41 KB
/
Copy pathconftest.py
File metadata and controls
125 lines (105 loc) · 3.41 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Shared fixtures: a tiny in-memory corpus and a wired Assistant.
The fixtures build the store directly from synthetic chunks (no files), so the RAG and
guard tests are fast, hermetic, and never touch disk. Ingest-from-files is exercised
separately in ``test_ingest.py``.
"""
from __future__ import annotations
from collections.abc import Callable
import pytest
from sprout.answer import Assistant
from sprout.config import Config
from sprout.models import Chunk
from sprout.providers import build_generator
from sprout.providers.deterministic import HashingEmbedding
from sprout.store import VectorStore
def make_chunk(
chunk_id: str,
source: str,
title: str,
text: str,
topic: str = "general",
language: str = "en",
) -> Chunk:
return Chunk(
chunk_id=chunk_id,
doc_id=source.split(".")[0],
title=title,
source=source,
text=text,
language=language,
topic=topic,
source_name="Synthetic Plant-Care Notes",
url=f"https://example.invalid/{source}",
license="CC0-1.0",
fetch_date="2026-05-01",
)
TINY_CHUNKS: list[Chunk] = [
make_chunk(
"mon-water",
"monstera.md",
"Monstera care",
"Yellowing Monstera leaves most often indicate overwatering. "
"Let the top 2 inches of soil dry before watering again.",
topic="watering",
),
make_chunk(
"mon-light",
"monstera.md",
"Monstera care",
"Monstera prefers bright indirect light near an east or north window.",
topic="light",
),
make_chunk(
"pothos-tox",
"pothos.md",
"Pothos toxicity",
"The cited source lists Pothos as toxic to cats and dogs; "
"ingestion can cause oral irritation and drooling.",
topic="toxicity",
),
make_chunk(
"spider-tox",
"spider-plant.md",
"Spider plant toxicity",
"The cited source does not list Spider plant as toxic to cats or dogs.",
topic="toxicity",
),
make_chunk(
"mon-water-es",
"monstera.es.md",
"Cuidado de la Monstera",
"Las hojas amarillas de la Monstera suelen indicar exceso de riego. "
"Deja secar las primeras 5 centimetros de tierra antes de regar.",
topic="watering",
language="es",
),
make_chunk(
"pothos-tox-es",
"pothos.es.md",
"Toxicidad del potho",
"La fuente citada indica que el potho es toxico para gatos y perros; "
"la ingestion puede causar irritacion bucal.",
topic="toxicity",
language="es",
),
]
@pytest.fixture
def config() -> Config:
return Config()
def build_assistant(config: Config, chunks: list[Chunk]) -> Assistant:
embedder = HashingEmbedding(dim=config.retrieval.embedding_dim)
store = VectorStore()
for chunk in chunks:
store.add(chunk, embedder.embed(chunk.text))
return Assistant(config, store, embedder, build_generator(config))
@pytest.fixture
def assistant(config: Config) -> Assistant:
return build_assistant(config, TINY_CHUNKS)
@pytest.fixture
def tiny_chunks() -> list[Chunk]:
return list(TINY_CHUNKS)
@pytest.fixture
def assistant_factory() -> Callable[..., Assistant]:
def _factory(cfg: Config, chunks: list[Chunk] | None = None) -> Assistant:
return build_assistant(cfg, chunks if chunks is not None else list(TINY_CHUNKS))
return _factory