haiku.rag 0.9.2__py3-none-any.whl → 0.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of haiku.rag might be problematic. Click here for more details.

Files changed (34) hide show
  1. haiku/rag/app.py +50 -14
  2. haiku/rag/cli.py +16 -4
  3. haiku/rag/client.py +3 -5
  4. haiku/rag/reranking/mxbai.py +1 -1
  5. haiku/rag/research/__init__.py +10 -27
  6. haiku/rag/research/common.py +53 -0
  7. haiku/rag/research/dependencies.py +5 -3
  8. haiku/rag/research/graph.py +29 -0
  9. haiku/rag/research/models.py +70 -0
  10. haiku/rag/research/nodes/evaluate.py +80 -0
  11. haiku/rag/research/nodes/plan.py +63 -0
  12. haiku/rag/research/nodes/search.py +91 -0
  13. haiku/rag/research/nodes/synthesize.py +51 -0
  14. haiku/rag/research/prompts.py +97 -113
  15. haiku/rag/research/state.py +25 -0
  16. haiku/rag/store/engine.py +42 -17
  17. haiku/rag/store/models/chunk.py +1 -0
  18. haiku/rag/store/repositories/chunk.py +60 -39
  19. haiku/rag/store/repositories/document.py +2 -2
  20. haiku/rag/store/repositories/settings.py +12 -5
  21. haiku/rag/store/upgrades/__init__.py +60 -1
  22. haiku/rag/store/upgrades/v0_9_3.py +112 -0
  23. {haiku_rag-0.9.2.dist-info → haiku_rag-0.10.0.dist-info}/METADATA +37 -1
  24. haiku_rag-0.10.0.dist-info/RECORD +53 -0
  25. haiku/rag/research/base.py +0 -130
  26. haiku/rag/research/evaluation_agent.py +0 -42
  27. haiku/rag/research/orchestrator.py +0 -300
  28. haiku/rag/research/presearch_agent.py +0 -34
  29. haiku/rag/research/search_agent.py +0 -65
  30. haiku/rag/research/synthesis_agent.py +0 -40
  31. haiku_rag-0.9.2.dist-info/RECORD +0 -50
  32. {haiku_rag-0.9.2.dist-info → haiku_rag-0.10.0.dist-info}/WHEEL +0 -0
  33. {haiku_rag-0.9.2.dist-info → haiku_rag-0.10.0.dist-info}/entry_points.txt +0 -0
  34. {haiku_rag-0.9.2.dist-info → haiku_rag-0.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,300 +0,0 @@
1
- from typing import Any
2
-
3
- from pydantic import BaseModel, Field
4
- from pydantic_ai.format_prompt import format_as_xml
5
- from pydantic_ai.run import AgentRunResult
6
- from rich.console import Console
7
-
8
- from haiku.rag.config import Config
9
- from haiku.rag.research.base import BaseResearchAgent
10
- from haiku.rag.research.dependencies import ResearchContext, ResearchDependencies
11
- from haiku.rag.research.evaluation_agent import (
12
- AnalysisEvaluationAgent,
13
- EvaluationResult,
14
- )
15
- from haiku.rag.research.presearch_agent import PresearchSurveyAgent
16
- from haiku.rag.research.prompts import ORCHESTRATOR_PROMPT
17
- from haiku.rag.research.search_agent import SearchSpecialistAgent
18
- from haiku.rag.research.synthesis_agent import ResearchReport, SynthesisAgent
19
-
20
-
21
- class ResearchPlan(BaseModel):
22
- """Research execution plan."""
23
-
24
- main_question: str = Field(description="The main research question")
25
- sub_questions: list[str] = Field(
26
- description="Decomposed sub-questions to investigate (max 3)", max_length=3
27
- )
28
-
29
-
30
- class ResearchOrchestrator(BaseResearchAgent[ResearchPlan]):
31
- """Orchestrator agent that coordinates the research workflow."""
32
-
33
- def __init__(
34
- self, provider: str | None = Config.RESEARCH_PROVIDER, model: str | None = None
35
- ):
36
- # Use provided values or fall back to config defaults
37
- provider = provider or Config.RESEARCH_PROVIDER or Config.QA_PROVIDER
38
- model = model or Config.RESEARCH_MODEL or Config.QA_MODEL
39
-
40
- super().__init__(provider, model, output_type=ResearchPlan)
41
-
42
- self.search_agent: SearchSpecialistAgent = SearchSpecialistAgent(
43
- provider, model
44
- )
45
- self.presearch_agent: PresearchSurveyAgent = PresearchSurveyAgent(
46
- provider, model
47
- )
48
- self.evaluation_agent: AnalysisEvaluationAgent = AnalysisEvaluationAgent(
49
- provider, model
50
- )
51
- self.synthesis_agent: SynthesisAgent = SynthesisAgent(provider, model)
52
-
53
- def get_system_prompt(self) -> str:
54
- return ORCHESTRATOR_PROMPT
55
-
56
- def register_tools(self) -> None:
57
- """Register orchestration tools."""
58
- # Tools are no longer needed - orchestrator directly calls agents
59
- pass
60
-
61
- def _format_context_for_prompt(self, context: ResearchContext) -> str:
62
- """Format the research context as XML for inclusion in prompts."""
63
-
64
- context_data = {
65
- "original_question": context.original_question,
66
- "unanswered_questions": context.sub_questions,
67
- "qa_responses": [
68
- {
69
- "question": qa.query,
70
- "answer": qa.answer,
71
- "context_snippets": qa.context,
72
- "sources": qa.sources,
73
- }
74
- for qa in context.qa_responses
75
- ],
76
- "insights": context.insights,
77
- "gaps": context.gaps,
78
- }
79
- return format_as_xml(context_data, root_tag="research_context")
80
-
81
- async def conduct_research(
82
- self,
83
- question: str,
84
- client: Any,
85
- max_iterations: int = 3,
86
- confidence_threshold: float = 0.8,
87
- verbose: bool = False,
88
- console: Console | None = None,
89
- ) -> ResearchReport:
90
- """Conduct comprehensive research on a question.
91
-
92
- Args:
93
- question: The research question to investigate
94
- client: HaikuRAG client for document operations
95
- max_iterations: Maximum number of search-analyze-clarify cycles
96
- confidence_threshold: Minimum confidence level to stop research (0-1)
97
- verbose: If True, print progress and intermediate results
98
- console: Optional Rich console for output
99
-
100
- Returns:
101
- ResearchReport with comprehensive findings
102
- """
103
-
104
- # Initialize context
105
- context = ResearchContext(original_question=question)
106
- deps = ResearchDependencies(client=client, context=context)
107
-
108
- # Use provided console or create a new one
109
- console = console or Console() if verbose else None
110
-
111
- # Run a simple presearch survey to summarize KB context
112
- if console:
113
- console.print(
114
- "\n[bold cyan]🔎 Presearch: summarizing KB context...[/bold cyan]"
115
- )
116
-
117
- presearch_result = await self.presearch_agent.run(question, deps=deps)
118
-
119
- # Create initial research plan
120
- if console:
121
- console.print("\n[bold cyan]📋 Creating research plan...[/bold cyan]")
122
-
123
- # Include the presearch summary to ground the planning step.
124
-
125
- planning_context_xml = format_as_xml(
126
- {
127
- "original_question": question,
128
- "presearch_summary": presearch_result.output or "",
129
- },
130
- root_tag="planning_context",
131
- )
132
-
133
- plan_prompt = (
134
- "Create a research plan for the main question below.\n\n"
135
- f"Main question: {question}\n\n"
136
- "Use this brief presearch summary to inform the plan. Focus the 3 sub-questions "
137
- "on the most important aspects not already obvious from the current KB context.\n\n"
138
- f"{planning_context_xml}"
139
- )
140
-
141
- plan_result: AgentRunResult[ResearchPlan] = await self.run(
142
- plan_prompt, deps=deps
143
- )
144
-
145
- context.sub_questions = plan_result.output.sub_questions
146
-
147
- if console:
148
- console.print("\n[bold green]✅ Research Plan Created:[/bold green]")
149
- console.print(
150
- f" [bold]Main Question:[/bold] {plan_result.output.main_question}"
151
- )
152
- console.print(" [bold]Sub-questions:[/bold]")
153
- for i, sq in enumerate(plan_result.output.sub_questions, 1):
154
- console.print(f" {i}. {sq}")
155
- console.print()
156
-
157
- # Execute research iterations
158
- for iteration in range(max_iterations):
159
- if console:
160
- console.rule(
161
- f"[bold yellow]🔄 Iteration {iteration + 1}/{max_iterations}[/bold yellow]"
162
- )
163
-
164
- # Check if we have questions to search
165
- if not context.sub_questions:
166
- # No more questions to explore
167
- if console:
168
- console.print(
169
- "[yellow]No more questions to explore. Concluding research.[/yellow]"
170
- )
171
- break
172
-
173
- # Use current sub-questions for this iteration
174
- questions_to_search = context.sub_questions
175
-
176
- # Search phase - answer all questions in this iteration
177
- if console:
178
- console.print(
179
- f"\n[bold cyan]🔍 Searching & Answering {len(questions_to_search)} questions:[/bold cyan]"
180
- )
181
- for i, q in enumerate(questions_to_search, 1):
182
- console.print(f" {i}. {q}")
183
-
184
- # Run searches for all questions and remove answered ones
185
- answered_questions = []
186
- for search_question in questions_to_search:
187
- try:
188
- await self.search_agent.run(search_question, deps=deps)
189
- except Exception as e: # pragma: no cover - defensive
190
- if console:
191
- console.print(
192
- f"\n [red]×[/red] Omitting failed question: {search_question} ({e})"
193
- )
194
- finally:
195
- answered_questions.append(search_question)
196
-
197
- if console and context.qa_responses:
198
- # Show the last QA response (which should be for this question)
199
- latest_qa = context.qa_responses[-1]
200
- answer_preview = (
201
- latest_qa.answer[:150] + "..."
202
- if len(latest_qa.answer) > 150
203
- else latest_qa.answer
204
- )
205
- console.print(
206
- f"\n [green]✓[/green] {search_question[:50]}..."
207
- if len(search_question) > 50
208
- else f"\n [green]✓[/green] {search_question}"
209
- )
210
- console.print(f" {answer_preview}")
211
-
212
- # Remove answered questions from the list
213
- for question in answered_questions:
214
- if question in context.sub_questions:
215
- context.sub_questions.remove(question)
216
-
217
- # Analysis and Evaluation phase
218
- if console:
219
- console.print(
220
- "\n[bold cyan]📊 Analyzing and evaluating research progress...[/bold cyan]"
221
- )
222
-
223
- # Format context for the evaluation agent
224
- context_xml = self._format_context_for_prompt(context)
225
- evaluation_prompt = f"""Analyze all gathered information and evaluate the completeness of research.
226
-
227
- {context_xml}
228
-
229
- Evaluate the research progress for the original question and identify any remaining gaps."""
230
-
231
- evaluation_result = await self.evaluation_agent.run(
232
- evaluation_prompt,
233
- deps=deps,
234
- )
235
-
236
- if console and evaluation_result.output:
237
- output = evaluation_result.output
238
- if output.key_insights:
239
- console.print(" [bold]Key insights:[/bold]")
240
- for insight in output.key_insights:
241
- console.print(f" • {insight}")
242
- console.print(
243
- f" Confidence: [yellow]{output.confidence_score:.1%}[/yellow]"
244
- )
245
- status = (
246
- "[green]Yes[/green]" if output.is_sufficient else "[red]No[/red]"
247
- )
248
- console.print(f" Sufficient: {status}")
249
-
250
- # Store insights
251
- for insight in evaluation_result.output.key_insights:
252
- context.add_insight(insight)
253
-
254
- # Add new questions to the sub-questions list
255
- for new_q in evaluation_result.output.new_questions:
256
- if new_q not in context.sub_questions:
257
- context.sub_questions.append(new_q)
258
-
259
- # Check if research is sufficient
260
- if self._should_stop_research(evaluation_result, confidence_threshold):
261
- if console:
262
- console.print(
263
- f"\n[bold green]✅ Stopping research:[/bold green] {evaluation_result.output.reasoning}"
264
- )
265
- break
266
-
267
- # Generate final report
268
- if console:
269
- console.print(
270
- "\n[bold cyan]📝 Generating final research report...[/bold cyan]"
271
- )
272
-
273
- # Format context for the synthesis agent
274
- final_context_xml = self._format_context_for_prompt(context)
275
- synthesis_prompt = f"""Generate a comprehensive research report based on all gathered information.
276
-
277
- {final_context_xml}
278
-
279
- Create a detailed report that synthesizes all findings into a coherent response."""
280
-
281
- report_result: AgentRunResult[ResearchReport] = await self.synthesis_agent.run(
282
- synthesis_prompt, deps=deps
283
- )
284
-
285
- if console:
286
- console.print("[bold green]✅ Research complete![/bold green]")
287
-
288
- return report_result.output
289
-
290
- def _should_stop_research(
291
- self,
292
- evaluation_result: AgentRunResult[EvaluationResult],
293
- confidence_threshold: float,
294
- ) -> bool:
295
- """Determine if research should stop based on evaluation."""
296
-
297
- result = evaluation_result.output
298
-
299
- # Stop if the agent indicates sufficient information AND confidence exceeds threshold
300
- return result.is_sufficient and result.confidence_score >= confidence_threshold
@@ -1,34 +0,0 @@
1
- from pydantic_ai import RunContext
2
- from pydantic_ai.run import AgentRunResult
3
-
4
- from haiku.rag.research.base import BaseResearchAgent
5
- from haiku.rag.research.dependencies import ResearchDependencies
6
- from haiku.rag.research.prompts import PRESEARCH_AGENT_PROMPT
7
-
8
-
9
- class PresearchSurveyAgent(BaseResearchAgent[str]):
10
- """Presearch agent that gathers verbatim context and summarizes it."""
11
-
12
- def __init__(self, provider: str, model: str) -> None:
13
- super().__init__(provider, model, str)
14
-
15
- async def run(
16
- self, prompt: str, deps: ResearchDependencies, **kwargs
17
- ) -> AgentRunResult[str]:
18
- return await super().run(prompt, deps, **kwargs)
19
-
20
- def get_system_prompt(self) -> str:
21
- return PRESEARCH_AGENT_PROMPT
22
-
23
- def register_tools(self) -> None:
24
- @self.agent.tool
25
- async def gather_context(
26
- ctx: RunContext[ResearchDependencies],
27
- query: str,
28
- limit: int = 6,
29
- ) -> str:
30
- """Return verbatim concatenation of relevant chunk texts."""
31
- query = query.replace('"', "")
32
- results = await ctx.deps.client.search(query, limit=limit)
33
- expanded = await ctx.deps.client.expand_context(results)
34
- return "\n\n".join(chunk.content for chunk, _ in expanded)
@@ -1,65 +0,0 @@
1
- from pydantic_ai import RunContext
2
- from pydantic_ai.format_prompt import format_as_xml
3
- from pydantic_ai.run import AgentRunResult
4
-
5
- from haiku.rag.research.base import BaseResearchAgent, SearchAnswer
6
- from haiku.rag.research.dependencies import ResearchDependencies
7
- from haiku.rag.research.prompts import SEARCH_AGENT_PROMPT
8
-
9
-
10
- class SearchSpecialistAgent(BaseResearchAgent[SearchAnswer]):
11
- """Agent specialized in answering questions using RAG search."""
12
-
13
- def __init__(self, provider: str, model: str) -> None:
14
- super().__init__(provider, model, output_type=SearchAnswer)
15
-
16
- async def run(
17
- self, prompt: str, deps: ResearchDependencies, **kwargs
18
- ) -> AgentRunResult[SearchAnswer]:
19
- """Execute the agent and persist the QA pair in shared context.
20
-
21
- Pydantic AI enforces `SearchAnswer` as the output model; we just store
22
- the QA response with the last search results as sources.
23
- """
24
- result = await super().run(prompt, deps, **kwargs)
25
-
26
- if result.output:
27
- deps.context.add_qa_response(result.output)
28
-
29
- return result
30
-
31
- def get_system_prompt(self) -> str:
32
- return SEARCH_AGENT_PROMPT
33
-
34
- def register_tools(self) -> None:
35
- """Register search-specific tools."""
36
-
37
- @self.agent.tool
38
- async def search_and_answer(
39
- ctx: RunContext[ResearchDependencies],
40
- query: str,
41
- limit: int = 5,
42
- ) -> str:
43
- """Search the KB and return a concise context pack."""
44
- # Remove quotes from queries as this requires positional indexing in lancedb
45
- # XXX: Investigate how to do that with lancedb
46
- query = query.replace('"', "")
47
- search_results = await ctx.deps.client.search(query, limit=limit)
48
- expanded = await ctx.deps.client.expand_context(search_results)
49
-
50
- snippet_entries = [
51
- {
52
- "text": chunk.content,
53
- "score": score,
54
- "document_uri": (chunk.document_uri or ""),
55
- }
56
- for chunk, score in expanded
57
- ]
58
-
59
- # Return an XML-formatted payload with the question and snippets.
60
- if snippet_entries:
61
- return format_as_xml(snippet_entries, root_tag="snippets")
62
- else:
63
- return (
64
- f"No relevant information found in the knowledge base for: {query}"
65
- )
@@ -1,40 +0,0 @@
1
- from pydantic import BaseModel, Field
2
-
3
- from haiku.rag.research.base import BaseResearchAgent
4
- from haiku.rag.research.prompts import SYNTHESIS_AGENT_PROMPT
5
-
6
-
7
- class ResearchReport(BaseModel):
8
- """Final research report structure."""
9
-
10
- title: str = Field(description="Concise title for the research")
11
- executive_summary: str = Field(description="Brief overview of key findings")
12
- main_findings: list[str] = Field(
13
- description="Primary research findings with supporting evidence"
14
- )
15
- conclusions: list[str] = Field(description="Evidence-based conclusions")
16
- limitations: list[str] = Field(
17
- description="Limitations of the current research", default=[]
18
- )
19
- recommendations: list[str] = Field(
20
- description="Actionable recommendations based on findings", default=[]
21
- )
22
- sources_summary: str = Field(
23
- description="Summary of sources used and their reliability"
24
- )
25
-
26
-
27
- class SynthesisAgent(BaseResearchAgent[ResearchReport]):
28
- """Agent specialized in synthesizing research into comprehensive reports."""
29
-
30
- def __init__(self, provider: str, model: str) -> None:
31
- super().__init__(provider, model, output_type=ResearchReport)
32
-
33
- def get_system_prompt(self) -> str:
34
- return SYNTHESIS_AGENT_PROMPT
35
-
36
- def register_tools(self) -> None:
37
- """Register synthesis-specific tools."""
38
- # The agent will use its LLM capabilities directly for synthesis
39
- # The structured output will guide the report generation
40
- pass
@@ -1,50 +0,0 @@
1
- haiku/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- haiku/rag/app.py,sha256=o64L7aj5V8lYHxWhAKBNj1tGfXiN6xr0_Cc1dEYd3As,11483
3
- haiku/rag/chunker.py,sha256=PVe6ysv8UlacUd4Zb3_8RFWIaWDXnzBAy2VDJ4TaUsE,1555
4
- haiku/rag/cli.py,sha256=3nlzrT5FPCyfnu51KHchLG4Cj2eVv9YsuGHMShBnVb0,9845
5
- haiku/rag/client.py,sha256=NJVGXzVzpoVy1sttz_xEU7mXWtObKT8pGpvo5pZyzwc,21288
6
- haiku/rag/config.py,sha256=SPEIv2IElZmZh4Wsp8gk7ViRW5ZzD-UGmIqRAXscDdI,2134
7
- haiku/rag/logging.py,sha256=dm65AwADpcQsH5OAPtRA-4hsw0w5DK-sGOvzYkj6jzw,1720
8
- haiku/rag/mcp.py,sha256=bR9Y-Nz-hvjiql20Y0KE0hwNGwyjmPGX8K9d-qmXptY,4683
9
- haiku/rag/migration.py,sha256=M--KnSF3lxgKjxmokb4vuzGH-pV8eg0C_8e7jvPqW8Y,11058
10
- haiku/rag/monitor.py,sha256=r386nkhdlsU8UECwIuVwnrSlgMk3vNIuUZGNIzkZuec,2770
11
- haiku/rag/reader.py,sha256=qkPTMJuQ_o4sK-8zpDl9WFYe_MJ7aL_gUw6rczIpW-g,3274
12
- haiku/rag/utils.py,sha256=aiuPu_rrfpyIvJJq0o5boUIIvCdNzdpKwAIPYYn3iG8,4965
13
- haiku/rag/embeddings/__init__.py,sha256=44IfDITGIFTflGT6UEmiYOwpWFVbYv5smLY59D0YeCs,1419
14
- haiku/rag/embeddings/base.py,sha256=BnSviKrlzjv3L0sZJs_T-pxfawd-bcTak-rsX-D2f3A,497
15
- haiku/rag/embeddings/ollama.py,sha256=LuLlHH6RGoO9_gFCIlbmesuXOj017gTw6z-p8Ez0CfE,595
16
- haiku/rag/embeddings/openai.py,sha256=fIFCk-jpUtaW0xsnrQnJ824O0UCjaGG2sgvBzREhilc,503
17
- haiku/rag/embeddings/vllm.py,sha256=vhaUnCn6VMkfSluLhWKtSV-sekFaPsp4pKo2N7-SBCY,626
18
- haiku/rag/embeddings/voyageai.py,sha256=UW-MW4tJKnPB6Fs2P7A3yt-ZeRm46H9npckchSriPX8,661
19
- haiku/rag/qa/__init__.py,sha256=Sl7Kzrg9CuBOcMF01wc1NtQhUNWjJI0MhIHfCWrb8V4,434
20
- haiku/rag/qa/agent.py,sha256=f4Keh-ESgctNbTg96QL95HYjINVLOcxa8t8crx92MMk,3081
21
- haiku/rag/qa/prompts.py,sha256=LhRfDtO8Pb06lpr4PpwEaKUYItZ5OiIkeqcCogcssHY,3347
22
- haiku/rag/reranking/__init__.py,sha256=IRXHs4qPu6VbGJQpzSwhgtVWWumURH_vEoVFE-extlo,894
23
- haiku/rag/reranking/base.py,sha256=LM9yUSSJ414UgBZhFTgxGprlRqzfTe4I1vgjricz2JY,405
24
- haiku/rag/reranking/cohere.py,sha256=1iTdiaa8vvb6oHVB2qpWzUOVkyfUcimVSZp6Qr4aq4c,1049
25
- haiku/rag/reranking/mxbai.py,sha256=46sVTsTIkzIX9THgM3u8HaEmgY7evvEyB-N54JTHvK8,867
26
- haiku/rag/reranking/vllm.py,sha256=xVGH9ss-ISWdJ5SKUUHUbTqBo7PIEmA_SQv0ScdJ6XA,1479
27
- haiku/rag/research/__init__.py,sha256=qLF41YayAxW_VeHhuTceVuz9hw1FNbuRV9VMhonUMW0,1078
28
- haiku/rag/research/base.py,sha256=ZUvqh-IxU8r4mOPRKjwZcHciKcIfrTnP6Q_9jVElelQ,4041
29
- haiku/rag/research/dependencies.py,sha256=vZctKC5donqhm8LFO6hQdXZZXzjdW1__4eUlhyZn058,1573
30
- haiku/rag/research/evaluation_agent.py,sha256=yyBobKr8MRwiox59I2Jqycp02ju9EGVaI9FceRGL188,1386
31
- haiku/rag/research/orchestrator.py,sha256=LrxRG74BWun0T4uOxhc9AuitxbPioS_eG_nE098ftyY,11765
32
- haiku/rag/research/presearch_agent.py,sha256=vf-WlY46g5tuuLKMBuPXXYYffynsBw7KVLr8LoTNHnU,1292
33
- haiku/rag/research/prompts.py,sha256=pVRB7_b_p3JaLF1bC3ANTbSFY78ypSjDhoq6peoU6jo,5685
34
- haiku/rag/research/search_agent.py,sha256=0iK7vCd9w7h8pWJgB6VUSPOdjlzB8peboNSXxuEGBK0,2464
35
- haiku/rag/research/synthesis_agent.py,sha256=jo5rg7aL4zGXLQP105cANqRPIiwJLqYe2unO5BQkNvE,1511
36
- haiku/rag/store/__init__.py,sha256=hq0W0DAC7ysqhWSP2M2uHX8cbG6kbr-sWHxhq6qQcY0,103
37
- haiku/rag/store/engine.py,sha256=fNrykqMX7PRSCt4LSRfuJ66OLrb8BVYq2bpbfI2iaWU,8455
38
- haiku/rag/store/models/__init__.py,sha256=s0E72zneGlowvZrFWaNxHYjOAUjgWdLxzdYsnvNRVlY,88
39
- haiku/rag/store/models/chunk.py,sha256=ZNyTfO6lh3rXWLVYO3TZcitbL4LSUGr42fR6jQQ5iQc,364
40
- haiku/rag/store/models/document.py,sha256=zSSpt6pyrMJAIXGQvIcqojcqUzwZnhp3WxVokaWxNRc,396
41
- haiku/rag/store/repositories/__init__.py,sha256=Olv5dLfBQINRV3HrsfUpjzkZ7Qm7goEYyMNykgo_DaY,291
42
- haiku/rag/store/repositories/chunk.py,sha256=1RmPyEYRYOFbrALbmLOo62t3f-xO2KgxUjcvPdrRZlc,14467
43
- haiku/rag/store/repositories/document.py,sha256=XoLCrMrZqs0iCZoHlDOfRDaVUux77Vdu5iZczduF1rY,7812
44
- haiku/rag/store/repositories/settings.py,sha256=wx3fuP_5CpPflZHRrIkeoer6ml-iD0qXERh5k6MQRzI,5291
45
- haiku/rag/store/upgrades/__init__.py,sha256=wUiEoSiHTahvuagx93E4FB07v123AhdbOjwUkPusiIg,14
46
- haiku_rag-0.9.2.dist-info/METADATA,sha256=IM9tGvye83CRTj2wOFtPP7oD9KtJvp3RXh4QdCFknD4,4681
47
- haiku_rag-0.9.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
48
- haiku_rag-0.9.2.dist-info/entry_points.txt,sha256=G1U3nAkNd5YDYd4v0tuYFbriz0i-JheCsFuT9kIoGCI,48
49
- haiku_rag-0.9.2.dist-info/licenses/LICENSE,sha256=eXZrWjSk9PwYFNK9yUczl3oPl95Z4V9UXH7bPN46iPo,1065
50
- haiku_rag-0.9.2.dist-info/RECORD,,