Record cassettes for embedder, ignore huggingface while recording
This commit is contained in:
parent
5844d07c5d
commit
1e9a10a235
107 changed files with 14227 additions and 7679 deletions
|
|
@ -12,7 +12,7 @@ except ImportError as e:
|
|||
class CohereReranker(RerankerBase): # pragma: no cover
|
||||
def __init__(self):
|
||||
# Cohere SDK reads CO_API_KEY from environment by default
|
||||
self._client = cohere.ClientV2()
|
||||
self._client = cohere.AsyncClientV2()
|
||||
|
||||
async def rerank(
|
||||
self, query: str, chunks: list[Chunk], top_n: int = 10
|
||||
|
|
@ -23,7 +23,7 @@ class CohereReranker(RerankerBase): # pragma: no cover
|
|||
documents = [chunk.content for chunk in chunks]
|
||||
|
||||
model_name = self._model or "rerank-v3.5"
|
||||
response = self._client.rerank(
|
||||
response = await self._client.rerank(
|
||||
model=model_name, query=query, documents=documents, top_n=top_n
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from zeroentropy import ZeroEntropy
|
||||
from zeroentropy import AsyncZeroEntropy
|
||||
|
||||
from haiku.rag.reranking.base import RerankerBase
|
||||
from haiku.rag.store.models.chunk import Chunk
|
||||
|
|
@ -15,7 +15,7 @@ class ZeroEntropyReranker(RerankerBase): # pragma: no cover
|
|||
"""
|
||||
self._model = model
|
||||
# Zero Entropy SDK reads ZEROENTROPY_API_KEY from environment by default
|
||||
self._client = ZeroEntropy()
|
||||
self._client = AsyncZeroEntropy()
|
||||
|
||||
async def rerank(
|
||||
self, query: str, chunks: list[Chunk], top_n: int = 10
|
||||
|
|
@ -38,7 +38,7 @@ class ZeroEntropyReranker(RerankerBase): # pragma: no cover
|
|||
|
||||
# Call Zero Entropy reranking API
|
||||
model_name = self._model or "zerank-1"
|
||||
response = self._client.models.rerank(
|
||||
response = await self._client.models.rerank(
|
||||
model=model_name,
|
||||
query=query,
|
||||
documents=documents,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ dev = [
|
|||
"mkdocs>=1.6.1",
|
||||
"mkdocs-material>=9.7.0",
|
||||
"pre-commit>=4.5.0",
|
||||
"pydantic-ai-slim[anthropic]",
|
||||
"pydantic-ai-slim[bedrock]",
|
||||
"pydantic-ai-slim[google]",
|
||||
"pydantic-ai-slim[groq]",
|
||||
"pyright>=1.1.407",
|
||||
"pytest>=9.0.2",
|
||||
"pytest-asyncio>=1.3.0",
|
||||
|
|
|
|||
120
tests/cassettes/test_chunk/test_chunk_repository_operations.yaml
Normal file
120
tests/cassettes/test_chunk/test_chunk_repository_operations.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
80
tests/cassettes/test_chunk/test_chunking_pipeline.yaml
Normal file
80
tests/cassettes/test_chunk/test_chunking_pipeline.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
120
tests/cassettes/test_client/test_client_document_crud.yaml
Normal file
120
tests/cassettes/test_client/test_client_document_crud.yaml
Normal file
File diff suppressed because one or more lines are too long
42
tests/cassettes/test_client/test_client_expand_context.yaml
Normal file
42
tests/cassettes/test_client/test_client_expand_context.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
242
tests/cassettes/test_client/test_client_search.yaml
Normal file
242
tests/cassettes/test_client/test_client_search.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
164
tests/cassettes/test_client/test_client_update_document.yaml
Normal file
164
tests/cassettes/test_client/test_client_update_document.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,13 +1,13 @@
|
|||
interactions:
|
||||
- request:
|
||||
body: "--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data; name=\"to_formats\"\r\n\r\njson\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition:
|
||||
form-data; name=\"do_ocr\"\r\n\r\ntrue\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data; name=\"force_ocr\"\r\n\r\nfalse\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition:
|
||||
form-data; name=\"do_table_structure\"\r\n\r\ntrue\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data;
|
||||
name=\"table_mode\"\r\n\r\naccurate\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data; name=\"table_cell_matching\"\r\n\r\ntrue\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition:
|
||||
form-data; name=\"images_scale\"\r\n\r\n2.0\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data;
|
||||
name=\"generate_picture_images\"\r\n\r\nfalse\r\n--4379b32700c5b8d95062406eb16d4651\r\nContent-Disposition: form-data;
|
||||
name=\"files\"; filename=\"tmpeojgnbxt.md\"\r\nContent-Type: text/markdown\r\n\r\n```python\ndef test():\n return
|
||||
42\n```\r\n--4379b32700c5b8d95062406eb16d4651--\r\n"
|
||||
body: "--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data; name=\"to_formats\"\r\n\r\njson\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition:
|
||||
form-data; name=\"do_ocr\"\r\n\r\ntrue\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data; name=\"force_ocr\"\r\n\r\nfalse\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition:
|
||||
form-data; name=\"do_table_structure\"\r\n\r\ntrue\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data;
|
||||
name=\"table_mode\"\r\n\r\naccurate\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data; name=\"table_cell_matching\"\r\n\r\ntrue\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition:
|
||||
form-data; name=\"images_scale\"\r\n\r\n2.0\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data;
|
||||
name=\"generate_picture_images\"\r\n\r\nfalse\r\n--313fb28cff30a333a81f610f9c6bdaf3\r\nContent-Disposition: form-data;
|
||||
name=\"files\"; filename=\"tmpgc9za8mg.md\"\r\nContent-Type: text/markdown\r\n\r\n```python\ndef test():\n return
|
||||
42\n```\r\n--313fb28cff30a333a81f610f9c6bdaf3--\r\n"
|
||||
headers:
|
||||
accept:
|
||||
- '*/*'
|
||||
|
|
@ -18,7 +18,7 @@ interactions:
|
|||
content-length:
|
||||
- '1011'
|
||||
content-type:
|
||||
- multipart/form-data; boundary=4379b32700c5b8d95062406eb16d4651
|
||||
- multipart/form-data; boundary=313fb28cff30a333a81f610f9c6bdaf3
|
||||
host:
|
||||
- localhost:5001
|
||||
method: POST
|
||||
|
|
@ -26,13 +26,13 @@ interactions:
|
|||
response:
|
||||
headers:
|
||||
content-length:
|
||||
- '1114'
|
||||
- '1113'
|
||||
content-type:
|
||||
- application/json
|
||||
parsed_body:
|
||||
document:
|
||||
doctags_content: null
|
||||
filename: tmpeojgnbxt.md
|
||||
filename: tmpgc9za8mg.md
|
||||
html_content: null
|
||||
json_content:
|
||||
body:
|
||||
|
|
@ -55,10 +55,10 @@ interactions:
|
|||
self_ref: '#/furniture'
|
||||
groups: []
|
||||
key_value_items: []
|
||||
name: tmpeojgnbxt
|
||||
name: tmpgc9za8mg
|
||||
origin:
|
||||
binary_hash: 9008975733065065710
|
||||
filename: tmpeojgnbxt.md
|
||||
filename: tmpgc9za8mg.md
|
||||
mimetype: text/markdown
|
||||
uri: null
|
||||
pages: {}
|
||||
|
|
@ -91,7 +91,7 @@ interactions:
|
|||
md_content: null
|
||||
text_content: null
|
||||
errors: []
|
||||
processing_time: 0.0017275830000471615
|
||||
processing_time: 0.002258999999980915
|
||||
status: success
|
||||
timings: {}
|
||||
status:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
interactions:
|
||||
- request:
|
||||
body: "--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data; name=\"to_formats\"\r\n\r\njson\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition:
|
||||
form-data; name=\"do_ocr\"\r\n\r\ntrue\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data; name=\"force_ocr\"\r\n\r\nfalse\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition:
|
||||
form-data; name=\"do_table_structure\"\r\n\r\ntrue\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data;
|
||||
name=\"table_mode\"\r\n\r\naccurate\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data; name=\"table_cell_matching\"\r\n\r\ntrue\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition:
|
||||
form-data; name=\"images_scale\"\r\n\r\n2.0\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data;
|
||||
name=\"generate_picture_images\"\r\n\r\nfalse\r\n--798e57b119ed24827326455c645311ae\r\nContent-Disposition: form-data;
|
||||
name=\"files\"; filename=\"content.md\"\r\nContent-Type: text/markdown\r\n\r\n# Test Document\n\nThis is a test.\r\n--798e57b119ed24827326455c645311ae--\r\n"
|
||||
body: "--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data; name=\"to_formats\"\r\n\r\njson\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition:
|
||||
form-data; name=\"do_ocr\"\r\n\r\ntrue\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data; name=\"force_ocr\"\r\n\r\nfalse\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition:
|
||||
form-data; name=\"do_table_structure\"\r\n\r\ntrue\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data;
|
||||
name=\"table_mode\"\r\n\r\naccurate\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data; name=\"table_cell_matching\"\r\n\r\ntrue\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition:
|
||||
form-data; name=\"images_scale\"\r\n\r\n2.0\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data;
|
||||
name=\"generate_picture_images\"\r\n\r\nfalse\r\n--a906caa5bbe5d30e17b44fb63c456240\r\nContent-Disposition: form-data;
|
||||
name=\"files\"; filename=\"content.md\"\r\nContent-Type: text/markdown\r\n\r\n# Test Document\n\nThis is a test.\r\n--a906caa5bbe5d30e17b44fb63c456240--\r\n"
|
||||
headers:
|
||||
accept:
|
||||
- '*/*'
|
||||
|
|
@ -17,7 +17,7 @@ interactions:
|
|||
content-length:
|
||||
- '1000'
|
||||
content-type:
|
||||
- multipart/form-data; boundary=798e57b119ed24827326455c645311ae
|
||||
- multipart/form-data; boundary=a906caa5bbe5d30e17b44fb63c456240
|
||||
host:
|
||||
- localhost:5001
|
||||
method: POST
|
||||
|
|
@ -94,7 +94,7 @@ interactions:
|
|||
md_content: null
|
||||
text_content: null
|
||||
errors: []
|
||||
processing_time: 0.002875374999803171
|
||||
processing_time: 0.004331874999934371
|
||||
status: success
|
||||
timings: {}
|
||||
status:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
122
tests/cassettes/test_filter/test_search_with_title_filter.yaml
Normal file
122
tests/cassettes/test_filter/test_search_with_title_filter.yaml
Normal file
File diff suppressed because one or more lines are too long
162
tests/cassettes/test_filter/test_search_with_uri_filter.yaml
Normal file
162
tests/cassettes/test_filter/test_search_with_uri_filter.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
158
tests/cassettes/test_rebuild/test_rebuild_embed_only.yaml
Normal file
158
tests/cassettes/test_rebuild/test_rebuild_embed_only.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
151
tests/cassettes/test_rebuild/test_rebuild_full.yaml
Normal file
151
tests/cassettes/test_rebuild/test_rebuild_full.yaml
Normal file
File diff suppressed because one or more lines are too long
151
tests/cassettes/test_rebuild/test_rebuild_rechunk.yaml
Normal file
151
tests/cassettes/test_rebuild/test_rebuild_rechunk.yaml
Normal file
File diff suppressed because one or more lines are too long
70
tests/cassettes/test_reranker/test_cohere_reranker.yaml
Normal file
70
tests/cassettes/test_reranker/test_cohere_reranker.yaml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
interactions:
|
||||
- request:
|
||||
headers:
|
||||
accept:
|
||||
- '*/*'
|
||||
accept-encoding:
|
||||
- gzip, deflate, zstd
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1261'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- api.cohere.com
|
||||
method: POST
|
||||
parsed_body:
|
||||
documents:
|
||||
- To Kill a Mockingbird is a novel by Harper Lee published in 1960. It was immediately successful, winning the Pulitzer
|
||||
Prize, and has become a classic of modern American literature.
|
||||
- The novel Moby-Dick was written by Herman Melville and first published in 1851. It is considered a masterpiece of
|
||||
American literature and deals with complex themes of obsession, revenge, and the conflict between good and evil.
|
||||
- Harper Lee, an American novelist widely known for her novel To Kill a Mockingbird, was born in 1926 in Monroeville,
|
||||
Alabama. She received the Pulitzer Prize for Fiction in 1961.
|
||||
- Jane Austen was an English novelist known primarily for her six major novels, which interpret, critique and comment
|
||||
upon the British landed gentry at the end of the 18th century.
|
||||
- The Harry Potter series, which consists of seven fantasy novels written by British author J.K. Rowling, is among the
|
||||
most popular and critically acclaimed books of the modern era.
|
||||
- The Great Gatsby, a novel written by American author F. Scott Fitzgerald, was published in 1925. The story is set
|
||||
in the Jazz Age and follows the life of millionaire Jay Gatsby and his pursuit of Daisy Buchanan.
|
||||
model: rerank-v3.5
|
||||
query: Who wrote 'To Kill a Mockingbird'?
|
||||
top_n: 2
|
||||
uri: https://api.cohere.com/v2/rerank
|
||||
response:
|
||||
headers:
|
||||
access-control-expose-headers:
|
||||
- X-Debug-Trace-ID
|
||||
alt-svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
cache-control:
|
||||
- no-cache, no-store, no-transform, must-revalidate, private, max-age=0
|
||||
content-length:
|
||||
- '210'
|
||||
content-type:
|
||||
- application/json
|
||||
expires:
|
||||
- Thu, 01 Jan 1970 00:00:00 GMT
|
||||
pragma:
|
||||
- no-cache
|
||||
transfer-encoding:
|
||||
- chunked
|
||||
vary:
|
||||
- Origin,Accept-Encoding
|
||||
parsed_body:
|
||||
id: 56d8804a-d476-4c6a-ade8-69deb3fc8c64
|
||||
meta:
|
||||
api_version:
|
||||
version: '2'
|
||||
billed_units:
|
||||
search_units: 1
|
||||
results:
|
||||
- index: 0
|
||||
relevance_score: 0.9438932
|
||||
- index: 2
|
||||
relevance_score: 0.8455478
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
59
tests/cassettes/test_reranker/test_zeroentropy_reranker.yaml
Normal file
59
tests/cassettes/test_reranker/test_zeroentropy_reranker.yaml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
interactions:
|
||||
- request:
|
||||
headers:
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- gzip, deflate, zstd
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1248'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- api.zeroentropy.dev
|
||||
method: POST
|
||||
parsed_body:
|
||||
documents:
|
||||
- To Kill a Mockingbird is a novel by Harper Lee published in 1960. It was immediately successful, winning the Pulitzer
|
||||
Prize, and has become a classic of modern American literature.
|
||||
- The novel Moby-Dick was written by Herman Melville and first published in 1851. It is considered a masterpiece of
|
||||
American literature and deals with complex themes of obsession, revenge, and the conflict between good and evil.
|
||||
- Harper Lee, an American novelist widely known for her novel To Kill a Mockingbird, was born in 1926 in Monroeville,
|
||||
Alabama. She received the Pulitzer Prize for Fiction in 1961.
|
||||
- Jane Austen was an English novelist known primarily for her six major novels, which interpret, critique and comment
|
||||
upon the British landed gentry at the end of the 18th century.
|
||||
- The Harry Potter series, which consists of seven fantasy novels written by British author J.K. Rowling, is among the
|
||||
most popular and critically acclaimed books of the modern era.
|
||||
- The Great Gatsby, a novel written by American author F. Scott Fitzgerald, was published in 1925. The story is set
|
||||
in the Jazz Age and follows the life of millionaire Jay Gatsby and his pursuit of Daisy Buchanan.
|
||||
model: zerank-1
|
||||
query: Who wrote 'To Kill a Mockingbird'?
|
||||
uri: https://api.zeroentropy.dev/v1/models/rerank
|
||||
response:
|
||||
headers:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '309'
|
||||
content-type:
|
||||
- application/json
|
||||
parsed_body:
|
||||
results:
|
||||
- index: 2
|
||||
relevance_score: 0.9392035026199311
|
||||
- index: 0
|
||||
relevance_score: 0.918713920386427
|
||||
- index: 5
|
||||
relevance_score: 0.0860773208330919
|
||||
- index: 4
|
||||
relevance_score: 0.08035746882220708
|
||||
- index: 3
|
||||
relevance_score: 0.07673913563377131
|
||||
- index: 1
|
||||
relevance_score: 0.07498651627727318
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1629
tests/cassettes/test_search/test_search_qa_corpus.yaml
Normal file
1629
tests/cassettes/test_search/test_search_qa_corpus.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
242
tests/cassettes/test_search/test_search_score_types.yaml
Normal file
242
tests/cassettes/test_search/test_search_score_types.yaml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -5,11 +5,17 @@ from pathlib import Path
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
# Prevent tests from loading user's local haiku.rag.yaml by setting env var
|
||||
# to an empty config file BEFORE any haiku.rag imports.
|
||||
# This ensures tests always use default config values.
|
||||
# to a test config file BEFORE any haiku.rag imports.
|
||||
# Uses Ollama for embeddings - HTTP calls are recorded/replayed via VCR.
|
||||
_test_config_dir = tempfile.mkdtemp()
|
||||
_test_config_path = Path(_test_config_dir) / "test-defaults.yaml"
|
||||
_test_config_path.write_text("{}") # Empty YAML = use all defaults
|
||||
_test_config_path.write_text("""
|
||||
embeddings:
|
||||
model:
|
||||
provider: ollama
|
||||
name: qwen3-embedding:4b
|
||||
vector_dim: 2560
|
||||
""")
|
||||
os.environ["HAIKU_RAG_CONFIG_PATH"] = str(_test_config_path)
|
||||
|
||||
import pydantic_ai.models # noqa: E402
|
||||
|
|
@ -101,6 +107,12 @@ def set_mock_api_keys(monkeypatch):
|
|||
monkeypatch.setenv("ZEROENTROPY_API_KEY", "mock-ze-key-for-vcr-playback")
|
||||
if not os.getenv("VOYAGE_API_KEY"):
|
||||
monkeypatch.setenv("VOYAGE_API_KEY", "mock-voyage-key-for-vcr-playback")
|
||||
if not os.getenv("GROQ_API_KEY"):
|
||||
monkeypatch.setenv("GROQ_API_KEY", "mock-groq-key-for-vcr-playback")
|
||||
if not os.getenv("GOOGLE_API_KEY"):
|
||||
monkeypatch.setenv("GOOGLE_API_KEY", "mock-google-key-for-vcr-playback")
|
||||
if not os.getenv("AWS_DEFAULT_REGION"):
|
||||
monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")
|
||||
|
||||
|
||||
def pytest_recording_configure(config: Any, vcr: "VCR"):
|
||||
|
|
@ -113,6 +125,7 @@ def pytest_recording_configure(config: Any, vcr: "VCR"):
|
|||
def vcr_config():
|
||||
return {
|
||||
"ignore_localhost": False,
|
||||
"ignore_hosts": ["huggingface.co"],
|
||||
"filter_headers": ["authorization", "x-api-key"],
|
||||
"decode_compressed_response": True,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ async def client_with_docs(temp_db_path):
|
|||
client.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_search_filter_restricts_results(client_with_docs):
|
||||
"""Test that search_filter restricts search to specified documents."""
|
||||
client, doc1_id, doc2_id = client_with_docs
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -246,7 +246,7 @@ class TestClientReadOnly:
|
|||
assert client.is_read_only is True
|
||||
client.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_raises_when_read_only(self, temp_db_path):
|
||||
"""Client.create_document() raises ReadOnlyError when read_only=True."""
|
||||
client = HaikuRAG(temp_db_path, create=True)
|
||||
|
|
@ -256,7 +256,7 @@ class TestClientReadOnly:
|
|||
with pytest.raises(ReadOnlyError):
|
||||
await client.create_document("test content")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_delete_document_raises_when_read_only(self, temp_db_path):
|
||||
"""Client.delete_document() raises ReadOnlyError when read_only=True."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -268,7 +268,7 @@ class TestClientReadOnly:
|
|||
with pytest.raises(ReadOnlyError):
|
||||
await client.delete_document(doc_id)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_search_works_when_read_only(self, temp_db_path):
|
||||
"""Client.search() works in read-only mode."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -278,7 +278,7 @@ class TestClientReadOnly:
|
|||
results = await client.search("cats")
|
||||
assert len(results) > 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_list_documents_works_when_read_only(self, temp_db_path):
|
||||
"""Client.list_documents() works in read-only mode."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from haiku.rag.config import Config
|
|||
from haiku.rag.store.models.chunk import Chunk, ChunkMetadata, SearchResult
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_chunk_repository_operations(qa_corpus: Dataset, temp_db_path):
|
||||
"""Test ChunkRepository operations."""
|
||||
# Create client
|
||||
|
|
@ -47,7 +47,7 @@ async def test_chunk_repository_operations(qa_corpus: Dataset, temp_db_path):
|
|||
client.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_chunk_repository_pagination(qa_corpus: Dataset, temp_db_path):
|
||||
"""Test ChunkRepository pagination with get_by_document_id and count_by_document_id."""
|
||||
async with HaikuRAG(db_path=temp_db_path, config=Config, create=True) as client:
|
||||
|
|
@ -96,7 +96,7 @@ async def test_chunk_repository_pagination(qa_corpus: Dataset, temp_db_path):
|
|||
assert len(empty_batch) == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_chunking_pipeline(qa_corpus: Dataset, temp_db_path):
|
||||
"""Test document chunking using client primitives."""
|
||||
from haiku.rag.client import HaikuRAG
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ def vcr_cassette_dir():
|
|||
return str(Path(__file__).parent / "cassettes" / "test_client")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_document_crud(qa_corpus: Dataset, temp_db_path):
|
||||
"""Test HaikuRAG CRUD operations for documents."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -84,7 +84,7 @@ async def test_client_document_crud(qa_corpus: Dataset, temp_db_path):
|
|||
assert deleted_again is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document(qa_corpus: Dataset, temp_db_path):
|
||||
"""Test updating document with individual parameters."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -155,7 +155,7 @@ async def test_client_update_document(qa_corpus: Dataset, temp_db_path):
|
|||
assert doc_chunks[1].content == "Custom chunk 2"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_source(temp_db_path):
|
||||
"""Test creating a document from a file source."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -186,7 +186,7 @@ async def test_client_create_document_from_source(temp_db_path):
|
|||
assert "md5" in doc2.metadata
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_source_with_title(temp_db_path):
|
||||
"""Test creating a document from a file source with a title."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -203,7 +203,7 @@ async def test_client_create_document_from_source_with_title(temp_db_path):
|
|||
assert doc.title == "My Doc"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_title_noop_behavior(temp_db_path):
|
||||
"""When content is unchanged, updating title should update document without re-chunking."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -225,7 +225,7 @@ async def test_client_update_title_noop_behavior(temp_db_path):
|
|||
assert got.title == "Title B"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_source_unsupported(temp_db_path):
|
||||
"""Test creating a document from an unsupported file type."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -241,7 +241,7 @@ async def test_client_create_document_from_source_unsupported(temp_db_path):
|
|||
await client.create_document_from_source(temp_path)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_source_nonexistent(temp_db_path):
|
||||
"""Test creating a document from a non-existent file."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -252,7 +252,7 @@ async def test_client_create_document_from_source_nonexistent(temp_db_path):
|
|||
await client.create_document_from_source(non_existent_path)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_directory(temp_db_path):
|
||||
"""Test creating documents from a directory recursively."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -287,7 +287,7 @@ async def test_client_create_document_from_directory(temp_db_path):
|
|||
assert not any("unsupported.xyz" in uri for uri in uris)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_directory_with_filters(
|
||||
monkeypatch, temp_db_path
|
||||
):
|
||||
|
|
@ -336,7 +336,7 @@ async def test_client_create_document_from_directory_with_filters(
|
|||
assert not any("debug.log" in uri for uri in uris)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_url(temp_db_path):
|
||||
"""Test creating a document from a URL."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -362,7 +362,7 @@ async def test_client_create_document_from_url(temp_db_path):
|
|||
assert doc.metadata["contentType"] == "text/html"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_url_with_different_content_types(
|
||||
temp_db_path,
|
||||
):
|
||||
|
|
@ -409,7 +409,7 @@ async def test_client_create_document_from_url_with_different_content_types(
|
|||
assert doc.metadata["contentType"] == "text/plain"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_url_unsupported_content(temp_db_path):
|
||||
"""Test creating a document from URL with unsupported content type."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -426,7 +426,7 @@ async def test_client_create_document_from_url_unsupported_content(temp_db_path)
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_url_http_error(temp_db_path):
|
||||
"""Test handling HTTP errors when creating document from URL."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -443,7 +443,7 @@ async def test_client_create_document_from_url_http_error(temp_db_path):
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_get_extension_from_content_type_or_url(temp_db_path):
|
||||
"""Test the helper method for determining file extensions."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -488,7 +488,7 @@ async def test_get_extension_from_content_type_or_url(temp_db_path):
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_metadata_content_type_and_md5(temp_db_path):
|
||||
"""Test that contentType and md5 metadata are correctly set."""
|
||||
import hashlib
|
||||
|
|
@ -523,7 +523,7 @@ async def test_client_metadata_content_type_and_md5(temp_db_path):
|
|||
assert url_doc.metadata["md5"] == expected_md5
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_update_no_op_behavior(temp_db_path):
|
||||
"""Test create/update/no-op behavior based on MD5 changes."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -562,7 +562,7 @@ async def test_client_create_update_no_op_behavior(temp_db_path):
|
|||
assert retrieved_doc.content == updated_content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_unchanged_file_keeps_timestamp(temp_db_path):
|
||||
"""Test that unchanged files don't update the updated_at timestamp."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -584,7 +584,7 @@ async def test_client_unchanged_file_keeps_timestamp(temp_db_path):
|
|||
assert doc2.updated_at == original_updated_at # Timestamp should not change
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_url_create_update_no_op_behavior(temp_db_path):
|
||||
"""Test create/update/no-op behavior for URLs based on MD5 changes."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -623,7 +623,7 @@ async def test_client_url_create_update_no_op_behavior(temp_db_path):
|
|||
assert doc3.content == updated_content.decode() # Updated content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_search(temp_db_path):
|
||||
"""Test HaikuRAG search functionality."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -666,7 +666,7 @@ async def test_client_search(temp_db_path):
|
|||
assert len(limited_results) <= 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_async_context_manager(temp_db_path):
|
||||
"""Test HaikuRAG as async context manager."""
|
||||
|
||||
|
|
@ -691,7 +691,7 @@ async def test_client_async_context_manager(temp_db_path):
|
|||
# but the test passing means the context manager methods work correctly
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_import_document_with_custom_chunks(temp_db_path):
|
||||
"""Test importing a document with pre-created chunks."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -762,7 +762,7 @@ async def test_client_ask(allow_model_requests, temp_db_path):
|
|||
assert isinstance(citations, list)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_expand_context(temp_db_path):
|
||||
"""Test that expand_context method exists and works with basic input."""
|
||||
from haiku.rag.store.models import SearchResult
|
||||
|
|
@ -779,7 +779,7 @@ async def test_client_expand_context(temp_db_path):
|
|||
assert expanded_results[0].score == 0.9
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_stores_docling_json(temp_db_path):
|
||||
"""Test that create_document stores DoclingDocument JSON."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -801,7 +801,7 @@ async def test_client_create_document_stores_docling_json(temp_db_path):
|
|||
assert parsed["version"] == doc.docling_version
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_import_document_stores_docling_data(temp_db_path):
|
||||
"""Test that import_document stores DoclingDocument data correctly."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -828,7 +828,7 @@ async def test_client_import_document_stores_docling_data(temp_db_path):
|
|||
assert doc.docling_version == docling_doc.version
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_from_file_stores_docling_json(temp_db_path):
|
||||
"""Test that create_document_from_source stores DoclingDocument JSON for files."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -850,7 +850,7 @@ async def test_client_create_document_from_file_stores_docling_json(temp_db_path
|
|||
assert retrieved.docling_version == doc.docling_version
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document_stores_docling_json(temp_db_path):
|
||||
"""Test that update_document stores DoclingDocument JSON when content changes."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -870,7 +870,7 @@ async def test_client_update_document_stores_docling_json(temp_db_path):
|
|||
assert updated_doc.docling_document_json != original_json
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document_with_custom_chunks_no_docling_json(
|
||||
temp_db_path,
|
||||
):
|
||||
|
|
@ -891,7 +891,7 @@ async def test_client_update_document_with_custom_chunks_no_docling_json(
|
|||
assert updated_doc.docling_document_json == original_json
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document_content_docling_mutually_exclusive(
|
||||
temp_db_path,
|
||||
):
|
||||
|
|
@ -915,7 +915,7 @@ async def test_client_update_document_content_docling_mutually_exclusive(
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document_with_docling_rechunks(temp_db_path):
|
||||
"""Test that providing docling_document without chunks triggers rechunk."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -952,7 +952,7 @@ async def test_client_update_document_with_docling_rechunks(temp_db_path):
|
|||
assert new_chunks[0].content != original_chunks[0].content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_update_document_docling_with_chunks(temp_db_path):
|
||||
"""Test that providing both docling_document and chunks stores both."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -990,7 +990,7 @@ async def test_client_update_document_docling_with_chunks(temp_db_path):
|
|||
assert chunks[1].content == "Custom chunk 2"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_file_update_stores_docling_json(temp_db_path):
|
||||
"""Test that updating a file re-stores DoclingDocument JSON."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1018,7 +1018,7 @@ async def test_client_file_update_stores_docling_json(temp_db_path):
|
|||
assert doc2.docling_version == original_version # Version stays same
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_visualize_chunk_no_document(temp_db_path):
|
||||
"""Test visualize_chunk returns empty list when chunk has no document_id."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1027,7 +1027,7 @@ async def test_client_visualize_chunk_no_document(temp_db_path):
|
|||
assert images == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_visualize_chunk_no_bounding_boxes(temp_db_path):
|
||||
"""Test visualize_chunk returns empty list when chunk has no bounding boxes."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1049,7 +1049,7 @@ async def test_client_visualize_chunk_no_bounding_boxes(temp_db_path):
|
|||
assert images == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_visualize_chunk_returns_list(temp_db_path):
|
||||
"""Test visualize_chunk returns a list (empty or with images)."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1082,7 +1082,7 @@ This is paragraph four about topic C.
|
|||
|
||||
|
||||
@pytest.mark.integration
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_visualize_chunk_with_pdf(temp_db_path):
|
||||
"""Test visualize_chunk returns images with bounding boxes for PDF documents."""
|
||||
from PIL.Image import Image as PILImage
|
||||
|
|
@ -1120,7 +1120,7 @@ async def test_client_visualize_chunk_with_pdf(temp_db_path):
|
|||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_text(temp_db_path):
|
||||
"""Test convert() with plain text content."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -1135,7 +1135,7 @@ async def test_client_convert_text(temp_db_path):
|
|||
assert "test content" in markdown
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_file(temp_db_path):
|
||||
"""Test convert() with a file path."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -1152,7 +1152,7 @@ async def test_client_convert_file(temp_db_path):
|
|||
assert "File content" in markdown
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_file_not_found(temp_db_path):
|
||||
"""Test convert() raises ValueError for non-existent file."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1160,7 +1160,7 @@ async def test_client_convert_file_not_found(temp_db_path):
|
|||
await client.convert(Path("/nonexistent/path/file.txt"))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_unsupported_extension(temp_db_path):
|
||||
"""Test convert() raises ValueError for unsupported file extension."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1172,7 +1172,7 @@ async def test_client_convert_unsupported_extension(temp_db_path):
|
|||
await client.convert(temp_path)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_file_uri(temp_db_path):
|
||||
"""Test convert() with a file:// URI string."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -1195,7 +1195,7 @@ async def test_client_convert_file_uri(temp_db_path):
|
|||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_chunk_basic(temp_db_path):
|
||||
"""Test chunk() produces Chunk objects from DoclingDocument."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1215,7 +1215,7 @@ async def test_client_chunk_basic(temp_db_path):
|
|||
assert all(c.document_id is None for c in chunks)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_chunk_preserves_metadata(temp_db_path):
|
||||
"""Test chunk() preserves structured metadata from DoclingDocument."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1244,7 +1244,7 @@ This is a subsection.
|
|||
assert has_metadata, "Chunks should have structured metadata"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_chunk_empty_document(temp_db_path):
|
||||
"""Test chunk() with empty DoclingDocument."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -1259,7 +1259,7 @@ async def test_client_chunk_empty_document(temp_db_path):
|
|||
assert len(chunks) == 0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_import_document_embeds_chunks_without_embeddings(temp_db_path):
|
||||
"""Test that import_document embeds chunks that don't have embeddings."""
|
||||
from docling_core.types.doc.document import DoclingDocument
|
||||
|
|
@ -1295,7 +1295,7 @@ async def test_import_document_embeds_chunks_without_embeddings(temp_db_path):
|
|||
assert results[0].content == "First chunk without embedding"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_update_document_embeds_chunks_without_embeddings(temp_db_path):
|
||||
"""Test that update_document embeds chunks that don't have embeddings."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1324,7 +1324,7 @@ async def test_update_document_embeds_chunks_without_embeddings(temp_db_path):
|
|||
assert results[0].content == "Updated chunk without embedding"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_create_document_with_html_format(temp_db_path):
|
||||
"""Test create_document with HTML format preserves document structure."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
@ -1359,7 +1359,7 @@ async def test_client_create_document_with_html_format(temp_db_path):
|
|||
assert "list_item" in labels
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_client_convert_with_html_format(temp_db_path):
|
||||
"""Test convert with HTML format."""
|
||||
async with HaikuRAG(temp_db_path, create=True) as client:
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ def small_chunk_config() -> AppConfig:
|
|||
return config
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_table_expansion_includes_split_rows(temp_db_path, small_chunk_config):
|
||||
"""Verify that table expansion retrieves rows that were split into different chunks."""
|
||||
docling_doc = create_table_document()
|
||||
|
|
@ -129,7 +129,7 @@ async def test_table_expansion_includes_split_rows(temp_db_path, small_chunk_con
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_list_expansion_includes_split_items(temp_db_path, small_chunk_config):
|
||||
"""Verify that list expansion retrieves items that were split into different chunks."""
|
||||
docling_doc = create_list_document()
|
||||
|
|
@ -177,7 +177,7 @@ async def test_list_expansion_includes_split_items(temp_db_path, small_chunk_con
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_code_expansion_includes_adjacent_blocks(
|
||||
temp_db_path, small_chunk_config
|
||||
):
|
||||
|
|
@ -223,7 +223,7 @@ async def test_code_expansion_includes_adjacent_blocks(
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_text_expansion_uses_radius(temp_db_path):
|
||||
"""Text content expansion should use radius, not structural boundaries."""
|
||||
config = AppConfig()
|
||||
|
|
@ -265,7 +265,7 @@ async def test_text_expansion_uses_radius(temp_db_path):
|
|||
assert len(expanded[0].content) >= len(original.content)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expansion_preserves_metadata(temp_db_path, small_chunk_config):
|
||||
"""Expansion should preserve document metadata."""
|
||||
docling_doc = create_table_document()
|
||||
|
|
@ -284,7 +284,7 @@ async def test_expansion_preserves_metadata(temp_db_path, small_chunk_config):
|
|||
assert expanded[0].document_id == results[0].document_id
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_format_for_agent_output(temp_db_path, small_chunk_config):
|
||||
"""format_for_agent should include source, type, and content sections."""
|
||||
docling_doc = create_table_document()
|
||||
|
|
@ -307,7 +307,7 @@ async def test_format_for_agent_output(temp_db_path, small_chunk_config):
|
|||
assert "Content:" in formatted
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_max_items_limit_caps_expansion(temp_db_path):
|
||||
"""Expansion should respect max_context_items limit."""
|
||||
config = AppConfig()
|
||||
|
|
@ -334,7 +334,7 @@ async def test_max_items_limit_caps_expansion(temp_db_path):
|
|||
assert item_count <= 2, f"Expected at most 2 items, got {item_count}"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_search_result_get_primary_label():
|
||||
"""Test _get_primary_label prioritizes structural labels correctly."""
|
||||
# Table should be prioritized
|
||||
|
|
@ -388,7 +388,7 @@ async def test_search_result_get_primary_label():
|
|||
assert result._get_primary_label() is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_radius_zero(temp_db_path):
|
||||
"""Test expand_context with radius 0 returns original results."""
|
||||
# Default config has context_radius=0
|
||||
|
|
@ -406,7 +406,7 @@ async def test_expand_context_radius_zero(temp_db_path):
|
|||
assert expanded_results[0].score == search_results[0].score
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_multiple_documents(temp_db_path):
|
||||
"""Test expand_context with results from multiple documents."""
|
||||
config = AppConfig()
|
||||
|
|
@ -467,7 +467,7 @@ async def test_expand_context_multiple_documents(temp_db_path):
|
|||
assert "Doc2 Section Y" in expanded2.content
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_merges_overlapping_chunks(temp_db_path):
|
||||
"""Test that overlapping expanded chunks are merged into one."""
|
||||
config = AppConfig()
|
||||
|
|
@ -522,7 +522,7 @@ async def test_expand_context_merges_overlapping_chunks(temp_db_path):
|
|||
assert merged.score == 0.8
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_keeps_separate_non_overlapping(temp_db_path):
|
||||
"""Test that non-overlapping expanded chunks remain separate."""
|
||||
config = AppConfig()
|
||||
|
|
@ -587,7 +587,7 @@ async def test_expand_context_keeps_separate_non_overlapping(temp_db_path):
|
|||
assert chunk5_expanded.score == 0.7
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_with_docling_merges_overlapping(temp_db_path):
|
||||
"""Test that expand_context with DoclingDocument merges overlapping results."""
|
||||
config = AppConfig()
|
||||
|
|
@ -642,7 +642,7 @@ This is paragraph four about topic C.
|
|||
assert r.doc_item_refs is not None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_expand_context_docling_merges_metadata(temp_db_path):
|
||||
"""Test that expand_context properly merges metadata from multiple results."""
|
||||
config = AppConfig()
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def test_database_created_with_create_flag():
|
|||
client.close()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.vcr()
|
||||
async def test_operations_work_after_database_created():
|
||||
"""Test that operations work after DB is created."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue