From 44fd0c9906f9565135b9ed790981cb3e1149e700 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Tue, 14 Apr 2026 11:19:29 +0300 Subject: [PATCH] add get_context() to analysis sandbox and improve prompt --- CHANGELOG.md | 25 ++++-- docs/agents/analysis.md | 2 +- .../haiku/rag/agents/analysis/agent.py | 4 +- .../haiku/rag/agents/analysis/prompts.py | 51 +++++++----- .../haiku/rag/agents/analysis/sandbox.py | 25 ++---- tests/agents/analysis/test_agent.py | 11 +-- tests/agents/analysis/test_sandbox.py | 43 +++++----- ...t_analyze_search_and_identify_source.yaml} | 0 ..._get_context_returns_expanded_content.yaml | 82 +++++++++++++++++++ .../TestSandboxHaikuRAG.test_get_chunk.yaml | 82 ------------------- tests/skills/test_analysis.py | 24 +++++- 11 files changed, 187 insertions(+), 162 deletions(-) rename tests/cassettes/test_analysis/{TestClientAnalysisIntegration.test_analyze_search_and_get_chunk.yaml => TestClientAnalysisIntegration.test_analyze_search_and_identify_source.yaml} (100%) create mode 100644 tests/cassettes/test_sandbox/TestSandboxGetContext.test_get_context_returns_expanded_content.yaml delete mode 100644 tests/cassettes/test_sandbox/TestSandboxHaikuRAG.test_get_chunk.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 75494c84..583c2faf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,22 @@ # Changelog ## [Unreleased] +### Changed + +- **BREAKING**: Rename RLM agent to analysis agent throughout: + - `agents/rlm/` → `agents/analysis/`, all classes renamed (`RLMResult` → `AnalysisResult`, etc.) + - `client.rlm()` → `client.analyze()` + - CLI: `haiku-rag rlm` → `haiku-rag analyze` + - MCP: `rlm_question` → `analyze` + - Config: `rlm:` → `analysis:` in YAML, `RLMConfig` → `AnalysisConfig` + - Skill: `rag-rlm` → `rag-analysis`, `skills/rlm.py` → `skills/analysis.py` + - State namespace: `"rlm"` → `"analysis"` + +### Removed + +- **`get_chunk()`**: Removed from analysis sandbox +- **`create_analysis_toolset()`**: Removed unused `tools/analysis.py` module. + ## [0.40.1] - 2026-04-17 ### Fixed @@ -21,21 +37,12 @@ - **`max_searches` default**: Raised from 3 to 5 — faster expansion makes additional searches inexpensive - **Improved QA prompt**: Stronger instruction to refuse answering from tangentially related content - **Improved judge prompt**: Asymmetric evaluation — generated answers that are more comprehensive than expected are not penalized -- **BREAKING**: Rename RLM agent to analysis agent throughout: - - `agents/rlm/` → `agents/analysis/`, all classes renamed (`RLMResult` → `AnalysisResult`, etc.) - - `client.rlm()` → `client.analyze()` - - CLI: `haiku-rag rlm` → `haiku-rag analyze` - - MCP: `rlm_question` → `analyze` - - Config: `rlm:` → `analysis:` in YAML, `RLMConfig` → `AnalysisConfig` - - Skill: `rag-rlm` → `rag-analysis`, `skills/rlm.py` → `skills/analysis.py` - - State namespace: `"rlm"` → `"analysis"` ### Removed - **`context_radius` config**: Replaced by automatic section-bounded expansion. Context expansion no longer requires configuration. - **DoclingDocument LRU cache**: No longer needed — the document_items table replaces in-memory caching for context expansion - **`cachetools` dependency**: No longer used -- **`create_analysis_toolset()`**: Removed unused `tools/analysis.py` module. ## [0.39.0] - 2026-04-09 diff --git a/docs/agents/analysis.md b/docs/agents/analysis.md index 80cda9bc..455eb7f9 100644 --- a/docs/agents/analysis.md +++ b/docs/agents/analysis.md @@ -59,9 +59,9 @@ The agent's code runs in a sandboxed Python interpreter ([pydantic-monty](https: | Function | Description | |----------|-------------| | `search(query, limit)` | Hybrid search (vector + full-text) returning matching chunks with scores | +| `get_context(chunk_id)` | Expand a chunk with surrounding content (adjacent paragraphs, complete tables) | | `list_documents(limit, offset)` | List documents in the knowledge base | | `get_document(id_or_title)` | Get full text content of a document | -| `get_chunk(chunk_id)` | Get a chunk with metadata (headings, page numbers, labels) for citations | | `get_docling_document(document_id)` | Get the DoclingDocument structure as a dict (texts, tables, pictures) | | `llm(prompt)` | Call an LLM for classification, summarization, or extraction | diff --git a/haiku_rag_slim/haiku/rag/agents/analysis/agent.py b/haiku_rag_slim/haiku/rag/agents/analysis/agent.py index 5dfb03c2..66d11b4d 100644 --- a/haiku_rag_slim/haiku/rag/agents/analysis/agent.py +++ b/haiku_rag_slim/haiku/rag/agents/analysis/agent.py @@ -34,8 +34,8 @@ def create_analysis_agent(config: AppConfig) -> Agent[AnalysisDeps, AnalysisResu async def execute_code(ctx: RunContext[AnalysisDeps], code: str) -> CodeExecution: """Execute Python code in a sandboxed interpreter. - The code has access to haiku.rag functions (search, list_documents, - get_document, get_chunk, llm). + The code has access to haiku.rag functions (search, get_context, + list_documents, get_document, get_docling_document, llm). Use print() to output results. diff --git a/haiku_rag_slim/haiku/rag/agents/analysis/prompts.py b/haiku_rag_slim/haiku/rag/agents/analysis/prompts.py index bb99626e..cee51c01 100644 --- a/haiku_rag_slim/haiku/rag/agents/analysis/prompts.py +++ b/haiku_rag_slim/haiku/rag/agents/analysis/prompts.py @@ -13,6 +13,10 @@ Inside execute_code, these functions are ALREADY available in the namespace. Do Search the knowledge base using hybrid search (vector + full-text). Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings +### await get_context(chunk_id) -> str | None +Get expanded content around a chunk, including surrounding paragraphs, complete tables, and adjacent sections from the same document. +Use this after search() when a result looks relevant but you need more context to understand it fully. + ### await list_documents(limit=10, offset=0) -> list[dict] List available documents in the knowledge base. Returns list of dicts with keys: id, title, uri, created_at @@ -21,18 +25,12 @@ Returns list of dicts with keys: id, title, uri, created_at Get the full text content of a document by ID, title, or URI. Returns the document content as a string, or None if not found. -### await get_chunk(chunk_id) -> dict | None -Get a specific chunk by its ID (from search results). -Returns dict with keys: chunk_id, content, document_id, document_title, headings, page_numbers, labels -Use this to retrieve full chunk details and metadata for citation. - ### await get_docling_document(document_id) -> dict | None Get the full document structure as a dict (DoclingDocument format). Use `list_documents()` or search results to get document IDs first. -- `texts`: list of text items, each with `text`, `label` (e.g. "title", "text", "section_header", "list_item"), and `prov` (provenance with page/bounding box) +- `texts`: list of text items, each with `text`, `label` (e.g. "title", "text", "section_header", "list_item") - `tables`: list of tables, each with `data` containing `grid` (list of rows, each row a list of cells with `text`), `num_rows`, `num_cols` - `pictures`: list of figures/images with metadata -- `pages`: page dimensions and metadata ### await llm(prompt) -> str Call an LLM directly with the given prompt. Returns the response as a string. @@ -59,24 +57,26 @@ For pattern matching or text extraction, use `import re`, string methods (`str.s ## Strategy Guide -1. **Explore First**: Start by listing documents or searching to understand what's available. Document `title` is often None — use `uri` or `id` to identify documents instead. -2. **If get_document returns None**: Use `await list_documents()` to see available documents (check `uri` and `id`), or `await search()` to find relevant content. -3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find. -4. **Use llm() for Classification/Extraction**: When you need to classify, summarize, or extract structured data from content you already have, use `await llm()`. -5. **Cite Your Sources**: Use get_chunk() to retrieve chunk metadata for citations. Track which documents/chunks informed your answer. +1. **Search First**: Start with `search()` to find relevant content. Examine the results to understand what's available. +2. **Expand When Needed**: If a search result looks relevant but incomplete, use `get_context(chunk_id)` to get surrounding content from the same document. +3. **Use get_document for Full Text**: When you need a document's complete text (e.g., for regex across the whole document), use `get_document(id_or_title)`. +4. **Use get_docling_document for Structure**: When you need structured data like table grids, document hierarchy, or section labels, use `get_docling_document(document_id)`. +5. **Iterate**: Run code, examine results, refine your approach. Don't try to solve everything in one execution. +6. **Use llm() for Reasoning**: When you have content and need classification, summarization, or extraction, use `llm()` rather than writing complex parsing logic. +7. **Document Titles Are Often None**: Use `uri` or `id` to identify documents. Use `list_documents()` to discover what's available. ## Example Patterns -### Counting documents matching a condition +### Search and expand context ```python -docs = await list_documents(limit=100) -count = 0 -for doc in docs: - content = await get_document(doc['id']) - if content and 'keyword' in content.lower(): - count += 1 - print(f"Found in: {doc['title']}") -print(f"Total: {count}") +results = await search("revenue figures", limit=5) +for r in results: + print(f"{r['document_title']}: {r['content'][:100]}") + +# Get more context around the most relevant result +expanded = await get_context(results[0]['chunk_id']) +if expanded: + print(f"Expanded: {expanded[:500]}") ``` ### Extracting data with regex @@ -108,6 +108,15 @@ for d in docs: print(f" Table {i}: {cells}") ``` +### Regex search across a full document +```python +import re +content = await get_document("Policy Document") +if content: + emails = re.findall(r'[\\w.+-]+@[\\w-]+\\.[\\w.]+', content) + print(f"Found {len(emails)} email addresses: {emails}") +``` + ## Output Format Your final response MUST be valid JSON matching this exact schema: diff --git a/haiku_rag_slim/haiku/rag/agents/analysis/sandbox.py b/haiku_rag_slim/haiku/rag/agents/analysis/sandbox.py index ddf4e3fb..e0f43547 100644 --- a/haiku_rag_slim/haiku/rag/agents/analysis/sandbox.py +++ b/haiku_rag_slim/haiku/rag/agents/analysis/sandbox.py @@ -7,6 +7,7 @@ import pydantic_monty from haiku.rag.agents.analysis.dependencies import AnalysisContext from haiku.rag.config.models import AppConfig from haiku.rag.store.compression import decompress_json +from haiku.rag.store.models.chunk import SearchResult if TYPE_CHECKING: from haiku.rag.client import HaikuRAG @@ -88,25 +89,15 @@ class Sandbox: doc = await client.resolve_document(id_or_title) return doc.content if doc else None - async def get_chunk(chunk_id: str) -> dict[str, Any] | None: + async def get_context(chunk_id: str) -> str | None: chunk = await client.get_chunk_by_id(chunk_id) if not chunk: return None - meta = chunk.get_chunk_metadata() - doc_title = chunk.document_title - if not doc_title and chunk.document_id: - doc = await client.get_document_by_id(chunk.document_id) - if doc: - doc_title = doc.title - return { - "chunk_id": chunk.id, - "content": chunk.content, - "document_id": chunk.document_id, - "document_title": doc_title, - "headings": meta.headings, - "page_numbers": meta.page_numbers, - "labels": meta.labels, - } + search_result = SearchResult.from_chunk(chunk, score=1.0) + expanded = await client.expand_context([search_result]) + if expanded: + return expanded[0].content + return chunk.content async def get_docling_document( document_id: str, @@ -131,7 +122,7 @@ class Sandbox: "search": search, "list_documents": list_documents, "get_document": get_document, - "get_chunk": get_chunk, + "get_context": get_context, "get_docling_document": get_docling_document, "llm": llm, } diff --git a/tests/agents/analysis/test_agent.py b/tests/agents/analysis/test_agent.py index 5cfe10ff..98e0eb51 100644 --- a/tests/agents/analysis/test_agent.py +++ b/tests/agents/analysis/test_agent.py @@ -139,17 +139,10 @@ class TestClientAnalysisIntegration: @pytest.mark.asyncio @pytest.mark.vcr() - async def test_analyze_search_and_get_chunk( + async def test_analyze_search_and_identify_source( self, allow_model_requests, temp_db_path ): - """Test analysis agent can search and use get_chunk for citations. - - Agent program: - results = search("content", limit=5) - for r in results: - chunk = get_chunk(r['chunk_id']) - print(chunk['document_title'], chunk['chunk_id']) - """ + """Test analysis agent can search and identify source documents.""" from haiku.rag.client import HaikuRAG config = AppConfig() diff --git a/tests/agents/analysis/test_sandbox.py b/tests/agents/analysis/test_sandbox.py index 12b50508..f40b0f6e 100644 --- a/tests/agents/analysis/test_sandbox.py +++ b/tests/agents/analysis/test_sandbox.py @@ -162,41 +162,44 @@ class TestSandboxHaikuRAG: assert result.success assert "True" in result.stdout + +class TestSandboxGetContext: + """Test get_context() external function.""" + + @pytest.mark.asyncio + async def test_get_context_missing_chunk(self, sandbox): + """get_context returns None for a non-existent chunk.""" + result = await sandbox.execute( + "ctx = await get_context('nonexistent-id')\nprint(ctx is None)" + ) + assert result.success + assert "True" in result.stdout + @pytest.mark.asyncio @pytest.mark.vcr() - async def test_get_chunk(self, temp_db_path): - """Test get_chunk function returns chunk with metadata.""" + async def test_get_context_returns_expanded_content(self, temp_db_path): + """get_context returns content for a valid chunk.""" config = AppConfig() async with HaikuRAG(temp_db_path, create=True) as client: await client.create_document( - content="Content about foxes and dogs.", - uri="test://doc", - title="Fox Document", + content="The quick brown fox jumps over the lazy dog.", + uri="test://animals", + title="Animals", ) context = AnalysisContext() sb = Sandbox(client=client, config=config, context=context) - # First search to get a chunk_id result = await sb.execute( - "results = await search('foxes', limit=1)\n" + "results = await search('fox', limit=1)\n" "chunk_id = results[0]['chunk_id']\n" - "chunk = await get_chunk(chunk_id)\n" - "print(chunk['document_title'])\n" - "print('content' in chunk)" + "ctx = await get_context(chunk_id)\n" + "print(type(ctx).__name__)\n" + "print('fox' in ctx.lower())" ) assert result.success - assert "Fox Document" in result.stdout + assert "str" in result.stdout assert "True" in result.stdout - @pytest.mark.asyncio - async def test_get_chunk_not_found(self, sandbox): - """Test get_chunk returns None for missing chunk.""" - result = await sandbox.execute( - "chunk = await get_chunk('nonexistent-id')\nprint(chunk is None)" - ) - assert result.success - assert "True" in result.stdout - class TestSandboxExternalFunctionEdgeCases: """Test edge cases in external function dispatch.""" diff --git a/tests/cassettes/test_analysis/TestClientAnalysisIntegration.test_analyze_search_and_get_chunk.yaml b/tests/cassettes/test_analysis/TestClientAnalysisIntegration.test_analyze_search_and_identify_source.yaml similarity index 100% rename from tests/cassettes/test_analysis/TestClientAnalysisIntegration.test_analyze_search_and_get_chunk.yaml rename to tests/cassettes/test_analysis/TestClientAnalysisIntegration.test_analyze_search_and_identify_source.yaml diff --git a/tests/cassettes/test_sandbox/TestSandboxGetContext.test_get_context_returns_expanded_content.yaml b/tests/cassettes/test_sandbox/TestSandboxGetContext.test_get_context_returns_expanded_content.yaml new file mode 100644 index 00000000..4ca2fa50 --- /dev/null +++ b/tests/cassettes/test_sandbox/TestSandboxGetContext.test_get_context_returns_expanded_content.yaml @@ -0,0 +1,82 @@ +interactions: +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '114' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - The quick brown fox jumps over the lazy dog. + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: 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 + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 11 + total_tokens: 11 + status: + code: 200 + message: OK +- request: + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate, zstd + connection: + - keep-alive + content-length: + - '73' + content-type: + - application/json + host: + - localhost:11434 + method: POST + parsed_body: + encoding_format: base64 + input: + - fox + model: qwen3-embedding:4b + uri: http://localhost:11434/v1/embeddings + response: + headers: + content-type: + - application/json + transfer-encoding: + - chunked + parsed_body: + data: + - embedding: M408uDtz9DyHoOA8G56VvNy9Brqc7hE9i1SaPZbiPL38Ze88kO5aO4m7KbxRQeU76nxtOzUX9rzCthE94hMQPHxJFz12wkC9EW1WvX/BGLwQvfu87iCAOttm2jfNDwm8e1BsPAJUJjyLgei8I4hnveW7ezwPF4e6yLQevcDk0rxDzmw903lvO5FcuDuLIyO9ol14vPc4nrscip68gejRvLtTHTxIXQ+9X2jVPC2CzTuHT9E8oX6YvP8GzjlTdTi8oF39vBlDurw83Gw7o9HpO3+tsjzZO9K8iMbRunVlzLx0j4A92VxNuwcJZjyRIIU82B+vu+lmVrwkYZ68pl/BvFmF0ruycam8Fo2Gu0tW0rwAjKE8BvM5upPZY7oZX1Y9E06UvABy1btGk907x773vB3pPrxYVeA8RSBvPFdngjzadK07cSj8uYCEkzwbiBk9dC5VPQCPMzxr7g49ZDJIO+pxB7sXINM7z9wtPLUeZD3lhTy8V8cYvLl8Yrtk6gM8UZcbvKntsbzJ3MO8WemAPDoFoLxiFJq8xoyjPBUJhrwdJqe8xZKvvHJC/7w822W7oDDwOqgDZLz7XJy7BuPeuqnJizz8nWS8IHrmvNeYELxwqS07E6RjPdg9NjypgI080OpNuxFksTxvpOy6ZTerPMhzazwWtgO86+CJu3aY2LysdgG9qvd0PEYG9jzgvDG8EeoLPPbxoTu28XQ8CswLO22uVLzbSlm8aBBvvByRX7w+AI67v44pO9wW1zvwjPK7w+qxvIBBhbwyuWK6xRkpO5M9MTwOqo47qI/DPEdlVbz1deg6VRuTPI/S+LtM/pA8jhiYvIYW6jkxRgY8vTAaPB2UBjxhkOo8bAKAO/L3LT3JUdQ8O2ILOqkT77zzXi+7IgLFvFMd77vGGXi7oW+3vEEiUDwQ5L289cxWvIDcdLxEOVi8dhyUu99x7jvWMiU8ooAnPCdveDy6DrO7BUSiOzSokjwKoLM7KiCVu/CgfTxvvUA8CW6nusUMMb0kjSS8Pm99OwDt/bzs35c7MQcYvEv5HrtE5SE7UVa8vPaaTj0+jOu7sY7XOqRdu7sf+Mq7uLdGO6TrF7rCZKo77pCDvBVbirvXT/C521xTPASni7y8vz28VaQRvfIvwrs9dva7L6LevOiB3ryEUCg92jUAPRf/ebtFaTE8ZAZVu9WwZTypQAW9pYbauhddBTyg4S08+/UFvIUQgry9kdC7pIzBPD3nyjry9W68Y4MVu1w2QTzTYMg7isICvfAOkzwpJhi6jxcUvTwGtry+hIu8wSV2PJUp+Tt7yRW9Wy6yuix+HrxLg+28JvCevINXp7oQBR+7t2/BPKaG6Lxkb/E73dYJvP4M8rz7NH+8mEKvvI9ZzDy8Xik8E8/vPEjShrzAU1S7fqYIPK7xfrokbaA8+yV0um+dTzyIJoa8AXODPeqxSDsgOU08QdYGPHnTjDvsTNA66msNPGiVjTuC2PQ7OLXxPN1WhLtlvSS8FEojPBTfATwiZGo81BcDvNkJgDxGdaQ8gHKrvJKw3Lt+NUs80SgGvc7UzDxc8K28A0DuO0f3DjzCpwG7zoUcvCLQ7zuH/aa88E5dvBGKbbxd1E47B61HvJt4aztkNPY8PL/uu0Y01Dsl/Aq9N4uNvE0ExbuhEfO8eEN+PCfGBjxOn947CfGIvUxeSDzzFnU7/TfqvG76G72mbsI8ErpkvXXLn7ulkh28CQmSvNI6iDzU7NY8eT1nOw0dq7up28o8uxsQvLseAz1AaD+8qAwkvJTGY7uhtkK64lQdvCGn7jxdmzQ9I98YPOzii7wy/0A8aTbSPJjCUrqxT7G8LTmdPFIEzDyZa3u7U5+HvLB5OL1lR1s8r67OvN4herxaYxa8r4TEuqprWDwAY7Q6VkhoO1QQr7wXqsu8irSkvMu3LDxN/sU7KPO0PLDgTLzdtU48rL2yum8Z9zzGEDS9piRzvJiRJDsFBWm8eOumPF0UN7zMVEY8ivD+uIZjxDmt2zW9mq1ivNgXbbmzePA86gpiu1fHQLuzS6Q8Eyleu7Ln8Tt+cRA76Rx/PEtk87xHN4+7wEibOxEamzzQxzE7JuxfPLmMDrxuOc88y9QiPKUp2zwBDEs8APW5OgxnJLupU5e81YZJvVpB/LyH/M47RH4YvHSRL7xTKps9CAygu1om9rsR4FO8S3/3PH2OhTyMtN27DmZpO1OfUDzP/Jk8m87pvBzbkLyWvBs8u2fOutwqE7l6/IW7g/evPJ97sDxegyM8wFx1vOP30jxBwY+8xpI5OVNk6ruNRYe8hclJPG7rLz1z4Es76chzvAZ8rzraudu84o6gOwkOnbzbily7cerWORoKyjqtfhA83v5MvDkkA7zIq7w848EIvOFq8jx8FFm92ydBu2szgLtQfIQ8lxZLukkGtbxZrAG88dfhO945mbzHqlK82oodvMXC0r3+MN07n0iJvCDTqzp0V6Y7Y40JvbE7V7yNIBK8GU7VPAFYGj1EQzW9eef2vH6gAr2Z24I8wQO5vLVcy7ukpxg8Nj+5PNkrHjywFQQ8PiYNPPr8k7vBF407+b2KPLFmE7wJFnc8UuYTPM89KT2UBYa85mlLvJln0Dw5NRo99YPAuksTTDxh2Qk8tPynPImbhDxaHyO9r9sqvHdHVTw6Gja7XDkCPYy9IbqRyY28Q4a3vElYmTx4cBg9u8IdvDqWwTyhxPI8dB3aO8uXTjzYuOm7qRX6vFXgEz0pF8e8ZuzfvJExkjtVAxE9sSNXvOfbwbwluLG8Utf8PDdzp7xYs8W8ICvRPDXeszwkgQ+96e2VPKL+BDxLGzG8JCmdu1PGobwnpsm7nBjdvOW1r7oH/w4938FiPRXFbzwDnEI7xEX1PHKEE7wVaZk8Uym5O+BrATyx3kI79yw/ussDuztfb7+8wvLNPJKpsrpFSoy6h2pgO53ewrwELZA7x2mZPLffmjtUn6Y8K0Hbu7oBJzzhPge8IH5oPIjpJryXJ9k8V/EkPJ3WK72FMPi8AJNJvFVyfLwvD+K85WGcOubbxTwLyOU8qUiku7vjt7yLoJG8RrbBPDLbcLzhMja9hU+BO7dbiDyZcqE8ArePO3a3Or18SpI8PEK0OojkDj3TfZQ6hALBPJlxzbu44fG7gd67uwS1F7w9Qxu9DgwUPPV6hrz7p1y7YloEvJjpPjyltDK8L9aOPakBFb0Uvve81G4mPPun+TvGgRC8BsWAPPd8hzwC/0q83GXDPNu6orxrifS79R9uvFkjwjxxQ6Y8jsJ4vYiviLw4KLK8MVwnvOrEb7zE5gS9xL7zvMcf2zu8amQ8qfZnPFTkmL2974s8/9f6O+rD9ruhXoO7LFEXvPN8wrwfkFg9FP6IOoMn5Dwfdze7fAlCvNoDDD3dTt87EeXSvPNRxDzej9o73ONLu9w8GTwxaxc9Gos4vI0h8Lw9lbe8fNlMvGjOXjztDdY6taGCuoVnPbwSg907z1z4O0p1qzz4lQA98XroO/dHjjw2IIO6nrGMO5y1iLycIP88613VO8RpOLy1F1Y8iS4jvRGMVrxMUB49Zy1oPNCXgDy9UQw98cbpvIUIJbypENk7JZgbvSg/HrzO1E283vqVu0r+JTx97+e7MTp2vPZT6TwM5Gi8jpomvAg8gTt5S5o8cp/vOhZ9W7t51UM8kDS3PEW+6rtyPau8mIIIPXcGXDzIz4Y82Ya4u5uVwzyjpbO8DL8EvXLFHzyQHfg8PxaqPFLk0joj5Fw7Ld20PICfqjzTuhw8kwKru+ODKT04Svo6TpjTvJpIz7s7Zae7PcipOkZqfbzhhDu9Rk9svCJfETwk5Pa70GrjvG4GqzwIyAK9PkYpuwbLPLwW6Ug8RwsgPA4SjzvpZIS7xmfrPFc61jwT+0O6TTxwvJCf7TyRuaq8jmPEO26WizvTT3A60HcSPCzJYLwRTAc9EO/VO9LqPTxeCtE8NGE1vVxp2jxBThW9kp0mvKWlzTwpuSE8gXVDPJfLCDxZV0I8abHdu5KMubpnz0e7MNWXu1aayTzAlQQ94ws9PE3phLyhUF+8KTDPu1CSoLyMBwK9WuwlO0Gkkjwf0zu8FfGyvC6O0jszpXa8VrXMPLfyk7xpGyM68Nm/PEilCzu5tbS8NbHUvLtRBz1Lgko7e0VmPbh60bxMLY88aO9BuYscIr2F2AO8W7epvKdpOrw5FH68zhMXvAWLxzzeTBY9jp7TOlOCRbz/3EI8zfCfvI3+mDsJcj885P3LvKsI7jpp+1q8vSLfu2N8xjvVMog9dTMquxbhBjyGH0U8tJk7uRX/LLvBbVo8nnw+PDXkGL0NprE7ua68PG+TH7t5Cym8ic/QPGxJgLxQZE48snUbPYNZBTy/Aws9lkODvB5dSzv1GqA80GVJvM58hTycb9O87H6Au98U0Lu3yIy5uByKvD+6rDzYrHw8KI+BvAsDFryNfWo6oO5qvcytOL1QOZs7fRUiPAu+Bz3spu08RiCXvBIQIrveTVu8YOOPOgpiwLymZ407w07DPJoNxbq7CnQ9BEeNuWIBWLtKAqw7/PP/PDkRID1nXfY7RfWBPCkhtLyx9Mw81XWtvLAruzolZwu9niNWvGeJGTskTUa85Woxu3683rvkCpm8eneWPK9rljwyJZw84VhoPNPawzzT7i+8SV5yPMxEiTs3WjA8GNTDudLsMzq14we8zX9FPbnToDw2zqS8BVSNPEzhjLxWUIK7DvhYu5glSryD84m8TK1KO/K2Mrz11ZU7tt5Lu4QYQzrL13w8+6iSvLfTezzeIde7rtMXvGr3+Twb9c86n2CRPNjn+7ogqUc8VeeHvPayvbpdrTk8WUhfuwWyjbtlNBW93RxLO2qxbbvZtDC9oqw7vNoXZjvEIIg86QHCu+FQtLxfFZw7RuOFOqTUbr2E8Ri8o1aLPalS57ygyGG7Vn5tO7mhLb1R1xq8mGMmvQBn1Dusmdq7MYJWvMHcYLyoA8i8xaGJvOYmXjzAqLA8kSLFO5eYqLvAr3E7LEw8PCkohj3M3/e8rebHOwiVjTwluSU8bYvSvJQXijznJ+a7Yn5du4CKpLxPEH488xpYPMfSBb2hBc072MkfPOl4IzvBcKG8KiQmvGT/NDywpMG8b/8sPPWkizwyIwA72TVIvHAagrwRwFi8KLeHvBFp8bqT9jO6RZE7PJ4a6TvntAk8DXbhPGwrvLzY/xg9k5BNPQlnSD2lJiW9O0vUO0i1nzxhqzq8N6ZxvOverbz8Bbk8RAf1OH6CWDumhj88XsdsvGNybLxWXok6jIpdO6Toh7uC+1Q9nXQbvVeONztHKY48YrVIOEArtbyVv408B9u6PN6B9Lt/nEo7fGljvFrxgzxs2rO8hxfUPN5GZLz5Lle7Qg+6uzFyu7xPUrW8ROaIu0N6EzyGLae7gg5uvJ5k4LwJmmA8dopJvFQ/Uzvf/8c8h+TIO8XEhTz7tWG8oypSPbJkqryZmwS90NNOu9eKhDxYc7a84XQnvNKhxzoVcSs6DwkdPPSwxLvqtEC6qQJYO2kuGLzfg028DKloOyWklrzWf0a8eaGMvDLASLzzGJg8Sw2Gu8HHZLt6w6G7Ai6mOppxBT1rquC73jIUvCeKHbzNQrI7BHNTO4HM9LuNdQa8rtc4PJEs5zx8vv660EFwvIIKQztyt2m6LjTZurVZgTwYhcs6wrdTvMM4+DwqOqm8JmjmPNx2cbzK/re7w7YVu9KfQLw0IdQ8HSVcvGOpPrz7td68Xx0QvWaPL7wQkgW9WPeOvA5bk7qH7oy89VtMPd1Gbjy7qWa83auiPJJhFjweXGa8mdMRvNcbZzt+1Qo9kRSPvBCgpLsBBkw7av6KOzGzRbw9u/w8slIWPLtkPruhzA69F2wJvDBxnbzSflM7DeEMPRrkpDxn/u48GEA3vO2VAjv4PSG8fkgdPMjXkTtt1rk7//tPutQ23juY40y83dNxOWt3drzwQgw8DNAJvMd3izzdf9m78ziLO98tdjxJHgg8wozzvMUAv7uY9x07TMOJPMjp1juZ9ZW7gjBdPUkLNjxa4E28fekcPPfxpDyMXII87TVqvCGyFDycTKu7GQWQO3WTejynAnk8Jc22uqcyBz0IBbA7pmU/uj+LLL1Idss6VJUsOuycaTz2uRe8rDEAPHEf6zvqur48U5JxupLvbjz1ncm7o3Xxu5iCgbwWvyI8X2gVvdlEdjzg1MK8xggqPIlDW7uOqCu9gkpGO0gb8rvhtS88H9UOPVGhI7wxMSM9AFZ7PJaROjw7Md26CVs6vY/7VDyWLN+7BN2FPERNRbyyKui8HKurO85KMLwa2fK7QLvjvLSW7DpjOuE8RZr5vHaHCbxHIzK8atN2PB5NNLxmisU752v4vOeD4zvWNcC8L7csvOYmn7z1NuA6lMmmvLJbwjrsQug66OALu7rfMDwY98m7TAcoPRLmBrwYRgI84hLNOz/DBj0+jEK8Tiiru+6X9DxIBrG8l4oBPVKaCTo0YRi8thX5u0IMuTupHJm8P+JZvFy2LLsJQfg6x8C1PBYMKDxV5uu7OfgsPBP/cDyuBKs7Pe8dPeKqC733UYS6BUZQvB8Zrrxv1Ag9m2XqPAF1OjwNLcQ8wmK4u7SGoDxe3pA91QMlvDdDgbzq8Cs8rVgNO5CZxzqwK3A5KZUOvNl3H7yS4xu83e2ZPOJucrwzpYS8wtP3O+oRgzyoUAU9dl1/vMR77Lo0Gky83k0GvWWpbrkxBBo8tmWnPPqPuLoDsKk7kWM6PGTK2Tv6k7480ZarvC7eTDxvheO8AKs5OnOtgrw/4g+9X3Y6uwqExbxtp2o85qwwPWAUoTzLAUS5pG8VvfahIb1/AnW8zI0QPXLA3rsqOhm9XMi/PGjwOzukFcO8pLGZvL+zfLsOavm8fpSDPFpiiLyYiP85hg0UvdENFzwsYBs64oBuPEj1f7zDW7I8RLY3vQBwpTw2uh48bb7MvHZ3LLxP8U88x9sNOkgVCbx1thI8CrKxPDVygbxq3KW80DqGvDsYojxgzxm8/LsPu875PLnQaeQ8QoSGPM/sBT0T8uW8rQR6POlM47srsMe6JN/QO45wL7xuSJg8OaZfvBOVsDyn4H07zDxCvKJeFD3f2b48ZWtJPT9aD71ZXbe8CirMvAVkRbwPTO88gb0iPcncCzzprzi9/wIBPaRBGj1Nxby8d7mwPHvY5buicrg8v6fdPAWcqjxrxye765vxPLvoFjzoUlw7l8/IO9h7qjyCU9S8LXOEO3Cdl7wO3Sk7KiwDPDHVRrsAlh48tehKvFcbljwonGg8QWQMPVcSZLtxu5e79q8nvNZrwTvQ8ZO8/qVYvKlYxbzKU4286boaO287yLxe8ie8DdjeuoRWkTxPEIk8evwjvZxdBDytpf88wqXQPCEyvjuon3o7Oe/bvCAM3zzv9RM8I4vhu6xJAj2Gfm68MINPvGpoLjzfjuw7GnegPBUstbxyJMY7aByCPCqbrrtV3uw87EKnPG/Cz7v1b+O8tpNLPFWfET2OzI86IK1bvbVW8rx2Z4K7KiVdO7PWi7vxLhe54WdovIQpBT2zxqs7t1eNvKpMWbsYtVu8jW+dvJE55Dz6Z8M8XVYrPKUM2bqcf3k84geuuzHNS7yGXJO8q92suMuijTx1SRI97262PB+eOT0xAKC6AjfkvHCqYLwR05k8Xxc2vP7JELyd2KS82vg0ON0pQzydmwu75ProOw35AL1KwDm7Z1McPb3Twbur+VG7j3WFuWnnCT00B1U7LI02O7ZBFTtbYyG8zPf+O/eroLspRx47VYwhPbeel7ykEbO82sntOcRPWzub4ky9QhXmOsQfdjyazDc8h2bHu1ib+roLqKc8KC9LPPdhXryimAE89kLhvEIChjx0yrc8V1EiO2BX7zw9RUC9ajQXO/AqqrukqDW8tQPKO1JbODx2gLo7fN9pvLStubqbM1C8oZxiPfLNQ7tkOiO9qyu3vO3607yLskW9DV7pO7ysHLykOoq8ydRnOuImv7xGLBW9zoc7PfiFOLxQjfg8eidrPDzGjbyHDK67x74pOriPlzwAioa7hhDYPHvioLsDQ3g8wDFJvCDfITx0Us87IL84vdxJirviOYi7JdKWPD9+Lrx7Tyw8jI/aPORSDLyynbU8xgqzOw8i3Tq68RA9WCrMvOcwgbnO0o88tO+gvB8jvTxfgWu8gzGWPMDcw7oFPJ86lCmZO0FZVTyT0jk8lJaIvEv3OrwbGEQ8qxeCvFK0pTo8+d66jUwGPE6MQzwLD5Y7B6juvORv/jxh7Zo7UoQgPGqUY7x8Sy88GhZVOxroRj10Afe8ePUqPCe5bztMqoW85kRzvD4QbjzpcLq7S8edPGbcFr0QVZw8WWxSPHVFuTyN/lK7RBGjPEzGaDwCLEQ8tLaVvB8KYTyu9VM7DIxFvOxmMTzOY5m8PywWPBf2gzyeUES8kWs9PJqQhjyXxJe8T/UdPP6miDp3yVI8zmqxut+gmrv7j568CoDrPMn4lTyfqwa7m8m8POOZprtQNSS9lLeQOVLe9jy53vK8EPBIvGT9vDysYpO8YNs0vA+Vp7qUJi+7rNqJPCyWVDy+37g6/H9mO1i5Q7sb6kS8SQrkPGLN2Dtp5kC7RAszPacZTzwp9gC8r2fkvJFsHj3dSRU9kyGQPALI/zwgFYC88N+KvM6IvDwlbWa7FgZ/Or67Zbwv5uO8Mvlyux6//rxXWjk9A5itvIbLjryxeDq8no68vFVqJzxTYAy9uYHCvFQuAjuXVIo81bB7uuRxsTwX/ag7WrABPWEGEjx4zGc8EP+6Ol/iuLipTr+6cbXJORP4xbpE0ym8soqJO/aWC7yGSjK8BI5uPeKPwDzXO428g0sHPNCHGbz/65S7gZbfvJr2bzxA32S7+XHsvJo/iTwAxIQ8N2kSuiQt7bxHci288lIBPXRfIL2PmoS7o4K1u5KmOLy91Q69A8YlukytIzzKZsS8v6ZhPLeBuzrNIx68G9I0PG+0hbu+8bK7gv/EvCF5QT2J6ZG7OhbkunoxtrzKM4q88r1NvJXgSDxY6068BmguPAzSXDzr48677zZLPOePQTzJ7zM7LARju6Ow3rzMuFY83JeIOwSa5TyPZXq8W20UvbT9pzx287Q7g3WtvCQOTLxOZqg7i1KKPDaLHjwEn788kgbGvBTGwbu7UAk7mey0PCxb2DxTt7g8DlzFO7IPBT1sLIY8Wo6dvC2LizxwKUK9+43jOri+y7wd8NI7Xr0vOzYFw7zDb667lKTUu7R9Az3Nm+i819wEvIGnZrlI9CK8Kk8BPOV11jwClK07y0bjuzr0TDx/18g8z+fXO/3i47zgAQy9B0ajPBL3zjx9KlQ8AvUcvLnKdzxhcI47fSEMvAQHrLz1YOy89Wn3u4W4ITqNQ2y8aTuUPM1FIbwndoE7REf/u/RL1jx54Eo7MXG7utzbnzwgPWK81virvPGaqDzCSOe8WH8gvERSrrtSc1A7N6RGvOQsIDxBwlk8p10gPROAGLv1X4c7VE2ROXNAjbo58GW8V5XRuq9BIDzsdOM7ZsN6O+IK0DxnMX28IboJPdy1y7wVGOE824mIPOUEYL3cgvM8tBZ/vIQqaj0RTJA5gIplPBu8jTo/4gc8TGJjOloG1zxeQ548vscQO7H2/ztCUmm8hZjwOyLQRTx4knE8XnLvu0HJwrmqdo68S0JYvNsbDrxEv/G8PZCWvDODk7y3uLS845OHvKnGh7xPYI48lc2YvL4bGzyMZpe8jjKzvMc5Xjx6Eb87X1AEPE2Ggbz+bss8WUtYvEn9ezwW8r68MnrUvPkpJjsdowe99/G+PLsMn7xrQic8FvXAvNcbBbtS2gs8+3hNu8JKyLzsIxa7WFDZut1dnryWCK68worOusf5MD0vfsO7E/6WvBwGZDyQTzu72nRePKctKrvdvwW7Oe9IPHo5+jzF8Rq9FeHiOs+4TzuPYi28Ow/bvIgTSzyxDQO8wZGrPP4F2DwZXb48UgkqPfW+vbzDFc27zqNJPK3bWjxc+848jD3pPHkB07unWoI7TXftPIF1szz4Wua8zqe2u0nM5DxTopk8p1OLvNT5iTwc6hw8du/WO6uvazwKYX+85pWAu1Hlhrx9f8u8V35VvQrpELsxUcE7E9Xiuop9rjwqg0q88H20vDW/ZDxohkK8UgaHPBllkTyPfdG7t8mxO7nbTjzyRRY8AOWQO0joLD2mPJW7H3VCvBS+ADzhKio8y3HKOZ0dbTuTaYc8O+5GPNzvr7ynibo7OteuPB/83LuxWh6942uDPIy0jTzlsr47M5kMPTTawTxAfYA8O8FuPJoywjzAwJ08xuq+PPR9fLtXWLQ8OmjSPE+arryjYFg8FGhNu+8yzTzj0Y27FHlNvCAgfbzExy68DfGuvCIkI71a2qo80zN/u00Hobrx6FW7CPBvPDc0/Lu4mLC7m5UHvdwJNr3SffQ7N/iGPLtUkzzCg3q7DEVSO76aSrzxFCe7s6MtO+ADUrwKTD68v03XPPjg6TsAPp28EYKBPJdQ9ztMNne9MGFQPPAfprpibNC8UHXrPGsYfriXVYI7TlgKPUgXIL0eMZi7PwJDPd623rvkHqa8Tx+0Ofm8Y7sDRRE8bmHivPmEGz3B7sE8jzHIuzc5RzteErO80gPZPEwqDj26+0O8oAilvNnSJ7wOfKu8QWWVPCyLNbxgPLS89pKfOgwkhr0ryr88CbK5vA6IYb0qxLy8gsU1PGIEQTzHja26T5dCvA5YNrwpOvQ7srZCvJyFSjtRMSU8rNvOvHGo7zwz4sA6JnBwPCQr4Lsm+i88NwAyuwzrDL1eaO48aFNnO/At5bzaWxm90dasvOSDhjyNDTy953kVvNwW5zv9nvW6ZjCUPMiTm7wIbeG8KQCxPN0Fhzs6h1A8n0ymu8+M9bsEkos8zIC0uiCGyToM4JW6I+YEvH5g/Dw+zQO7JNqVuQjiUDyiVcG858EYPFT2zDwqjRC9PoJiukk5R7xkP+m8/gLIuxlvrjwjtr28KKsJvQYV3bzTbOe89m3uO3rDx7yDtlc7PFlTPBhomTwCmSw8Gi3JvEPaKLyZ+Yu7lQEmuyH3sTyBZia9LJCFvAMzurzfJey7pqOBPDafJb0QAEu8UgmTPG/M27sdmY07FBf7PHcWwDuWnc48neI1vFOCaLz9n9K8by3dPBsRpzwMR2q8mfcFu8aAnDwX+fo8muGmPFiYTTx3MCw7xfjOvISirLyAJtK8eCpuvJuFhTzu3aU8yodYPNSlh7vL+h+7SziBPLqJX7xT5mc8QLTBvNzPjrwkrVc8taEnPBevGLyHWWg8Tm4IPOh+BLyccsS79zHGO0ZsnbtjXJg8pq4LvSchwzz9YHm6g7GKPJHb3Dqs7cs762x2PP01k7vGDiO8Nwm5vBMMwTyH9AY89q4CPMaHFj3CLiw8etD6PCoXvDycIZo8GDg1PSoErbyGDGK7eC5BPAVnM7xmhdU8/OgfupIW6by3VjK80uRUvI6P4LwC7Oa8AJguvMeZ8zolSk68kN3+uytAF71/gJ+8gEjNvCk5a7wyJwi9Rc2au26QXzyuD0+8VfXCvIh+trzYAqU8xBvGu8FugTxwkrS8+1bOu7FBD7291I88LBMHOilSbjxIaY68DnS1vLguBT2XYfg8CHCAPCOqDrzMe5w8sXC1um02KbwR6++7WlHOPHHmnLxhrzG9algZOpIBHL2sil08AmIIvcSx0Dwiksc70NbHvOWOzjs1vxe9rFF2vDujmbwz15w7MWkyvACyqLw2ex09I6InvYttjzzQmu07TTG7vLFEIbsqLp87DiTVPFsPXrqYWzO5hBSTvDN5yrvQTmk8ll5mPIvRczxckpc8bNmWPK3TDzwsbsO70P4JuoWkMbyVaBk8eBGJPBP/Jr1mBiW8nm+8OdlSHbwGtse7p624vDtcoryditS8HjP2vFWKjDzjS4+8Q180PI0tJbyR0G88Pm7rvGvQ9LzVGA+8ADqcvMfpYzyjKQS8XnySvNBxHLvhjs48iT0nvKU8tLxxH708XJW2PFy4Fj2IURO8B6WdvGStA7wtCBm9X+uPvLb0Qr10C0i8GSgAPUiPLb1KAEo7/45oPKe35DwrsRK9jrPcO2BXSzt9i6U79JqOPEbOZDxVZkA8kqAYO5G0Bbqi3Ji8P0EbvArtrzw2DsI83WydPIfsWrzeSvc7LTD2OymqWTxxSiM86MqouwNfSjs+bCU8pABIOyDB1zvbVZU81aISO8/9zjxZIcg8Uh8vvBAcWzxWZK68jNPzvFOQ3rzIZNA8WdsLu8+2dzw9m0288SGmvH/SwLyoemq8cQkXvPMxyzzr/fY8NknEu1Z2q7zcizM8ch76ulhMnzt8fRQ7Kcuou5brWTxTkAy8l3KfvAPCWzyaUkO8HrsqvJLLJjyGpSQ730IMvYMefzye6tU7sN2CvLbbkrtTGnU83/omPFQde7xTjOq81RRVPP0rcTzW/bK75ewsvCZYqzqyoSO9XsgJPcMmtzuFGwW8V9X8Ox1TnDyhSP+6T2vhvAizP7tbOuu8BcPpu6vJsbtgZNG8skF+u0cbMbwUOq66kQGQPHz0uTyC+268ToWQPPaQQ7we9Lu8pO+PO/+KLLt4pG28lzEwPMKjgrxAOvi7TxtaPPZuhbwBRko8rxbVOz2k0TvlHCc9c23DO7+avjxlVWA5t5DVu861XrzEfh08aPASPFVwyToe3Ik8MCCGvLTnlbvtZdE846yQOzoLEz13IKU8h7MUvdiJkLyxg0484CnKPEEvlrv5y0o8C+cbvOgPwLtSZmG7zajjvPLyubtb96Y76gAhvEXFzjxZCxq8Hi5WvDBesDywlbA6K89fuoueJTxR+bk7+FuNO4tLaryiBAu9EgFJvFDsEjpqYhQ9/xYDvW16K73sXtI72OufvNtLxjtXbwS85Enuu5iM3ryOj5w8OEn9uwYlijzv1Fu7UeKcPJq1r7zmqMO8l0zAPDKF9byFmxK8ZA/NPLUyTLxQ5XA8uW+pPNnr67vewr47kXiDPGnDRrs516A81+TePH6MhrplbUa7/6rYOpr8S7yAzp07D9YrvWItrzwE8D47XJPDOxRiZbyT1FA6GSN9PCPlBz3M3ag8QwtQPDCYxrxq/nq7KSrIvPrOIrwmRuc7eWY2PN+cSrzoRkm8ptY4vNss1jz/xqy8FiJtOzrZdjza/es6qpMLPE0SQLylZxM8kGUBPLB9Yrx1jyc8C+qHvJcJgTxE5CO8bM4OPcP5Rbx6a788j9t5PE1rpjoSG3S795gZPPZdODsj9rS8qsuSO80bcLrwIRU7ZSsIvH89Cj1Veom8p4ysOY2xKLymIpu87w3cvOwzwjs6oE27jRd6PEHwDjyUnZ487oPZu7I7rbtvJm87S27eO8grHDp8zsi8TUFBPKV4yTyFmyi731hGuz7miDyr3188hb3OPBnzmLy2fgU6qcgAOwTitrwd/B28lrakO3CgoTzw2G08shmbOwjsjrw0hmq84EQlvKslxbuEKHI82jTFuUSknLt8LAe8KTCLuQGqTTw7i528EX6hu1AHvLzG/qo8oVj7O0k1xbsUyUI82ozqu11HC7wyoqG8fSVePAHcwbvgI548MH6Uug== + index: 0 + object: embedding + model: qwen3-embedding:4b + object: list + usage: + prompt_tokens: 2 + total_tokens: 2 + status: + code: 200 + message: OK +version: 1 diff --git a/tests/cassettes/test_sandbox/TestSandboxHaikuRAG.test_get_chunk.yaml b/tests/cassettes/test_sandbox/TestSandboxHaikuRAG.test_get_chunk.yaml deleted file mode 100644 index 6977ce26..00000000 --- a/tests/cassettes/test_sandbox/TestSandboxHaikuRAG.test_get_chunk.yaml +++ /dev/null @@ -1,82 +0,0 @@ -interactions: -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '99' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - Content about foxes and dogs. - model: qwen3-embedding:4b - uri: http://localhost:11434/v1/embeddings - response: - headers: - content-type: - - application/json - transfer-encoding: - - chunked - parsed_body: - data: - - embedding: dawKuTdqLD2fSY28LtbAvA1IWbpvvRw9mjBkPZK5jLypDNs8u0DZO0NWtLwlbJc7sEiZO7KVG73NSpU8XWGuOg9rFz0FPuW8Zt7/vMOoALzkcMK8FQPMOtHjBzzAnEk7EdXTPPcRRbzDode8IVl7O/6PkTy3ZxK8WBIUvSe5Ar0o8ws9YbQ7vI1NaDslKLC8YLcIO+D+qLvwJUs7ipyOvCZ2yDvw9hO9+y/VPMDXfzp4cdC885wXu6gstDvsZZw89DMcvdwZB70BLZw7g7BOPJVvZjzNSLK89djuPNlOVLvfOGA9Yt0HvHhYuLrOkRS7zsU/vLhSA735h467LzdnvHFyIruxu5+8N3ZTvKIAdDqXkX48IGkBvaC+vbvjjRU9T5LEvIfBXDuY2ew7QZntvLbaGrzABsw8XnjAPC4eHzzWpeg8wbWdPGmuEDtJVio9jFw/PbbBgjvT3Bw95tafO7nHqbztc7g8Jv5UPAGOJTzIGr+7a+/vu/DauroyGyI8ePmRvL6bjrxjCja8cxSbPDoVp7trQ7m8ZWTTPB/sgbxqTB28kbgEvX7Pl7yeRF68DUh5u2lAH7zXnoa7Fv6JPHeh7DzIRN+8oCRUuxgB2buZBtY8/9VcPSZo9zt25AU98Mvju71iOjzy5CG8CK28PEwN0js3oNa8hEx0vIB60Ly1Zmq82Y0oPF2EvjxTqI68xuz2POnWKDoGi488zkBXPIqydjsOomC86RkjvG0DWzwlsAC8A5Gju1JVAzsiDRs8n1HovJ5BnLv6zUO8zXJVPDQsTzx1Og88DLj8PPEo5bun1Os78PzePDlGDDyxRt48fY7XvCx/lTs68zQ7DTNaPM6TzTsUR+A820QVPB4DQTx3aJk8j1HyOzgiD73Gm4y8Mcb2utktjrxiqIG886u8vB7GpDk3UoC84WNRvJ+hbLpZhRW92sm+O6tHB7wIm7Q6aG7CO/xTG7w1g4I8yKtCOwpj7DxRUsG7GSMSu4tYXDzzBY25kjOqO4YkvLw2kok8BDwSOhgFF7ysq187Bg5bvBEhXbzpCQs871+ovFp8Bj0s1BY7GEyMvCvjIbyICke8c5lXPJ2BK7y248i7HyXFvDSjtDtVCbA7fve3PGKhLzuqL5W89U2ovKc7mjsQ1Tq8LOOwvMaArrwXWRw9kygDPSWfwLkNYh48NP/5ux23fjsSv8e8pi4IPJg2BjwuiUg82jGXO7pyhLybY/I878LPuqVGMDx9eI28cb68u5EsSTx0d488Oys2u8Y5Iby1c0S8YC0mvePrx7z3mZe8/86FPEwRAzvrerG8ZuAAO80OlLvK2Qe8bDfLvN9FmruYq5S6SGUuPMvOJLxKuFO8kQoQvFj+mrwmG2i8s0qYvG+bBD3vD+k60gfaOwMCq7owKv27p5YGO35YcrzYGMM8OkPWu/ETgjxsBMW8uF1ZPZfGoLtA9YY8R0p7POcuhjogQ8q7VzMbO6GnOLxgkag7ADTkPIvWZryAscO7KmZkvKIqlDufx504nH8qurTpXrtiQc88E97HvHSTVDy7MpU8YNMMvStm0jxFKo+8QPXYuihbrzxpvNS477zcvM7lSbzq9+q8eFmQvPNJXrw1ZSW7yA2MPIOjpTw6yxg9lAlAO6JaVTx8+AO90X6+vIX7srxvHBO7l+4FO64A4Tvoc708U+JBvRWQibsPc765MnqYvAUCAr10Uyg5tR3WvLBj27uxwhe5fdFZvOWKUjxMFAA8W+svPGhkrbwsHjI9fktoPNpvtjy9gAW95CqRvKb/mbsbSRi7kmmKu6vJDz1eIrk8iAlhPLloRbw7I0m8qtGKPBAoFryDNbm8J5A+OxJDRjzbKM27TEFevJPgxbzIkxK7BweevOckx7x9OtS7X2NiuhEWsjzVf+C7OGvdPCcDvzwjuu68SQdKvCiwiDqSUAY8fzStPAdy+LuQDlA7qKTMuxL5Iz1MZDy9rCZQvAEv8jgUXn08uPYQPJvkU7yYdrs8JdmbvDpMBz1vIgG9ScSGvPRmpbuMXmE8Tvq7Oup+g7wNxng6fn+Zu83yWDuousq8iwRUPBfS5DtMEe07c4rSPBq1sLv0odw7sNnUPAAND7zbTok8WTJVPOhaijxWL2Y96UofvBNnv7wJ+oq7ET8ZvVTmdry0KJ88VadCu4n6mrxN3oo9/1AqPCMPK7yTE7W88CWEPFZrejvwQl28uJaJO1QlWjwvkLY8i9zvu2jFnbxe+Io8hA7xuiAJCryIAhY8o1E8O5KedzxkLJM8v3e+uzmkrzzJ9868VPcCvRRzfLzkJYC8kTiIPF3TUT2NID+8U8qMPAlRTLwPSWa8Z5/sOp1mjbzaElC8yFPpu61syTzxElo8rcmMOjc/kztry0I8fEyJvF9bHLoVEkS99a0GvVapOzyqskI8/B6gu+SwCb0ilR886HzAOwXBo7wN1aK85C6yOqR+s73K4JQ6MQ3Su6W5xryaXPU7HqPqvDinprx8X1C8gIRcPRaPAz0vPym94GGsvJ3Ow7yvt+E8DuTCvMozgLvjlfI7RHT0O07hkjwmsxS8/w2BPHI9dzslAF68LDKtu80HKruAjUc83GOWPNNF0Dwxj7U7QYuGu7uBdzxFGyU685K4uzfcs7wsozs8qMUQPAGTDDxzFse8YTXeuELe77rfGW27zMYIPUG6CTzZSsq8sriOvI3/izxHEe48AxbyvMNbrDsQBBw9Jd3EOQW9hjx+Hs08fo/dvPYh6zxP4OW7/RgEvVQ74Lywgl27WYzEu9LNwbzORDe8jx2GPHU78LxtXCC9GnwbPcSzmjybAeK8GBxwvMChBLyQ36e87OyxPODYhrrhQ967KobkvEIu4rrCmQE99z/tPCaPnTxdUuO7tGe+PFo3Zzo6pYQ7qIbdO2RWdDxP4/G8PmO8PMCTLjxtPYq8mXX+PKEwEzxnsqy8zngfO7b9+rwFSY06E/m9PDAgP7xtdjm7PU5vuh8OGbqCP7C5pHdRPOqTH7v0Duc79XW1PBze3LzV3NO8CMNtvDneBb3s2Zm83fENPBVuHz1SlUQ8MuGCPGRS97wQpi+8S1LXPLVfhrwd6zS9780uPFzDpTvffcM8HNN9PJ3HEryk7eo6rMUVPFMktDwo+Ys6DzdsPI2MwLz9uXe7/2aUO3PB+TqC6Tq99KHuPOIBrLzOxZC7Jvi4vN5nUjwH1O87LDWhPXV1e7ylzw+91gQDPAMXNbvdiwW830hfPM8urDwA7g+9gLIKPbP65bz8AAO9vs2lvIkh9jwXors8w2OVvDreuLwdnBG9L75/vAqwrrxspxK9lc0dvGjqGLoTnfe7X405PJ5zkr2RAb08hwD/O/PO5TscMf28VIO9vO00u7nk9kU9TiigO1f4CTtROAe8oFoDvQt5Kz0gENs7qwYZvXlz5zwwouu5rsqyOxylozudFXg8A0LMu5IvX7xSgjG857Dmu34mAT0QbAe8UXzfutjrPbyFeHQ7M1OxPFDqajsR1Dc9sq0APCJHXDzyf7s5eS5MPAaFgrxnLLc8t0S6PHTydLvJI+08bcbDvCb2zrtIfvY8umRvPKEFeTyE6Qw9EldivPCMW7zJtQk8xFrzvMZHXrxHQEa88/ePu0O+QzuLSTe8UJb+u2jBwzzEzz29gX7POnx027t7Qhy84cjjPJ/K8zv3jl88BQH+O2dhozpZD/+8A9HsPAoa/7sfJts7KnY4PL0WizzBZrC8aaLNvB3jqbyixOQ8pKF4PIP9HjyLd6q7aRYIPSVjhTwigJM8muEXPC2NAj0vbGw714MTvUQ7n7wcFW87OQNZvKiJt7yv8RS9IhBjvOf9rjy82n+85kJsvBrnGjwGnie9UMxEvMbphbzTMWQ7wR+TPPw7S7y/bqW8vgRTPazK2jyX+x88WrSqvG6GIDyFYzS9k9QVPKOqUrzzuQO8EDnAO64AhTuZ2jG8c+IsvC6Jhjz6Lyo89bPkvHQmCz0T3Qa9rgkpvZf9hDwUWdE8uiruPOFHlzcPDQi8HSq1vCHtmryLpuI8G9fWO+z1ezuH+QY9vxcCPNzULDsizuO6oKcHu3mghrwalDO8wmSCvG3xlTyJg0a8P5j7vIzyqTzN+sC8QJ3IPKcvL7zx8ja8wGJ2O8GdyTsGXF+85VLdvCVOcTzgEmK8bWxZu5eLA73JnWE89UDkOmuY9bzHUsA7hS7NvJP2zLzZfLW5CONXvZWE6jx5hcQ8co+UvGc3wLwZmMI7GImNvLtEhbvhUW28510nvYjeWzsPDHA7Jb2tvIkRlbx8mWI9uZlrPNU9aDyUEzc7muMoPMh/0DvUgZA8NMz2OQCv47wdKLC8qF21PAk+Pbz/6Ey8EIsbPWKykbzRH7K6fL3iPPTdGLzU4Ro9UqSzvIn8GLyoaKY8DR1qPGf5oTz5g0i8HVxrOz8UuTwhLAk97/PVO4e4/TvUYUo8FckOvKC9mrzEWce7vhY8vahLJL0GrCC86MxFPA1PG7zz9QQ8gECWvDYYALwkdyK8fxz2u7HnkzrJw7G7vDgmPOg317jWRWA9HAblOlXAZbtcnqm8Ujg2Ozb59jyY8SQ8JM7YO28pJ7zWzb08iJb5vA6QmbtD7/q8P5tFPB7BxDvyHTu8iWBIvPRXGjz/fIW84UFUPK3V1DzHIL48nvMevClkozw4qwm75lsGPOdFO7w2l467yVw/vOP7PTx3ayk7dPNRPXUQFjxm9fG8w5z5PI/KTDzeKcK6GnRYu4/L8LqEYlW8QugZu/5pK70ST468HoPsu07uCDwM0A494NnsvCmHjTzF5268ohG1vJseNTyjHfo6SrixO/asgryaf4o8KGJMvFWekrwBQA88iWJBvFLGSLqDpwC9qn3wOrWbYjyCaA+9tmwEPDAFvDtQdI08xYHFvPmdyLz82c88uMapvKuwE715SEi8LFl2PQfcJL1T/Xy8t+InPNek9LzzhPu7xve5vDUFl7zdpGO72kMuvD9v1rtJHC28l7cyvD/yH7ura+88xIW9u/ZnszsRUmc86GTfuhwiUD1oaRe9lCglPGjEPjwC6l678tRRO/HIhjzrbpC64riCPIxCGbyb7mU8ZpqAu6fTTLw72tW7ithWPEwy8joDbqO7Fn8HvNGT0Dt0S8o7ZHGjO1qlnzwJ/lQ7FaWeOlyvG7xb1yA75fnCvG3nzTocjQ69Q1yGO66q9zsK+866Rq8IPQsSfDtQCD497OgUPaZREz03UQ+9DIIJvDGfNDyXaDS8XcWevBqkAL3uoIS8XmRwu2lieTx+DPg7kzX3ODTH7TqdWaQ7XkG7u4OvLDvbyu48K04Jvcxo7TxEu6o8S/j3OxmHJb0fzaM8As8EPKhZsTrj/QU86LREvQECyDy8JKS8U7LYPA0U5zok8r+8U5rPu4tMarzJmxW7qyczPFdNBzzUfGq77N1bPBx0LL1pGc482kIavbzLj7s0e1o8NvAWvHwviLt3+n68Fqz7PPyI5ztSzbO8RpemPK5KPbypTyY8LGwpPMQYDjyqCXw8wit1POFXoLzFTPA7WHZUO5lWQTwoH6O8y5Gou1whybz7QZG8RK5kvIjnBLtZC7q6U7mcOwC++7zCKCC8BGyaPBsggzsAgAY8xJ+HPKNiNDxqok88aTsEvFIVobuvAT08pue5PCyvwzumKnC81h66u/qbizyLdAK7LSWEvBn6j7vE8i291qh+unevFjxCUie9ofTMOu18zbu1dg082MDXPNPEerxcjZ88+zinvMH0obtvk227TlskvZ7Eabwoemq87YRJuw196rtlpY68SVnzPCb5ZjvSaXc6alHZPAIEPTwN6RW8U7q4vNJz3TqPieU8Sk7Wu5u+27sbqYw8kvflPGazbbxEYy08vm0YPKKZCryubOi8SlylvHoWJDvNOw88SV6jPMoOkzvSMUE9hleZvH02QDw53je6lFx/PIo/pbwfNhi7hqJbvHowGzx1FWW8UiThu/a2sLygTZs8ZlJTuxnbCj1EpjK8pMOBu8bURzz0CKO8K6D/vEnFmjpujv+7SD0NPYaLajzejgs68d2GPRKUYTy8blC8HEGmPE/6ED05RA8609BNu4TIPTxb0Um8v/z3vJ6KOrvTePo7pvGYu20WcDycWsQ7czWTPM+7Cb0vixi8DbG9O2sKoLqr13q892hgOz6F5zvY5808RvTdOpgebzyWTIS8PzXQOz4Ijzw5k6M8Kw0uvefZ0DyrGvY6mxUIuz5ByTujQOq8wtvoOspcrToK/rc8XE09O55vo7zbDQQ9QMIsPfGMxDlm/zI8aLMVva2zQbtSs+Q5TzlNvNcywbwVxL+75j9/PB8XO7uothO8/NuuvKWlbTsGO9Y8I1O/vNOgfzvJ+P66nhA6PDg1trx1szU8rcawvGxqgLuIWjC96XhGO/fgVb0BONo7Xg+CvM0o0TuGQQ48mIcyPMNfSDwUoys84fArPZt8mryJ3aW8cyMxulkWtjzRx8G8ENfUO5A9tzzWJio8O5FCPNg2VrwiMd07/5UuPLc3bzx5HMm8wBcTvHOh9TwaDyC7LX0tPSSHzDxNjlK8tT1sPBjrMTy3jnQ8ym+YPGYiLr05ZHy7TyUEvXhRGL3uQ8I8IbMbPbvOyTqQ0x48Nl8yuwFTHj0VxWE9UMxHO8SSP7zdxrk77J2MPJnRkTzhbvK71KoGPD7GJzwumAW8jkqTPOVmoLzJPkm6YcVvvJb77zuFufA8JsIjvMWtzbvxmne8ZrJrvEUvJ7weD0a7sO7gPC5QirqFlRy6ETlUOwMTnTzuZ+E8AK3tu7HMEDx/1b28IRTAvOL3OrzsGzm9lAmmunAaorzV6Kg8fssIPZoJqLunFUc8noUAvUv1hrzIvda8J4QHPTQ9BLwNTBa92PG5PPBOWbylkei893UPvb/+cLzesTO9Wph3PCf3Obz6zbi8QVC9vFjAfDthT5+8atknPHbbELxYNm28W5rFvM7y1jyTzkG6mRy+vLBuUrzasxa76Wu3OuiMfbzQuGW82xwVPaGBiTraZiG8CAM6vO+PebxeAy28NQFSvDlStrzEclU8tKipO07SpTy+Bue8TEywu1jY+byWfzg5hw/guuTVPbwGZDQ8LGFaPD/Puzy1cDK8DFK2u3hTpTy1nz67DVQSPVllgbxKyGe8U5gTPDnqibwHf4g8Q6aAPAHkpTwWwgi98N/RPPQomzxZwwO99rJ/PMrKELz83N+551upO2I8xTzznkK8IwBlPHxiFDxaOoU8FZy+O28xsTxluhm9aA2CPIRolLuuApO8dsuAPLNAQDzSDys8Hj/3O2RqvjxgPFi8prQkPdHMiLwWpJO7Kn1TPJ20Jbx+kJy80xwEOxxOlby9vEC8IkySO7z5gLxqaQa8NmmMPFVRmzwS4do7ir0OvU4AoTzImsI8pBMJPRVnQrv9F5C8cB8ZvaGHmDzPzau7FJPfu886Ez3DqTu8B7o4vPLIELuK/VC6ukKUPCHDBbzS2K08DjKfO0m8brxxQHc8w3sguhvj6rxpsEW9Pgt0uWLjPj2nIoy81LcAvcPYkLzia7q7qviRuumJlLyHn1e88jT5u1Mywjw1uxO7o7a2vAgPB7wuwK27BBAEvIZhIjzS+kY8Zm5HvBkjWbxkpMM8CV+RvDG0WLmD8Qa8gLIFPPYefjugj5E8xh24PA6wJj1enoQ8Yaz8vJ2m6bxnj9w8cEx/utZrM7wbWhC9JYqdu0h3t7u1LXo8ghIZPLjK6rxj8jU8B7PWPNnCiDtjUgI9BjEYPBRMHT1RrN67j4CJOp63mbuAdYA858VsOxxtTjwViWu7Nn5ePSgHoLswhXi8Vl0XO8plRzsA0y69vNalvMdPUDzCiKK7EGuSvPhnOLoLfF893pDSPLFWITzpwSq8a/emvJKFrjlriyE9lYorPEr/VTweIju9Fukyu/lRVrpVKJ28EqxzPPLZgTxR7wE9ajBavGwyIbwzX5i6itYOPdE1k7xpkbq8uWdgO3hw3TuLdza9I51AvPMqybq6+Pm8IftOPOdRlLw2Ife8HKHLPIqOjrwJEdw7cgI4O0ZX6LsGJnS7O78DPJG0+TxK8py8NK1fPKc5CLxI9JE8mBCfvKpdZLtQwQc8dyYYvdjvKTzQk9w7b+jhO1pEYrzVZIY8cP9PPNyuFzwkh0I8JWuLu0GTTbxISp88a6yevHBKw7zGAH48C88UO1xgKDxBmY05k25pvBNwdbwNMj08Gn6ZPFRIsjwo2GA83FaMPE89Ozz2Unw8YU9Xu+wvxbt9UEm84MfMPB/YUTvijFy7wBQ7vUewEz21LHU8Rq9mPC6upbzawQI8ADmkvAh0ST0hG6a8vXrNOFLiFDo1k9K77OHxuShxIj2hgzi73XU4u0veG73L1EU7YDa+PBjbPj30kuK7DIo9vAZk9DzGeO87tIb9u2Awrjybgsk8gBakuyicbjveiMk7a3sIOowQVzxPXrq7qauOPBFwejtUncm8MascPEw7Ebs0MTo8+cvVvAZxdruyNHe8WPtTu8l98js2OTS5jztjPOrQGTpo6PO86rFOvAxeJz3Sw129OPWJvHrcjzw4X5a86yvNvCuFLDt5DWQ8eAZmu7mxiDyQzNO7Xj0RPBT82byltE48PXs+PKmLxDwB7oe8Zv0gPcjRFzywnny8hxbVvK2C5DwQI0s96f6qu8sZ7zvCKjK9SLjhvDvwpDwMefQ7vV4APcJnlry0Jbu8v1s8uxz1Jb2ONAQ9NkcFvB3A6ruAFbY7KeaFuyp2mzpOfC69cE0yvAG+mbx28rC8Cp/OO0oxEjzN/4Q8wQQzPdcM2Dq1+Hc7LTY6Oijh6jttp7I8YfGAvKwwa7nlcYu8tvM2Oy+rn7xWcVu8HEs+Pa7G7Tzt16+820IEvOBOB7zz7jS6/Ti3vE1sAT2UM5e7YdD0vFlgQj0aQkE8UFI9PM/tE73LECK9m5t8PK/3a72Khb68EyQVvNFkwLsCtbq8GCoJPeKeTTyDH2S9yD3aOzMOrjzYjjW84NgBvNJPK7zlti68yoTavGPuGT1Pb+u6QULQPBUoMLzfn6q8O2fZvKJB+jvhmAK9/a6rO84WszuFdj083eUnPXoN9zw0Y5u8elBiu3KQHL1GDzw8zp1wu9gmHzzzdoi86dzxvFt4i7tWtY487KA0vf6mrbyco5c8pn56PLtDmjv7hrU8A/DtvCtJmrqraKU6zq27PEDEKT0jbes8D64ePA/2pTyZ8YA88UKHO1CnBDwUQfa8LoOjPF0Zu7zTf346MR+8vAL4hry5ggO8ZoYCvW72KT1Cmea8dNDQvKDzMzwFYCC8uYj7O+vYfjzP8Ts8RveAvLzQzLsnlg490BuAukTa0bzpH+28dLu5PNDV6TzowXO7IvexPBL5BjwcrEu81ewCvMciY7wkh0y9+PALvU46fjsZIPG8kuGqPHFbjLygRAW8fPjzu01J0zxCewk80C/AOw3qMTvVQGG87FZ6vO3Z4zzSs428EqWovH+la7sJzjM8RonrvGQmk7oxOxE8x3DzPHYhhjx2eS06nYqbPA4bkrxILwu9+E2TvPpPtjsTppO8i+EAusgB4zw1xLO8PftIPTNCkrwcdf88kMRrO+4C87wPQ+Q7KZQAvOKCQD1Q9ZS722xIvElKmjunpe27DCwSvECBJD34s7U8mzR0PGbD2ztDkyk5yBStug7IRjz9kU48DYMSvQgPxrpIdeG8p/+LvCfJAr3/GtC82aQjvWkeC716n5S89me7vCT7o7sojKs8wvWDvG7jBTwuB1697lQEvN/tRzv5AX687Z3cO8QIj7wu6Tw82bOovAQ+2DysQzC9USTPuupngbq6uSe9ohGEPJMTgrzHTs87xs+vvM9KablqBMc7SLBSvMOCnrxYQYe8rergu0l+0LxQIsA6gBiPO111tDtRCDW7Rrv9vOGOGLz5FrC7BQ9kPDbsRzuZ1VS8ZyK5PC+OvTxymTa9a1WfvPC8hbpiBa46tNPJO19tHTzylwO8CwTxPMcrpjy0v8Y8P/QOPRIBLbzQDhc76PoHPX0tET2I5u88E/LsPB/k8Dss/688D9HmPNRFnLuLOc67abYxOBRwST3yIaY8o0JovDQmqTzWxK885+7du/aV1zpkCY+5gaRVvNrYH7vsDqW8OY79vBytvLniJXG66beCu5W8wjscGba8a9Z5vAYXID2fyta6NMcIPBrAwTsZtgO9qhxevErUvztlkA+7S2r4u8f/dDyHbtK8KM+gOtoOHT0wypQ7gnmOOniF7bsRKPY8I5AzPEwLj7y7zIO7BfpZvAsa7jsgsPm8vMIdvOJ7zLsjhM8777SUPL+18Tyc38083HU8PNKAvTlkPcE7wck+PR0i1LuobgI8masaPcIgG714IDo8zbG3u0KGlDz3AJO6WUoFvUQfHL0/RCw8mWRrO0ByBL2RW0I8rvIyvCSwmTvFSt4733HKO4YSlLvFFUc7cc4RvZt9zrzzU5q8koubPIlseDy/svm8ur5YOv1+MrzfVem77CSivKZu6ztLkxA7bn4DPXKScjwapse828yRPIG12LvqgZe9bx4KPU+mZLxSyDa8i/EmPNGGozzvWry847hDPao1tLywmbY6LmUSPZjwmzmUWwy9sApEvGy65DvMSia879XqvBRgzTy6e3I88AjuuyMkjToY8Be9qkPOPLZDJT1lJgU8rSkWvLkfWbuAAf68gzTTPCw6azyklpY7FK+4u6+h6Lyqc8o7+kNhvKdUZL1wDIO8drxnPB6oiDxqBIu8RceAvLVRWDokef47QhhRvJwIzbtDF587JK5CvZt3kTzgXeu77o+mPA74RjvZ4748p+xwu+KakrwmMek8D5t1PCkD9LwskgS9EwFRuwd/EryDdaK8/TkQu0y2DTyaQ8m7NO6vO6EYQjqQffe85KhMO+3XQ7uSd587jt7puxohoLomWvM8clnvO9JbWTyaHqQ7iuj7vDJlDT27dwU8MNo/OhGYBj0BOgG9qgHnOgEFYTyBTiy9HbsYPPWwz7v4ROG8Xeeeu935DD0/kD28NcMzvUeLqbwMnSG9TD7HuwsWorxSx128pKtQu5XtAD3eIpS83YzlvHO/nbxosT28JH4TvNUAOTxgEQO99YhyvPU/kDy52xA8VR/Eu3u4Db2x5bK7JCebPElPOLpQjIQ7aqoFPd0df7w0iEc8Cn2hO20Ujry9zKK8PZgVPB5jqjs45w27Q8GtOlmWvTy0IVs8JDnZO6Hn2zwOeey7ifwQvAmHWru2rOO8kIjqu8mySzzVfuo7/gOsPCIsl7xcm8W7005tPDnatjvPVmE88Z7MvJc7urzMhyI901s5PB6OrrvuG4k81v+rO5RCAryFeTo7SBY9O7ltwLtbuNA8IaMWvbK0kzwgxXu8s9bau2uiJrtXEp+8SfrlPBzfdjxXZuC81DHwuwGGPD2BIR86/Jk1u3s1Jz2tfIy8HKEPPb8qqzyompo8FmGGO7f3mrxcRwE8mvIvOycFw7w0JoQ8kxw2vL/aGzserEU8wfRDuxaB2rtXm5u7yASovG6Xurlh/YK8FWzBu9iY3LzscaO7/5oVvV4PjTuNCYe8Ucf1O2iMhrrovoE8L+l0vH71rbw27do67iS7vESV1rt1dJW8p1Wcu7EwGL0dmF48T4imuyUNVTvMS2s7Jh13PLXGPjyC7uQ8q/ZAvNGHq7w0D1W7PhV8vEULHjtKcDk79x+9PBS+frzbKkq9LZOovBFZpryPdoc80v8ivQoqArwK/D87v/i+vDElqzzdEAO9/YigO+WpH7zQAc65XdiCvIez8LzqzvI890YIvYzcozwwZbw8VV5WugdO37q3bmG77QXZPEAwDTwXZq86DnQAvLNEXbt5WdA8qg6XPAVUtjpzLWY8Y/5MuqmJKrzAEU28mvbZO7/XmLxZGrQ8720SPfz84LxHaZ67/cusOuWwtzxJEnC7UTFqvF2l1ryZ6+285b4rvJFVNbx4Y1E8zpruu9++pbxjxfI804TyvCeAgLz/Cdq8knJYum9UM7tCB827/Y60vB9xnjvVW6o8biqMvLwxpbtBHB08E8RYPMSR4TzJ4aW8DTKkuyeOirqLRKS8TyrNvO7SKr03+Ju8sXchO0ssDb0K78I7zc7YPCxIMj1HA5y8bk8ePIfvf7uwQTO74y7SPHIRDrwM+Pw8M5s0PLQsWTtOJzO8/gBqvEyQojy86tI7mWmzPABVi7z0Nsc8ToC4OXSF+Dy6nPg6aQFtOurtHjub5zo8rUL4u+chSTzgmYO8hteDO3mBuDt+G7k6j/sCvOp/FbmazhW8UWDUvLVf67uQSyE8GViQO0QpijxZWnY7pfSCvPxmFb2CasW7Vxq9vJvltDy/aAA93npxuer2KLzECZc8nATeO/YqnjypDnM7tyUqvJEJhjw9x1m7aJe8u/ZLTzxUJQi8cHDou96nijvOFXy8j8wpvZiXBLzdZTk8ZxvzvIsDazvW2RA8TcacPMeH5bqbpAC95QwWPFm2kruxeqS7++ICPEZZmzv66BK9py3OPKP6JzyQspA6X58jO/0gGDwhnTo71N3OvDSAPDxEfb28rnAovPjxc7gOzhW9ZjQJvHRyAbukHmO6PJNgvFmzDrtSOpK8InWMPJnZHrxC7ha9z8GIvNn6pTwG9qy8gI0TPXXgGLzGVGE8mafRO1rVtzyULwU9hU6wO/VseTzn4w49NalbuzZBAz1gvBi6vjaju0JKHzyZUGs64hhCu9wfxDvAgyw8Y5rYOybCRTy/KUQ8SMUuPJYv3zxNXvg8b09gOgYzOjuVPRC6R83ePNImB7v+0m07NWnau+UrwLy0tJ27lfxZvYQZkDyVq6g7kgECuYNVjTzNQco7MNzzu1K3ojqY0mO76VYeO9fOGzzWd6+7kc4WPDwwurw/8Yi8pNlyvPqGibwU9/881dGbvNFrS71UZfi7NTuvvFDmITqqa/a7ZKJEvNHPEb39iSU8foDnumaovzwTPo+7QjP5PFRV6bwdZBm94jk6O8N/GDwJifs7NJtoPDgqWLwN7Vk8Or/MPLaMWjsmPsA8sHQgPIbTNjxri3E7DEjQPJkJ87s7rra7dO15PKrwK7vJZLO7eXv+u/BSnzwBrc47CLw1vNqZTbstakc88a/5PEZ5hTw3PHs8tjPiu/kOY7xM2NU8CkyFvGaE27wRUWE7JBgcuuxgHzysMAm91+swvIm3rzwmqbq8+JCAO2+OxTyB7za7zdmUPL/QYbxeXUI8XCogPPOhB7vEWfS6WaAevJDLRDxQUI25K8p0PPFc07ptEzw9FHzaPMcljzwlvEq88Pd1PGrNC7uivvy8lqhMPONrCDyn4wu8rBYFuRRC5zw+WXG8BAnhuyFkGLvTgqC8n59svIUHH7qNDRS8bJbhPFLMITz0zdW5kNvBvMVB7rtJ5CO8tCSRvH0ddjzW4qa8GMm6OoYFSTymkoa8G73Cu+sn4Tq4y688G6ssPNX2EL2CVd25hYpXuqo17DsnmjQ65vvEPGD0WjxZJ9u7XPcLvPeXPrwv6jM8aPK8u8wXNDxVhls8nQaXucciy7zcJ8u89OhJPIyAPTzNZpq7PvhbvPOH2bvEtuw7PUlTvI/cyLuZgHs8EBuAu55XP7z1IpC8IZmXu+0dAjwYqoK8vpFAug== - index: 0 - object: embedding - model: qwen3-embedding:4b - object: list - usage: - prompt_tokens: 8 - total_tokens: 8 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '75' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - foxes - model: qwen3-embedding:4b - uri: http://localhost:11434/v1/embeddings - response: - headers: - content-type: - - application/json - transfer-encoding: - - chunked - parsed_body: - data: - - embedding: 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 - index: 0 - object: embedding - model: qwen3-embedding:4b - object: list - usage: - prompt_tokens: 3 - total_tokens: 3 - status: - code: 200 - message: OK -version: 1 diff --git a/tests/skills/test_analysis.py b/tests/skills/test_analysis.py index 62e450a5..f647abc4 100644 --- a/tests/skills/test_analysis.py +++ b/tests/skills/test_analysis.py @@ -155,7 +155,29 @@ class TestAnalyzeTool: assert state.analyses[0].answer == "42" assert state.analyses[0].program == "print(42)" - async def test_analyze_with_document_filter_in_state(self, rag_db, monkeypatch): + async def test_analyze_applies_document_filter_from_state( + self, rag_db, monkeypatch + ): + from haiku.rag.skills.analysis import AnalysisState, create_skill + + captured_kwargs = {} + + async def mock_analyze(self, question, **kwargs): + captured_kwargs.update(kwargs) + return AnalysisResult(answer="42", program="print(42)") + + monkeypatch.setattr(HaikuRAG, "analyze", mock_analyze) + + skill = create_skill(db_path=rag_db) + analyze = _get_tool(skill, "analyze") + state = AnalysisState(document_filter="title = 'AI Overview'") + ctx = _make_ctx(state) + await analyze(ctx, question="How many documents?") + assert captured_kwargs.get("filter") == "title = 'AI Overview'" + + async def test_analyze_combines_state_filter_with_explicit_filter( + self, rag_db, monkeypatch + ): from haiku.rag.skills.analysis import AnalysisState, create_skill captured_kwargs = {}