diff --git a/docs/agents.md b/docs/agents.md index ee1b2f26..71ec3658 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -62,14 +62,13 @@ Key features: ### Tools -The chat agent uses six tools: +The chat agent uses five tools: - `list_documents` — Browse available documents in the knowledge base - `summarize_document` — Generate a summary of a specific document - `get_document` — Retrieve a specific document by title or URI - `search` — Hybrid search with optional document filter - `ask` — Answer questions using the conversational research graph (automatically recalls prior answers) -- `analyze` — Complex analytical questions via code execution (counting, aggregation, comparison) The `ask` tool automatically checks conversation history before running research. It uses embedding similarity (0.7 cosine threshold) to find semantically matching prior answers, which are passed to the research planner as context. When prior answers are sufficient, the planner can skip searching entirely. diff --git a/haiku_rag_slim/haiku/rag/agents/chat/agent.py b/haiku_rag_slim/haiku/rag/agents/chat/agent.py index 0f3d1c14..c1081f57 100644 --- a/haiku_rag_slim/haiku/rag/agents/chat/agent.py +++ b/haiku_rag_slim/haiku/rag/agents/chat/agent.py @@ -447,65 +447,4 @@ def create_chat_agent(config: AppConfig) -> Agent[ChatDeps, str]: return f"**Summary of {doc.title or doc.uri}:**\n\n{result.output}" - @agent.tool - async def analyze( - ctx: RunContext[ChatDeps], - task: str, - document_name: str | None = None, - ) -> str: - """Execute a computational task via code execution. - - IMPORTANT: Provide a clear, specific task instruction that describes - exactly what to compute. Do NOT pass the user's question directly. - - Examples of good task instructions: - - "Count the total number of documents using list_documents()" - - "Search for 'Python' and return the titles of all matching documents" - - "Calculate the average word count across all documents" - - Args: - task: A specific, actionable instruction describing what to compute - document_name: Optional document to focus on - """ - from haiku.rag.agents.rlm import RLMContext, RLMDeps, create_rlm_agent - - client = ctx.deps.client - session_state = ctx.deps.session_state - - # Build session filter from document_filter - session_filter = build_multi_document_filter(session_state.document_filter) - - # Build tool filter from document_name parameter - tool_filter = build_document_filter(document_name) if document_name else None - - # Combine filters: session AND tool - filter_clause = combine_filters(session_filter, tool_filter) - - # Call RLM agent directly to access code executions - rlm_context = RLMContext(filter=filter_clause) - deps = RLMDeps( - client=client, - config=ctx.deps.config, - context=rlm_context, - ) - - rlm_agent = create_rlm_agent(ctx.deps.config) - result = await rlm_agent.run(task, deps=deps) - - # Format response with code executions - answer = result.output.answer - code_executions = rlm_context.code_executions - - if code_executions: - code_section = "\n\n---\n**Code executed:**\n" - for i, execution in enumerate(code_executions, 1): - code_section += f"\n```python\n# Execution {i}\n{execution.code}\n```\n" - if execution.stdout.strip(): - code_section += f"Output:\n```\n{execution.stdout.strip()}\n```\n" - if execution.stderr.strip(): - code_section += f"Errors:\n```\n{execution.stderr.strip()}\n```\n" - return answer + code_section - - return answer - return agent diff --git a/haiku_rag_slim/haiku/rag/agents/chat/prompts.py b/haiku_rag_slim/haiku/rag/agents/chat/prompts.py index 6589690f..4d1f5684 100644 --- a/haiku_rag_slim/haiku/rag/agents/chat/prompts.py +++ b/haiku_rag_slim/haiku/rag/agents/chat/prompts.py @@ -15,19 +15,6 @@ How to decide which tool to use: - "get_document" - Use when the user wants the FULL content of a specific document (e.g., "get the paper about Y", "fetch 2412.00566", "show me the full document"). - "ask" - Use for CONTENT questions: "What does X say about Y?", "What are the main findings?", "Explain concept Z from the documents". This tool retrieves and synthesizes text from documents. - "search" - Use when the user explicitly asks to search/find/explore documents. Call it ONCE. After calling search, copy the ENTIRE tool response to your output INCLUDING the content snippets. Do NOT shorten, summarize, or omit any part of the results. -- "analyze" - Use for COMPUTATIONAL tasks. IMPORTANT: Do NOT pass the user's question directly. Instead, write a specific task instruction describing what to compute. - -IMPORTANT - Choosing between "ask" and "analyze": -- "ask" answers WHAT questions about content (retrieval + synthesis) -- "analyze" answers HOW MANY/HOW MUCH questions requiring computation - -CRITICAL - When using "analyze", reformulate the user's question into a specific task: -- User: "How many documents are there?" → task="Count the total number of documents using list_documents()" -- User: "What is the total revenue across all reports?" → task="Search for revenue figures in all documents, extract the numeric values, and calculate the sum" -- User: "How many documents discuss climate change?" → task="Search for 'climate change' and count the number of unique documents returned" -- User: "List all the dates mentioned" → task="Search across documents, extract all date patterns, and return a deduplicated list" - -When "analyze" returns results, include both the answer AND the "Code executed" section in your response to the user. This shows transparency about how the computation was performed. IMPORTANT - When user mentions a document in search/ask: - If user says "search in ", "find in ", "answer from ", or " in ": diff --git a/tests/agents/chat/test_chat_agent.py b/tests/agents/chat/test_chat_agent.py index 165c2f78..41f2f7d9 100644 --- a/tests/agents/chat/test_chat_agent.py +++ b/tests/agents/chat/test_chat_agent.py @@ -1265,47 +1265,3 @@ async def test_summarization_task_cleanup_on_completion(): # Task should be cleaned up assert session_id not in _summarization_tasks - - -# ============================================================================= -# analyze Tool Tests -# ============================================================================= - - -@pytest.mark.asyncio -@pytest.mark.vcr() -async def test_analyze_tool(allow_model_requests, temp_db_path): - """Test the analyze tool for complex analytical questions.""" - async with HaikuRAG(temp_db_path, create=True) as client: - # Add test documents - await client.create_document( - content=DOCLAYNET_CLASS_LABELS, - uri="doclaynet-labels", - title="DocLayNet Class Labels", - ) - await client.create_document( - content=DOCLAYNET_ANNOTATION, - uri="doclaynet-annotation", - title="DocLayNet Annotation", - ) - await client.create_document( - content=DOCLAYNET_DATA_SOURCES, - uri="doclaynet-sources", - title="DocLayNet Sources", - ) - - agent = create_chat_agent(Config) - deps = ChatDeps( - client=client, - config=Config, - ) - - # Ask an analytical question that requires computation - result = await agent.run( - "How many documents are in the database?", - deps=deps, - ) - - assert result.output is not None - # The answer should mention 3 documents - assert "3" in result.output or "three" in result.output.lower() diff --git a/tests/cassettes/test_chat_agent/test_analyze_tool.yaml b/tests/cassettes/test_chat_agent/test_analyze_tool.yaml deleted file mode 100644 index 0bdc6fd4..00000000 --- a/tests/cassettes/test_chat_agent/test_analyze_tool.yaml +++ /dev/null @@ -1,1199 +0,0 @@ -interactions: -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '730' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - |- - DocLayNet Dataset - Class Labels - DocLayNet defines 11 distinct class labels for document layout analysis: - 1. Caption - Text describing figures or tables - 2. Footnote - Notes at the bottom of pages - 3. Formula - Mathematical expressions - 4. List-item - Items in bulleted or numbered lists - 5. Page-footer - Footer content on pages - 6. Page-header - Header content on pages - 7. Picture - Images and diagrams - 8. Section-header - Headings for document sections - 9. Table - Tabular data - 10. Text - Regular paragraph text (highest count: 510,377 instances) - 11. Title - Document titles - The Text class has the highest count with 510,377 instances in the dataset. - 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: 166 - total_tokens: 166 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '481' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - |- - DocLayNet Dataset - Annotation Process - The annotation process was organized into 4 phases: - - Phase 1: Data selection and preparation by a small team of experts - - Phase 2: Label selection and guideline definition - - Phase 3: Annotation by 40 dedicated annotators - - Phase 4: Quality control and continuous supervision - The Corpus Conversion Service (CCS) was used for annotation, providing a visual interface. - 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: 90 - total_tokens: 90 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '412' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - encoding_format: base64 - input: - - |- - DocLayNet Dataset - Data Sources - The data sources for DocLayNet include: - - Publication repositories such as arXiv - - Government offices and official documents - - Company websites and corporate reports - - Data directory services for financial reports - - Patent documents - Scanned documents were excluded to avoid rotation and skewing issues. - model: qwen3-embedding:4b - uri: http://localhost:11434/v1/embeddings - response: - headers: - content-type: - - application/json - transfer-encoding: - - chunked - parsed_body: - data: - - embedding: 1B93udC80DrPAwi8BUoePQ9ck7ocgVg92ju1PE6CSTsRee470aWguomYnLxsawc9aS9PO+x+6DyntT+9O7n3vMcy1DyP4aW80hKpu4CiSbrpUQg79am9PMvOZT2GAqA8/NUMvXOXEL3ICJu8SG2yvKI+wbxifwE91f5CPeSSTbzL8QW8qXssPFq1STtsATi8PMM5O9coUjuFalU8qjQvPEm9pTxFBy27tS57PNgcOTuBOYK86anEvNIh7Tvrv0K88Z/3vJl/krv2t008cpYKPOWgNr1uDQS7Als0PXPyKDtPKwQ9QLkzO0extrw1BRk801Lyu3i1B73yirI7h5qBvN1a0Lt5uXe8co9BPHNJlrx/PZE8WQZqu1zEwrzC3Mm8n4+pOx1SbTxchKk8JyWAvB19bDvshzI85oNovNKAvDrgaLQ7Zlk2u6qMFjzAsxw7q24Xu5GXZzx8Ig4811ywO7QH1bz7Vew8wLF2O0Nr5zxqNAO76IGEPMPuo7oKo6Y7MobEvD+3ALz3Txg8OqqiuDogG7u2vdG8yTecPOZPlLpuBKM8GeTHvAEje7voj4S7KfvOO4dSHjwxtAI6eOcIvKRfJbwqoFg8PiSHPCZ9IbwvUMG7spgdPOlUPzwwoaw85ggkPPdyV7xwww+8Xmo1PFxlBLxhCMC93AldPOPrprzQRtQ8yUQcu3A9qTx2EJa7TG/EPOJEw7zlgx08LiMsO16D07y/ZzY8WllnO1LpIDxT2aS8CzJRO8BRejtU13I8y0Lmu1m4Cb0DCuY6YP7xvIjfg7o7Rxu8qoSxPHsrJbsMbvk7FCnYO50WXDzdKIE8Lo3zvGtx5LvIGGI8fzveO5mD4juBbnI8vtZFvA68ajw1nag8q7BsPL/29Dq4hgS7fxCouXRKyLz6F/g86lE4vDcaLrvbEkm6jI/6uxY+Zbyp9QI8T2yqPPgCS7yumLw8wUhfPB92Gj1BOuG8qW4aOxuiFTxYVb+8b2ikuxOZk7tYtv47IrK3PPmubTojTdk8bnHJu/zAlTxt79C6BUFdvBNa+ToUE+k8hPHkvNUBSDyHOEm7i6wlu2V25DwtxIe8uhRIvNMk37sSLFa62ihTvEXp5DsZ+Vq8v4u5O4fL/LygHzy8LmACPY72CTxvLN85HkBovFaHsrw0a/A8YxaEPA/2YjwTSNQ6A14SvEzZQDzRYu+3adk0PJb0QTwaQka8slMzvH6kRryrDXI8wXovPI7jaTs4h2k83k0cPEXNVDot0YE6mRVgO8fgijwejqO8umvKPDnMrbzT/Ku5eabDOdhNCjkMDhc6ZrqCPOQ6sLw5hLe8hWXKvAHKZLswpGo8uZuOO1ocbbwgIk29bsFbvIPNaLznnOK7Jq6Mu7mfPzsnu6W7rQ/du9a6DLz4hAi8aqkPvDPcmDzxfEI8abZnvBLnM7wZhaY852ukPCoe7zs3QAE9xqdnu79C3bye4Ta8M6o1PBYTuzyVPam7OCqDO2vF87zXbu67pa4avP00frxMh0W8Q+e5O6dZZT0S+xW8a+wXunBgdzxyJLo8f2YHvfZTpzzWFE68+3QZvCUsLz14lIM8TgqYO4jXZrzJG/g7svy2uS1GnTqRM1k8yV+suuhRDbvVdqo8u2rFPJ8dZryLFPQ8ujmgu64TlbypmJg833TCutrslzwwdvQ8zQnJvPkc7ruNSfg7AkBNvOxGJ7y1qpK8HshSvRB/zzzhtP071jKsO4N3nDyytqI6yO2qPLqAFD2ColW8Cq6EPB03+zzl/zq9ulopPBrkbDtbPso7G2D3uw4NijwtPt47WwwVvPP0VLzuv4k8Ac4CvO/IorxA8Gi8GZNlOzFLL73rwI87aABuvLaqzbzn6UC8oh0PvaxNgL1S82c8vh4RPRBEybzeN9A3hlWhO2uHoDzTv++8GsHTum4ptLzB06k7RnZAvFz5iDzbiqG7tLEEvFDSuzxu+Rs9enNXvAqthDxmHAA9MUIaPSZlSjz2ysy7CGB+vPCE3zy9BuO8NO2UuWWsLrxSY+Q74mhdOyEN7rocoeO7b92avFlPiTwlOT88ufKGOH4kXzsogAQ7xK3wuvFCRT3b3Rg8vsB2vN8uDr2tZho9+aUmOyWOrjwo4FU8VS3TvGvlXbyl3t47F8eNvPiLaLwn4Yg8jh4wveziCL35KgQ8kFdMO4xJRDz/rYq8OD66OwD5sjs3w5Y6a6Fyvd3YgTxB0Ao8Hl9kPKuup7rRJYg8aTCtu147R7x+j8Q84YDAO9fsL7rHIIE8BM/8OwgW0zzjjh08MDBKvSoPurwSuhY96bGOu4TTuDy63Kq8I2KWPO8QGzqdn4274rFwu4Reo7zQfzA7Jr8MPew2zruLiq88ABTUvLrkKrz6AxM8feUOPd6qhzxrR0K9bSQ0vSwDNjwmciW83mc8O06mnjopGVC8fmwqPCgePTvuI3S9cUP0POMiLL2xUmw8vvMcOxSdQ7su14487ZWbvITeFLu7Tzm8inwtvIR8gjzRpb85eyDTPCPT8DxQsbq86iwTvJvJCDw41hc8RehDvH6MWrzA7K87U0rpPAcaCrw+MfU7Ug/lu3Q+aTx9XfE8zk/lPNxUnbtZ5EM8UYuBO6ViDj284TC8ArC9vBR+dDydQpG5ETHNPC4YgTwWd668RyP9OyqjsrwTTma4czEJva23SDwOd7W8Ia4rO9ePOzwHBKA8K3QLPde6R7yGhcY8njbHO7NhFDwc5YU7dgPNvFB/1DwAeIq7E4UfPD1dFry9XRq9GO8NPVa2LjuOosM4i1xrvNLkBrrvKC48J5oQO33MGD1H77Q8n13TO+IhYTzExXG8y31UO7KzlzxjT4K7yR1PvGDafDyD8UW8NyQMvG41tDvwPEE920OdvPTRpDuJ6yq8fDskPGo6sry1iKY71dLSPD7Hijp7D0M6QeuGu6aoADxhPQ69moKmur5KJjwoiRQ88pGDOoanEb2kMs88MrZyPBegTrsXA4q8cOhsPDym9rovGFg7JeluO+rD9zvyjbG787alvH1igbyljIS7PBOAvP2S27vNN/m7iWvwu72gcj1LncM8kLOEPLk+m7ti+zA8bFmpPPEcyTwFoQy7abgyvC7JZTqB4qg76zGZPAiBjDtJVdc8tO+kPPZGB70ib0W8PrvBO7f3yTpsqa47qekJvYnA1jxrDSi8b9AsvZxPmTs/0Em8exJDPUL0wbypcYK8wjTPu7ildLy5BW47Aagpux+HSryPUKK6cSbTvJyBkDr8ULY7U7DXPEfwWjzGjeW6ZiPtvEc/p7yyHSS9GUSMvCxfOrsMftg8PGDlPMQWNrzFOMo7iLGKvBcjVzwdWYO8BoEmvXMFmrxm9+c8IOV/PBHvdzviUEU9daOcPEI1rDu8uqq8YLyIvX+oCrz0+1w7HT//O6C/GT0GKrk8nFpjPMWMwjwH2jE9KlKGPEuqirwx2le9kjcJPGG6E7xQUxg8EmhMPKYWDTzKBUi6eTL4vK8knjyr18k8+7yYvLc0Rjw9+K+761wYPbeQVLx5n5+8ZlqOPPLhWz1ACYw87vuqO8O0Crzr0aW7bfwLvWRpJbyvZd48YmV2Pbj80LvWbE494Sz4vHuIZTsdSii5FO5KPPyo6TvVVIA8j5XDPKgUnbzSg4E7PrbIPGAyV7z49q87965evOFOVzwQV/e7CrdAvAbMHrxCgdm7vBMlPAmgfjqGqCQ9q4KgPFCUbrzrDUq8k+TrvC63Yrs/ygy9o7usvHLeSL1PDKE7lLihu5uczzyQkZi8700XPbjimTyJK8W8eKMIvdrZOryUR4u8WNJOvJYC7jn4jHi8fd1vPPJaOzt2zaw7FN2tvFUk/zpTAYS8XhOru7iKbbtybWy8TEd5vKtg2jwz8CG94q8bPSLjlDxDT4G8OY9LvKq8IjzV8QS8XamFPB/bJzx4Ir+8DNPnOUPuuzyu78Q83x+nPGyO0Lp0VHM7acSEu4jHwDu70Aa9rn4kPQ4vObxLtFg8/ZLRPPayorzruXy8rAvdPIQk9DqWQYQ8EeWtPPUrWjzKhVg7v9e1vNpOCrybsQC9NqsGvbu2i7xXPM67FHcSu+kLETzuC/67VwLSvLweODv1n2K7Ga/XPM18mTxuFgi8tjQ3Pe/htbukqnI7L2JhvHl19jwaFo88Zp5EvRgufTwVsuM8i3cQvcVQnTwZi348S+a4O8dbq7ttbqg6EfbcvMqZDr3TliC83Ds5PCSZ8Twe6cw6YmkvvYKzAbyuanK8zEREvUY4q7sb9s48sbjtuUBtwTx7NRk8xqCFvLZ/uTxAhSU9PUaQvHwAMzsMLmk6WKivvJGHDr2RZYU8XK9LPDIQa7y5AZ68a7oSubpvIjyLhCa8YZayvHlubzwHqws8VhKguylSsLuXvvI6cJwDPE9hCD0Svgq82pAhPX/T6TwcVrU8R4ugPJTlMrtojew8WfDHPJOPm7meA5o7iuFGveCJHrxD9ka9gBRGu7ZXqLx5Oio93k5XvJ2FOTuKPF48qg3CvNVHvDz5vvG7DQtLu5z5kLiEGm8950oIPbBy8roO7s46CznivA5NhDxsPpM8lXILPOl4Fbza/cU78qHouxBUNbwD6NM7GN7MvNLFLD1+kmU8c5V8vRuDNrrQ1oC8wXj0PA8KSTysChO9GjGAPAifxDyQC6+7RdRluwkTELu8FjY87dT8O6OtMDyK5Km8NpIMuyJogjwmT8O8B1A9PE1mY7yzSV48pl9pu33qx7uwmMM8w5gLvLa0WLxycAa8XHc2vEFQKjwjD6u80ISQvBbAvTwqeVG8mfG7vPe+BzzmR0e8UPBtPD9oPj116ps7bMKUu6l3jDzGxS49rxsDvXXuAL13Dp67iQ6evN2ku7sYcBC8hc6EO3NCQztRGQs8dTxFvdbliLwL/pw8AFGdPOgWTLz/aC88P9CpPCLyh7xH/2C5+TWqvALvX7yajKs7v56uvH90qryrELc75HSxvLu0Pj2DX4g8Hp89vEUv+jpKyeo86DkGvYSFKr0uiZu79wUtPVqJNLqrW868rwqCuwSTirvLLww9PSNYPFw6Hr27cvY8xu8KvAyMjTxTPQG97S/IOtsHQrpS3p27mv/3OK+MzLrrKz88dEFRvO5kmDrNpaC8BhjWOx6QDzw3+Q085OX0PJviB7tCOkO8FnuPusibRzuk9VO8T7Y6vPPcazu7dMK7W2zLO+QLZTzpMCI9xpWuvGKJQTztwQe84lajvKqKajzLAvE7SDP+usz2BTwxGOM7K7+lPDAQ+7zKY4873e4RvZ5HhzskaNE8nT3pOzeC3Tz0CHQ9whU5PMlhOzxHfTM8V0yOvKKF17yJrw491ZzBvDgogjq19Vw7sRngOw9/Cjz2nR072qkYPUFoBL3HRBu81pMYvN8NSjz4N2M6nFdEPLqvp7zaeTO8T7BgPZ39ubzAAQU9/xohu6hVrDscQzO8M8U1PWCQzjwVIh69U8cUPJrPgzz5Y7G62E2XPDMyDbwIi5U86ExivZuVr7wJtGG8GopjvJa7IrvQPva7IQNNvMAZFbmCFP67uWvwPLK+Rry/dQm9O0WcvJpKlzxrctG8tchxvEANw7tGkEc8Ma9DuscrpToHfnC8/NwAPeQVtbxR+eG7Z3qiPLloLjznHC27oBKrPA3xCbx5xwe9zk1TvMxbPr3L/Ra8zzEnvY2ecLrVETU8qMEbPLtLtbw5ip+7r0rKPFskcLzFXAe8ajtsPM5417yTGc67d9f8vEsxmbxKQcw8bE0WvEclbbxl0wq9W8gHPWBeZr3VVy87CGzzPN6N5LrCmoK7u2u2PNzmjruBKI+8fnZkunoZertXwsA89wXbvIsfXLze/de756w/vHruDbwZtK48Ow0VOlJqmTx66wU9li27vHbTx7w+3p07Xq//vCOQsrwuVrM8ftcUvbVyqzwkMOe6pBRTu4XeCjwMoU28TMq5vH7a1bw9reG7zHixvNcjgTybmAe8xLV8vPp+TT2ysIq7+IMqO08xbzy74o672Ah2PPEf8DxMtay7V1UTvFOjSjxo9Rq8aLDwu5UoFD367G283w5kPH078jyjfsS6OebMuxCREL3+U8Q8TksMvB5bojx1LsC868vEvPAUnjy3O+68b3ywO11LEL2wORE80FetOmGcAT2jDW88zUUzvIclQbzzYrs8nh+qPN7s0bsCzf47vP6kPCBA3jyXNGW7eTtivFIB3DsI+4E8VVR1u700hDqalnA8NLXGOxoedrxbK0i7yM4MuyHDfrterkW8XPyHPPZtLL0MDSq7M/kHu/cQFDvq+U04qJMWPdrvMr0ahSC6rysWPfAvJzwLhas8+1qzPPkJdTw1PIM8DaWsPK+vLLyNS2i8w1QIPEERMLzqmA287OvwOxPXlb1hT1e8RVgqvA5gD73rKUs8y6XCvIi6U7zlP8S6g9gTvTkwyjyRobA8De0fPUJEEbyjdx281+yIvDM4kbw1WKM7X/+LPHcbyDu5NTQ8+u/aO0/cQDvZ/a68fM4GPNMEVjyS4h+7iajpujT0gr27upQ890n5PKyDEz22quY7DX+FPJvXEjvQyEk7keGlOy3mHrtc6yE7+9ocvObLcLx7djO8wOuPPD0NErw43ws8sH0yPHDSlrwOVIo9dBrvOwpApTxEn5U8bDxMvOQAKzx2NJe8p+GcPFuyp7yotEy7QixevPe4kjyIKbA8HMF+PFWSRL3dST09kEI8vOPXD73isy+8B+iXO+cJVDx9nCi9YozbPPpiE7xh4yy8ElwwPBDorrcrXRS9kZgFPe9tmzysuT88expsvBtgmDvKqr08qBauvNFdR7wPiRE9ilqju4qaAbtOULu700FYPHpOAbwdO8O8rOT7PDb91ztCsrG89/mwvPKK+7u/b5S736FHvEAOzbsNMbg8Qk7FPO5hnTv/a287+IsVvIW+l7w7n2A7lZ0qOw5uxDx0lNG7wT6lvIGCdTxd2am8WxDAPDTuWzub5rk84cwyvTBnZLzkLza81t08vDjWmbzzloS789arvO2ckbxMIn27Xdh8uhQO0jtjd1S8GmiJvJp9MbyjUN27TEB5vDkyYTyO2ku763duOrPQzjyFz5C80OoIPcUglTxX9y28AHIFPNIZ8jwwJRQ8R/UTPQPf/Do4ToS8boMNPIpb5btfUp+7A791u9CKt7vAbzy9g13ivPfm/7yx8f27SON8PCYXBrxXEOM7ObigvPqQCj1zU5I8c/BOPHWINTxNwK87cowevLlhO7rOphS9J28/POR4AzzTz7s85PgePfWpmjxSp3E8FZyGvOkIFTzfp/c8t0IAPbuqJDzHkRW8LlcevJsxj7xImQC8OdgPPWaAorxKwNi74qoGu1RqFjwDi4M8iCKHO6/3DD17pc48h3XKvOcVtTwdywU7RkWHPBFZdrpywTG88zpcvLxy3jzuUFO8Lkm0vMk4hjxquOs777+dOyXLnLzg8l07c1QdvAZpC73ExSy8i1UrvETmArs12SE8uTosPKkpUrsMHJK8+qVhvFGGUT38Cxq8WjtxPK39ATyKKDC9ND6CPE103rzCO447X7k8vOKukjsd9Y+9XX2EvEx+rrz+nM05UyBmvLzhxDstmAe9vmECvDnXVLypE5m8iUtKvLHppbwJuEm86fZZPN8Vvju276+8CV2FvILDNjwwc7A7gTuMvFDkQLwN0PK7f5zKuxzkmbvIjz87ojQZvF93HbstFpa7v+IbvHcYjDpFHXE8BtwGPS+0Pru7dmu8k50BPVqJWDzGX0C895Y0PG5Mm7xIPa88GR2gO8mvV7xHMVU8EVQGu94YA7xkkQS92arsOvK8lTp2KIa8aWy0O9tNYDuxQQA96wWIOkgVsby9AY48ln03t2a5Yrx0T6Q8EnCCvLrMyjx58iu8NZAQPMt0pbzTrVy8tLIGPEs3mzuB0ZA7B73RPL5Rjrzwo/G6R+p3vHHM1zyV1DA7b65gPPUKgrwkoxm9/0abvFYVpbzMjpK8mMT3PNILVbtYE+q8t2ePu1HWgjzZ/DK7E4nvuvK6xby8U4S5qoiku0F8zztK6h27MfOJPDfW4TzjbiA8QRUBvMNZITn0WTa80t1ivGknGz2xgeG7KjkCvd4oAz1h2ua8uc9avAIVDbw+0TM9ipozPEfNVzvylRc9OdHPPNMgbjqTptG7JV6lvNgNHL2bUCI8lxgkO9yBOLwY64A8xucOvbTaPzzMQVM821UjPemwC7y4DU67xwb6usc+GT3USOy6jBt0uzCaGT08fBs7YPxBu3LUmzxjRRo8qjHJvHW3MjydxQ28KhaLvMUu6jvPfXw8FEYFu89oHz0l2TK9xeJtO3OuGjsXkTY8I/bSu5c8KzzXSfc6wlZaO0PcG72AZ487z5jLuwHOCLxhEKi6EeqVOxhpjLuAQcO6j2zePNkorbzexCI9r+vSPN3qQbpwpJO8+UUPvBV/bDyHxXI8wkMKPUXZlDsXM7y6VIRDvI1LSb17Cuk61MLJO/l9gjxHPfG8clCyvK7SODw8vfI8AbaAuyPRLDtI1Ie7U9OEvNUWpjwbqoC84U4DPdNfgjy/TBK8X9XSOlPVnrsIoTS8r79cvBYZv7zguuc8yc43vPCeXrz9o9G7jA8WO0A9AD0KPaY6pZDWPIynWzzCAhE7fOQ5PErg4TqWkCU8mVJju1RDg7zVqo48RPYwu8LfNjxag3i8/D6quzcDnjsu7028HbKnvAEDaTy9+xw9cliVPAegnrzBjxo8khV7u+Qw8Dy4RI284PQSvHVaBr0h4TU8RgFZPOAGlDzAZf08r8h0uiye2jzQTwo9NIkJPf9dpzwVB5Y7hZUkudPSKz19aJq8n/ocvNrjz7o7CRk85SQZPIxOtzzvSFC8H2GhPKt+UjvUn2C8w8GNvKqySD2IEiS8hmLIvPfI8Dya4Y47n/NRPaCWCL128qC8iUsmvA1dvDq4oIs7Ve+SOpUcgbxZonq8lQscPR/1Ab0TZ029mgTjvJzpIzuUMAe9SsI1PXdm3Tx74hE9iJdgu4mUlzyyrUs8SgJZPLx3sDxqvie9wYDmu90XmLtGENI7VD+mPARSkbyCzoa8uVFvPI8evbtipQU8hn23uqXngbzZcem8QtfRvCKVuTz/qmG79ivaO7+vrbxk/JA84iT2u6dTkju8cw09bnebPMSP6jxPVzU8570uvE3YUTxS7IQ6iKX/PIosdj3w91I8V3lhvHic0bu/c0E80J/YOrqzHb20Ig88HVuPPHAtiryky1W7zu46vKeOPLy3sMa8xmSnvIetqrzYfY+8E9EOvJTko7tysCc7C4wMOlziQjzB7RU95Yvru5VZrztzc6M80wfAur/tabo/Ch694Rp1vNwyBzybZVE8lwWjvFk0YDuTqJs7TCGTvOS0H7tmWlO6OYSJvI26Lrz314O8v78rvB2+TzxPUqG8bO0mvACvDrwddPC8aLzDPJUT6bzNu9+7OJNWu/qlrzpsWkw8KWbjvH5iCb2QXFi84Wp9vQtljLwr/3U80uQaOpAWJzxgSKk7PH8EvBwuuzvZ7Su9nGa9PKV42zuY4We8OH4KvRYEOTxXslK9vXFlOzJVKr3sM9o80V+POpYCnTzM/Ag8bWCAvKBfsLv/DPQ8Is23vI+x9LxhdAC9TkcaPDIeFzy/0US7kBBmuxvWIzzN33Y8dmsdPMs1O70Enws8+uuZPAwtPLiuRM+8vDDdOZKA/Lxh3ig9RL+ZvOf7OjzTLYC85nq7PMXpFzxGqjW8/pYLvGUGabxVwIu8UN/VvNSfODpBOzG8pdYhPAQn3LxIk8c8Q/SuPBOi1DurKVe8tR7aOnX2PTxoosK7K24PvQ7Aq7vp4po89WtSvMgJWTy0u8Q8ScajvEo4Ar3Shba7xyxqvHfEC7xiK5G8FMA4O+rGITv2Zj+9C5aPvDYdv7w49Q68/aBXu/46vzwp/yG9QIE+u/IikDsIPn+8Tiq5vNtynrzFf+28rJJ5vAFnODzBJgs8QK9XPJcHgTxliiI70YItPPXfNTwon+A7Dh5nPMhkkbouiwA7v1pNvBwwuzs6PcM76YCrO5G6tTyby+K8US1WvOvKoTtOSX283Hatu6jNy7vEMSq7FFt8vHmNPTxm0Y888vsHPc+ebjpStKa8lVcZvHRt4Dy9igq9Et8BPFqIITwFVUu88sXWOwyAHDp3pRw7t/yovD38lLzigAs8LDT0PKRdL7wZek25orjsO03yvbykpKG8CGCtOhIEvDwZlkk8umsXPIoXpzzpZrm8nVqBPLWpDrwFajc8NN3Tu5jIM7wGdDe8nRR+O8lKs7wAW4+7L5zoO67/DbyjGgM9pIeqPEQ1hLtwdz28l0AmPUZinbw8gA+94aJvPMJH+7vB1pu51PwKPUvp3DxUmvM4Kcg7vO1bljyIuUM7hn/bPOr6CTt1sE28S6jvur4cnbwPtrO7oN67PBwB4TysneM8DAedvHWAAbwp8bq7kD6GPIMJRrzz8WC8I1qKupdGb7yEr1o8L2tTvEJNMjt7qPM7Fh6rPLcxuLx6Ey49rYNIOw8ZFLwtp9a8srb+POxuGrzRroI8T42+u6P6NbxQGA07X5vIPOxwcbzmdIo8G9GUu9LltrsTUEE8QiRBvAO8brx/tOm78RMCPALU0DzJ3hg9B5lzPLCviDz1xRG8HGqXvIL3gTn0QCC8mTzzPO/Kgrz7btu8u4XqOywch7wYHjC8VuevvHuKxbwL7SW8AM02PBSGsbyK3+q8FWK2u0N5mDw8UJK7zDI5O8iOYDxrPT470QiUPFw1PTy4P6a84R0mvf6zyTw+ugY7XPwQvWLy4zy+jsC8NSRCvVHZOL32mSA9kR60PBvzojwf1Ni8afZDPNgsKD3Yxq+8i1qcvMmp+rvLPoO8nfK7OrSlgDwMkKW8EFu0O//uFrwvek68WqS7uwlKrrwktIc8zSUXvV+fvrq6Yhu8q7GVvDuyDz1d47I7bfofu+qGAT1GEzq9RlAJPRvsuLu/T9C7MqEPPdYggrz+54M71hkIPF+WIjsGMs66KRb5u5JrBTyE+c28tKH3PBRPqLwUe9o80lQ2vCbeQryE0+q7dep8O8cfajssJ1A8xBXjvGnaYTyv2fI7XjsRPGrXpDwXLtA8dsCLvBCd1ryAeSy8Mz+DPD12C7ypSrw82yzyPAiIBD0ikT27Ef6JvO+kGD3Mi2W8k0eCvGWquLwsF2I6Ub8iPWIqwLpipDi7AhbaPNPwGrzQ26O8mlQnO54dAbxRUxe9ckwVvJTZXbyN7Qu9jJKCOyNlYTvzoOk7k6alvGFNJ7qoB5A8j9zIOzGP0rzEYBY90MHMPNN8P7tHOUG8VSWcPF/EHrw3vIk8l0yIvLJfg7yt9lO8lhAjO+F9YztYL0G9XsCKOz0G5Dx9w826NJnkO5grA7pp46q8fqkvPFNSRjv2B5Q8S8EOPLIGDr3ONwo8A/HvPIPywDy82de866UxvA/aMDyWKiK8GFGNu+U9uLzmw+k8BLMNvb1C8rv0oqQ8XarmO1OjeDypN808m/YfvWIBubwrNvQ65B/gvEbgobw/ZeU6aaWavIytNTz41787Hgy9PEzJjbvOE2467pypvASJ0zzwQ1I77JNUuknzWD1U6BQ8U4ZOvKr62bx8too7wu9zuvYo67zg9p471z8svR4ZlTzMd0Q9yIHLO4xOhDwe1Z27LV3TvIwjLzx9d/S8U4yPPAqvYL0DWIu8B/bcvFNyp7ziqPs7zq2nu6P1f7xRY5G82tTPvDCjRT0JJuw7epf5POVlbDy+uzK94Oa+PEkCZLz3I2w8H6DjvF3dHT16k0g8UcM6vNGSDrskbg28pwkuPEHVD7zw9B86FI4SveU0ED3TSQ87YcRkulS5rjwkKIE661elu/8C4bsBO467IH0ovIwPQDzUKnk8LWTGu/omxLz05Ys6tPaGvNRcwDxI+h+9eOG1PNyxx7z0FyG8Ujb9vNEcpbzqzTm8vIyiPGHmj7tybXQ809qdOsRaOTy5Bpu8gmhpO87xTTxwxtY82gE7O2SHBbyf7Jg8LLVIPOETPrw+nZ27Wv4XvUgYHj33iNu7ZS6xvDoQND3Jq4U8GEjzuz3mWjtfSeS7Opr1vNUArryEEtW8oVzuPMaXmbzCQgy9vC3nu78PgLx0Fb48PkwDOyB3rjzgC8k8dfGjPGTZ6Tubuma8WO+svCaiZL1bdvm7Eu4xO8RoKru+vVA9+46uuruWcLszJqw725LLvPlchzwJj/a8OP4ZPHbRKryv1x09TACBvL/hJr3/jZS8X14HPU8msbw3O2+7BdllvDEIODyAPRU8cdCCOU75FTyh45G7MCRXvBB1dbtqYFE5H5DIu39+KzwZER66dnSkPPqRFjz5y0c8TGWcvLJh6bvWauQ8oqsSPIoUAzylI9w8r48evFW4jbxhYdm8AcA5ugnZBLxkXPu7CpSdPFU2iTyn5TI8iFKOvAO6hzzE8SK8p13sO5XsRrwTJgo8jVIqvLBlJL1aCCs8pnEmu05hLb3xmcC8RiR2uiOrojtbQmY8GPqYPFdJFbzn05m8QW0EvKlyXjzOzNk7TEkrO6pX3rswoo28caocPIy5pLuc5048qezGPBPSjLvQQqg7ByrIPD9RTrthxEu8kJGZPPQ1BT2t9Oq8r/EAPeLspTyZBZw78IOyO9MTsjyGm9g8chyQPCOLHbwh6PY7RmikPBWrMLwaA607k38evNYEnjydPgy7vaPFPBi22TzRw+Q8npc8vG7forwAN4M7MRSpu/q9w7uFP788+8lWvFMND7oDMW+8X2nOO+zhdLwPyQs87g9WPDZqHLzerJm8few3vK6ggjz3lik6pag2u/1amLtHIXy8CiJYvJGJNjtzmGq8GheSvLiaq7uRKIk8nJosvL9airwICLm7ZT6evO1yRrx3av+7aHmGvJov3rwD25g7zUKJvHULEzxxqK285z7Xu5jskLwYxPI8iYiovFGxCbySyuC8XphPPCSrfDxP6CK8/5YEPArZxrvRMJM88nv9O6UJ27n8S6+8LV8gPFaBq7sctem5EBX8vPZyhrzAs8Q7KpdFPRtcRLuQ0Nk7h5MNPWB/HLxfsGe89txqOxa9Fj35g647Ey/6PAb9vDym5iM9UKFEPICDi7xDedo8zfjVuwRL3DkaKtE8hnXPuoTKxDt4MAM8aI4jvWfJQrxrLtS8hLXNu9qVaT38a4G8wdgnvZlTjzwqVqc8BcRKPO5elDx2N4C8dNLWu/Gkwjx7ig88dT6KO5RBjztjvqA5fLKjvIADsbySF3I91r36uJnBGLwfCBI8XmZPvFJE2jvIyoO8L3XFPH0xdDv/6Ke6gRT7u2SEUry6uMA7guqCPGFbzDvhsqS86XhePBOJfTysAn+8UzzpPGRNO7sfcJc77s+/uwe1nzz0dy67tzS1vFSGZbyIV7q7u6KJvFAHurweSQy84meau6zy1jxOnMs8qLD2O51OzzxtJrA7ydQlPI+OgjtLkgM9rr4+vNkcYLyi8yg6FQEQvF+F3zzH8ac8BlSIvObkH7zMPZG80S9RvHaQpTwC0c07oQ23PKuZsTqb/by8BqctPOyt3TuyNAu8tOeSO9iQBj1U/HE8Qsqiu0STTjxm1jU8O3EBvBN+Cb1NS9C8Nhiuuw== - index: 0 - object: embedding - model: qwen3-embedding:4b - object: list - usage: - prompt_tokens: 68 - total_tokens: 68 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '7066' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - messages: - - content: |- - You are a helpful research assistant powered by haiku.rag, a knowledge base system. - - You have access to a knowledge base of documents. Use your tools to search and answer questions. - - CRITICAL RULES: - 1. For greetings or casual chat: respond directly WITHOUT using any tools - 2. For questions: Use the "ask" tool EXACTLY ONCE - it automatically uses prior conversation context - 3. For searches: Use the "search" tool EXACTLY ONCE - it handles multi-query expansion internally - 4. NEVER call the same tool multiple times for a single user message - 5. NEVER make up information - always use tools to get facts from the knowledge base - - How to decide which tool to use: - - "list_documents" - Use when the user wants to browse or see what documents are available (e.g., "what documents are available?", "show me the documents", "list available docs"). - - "summarize_document" - Use when the user wants an overview or summary of a specific document (e.g., "summarize document X", "what does Y cover?", "give me an overview of Z"). - - "get_document" - Use when the user wants the FULL content of a specific document (e.g., "get the paper about Y", "fetch 2412.00566", "show me the full document"). - - "ask" - Use for CONTENT questions: "What does X say about Y?", "What are the main findings?", "Explain concept Z from the documents". This tool retrieves and synthesizes text from documents. - - "search" - Use when the user explicitly asks to search/find/explore documents. Call it ONCE. After calling search, copy the ENTIRE tool response to your output INCLUDING the content snippets. Do NOT shorten, summarize, or omit any part of the results. - - "analyze" - Use for COMPUTATIONAL tasks. IMPORTANT: Do NOT pass the user's question directly. Instead, write a specific task instruction describing what to compute. - - IMPORTANT - Choosing between "ask" and "analyze": - - "ask" answers WHAT questions about content (retrieval + synthesis) - - "analyze" answers HOW MANY/HOW MUCH questions requiring computation - - CRITICAL - When using "analyze", reformulate the user's question into a specific task: - - User: "How many documents are there?" → task="Count the total number of documents using list_documents()" - - User: "What is the total revenue across all reports?" → task="Search for revenue figures in all documents, extract the numeric values, and calculate the sum" - - User: "How many documents discuss climate change?" → task="Search for 'climate change' and count the number of unique documents returned" - - User: "List all the dates mentioned" → task="Search across documents, extract all date patterns, and return a deduplicated list" - - IMPORTANT - When user mentions a document in search/ask: - - If user says "search in ", "find in ", "answer from ", or " in ": - - Extract the TOPIC as `query`/`question` - - Extract the DOCUMENT NAME as `document_name` - - Examples for search: - - "search for embeddings in the ML paper" → query="embeddings", document_name="ML paper" - - "find transformer architecture in 2412.00566" → query="transformer architecture", document_name="2412.00566" - - Examples for ask: - - "what does the ML paper say about embeddings?" → question="what are the embedding methods?", document_name="ML paper" - - "answer from 2412.00566 about model training" → question="how is the model trained?", document_name="2412.00566" - - Be friendly and conversational. When you use the "ask" tool, summarize the key findings for the user. - role: system - - content: How many documents are in the database? - role: user - model: gpt-oss - reasoning_effort: low - stream: false - tool_choice: auto - tools: - - function: - description: |- - Search the knowledge base for relevant documents. - - Use this when you need to find documents or explore the knowledge base. - Results are displayed to the user - just list the titles found. - name: search - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document name/title to search within - limit: - anyOf: - - type: integer - - type: 'null' - default: null - description: 'Number of results to return (default: 5)' - query: - description: The search query (what to search for) - type: string - required: - - query - type: object - type: function - - function: - description: |- - Answer a specific question using the knowledge base. - - Use this for direct questions that need a focused answer with citations. - Uses a research graph for planning, searching, and synthesis. - name: ask - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document name/title to search within (e.g., "tbmed593", "army manual") - question: - description: The question to answer - type: string - required: - - question - type: object - type: function - - function: - description: |- - List available documents in the knowledge base. - - Use this when the user wants to browse or see what documents are available. - name: list_documents - parameters: - additionalProperties: false - properties: - page: - default: 1 - description: 'Page number (default: 1, 50 documents per page)' - type: integer - type: object - type: function - - function: - description: |- - Retrieve a specific document by title or URI. - - Use this when the user wants to fetch/get/retrieve a specific document. - name: get_document - parameters: - additionalProperties: false - properties: - query: - description: The document title or URI to look up - type: string - required: - - query - type: object - strict: true - type: function - - function: - description: |- - Generate a summary of a specific document. - - Use this when the user wants an overview or summary of a document's content. - name: summarize_document - parameters: - additionalProperties: false - properties: - query: - description: The document title or URI to summarize - type: string - required: - - query - type: object - strict: true - type: function - - function: - description: |- - Execute a computational task via code execution. - - IMPORTANT: Provide a clear, specific task instruction that describes - exactly what to compute. Do NOT pass the user's question directly. - - Examples of good task instructions: - - "Count the total number of documents using list_documents()" - - "Search for 'Python' and return the titles of all matching documents" - - "Calculate the average word count across all documents" - name: analyze - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document to focus on - task: - description: A specific, actionable instruction describing what to compute - type: string - required: - - task - type: object - type: function - uri: http://localhost:11434/v1/chat/completions - response: - headers: - content-length: - - '539' - content-type: - - application/json - parsed_body: - choices: - - finish_reason: tool_calls - index: 0 - message: - content: '' - reasoning: Need to count total documents. Use analyze tool. - role: assistant - tool_calls: - - function: - arguments: '{"task":"Count the total number of documents using list_documents()"}' - name: analyze - id: call_w7qynecj - index: 0 - type: function - created: 1769785117 - id: chatcmpl-187 - model: gpt-oss - object: chat.completion - system_fingerprint: fp_ollama - usage: - completion_tokens: 43 - prompt_tokens: 1373 - total_tokens: 1416 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '8337' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - messages: - - content: |- - You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code. - - IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do. - - CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly: - - search("query") ✓ CORRECT - - from haiku.rag import search ✗ WRONG - will fail - - You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed): - - ## Available Functions - - ### search(query, limit=10) -> list[dict] - 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 - - ### 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 - - ### get_document(id_or_title) -> str | None - 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. - - ### get_docling_document(id_or_title) -> DoclingDocument | None - Get the structured DoclingDocument object for advanced analysis. - Returns a DoclingDocument object, or None if not found. - See "DoclingDocument API" section below for how to use it. - - ### llm(prompt) -> str - Call an LLM directly with the given prompt. Returns the response as a string. - Use this for classification, summarization, extraction, or any task where you - already have the content and just need LLM reasoning. - - ## Pre-loaded Documents Variable - - If documents were pre-loaded for this session, a `documents` variable is available: - ```python - # documents is a list of dicts with keys: id, title, uri, content - for doc in documents: - print(doc['title'], len(doc['content'])) - ``` - Check if it exists with: `if 'documents' in dir(): ...` - - ## Standard Library Modules - You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing - - ## Strategy Guide - - 1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar). - 2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content. - 3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find. - 4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with. - 5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections. - 6. **Use llm() for Classification/Extraction**: When you need to classify, summarize, or extract structured data from content you already have, use llm(). - 7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation. - - ## DoclingDocument API - - When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis. - - ### Properties - - `doc.texts` - List of all text items (paragraphs, headings, etc.) - - `doc.tables` - List of all tables - - `doc.pictures` - List of all pictures/figures - - `doc.name` - Document name - - ### Methods - - `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level - Returns tuples of (item, level) where level is nesting depth - - `doc.export_to_markdown()` - Export entire document as markdown string - - ### Text Item Properties - - `item.text` - The text content - - `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc. - - `item.prov` - Provenance (page numbers, bounding boxes) - - ### Table Access - - `table.data.num_rows`, `table.data.num_cols` - Dimensions - - `table.data.table_cells` - List of TableCell objects - - `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx` - - ### Example Usage - ```python - doc = get_docling_document("My Document") - - # Get all headings - headings = [t.text for t in doc.texts if "HEADER" in str(t.label)] - - # Iterate with structure - for item, level in doc.iterate_items(): - print(" " * level + item.text[:50]) - - # Extract table data - for table in doc.tables: - for cell in table.data.table_cells: - print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}") - ``` - - ## Example Patterns - - ### Counting documents matching a condition - ```python - docs = list_documents(limit=100) - count = 0 - for doc in docs: - content = get_document(doc['id']) - if content and 'keyword' in content.lower(): - count += 1 - print(f"Found in: {doc['title']}") - print(f"Total: {count}") - ``` - - ### Aggregating data across documents - ```python - import re - numbers = [] - results = search("financial data", limit=20) - for r in results: - matches = re.findall(r'\$([\d,]+)', r['content']) - for m in matches: - numbers.append(int(m.replace(',', ''))) - print(f"Average: ${sum(numbers)/len(numbers):,.2f}") - ``` - - ### Using llm() for classification - ```python - # Get document content - content = get_document("Q1 Report") - # Use llm() to classify sentiment - sentiment = llm(f"Classify the sentiment as positive, negative, or mixed: {content}") - print(sentiment) - ``` - - ## Workflow - - 1. **ALWAYS start by using execute_code** to explore the knowledge base - 2. Run multiple code blocks as needed to gather information - 3. After collecting data, provide your final answer - - ## Output Format - - CRITICAL: Your final response MUST be valid JSON matching this exact schema: - ```json - {"answer": "Your complete answer here as a string"} - ``` - - The `answer` field should contain: - 1. A clear answer to the user's question - 2. Key findings from your analysis - 3. References to specific documents/chunks that informed your answer - - Do NOT return arbitrary JSON structures. Always use the exact format: {"answer": "..."} - - CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first. - role: system - - content: Count the total number of documents using list_documents() - role: user - model: gpt-oss - reasoning_effort: low - stream: false - tool_choice: auto - tools: - - function: - description: |- - Execute Python code in the sandboxed environment. - - The code has access to haiku.rag functions (search, list_documents, - get_document, get_docling_document, ask) and safe standard library - modules (json, re, collections, math, statistics, itertools, - functools, datetime, typing). - - Use print() to output results. Variables persist between executions. - - Structured result with success status, stdout, and stderr. - - name: execute_code - parameters: - additionalProperties: false - properties: - code: - description: Python code to execute. - type: string - required: - - code - type: object - strict: true - type: function - - function: - description: Result from RLM agent execution. - name: final_result - parameters: - $defs: - CodeExecution: - additionalProperties: false - description: Result of executing a code block in the RLM sandbox. - properties: - code: - description: The Python code that was executed - type: string - stderr: - description: Standard error captured during execution - type: string - stdout: - description: Standard output captured during execution - type: string - success: - description: Whether execution completed without error - type: boolean - required: - - code - - stdout - - stderr - - success - type: object - additionalProperties: false - properties: - answer: - description: The answer to the user's question - type: string - code_executions: - description: History of code executions during the RLM session - items: - $ref: '#/$defs/CodeExecution' - type: array - required: - - answer - type: object - type: function - uri: http://localhost:11434/v1/chat/completions - response: - headers: - content-length: - - '527' - content-type: - - application/json - parsed_body: - choices: - - finish_reason: tool_calls - index: 0 - message: - content: '' - reasoning: Need to run list_documents and count. - role: assistant - tool_calls: - - function: - arguments: '{"code":"docs = list_documents(limit=1000)\nprint(len(docs))"}' - name: execute_code - id: call_quotbvly - index: 0 - type: function - created: 1769785119 - id: chatcmpl-208 - model: gpt-oss - object: chat.completion - system_fingerprint: fp_ollama - usage: - completion_tokens: 46 - prompt_tokens: 1759 - total_tokens: 1805 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '8780' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - messages: - - content: |- - You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code. - - IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do. - - CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly: - - search("query") ✓ CORRECT - - from haiku.rag import search ✗ WRONG - will fail - - You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed): - - ## Available Functions - - ### search(query, limit=10) -> list[dict] - 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 - - ### 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 - - ### get_document(id_or_title) -> str | None - 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. - - ### get_docling_document(id_or_title) -> DoclingDocument | None - Get the structured DoclingDocument object for advanced analysis. - Returns a DoclingDocument object, or None if not found. - See "DoclingDocument API" section below for how to use it. - - ### llm(prompt) -> str - Call an LLM directly with the given prompt. Returns the response as a string. - Use this for classification, summarization, extraction, or any task where you - already have the content and just need LLM reasoning. - - ## Pre-loaded Documents Variable - - If documents were pre-loaded for this session, a `documents` variable is available: - ```python - # documents is a list of dicts with keys: id, title, uri, content - for doc in documents: - print(doc['title'], len(doc['content'])) - ``` - Check if it exists with: `if 'documents' in dir(): ...` - - ## Standard Library Modules - You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing - - ## Strategy Guide - - 1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar). - 2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content. - 3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find. - 4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with. - 5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections. - 6. **Use llm() for Classification/Extraction**: When you need to classify, summarize, or extract structured data from content you already have, use llm(). - 7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation. - - ## DoclingDocument API - - When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis. - - ### Properties - - `doc.texts` - List of all text items (paragraphs, headings, etc.) - - `doc.tables` - List of all tables - - `doc.pictures` - List of all pictures/figures - - `doc.name` - Document name - - ### Methods - - `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level - Returns tuples of (item, level) where level is nesting depth - - `doc.export_to_markdown()` - Export entire document as markdown string - - ### Text Item Properties - - `item.text` - The text content - - `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc. - - `item.prov` - Provenance (page numbers, bounding boxes) - - ### Table Access - - `table.data.num_rows`, `table.data.num_cols` - Dimensions - - `table.data.table_cells` - List of TableCell objects - - `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx` - - ### Example Usage - ```python - doc = get_docling_document("My Document") - - # Get all headings - headings = [t.text for t in doc.texts if "HEADER" in str(t.label)] - - # Iterate with structure - for item, level in doc.iterate_items(): - print(" " * level + item.text[:50]) - - # Extract table data - for table in doc.tables: - for cell in table.data.table_cells: - print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}") - ``` - - ## Example Patterns - - ### Counting documents matching a condition - ```python - docs = list_documents(limit=100) - count = 0 - for doc in docs: - content = get_document(doc['id']) - if content and 'keyword' in content.lower(): - count += 1 - print(f"Found in: {doc['title']}") - print(f"Total: {count}") - ``` - - ### Aggregating data across documents - ```python - import re - numbers = [] - results = search("financial data", limit=20) - for r in results: - matches = re.findall(r'\$([\d,]+)', r['content']) - for m in matches: - numbers.append(int(m.replace(',', ''))) - print(f"Average: ${sum(numbers)/len(numbers):,.2f}") - ``` - - ### Using llm() for classification - ```python - # Get document content - content = get_document("Q1 Report") - # Use llm() to classify sentiment - sentiment = llm(f"Classify the sentiment as positive, negative, or mixed: {content}") - print(sentiment) - ``` - - ## Workflow - - 1. **ALWAYS start by using execute_code** to explore the knowledge base - 2. Run multiple code blocks as needed to gather information - 3. After collecting data, provide your final answer - - ## Output Format - - CRITICAL: Your final response MUST be valid JSON matching this exact schema: - ```json - {"answer": "Your complete answer here as a string"} - ``` - - The `answer` field should contain: - 1. A clear answer to the user's question - 2. Key findings from your analysis - 3. References to specific documents/chunks that informed your answer - - Do NOT return arbitrary JSON structures. Always use the exact format: {"answer": "..."} - - CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first. - role: system - - content: Count the total number of documents using list_documents() - role: user - - content: |- - - Need to run list_documents and count. - - role: assistant - tool_calls: - - function: - arguments: '{"code":"docs = list_documents(limit=1000)\nprint(len(docs))"}' - name: execute_code - id: call_quotbvly - type: function - - content: '{"code":"docs = list_documents(limit=1000)\nprint(len(docs))","stdout":"3\n","stderr":"","success":true}' - role: tool - tool_call_id: call_quotbvly - model: gpt-oss - reasoning_effort: low - stream: false - tool_choice: auto - tools: - - function: - description: |- - Execute Python code in the sandboxed environment. - - The code has access to haiku.rag functions (search, list_documents, - get_document, get_docling_document, ask) and safe standard library - modules (json, re, collections, math, statistics, itertools, - functools, datetime, typing). - - Use print() to output results. Variables persist between executions. - - Structured result with success status, stdout, and stderr. - - name: execute_code - parameters: - additionalProperties: false - properties: - code: - description: Python code to execute. - type: string - required: - - code - type: object - strict: true - type: function - - function: - description: Result from RLM agent execution. - name: final_result - parameters: - $defs: - CodeExecution: - additionalProperties: false - description: Result of executing a code block in the RLM sandbox. - properties: - code: - description: The Python code that was executed - type: string - stderr: - description: Standard error captured during execution - type: string - stdout: - description: Standard output captured during execution - type: string - success: - description: Whether execution completed without error - type: boolean - required: - - code - - stdout - - stderr - - success - type: object - additionalProperties: false - properties: - answer: - description: The answer to the user's question - type: string - code_executions: - description: History of code executions during the RLM session - items: - $ref: '#/$defs/CodeExecution' - type: array - required: - - answer - type: object - type: function - uri: http://localhost:11434/v1/chat/completions - response: - headers: - content-length: - - '347' - content-type: - - application/json - parsed_body: - choices: - - finish_reason: stop - index: 0 - message: - content: '{"answer":"There are 3 documents in the knowledge base."}' - role: assistant - created: 1769785120 - id: chatcmpl-514 - model: gpt-oss - object: chat.completion - system_fingerprint: fp_ollama - usage: - completion_tokens: 21 - prompt_tokens: 1852 - total_tokens: 1873 - status: - code: 200 - message: OK -- request: - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate, zstd - connection: - - keep-alive - content-length: - - '7582' - content-type: - - application/json - host: - - localhost:11434 - method: POST - parsed_body: - messages: - - content: |- - You are a helpful research assistant powered by haiku.rag, a knowledge base system. - - You have access to a knowledge base of documents. Use your tools to search and answer questions. - - CRITICAL RULES: - 1. For greetings or casual chat: respond directly WITHOUT using any tools - 2. For questions: Use the "ask" tool EXACTLY ONCE - it automatically uses prior conversation context - 3. For searches: Use the "search" tool EXACTLY ONCE - it handles multi-query expansion internally - 4. NEVER call the same tool multiple times for a single user message - 5. NEVER make up information - always use tools to get facts from the knowledge base - - How to decide which tool to use: - - "list_documents" - Use when the user wants to browse or see what documents are available (e.g., "what documents are available?", "show me the documents", "list available docs"). - - "summarize_document" - Use when the user wants an overview or summary of a specific document (e.g., "summarize document X", "what does Y cover?", "give me an overview of Z"). - - "get_document" - Use when the user wants the FULL content of a specific document (e.g., "get the paper about Y", "fetch 2412.00566", "show me the full document"). - - "ask" - Use for CONTENT questions: "What does X say about Y?", "What are the main findings?", "Explain concept Z from the documents". This tool retrieves and synthesizes text from documents. - - "search" - Use when the user explicitly asks to search/find/explore documents. Call it ONCE. After calling search, copy the ENTIRE tool response to your output INCLUDING the content snippets. Do NOT shorten, summarize, or omit any part of the results. - - "analyze" - Use for COMPUTATIONAL tasks. IMPORTANT: Do NOT pass the user's question directly. Instead, write a specific task instruction describing what to compute. - - IMPORTANT - Choosing between "ask" and "analyze": - - "ask" answers WHAT questions about content (retrieval + synthesis) - - "analyze" answers HOW MANY/HOW MUCH questions requiring computation - - CRITICAL - When using "analyze", reformulate the user's question into a specific task: - - User: "How many documents are there?" → task="Count the total number of documents using list_documents()" - - User: "What is the total revenue across all reports?" → task="Search for revenue figures in all documents, extract the numeric values, and calculate the sum" - - User: "How many documents discuss climate change?" → task="Search for 'climate change' and count the number of unique documents returned" - - User: "List all the dates mentioned" → task="Search across documents, extract all date patterns, and return a deduplicated list" - - IMPORTANT - When user mentions a document in search/ask: - - If user says "search in ", "find in ", "answer from ", or " in ": - - Extract the TOPIC as `query`/`question` - - Extract the DOCUMENT NAME as `document_name` - - Examples for search: - - "search for embeddings in the ML paper" → query="embeddings", document_name="ML paper" - - "find transformer architecture in 2412.00566" → query="transformer architecture", document_name="2412.00566" - - Examples for ask: - - "what does the ML paper say about embeddings?" → question="what are the embedding methods?", document_name="ML paper" - - "answer from 2412.00566 about model training" → question="how is the model trained?", document_name="2412.00566" - - Be friendly and conversational. When you use the "ask" tool, summarize the key findings for the user. - role: system - - content: How many documents are in the database? - role: user - - content: |- - - Need to count total documents. Use analyze tool. - - role: assistant - tool_calls: - - function: - arguments: '{"task":"Count the total number of documents using list_documents()"}' - name: analyze - id: call_w7qynecj - type: function - - content: | - There are 3 documents in the knowledge base. - - --- - **Code executed:** - - ```python - # Execution 1 - docs = list_documents(limit=1000) - print(len(docs)) - ``` - Output: - ``` - 3 - ``` - role: tool - tool_call_id: call_w7qynecj - model: gpt-oss - reasoning_effort: low - stream: false - tool_choice: auto - tools: - - function: - description: |- - Search the knowledge base for relevant documents. - - Use this when you need to find documents or explore the knowledge base. - Results are displayed to the user - just list the titles found. - name: search - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document name/title to search within - limit: - anyOf: - - type: integer - - type: 'null' - default: null - description: 'Number of results to return (default: 5)' - query: - description: The search query (what to search for) - type: string - required: - - query - type: object - type: function - - function: - description: |- - Answer a specific question using the knowledge base. - - Use this for direct questions that need a focused answer with citations. - Uses a research graph for planning, searching, and synthesis. - name: ask - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document name/title to search within (e.g., "tbmed593", "army manual") - question: - description: The question to answer - type: string - required: - - question - type: object - type: function - - function: - description: |- - List available documents in the knowledge base. - - Use this when the user wants to browse or see what documents are available. - name: list_documents - parameters: - additionalProperties: false - properties: - page: - default: 1 - description: 'Page number (default: 1, 50 documents per page)' - type: integer - type: object - type: function - - function: - description: |- - Retrieve a specific document by title or URI. - - Use this when the user wants to fetch/get/retrieve a specific document. - name: get_document - parameters: - additionalProperties: false - properties: - query: - description: The document title or URI to look up - type: string - required: - - query - type: object - strict: true - type: function - - function: - description: |- - Generate a summary of a specific document. - - Use this when the user wants an overview or summary of a document's content. - name: summarize_document - parameters: - additionalProperties: false - properties: - query: - description: The document title or URI to summarize - type: string - required: - - query - type: object - strict: true - type: function - - function: - description: |- - Execute a computational task via code execution. - - IMPORTANT: Provide a clear, specific task instruction that describes - exactly what to compute. Do NOT pass the user's question directly. - - Examples of good task instructions: - - "Count the total number of documents using list_documents()" - - "Search for 'Python' and return the titles of all matching documents" - - "Calculate the average word count across all documents" - name: analyze - parameters: - additionalProperties: false - properties: - document_name: - anyOf: - - type: string - - type: 'null' - default: null - description: Optional document to focus on - task: - description: A specific, actionable instruction describing what to compute - type: string - required: - - task - type: object - type: function - uri: http://localhost:11434/v1/chat/completions - response: - headers: - content-length: - - '332' - content-type: - - application/json - parsed_body: - choices: - - finish_reason: stop - index: 0 - message: - content: There are **three** documents in the database. - role: assistant - created: 1769785121 - id: chatcmpl-668 - model: gpt-oss - object: chat.completion - system_fingerprint: fp_ollama - usage: - completion_tokens: 14 - prompt_tokens: 1481 - total_tokens: 1495 - status: - code: 200 - message: OK -version: 1