haiku.rag-slim 0.16.0__py3-none-any.whl → 0.24.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-slim might be problematic. Click here for more details.
- haiku/rag/app.py +430 -72
- haiku/rag/chunkers/__init__.py +31 -0
- haiku/rag/chunkers/base.py +31 -0
- haiku/rag/chunkers/docling_local.py +164 -0
- haiku/rag/chunkers/docling_serve.py +179 -0
- haiku/rag/cli.py +207 -24
- haiku/rag/cli_chat.py +489 -0
- haiku/rag/client.py +1251 -266
- haiku/rag/config/__init__.py +16 -10
- haiku/rag/config/loader.py +5 -44
- haiku/rag/config/models.py +126 -17
- haiku/rag/converters/__init__.py +31 -0
- haiku/rag/converters/base.py +63 -0
- haiku/rag/converters/docling_local.py +193 -0
- haiku/rag/converters/docling_serve.py +229 -0
- haiku/rag/converters/text_utils.py +237 -0
- haiku/rag/embeddings/__init__.py +123 -24
- haiku/rag/embeddings/voyageai.py +175 -20
- haiku/rag/graph/__init__.py +0 -11
- haiku/rag/graph/agui/__init__.py +8 -2
- haiku/rag/graph/agui/cli_renderer.py +1 -1
- haiku/rag/graph/agui/emitter.py +219 -31
- haiku/rag/graph/agui/server.py +20 -62
- haiku/rag/graph/agui/stream.py +1 -2
- haiku/rag/graph/research/__init__.py +5 -2
- haiku/rag/graph/research/dependencies.py +12 -126
- haiku/rag/graph/research/graph.py +390 -135
- haiku/rag/graph/research/models.py +91 -112
- haiku/rag/graph/research/prompts.py +99 -91
- haiku/rag/graph/research/state.py +35 -27
- haiku/rag/inspector/__init__.py +8 -0
- haiku/rag/inspector/app.py +259 -0
- haiku/rag/inspector/widgets/__init__.py +6 -0
- haiku/rag/inspector/widgets/chunk_list.py +100 -0
- haiku/rag/inspector/widgets/context_modal.py +89 -0
- haiku/rag/inspector/widgets/detail_view.py +130 -0
- haiku/rag/inspector/widgets/document_list.py +75 -0
- haiku/rag/inspector/widgets/info_modal.py +209 -0
- haiku/rag/inspector/widgets/search_modal.py +183 -0
- haiku/rag/inspector/widgets/visual_modal.py +126 -0
- haiku/rag/mcp.py +106 -102
- haiku/rag/monitor.py +33 -9
- haiku/rag/providers/__init__.py +5 -0
- haiku/rag/providers/docling_serve.py +108 -0
- haiku/rag/qa/__init__.py +12 -10
- haiku/rag/qa/agent.py +43 -61
- haiku/rag/qa/prompts.py +35 -57
- haiku/rag/reranking/__init__.py +9 -6
- haiku/rag/reranking/base.py +1 -1
- haiku/rag/reranking/cohere.py +5 -4
- haiku/rag/reranking/mxbai.py +5 -2
- haiku/rag/reranking/vllm.py +3 -4
- haiku/rag/reranking/zeroentropy.py +6 -5
- haiku/rag/store/__init__.py +2 -1
- haiku/rag/store/engine.py +242 -42
- haiku/rag/store/exceptions.py +4 -0
- haiku/rag/store/models/__init__.py +8 -2
- haiku/rag/store/models/chunk.py +190 -0
- haiku/rag/store/models/document.py +46 -0
- haiku/rag/store/repositories/chunk.py +141 -121
- haiku/rag/store/repositories/document.py +25 -84
- haiku/rag/store/repositories/settings.py +11 -14
- haiku/rag/store/upgrades/__init__.py +19 -3
- haiku/rag/store/upgrades/v0_10_1.py +1 -1
- haiku/rag/store/upgrades/v0_19_6.py +65 -0
- haiku/rag/store/upgrades/v0_20_0.py +68 -0
- haiku/rag/store/upgrades/v0_23_1.py +100 -0
- haiku/rag/store/upgrades/v0_9_3.py +3 -3
- haiku/rag/utils.py +371 -146
- {haiku_rag_slim-0.16.0.dist-info → haiku_rag_slim-0.24.0.dist-info}/METADATA +15 -12
- haiku_rag_slim-0.24.0.dist-info/RECORD +78 -0
- {haiku_rag_slim-0.16.0.dist-info → haiku_rag_slim-0.24.0.dist-info}/WHEEL +1 -1
- haiku/rag/chunker.py +0 -65
- haiku/rag/embeddings/base.py +0 -25
- haiku/rag/embeddings/ollama.py +0 -28
- haiku/rag/embeddings/openai.py +0 -26
- haiku/rag/embeddings/vllm.py +0 -29
- haiku/rag/graph/agui/events.py +0 -254
- haiku/rag/graph/common/__init__.py +0 -5
- haiku/rag/graph/common/models.py +0 -42
- haiku/rag/graph/common/nodes.py +0 -265
- haiku/rag/graph/common/prompts.py +0 -46
- haiku/rag/graph/common/utils.py +0 -44
- haiku/rag/graph/deep_qa/__init__.py +0 -1
- haiku/rag/graph/deep_qa/dependencies.py +0 -27
- haiku/rag/graph/deep_qa/graph.py +0 -243
- haiku/rag/graph/deep_qa/models.py +0 -20
- haiku/rag/graph/deep_qa/prompts.py +0 -59
- haiku/rag/graph/deep_qa/state.py +0 -56
- haiku/rag/graph/research/common.py +0 -87
- haiku/rag/reader.py +0 -135
- haiku_rag_slim-0.16.0.dist-info/RECORD +0 -71
- {haiku_rag_slim-0.16.0.dist-info → haiku_rag_slim-0.24.0.dist-info}/entry_points.txt +0 -0
- {haiku_rag_slim-0.16.0.dist-info → haiku_rag_slim-0.24.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
haiku/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
haiku/rag/app.py,sha256=2qlhInl44ht6A91rGbelJ37try05_cClGBmuavfVzvs,35660
|
|
3
|
+
haiku/rag/cli.py,sha256=o2eraDHEapSMMuV9rJbYwj58lW1Gm4WygKUMUXtU-js,17752
|
|
4
|
+
haiku/rag/cli_chat.py,sha256=CFKqsI2Ppq-BM8VYl-MeiVDW79d06JiPO8lTFbJPeTY,19662
|
|
5
|
+
haiku/rag/client.py,sha256=CVAJuLlYIKzcm_aVqCc-xSY4s5r01iUKz2rSyT7Nq0g,65286
|
|
6
|
+
haiku/rag/logging.py,sha256=dm65AwADpcQsH5OAPtRA-4hsw0w5DK-sGOvzYkj6jzw,1720
|
|
7
|
+
haiku/rag/mcp.py,sha256=0lkE76fKlqRLFy2Yrvw-NHepKfnjNKNbDTmPVeqWaeo,9219
|
|
8
|
+
haiku/rag/monitor.py,sha256=KNN05YFwCXotgRTN6AMfOZLyqfLyfbrMMe5v8nVubAA,8005
|
|
9
|
+
haiku/rag/utils.py,sha256=_wgx60F_IFqlMT2E9iL6qpHtdwIghCRwRL9Jy0G3xO8,14063
|
|
10
|
+
haiku/rag/chunkers/__init__.py,sha256=V1eMI6bGEDOQxLj5hGE9LbJGQK0Vg8xU-_D3uI7Gwac,984
|
|
11
|
+
haiku/rag/chunkers/base.py,sha256=LONA653zBZ9dkfY6WVNaDY56u5pZU4QL_Ei7MHOHBec,924
|
|
12
|
+
haiku/rag/chunkers/docling_local.py,sha256=ycBV6YlKUPOqQM9FXs2n6oQ5KjEFKPDJJ8uI7fvC8tg,6469
|
|
13
|
+
haiku/rag/chunkers/docling_serve.py,sha256=pOFSRXGc_pH19Qu67XcSQ4nIn_wWb0enXq_B0eaD3K0,6358
|
|
14
|
+
haiku/rag/config/__init__.py,sha256=rDIHz0tRLgoBESPFfpf02826_2X11Cl5TKVtv4fHBIg,1780
|
|
15
|
+
haiku/rag/config/loader.py,sha256=YX2sq2_sn5GLQlmnbxugmF46RK2sBVGYjEHsgSNHdZ0,1564
|
|
16
|
+
haiku/rag/config/models.py,sha256=rQ0wJaxWcaCYhK4BFAMgKwsQHfnv_ikFI-8M1hmropc,6097
|
|
17
|
+
haiku/rag/converters/__init__.py,sha256=w3YXOO0cw175CRXN4y5LseUXZjgh_gZmgMjK0jj4hlQ,1033
|
|
18
|
+
haiku/rag/converters/base.py,sha256=PWPW2KmPqhOeHs6rFjeSKpz9l4lq0TwT6yVTyKt7fP0,1880
|
|
19
|
+
haiku/rag/converters/docling_local.py,sha256=5qMpEVqje_GCSApezHCqd1X-rKgJX6LQfciQvUdowik,6830
|
|
20
|
+
haiku/rag/converters/docling_serve.py,sha256=pWojTRTqqkeBhnP71INYo7_lu_OwJUcGpslF9yntAKg,8220
|
|
21
|
+
haiku/rag/converters/text_utils.py,sha256=G_7YSSxlAYT9UNdxwFXrrxstKTsL2QAtDZ60V-v32wk,7016
|
|
22
|
+
haiku/rag/embeddings/__init__.py,sha256=jFfLesylVjoZk3SWonUsmMnd_Qc1Xgxc30J5ttFGTRs,4896
|
|
23
|
+
haiku/rag/embeddings/voyageai.py,sha256=5QtujhGT-kPh9HmALvxTj9Bqq0OXFlmZXfDlE2UQUWU,6029
|
|
24
|
+
haiku/rag/graph/__init__.py,sha256=DJkmRj_MsoscV-dEtztRwf9kNUEa-5s174JlnfvNk_s,320
|
|
25
|
+
haiku/rag/graph/agui/__init__.py,sha256=qjsGCNYgWGTTwjD0oIMomIkiKt_q_UeqmgZFaOfttpM,1472
|
|
26
|
+
haiku/rag/graph/agui/cli_renderer.py,sha256=jK_FUj17y2ArBFGNAItiu3ItPWII5FxXeDn7FprZZxw,5188
|
|
27
|
+
haiku/rag/graph/agui/emitter.py,sha256=aybeCL85fRuRArJ1woUQ0wF4FJlkskyHHvZKL_k5I40,12148
|
|
28
|
+
haiku/rag/graph/agui/server.py,sha256=njBVWz7GbKb55c4R0BDOWVpOWVRxM7VIW8wvIXTA3x0,8511
|
|
29
|
+
haiku/rag/graph/agui/state.py,sha256=LkuuAY9w32pc0kkXkLJvyNGC0JzhXn05IfIVZzCXAv0,965
|
|
30
|
+
haiku/rag/graph/agui/stream.py,sha256=t2_Y5KCs-HQ-XCQ2J475JJjN7hvNJXylz_hyA_s_DY4,2654
|
|
31
|
+
haiku/rag/graph/research/__init__.py,sha256=hLpyshx6yhTd7QHsg142PRAoSB2lZ8td1A5Vj9ArV_I,196
|
|
32
|
+
haiku/rag/graph/research/dependencies.py,sha256=n8nbim6ZsicjAmBO7OzQHqIsmObYPdAQKFmubdRg9hM,1250
|
|
33
|
+
haiku/rag/graph/research/graph.py,sha256=X5iJGfEBThAEklLwPu5P4mERLgH8Cpd-MPw_FTalowE,20622
|
|
34
|
+
haiku/rag/graph/research/models.py,sha256=TnR6s1ITcFKUzzxWVfuFLBEhVmm6nIV9A2ch6x6TBqQ,4506
|
|
35
|
+
haiku/rag/graph/research/prompts.py,sha256=Y_X6sf66wB0P9TV_86PB2zuBDi2e9zKdq24r1DLJZKA,5071
|
|
36
|
+
haiku/rag/graph/research/state.py,sha256=nsOAwwqtgt8kCOisRbop9GpD2JDyhWtDI-wSJcTxEJo,3274
|
|
37
|
+
haiku/rag/inspector/__init__.py,sha256=39qX_LMtypITucYi_9gdKarGRH2wG4vK0iAt208AKy8,285
|
|
38
|
+
haiku/rag/inspector/app.py,sha256=HiCvBVLnDG4iwrop80ykYkWyNAzYgoH3voLPuVuGSh4,8075
|
|
39
|
+
haiku/rag/inspector/widgets/__init__.py,sha256=XX2Ec-MOgJ9juzs0IfShkjFno_17V0ovpK8s37mqQNE,344
|
|
40
|
+
haiku/rag/inspector/widgets/chunk_list.py,sha256=JJmGQ1emPsOWkwP5PjdCtquIZAfJmu4PxrTAdcAZ5pc,3391
|
|
41
|
+
haiku/rag/inspector/widgets/context_modal.py,sha256=Ywx-eZRq6Qb1hN78Ni-JBamYeVfy8BHWOE91MWnv57s,2645
|
|
42
|
+
haiku/rag/inspector/widgets/detail_view.py,sha256=w8h8WSAN4GpGYOq_stga1YhCQqSx2p-iFO4vLHaoPI4,5074
|
|
43
|
+
haiku/rag/inspector/widgets/document_list.py,sha256=K5P0Y2qUl0mh-psUQzbJJXSitlZrHqtT9WOIcw7mABw,2853
|
|
44
|
+
haiku/rag/inspector/widgets/info_modal.py,sha256=UJ_KHRVcPWD5FR9cr7De2tTIU-qMsCwCYm0xaHuFesM,7156
|
|
45
|
+
haiku/rag/inspector/widgets/search_modal.py,sha256=dYAxCvwdKc3cHLjh4hI5ROQt0nS9mFLzz_1UPV9Shh0,6376
|
|
46
|
+
haiku/rag/inspector/widgets/visual_modal.py,sha256=Pk_3cDIDHE_6_PBxV5MPtY9zhi9f7ODnhZNO4QJnjUQ,3959
|
|
47
|
+
haiku/rag/providers/__init__.py,sha256=Tih4mcHM6bFe1R-fZvvb9KSVennxVX7mb44NrNERNQw,146
|
|
48
|
+
haiku/rag/providers/docling_serve.py,sha256=cT1J3Xo-BW0_lZwHSNeL14wjCJ4TTf9s3H0qBkNkmN0,3834
|
|
49
|
+
haiku/rag/qa/__init__.py,sha256=4E7wyeN6mxyJpKnNsO2Hr0aoK4LqSoaEUBK4sLU4QGs,1112
|
|
50
|
+
haiku/rag/qa/agent.py,sha256=BOon9aRo-5Vs5yCKVSnY1slMiEvXmiaH8VTi0fwVHJk,2698
|
|
51
|
+
haiku/rag/qa/prompts.py,sha256=Q6Pxf_obroiX6aWGvf9qjD__2KFy77_b_XrqCZpI8WQ,1403
|
|
52
|
+
haiku/rag/reranking/__init__.py,sha256=03LKxmcd6Qt03o7yfNtEj1kDLKkmGZv9cQDQdohGm54,2223
|
|
53
|
+
haiku/rag/reranking/base.py,sha256=nwrlGzNkdBg2WVBzPMsrvqGYQPmjwPrOvfPs9KyydVI,456
|
|
54
|
+
haiku/rag/reranking/cohere.py,sha256=KntIQPIHDxa3WlFgx0ETvItirRVw_RnJehFA2ZHvLSE,1130
|
|
55
|
+
haiku/rag/reranking/mxbai.py,sha256=XVIyMHTXHlDsgvml3J1uvm7wIggA2E-0E8ATt7p-PfY,1042
|
|
56
|
+
haiku/rag/reranking/vllm.py,sha256=J-b9S0l3at9H_DwTZ0BkwVRgwVb-D62kunQyQBh2nRE,1459
|
|
57
|
+
haiku/rag/reranking/zeroentropy.py,sha256=bT4_KQd8aksPiyX8wjqdMerPoME-223lCRb1BoxfYvY,1995
|
|
58
|
+
haiku/rag/store/__init__.py,sha256=ixTDcjtFZ1MCqB9CIM1P9c9K-5mlc9uRtvD3ekZCn0E,159
|
|
59
|
+
haiku/rag/store/engine.py,sha256=wcwmxmHBdO4vHXAPpsd3lOtFLL5O1qmycIp37zqhl7w,19129
|
|
60
|
+
haiku/rag/store/exceptions.py,sha256=l7wxxI3CsXTkhRwYZSwH5nXhTTGO2jCg3mRqzG0pPzI,117
|
|
61
|
+
haiku/rag/store/models/__init__.py,sha256=aUgKHt3XYVwqVmiAaW4z2u8sBOrP9mnqTZXxq0zHCHE,202
|
|
62
|
+
haiku/rag/store/models/chunk.py,sha256=n9lCaEtY9B2S8pGW9PdX_c-SSmZvADY6Qprqu-u68Bc,6557
|
|
63
|
+
haiku/rag/store/models/document.py,sha256=MGP2ai9wOQ53vWRTlw6FGAyg--GlVFBj8E0e828qEIE,2045
|
|
64
|
+
haiku/rag/store/repositories/__init__.py,sha256=Olv5dLfBQINRV3HrsfUpjzkZ7Qm7goEYyMNykgo_DaY,291
|
|
65
|
+
haiku/rag/store/repositories/chunk.py,sha256=htGEM5te7ToKQugtz1RzJPP8W-8SY7HEIo-iug834c4,16757
|
|
66
|
+
haiku/rag/store/repositories/document.py,sha256=SsxwdcPvrRNOvJJadxazYn5GyV8pvm4-On8NnodTizY,6588
|
|
67
|
+
haiku/rag/store/repositories/settings.py,sha256=lmk6Fk0abmbl2h3xNSGOscCpi6Y7GzYWzpzMIfEuFmk,6015
|
|
68
|
+
haiku/rag/store/upgrades/__init__.py,sha256=or5dxhgVOCHt-w0R5NnTPWmrlDVVPMrLnZ9vaiAedeg,2589
|
|
69
|
+
haiku/rag/store/upgrades/v0_10_1.py,sha256=fzLNz2nQO7BR25x_H6vz20Uyo4MZjhbz3Kz22sYgaAI,1979
|
|
70
|
+
haiku/rag/store/upgrades/v0_19_6.py,sha256=5k__79mdn7u0UmlaGN7w2t74uVhnmScsFz0zCbnoPAU,1907
|
|
71
|
+
haiku/rag/store/upgrades/v0_20_0.py,sha256=yFkZzOh59WSfcsTUsBVqFu-FGBsBvwGP_Y3Dn4BLh04,2267
|
|
72
|
+
haiku/rag/store/upgrades/v0_23_1.py,sha256=ZuMuIZWWnC7_Rq63QB88fTIBbo121JAFjBrjv1wVpyk,2897
|
|
73
|
+
haiku/rag/store/upgrades/v0_9_3.py,sha256=5zsOCeMaB5tHhx5AR8wGtCJGqqzA944sqYzDUPvYa4c,3382
|
|
74
|
+
haiku_rag_slim-0.24.0.dist-info/METADATA,sha256=XZLY786eWEZjVaoUi_90r_1JqnRA4kLFx6I8YZHLhmw,4384
|
|
75
|
+
haiku_rag_slim-0.24.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
76
|
+
haiku_rag_slim-0.24.0.dist-info/entry_points.txt,sha256=G1U3nAkNd5YDYd4v0tuYFbriz0i-JheCsFuT9kIoGCI,48
|
|
77
|
+
haiku_rag_slim-0.24.0.dist-info/licenses/LICENSE,sha256=eXZrWjSk9PwYFNK9yUczl3oPl95Z4V9UXH7bPN46iPo,1065
|
|
78
|
+
haiku_rag_slim-0.24.0.dist-info/RECORD,,
|
haiku/rag/chunker.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
from typing import ClassVar
|
|
2
|
-
|
|
3
|
-
import tiktoken
|
|
4
|
-
from docling_core.transforms.chunker.tokenizer.openai import OpenAITokenizer
|
|
5
|
-
from docling_core.types.doc.document import DoclingDocument
|
|
6
|
-
|
|
7
|
-
from haiku.rag.config import Config
|
|
8
|
-
|
|
9
|
-
# Check if docling is available
|
|
10
|
-
try:
|
|
11
|
-
import docling # noqa: F401
|
|
12
|
-
|
|
13
|
-
DOCLING_AVAILABLE = True
|
|
14
|
-
except ImportError:
|
|
15
|
-
DOCLING_AVAILABLE = False
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class Chunker:
|
|
19
|
-
"""A class that chunks text into smaller pieces for embedding and retrieval.
|
|
20
|
-
|
|
21
|
-
Uses docling's structure-aware chunking to create semantically meaningful chunks
|
|
22
|
-
that respect document boundaries.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
chunk_size: The maximum size of a chunk in tokens.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
encoder: ClassVar[tiktoken.Encoding] = tiktoken.encoding_for_model("gpt-4o")
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
chunk_size: int = Config.processing.chunk_size,
|
|
33
|
-
):
|
|
34
|
-
if not DOCLING_AVAILABLE:
|
|
35
|
-
raise ImportError(
|
|
36
|
-
"Docling is required for chunking. "
|
|
37
|
-
"Install with: pip install haiku.rag-slim[docling]"
|
|
38
|
-
)
|
|
39
|
-
from docling.chunking import HybridChunker # type: ignore
|
|
40
|
-
|
|
41
|
-
self.chunk_size = chunk_size
|
|
42
|
-
tokenizer = OpenAITokenizer(
|
|
43
|
-
tokenizer=tiktoken.encoding_for_model("gpt-4o"), max_tokens=chunk_size
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
self.chunker = HybridChunker(tokenizer=tokenizer) # type: ignore
|
|
47
|
-
|
|
48
|
-
async def chunk(self, document: DoclingDocument) -> list[str]:
|
|
49
|
-
"""Split the document into chunks using docling's structure-aware chunking.
|
|
50
|
-
|
|
51
|
-
Args:
|
|
52
|
-
document: The DoclingDocument to be split into chunks.
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
A list of text chunks with semantic boundaries.
|
|
56
|
-
"""
|
|
57
|
-
if document is None:
|
|
58
|
-
return []
|
|
59
|
-
|
|
60
|
-
# Chunk using docling's hybrid chunker
|
|
61
|
-
chunks = list(self.chunker.chunk(document))
|
|
62
|
-
return [self.chunker.contextualize(chunk) for chunk in chunks]
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
chunker = Chunker()
|
haiku/rag/embeddings/base.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from typing import overload
|
|
2
|
-
|
|
3
|
-
from haiku.rag.config import AppConfig, Config
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EmbedderBase:
|
|
7
|
-
_model: str = Config.embeddings.model
|
|
8
|
-
_vector_dim: int = Config.embeddings.vector_dim
|
|
9
|
-
_config: AppConfig = Config
|
|
10
|
-
|
|
11
|
-
def __init__(self, model: str, vector_dim: int, config: AppConfig = Config):
|
|
12
|
-
self._model = model
|
|
13
|
-
self._vector_dim = vector_dim
|
|
14
|
-
self._config = config
|
|
15
|
-
|
|
16
|
-
@overload
|
|
17
|
-
async def embed(self, text: str) -> list[float]: ...
|
|
18
|
-
|
|
19
|
-
@overload
|
|
20
|
-
async def embed(self, text: list[str]) -> list[list[float]]: ...
|
|
21
|
-
|
|
22
|
-
async def embed(self, text: str | list[str]) -> list[float] | list[list[float]]:
|
|
23
|
-
raise NotImplementedError(
|
|
24
|
-
"Embedder is an abstract class. Please implement the embed method in a subclass."
|
|
25
|
-
)
|
haiku/rag/embeddings/ollama.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
from typing import overload
|
|
2
|
-
|
|
3
|
-
from openai import AsyncOpenAI
|
|
4
|
-
|
|
5
|
-
from haiku.rag.embeddings.base import EmbedderBase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Embedder(EmbedderBase):
|
|
9
|
-
@overload
|
|
10
|
-
async def embed(self, text: str) -> list[float]: ...
|
|
11
|
-
|
|
12
|
-
@overload
|
|
13
|
-
async def embed(self, text: list[str]) -> list[list[float]]: ...
|
|
14
|
-
|
|
15
|
-
async def embed(self, text: str | list[str]) -> list[float] | list[list[float]]:
|
|
16
|
-
client = AsyncOpenAI(
|
|
17
|
-
base_url=f"{self._config.providers.ollama.base_url}/v1", api_key="dummy"
|
|
18
|
-
)
|
|
19
|
-
if not text:
|
|
20
|
-
return []
|
|
21
|
-
response = await client.embeddings.create(
|
|
22
|
-
model=self._model,
|
|
23
|
-
input=text,
|
|
24
|
-
)
|
|
25
|
-
if isinstance(text, str):
|
|
26
|
-
return response.data[0].embedding
|
|
27
|
-
else:
|
|
28
|
-
return [item.embedding for item in response.data]
|
haiku/rag/embeddings/openai.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from typing import overload
|
|
2
|
-
|
|
3
|
-
from openai import AsyncOpenAI
|
|
4
|
-
|
|
5
|
-
from haiku.rag.embeddings.base import EmbedderBase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Embedder(EmbedderBase):
|
|
9
|
-
@overload
|
|
10
|
-
async def embed(self, text: str) -> list[float]: ...
|
|
11
|
-
|
|
12
|
-
@overload
|
|
13
|
-
async def embed(self, text: list[str]) -> list[list[float]]: ...
|
|
14
|
-
|
|
15
|
-
async def embed(self, text: str | list[str]) -> list[float] | list[list[float]]:
|
|
16
|
-
client = AsyncOpenAI()
|
|
17
|
-
if not text:
|
|
18
|
-
return []
|
|
19
|
-
response = await client.embeddings.create(
|
|
20
|
-
model=self._model,
|
|
21
|
-
input=text,
|
|
22
|
-
)
|
|
23
|
-
if isinstance(text, str):
|
|
24
|
-
return response.data[0].embedding
|
|
25
|
-
else:
|
|
26
|
-
return [item.embedding for item in response.data]
|
haiku/rag/embeddings/vllm.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
from typing import overload
|
|
2
|
-
|
|
3
|
-
from openai import AsyncOpenAI
|
|
4
|
-
|
|
5
|
-
from haiku.rag.embeddings.base import EmbedderBase
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Embedder(EmbedderBase):
|
|
9
|
-
@overload
|
|
10
|
-
async def embed(self, text: str) -> list[float]: ...
|
|
11
|
-
|
|
12
|
-
@overload
|
|
13
|
-
async def embed(self, text: list[str]) -> list[list[float]]: ...
|
|
14
|
-
|
|
15
|
-
async def embed(self, text: str | list[str]) -> list[float] | list[list[float]]:
|
|
16
|
-
client = AsyncOpenAI(
|
|
17
|
-
base_url=f"{self._config.providers.vllm.embeddings_base_url}/v1",
|
|
18
|
-
api_key="dummy",
|
|
19
|
-
)
|
|
20
|
-
if not text:
|
|
21
|
-
return []
|
|
22
|
-
response = await client.embeddings.create(
|
|
23
|
-
model=self._model,
|
|
24
|
-
input=text,
|
|
25
|
-
)
|
|
26
|
-
if isinstance(text, str):
|
|
27
|
-
return response.data[0].embedding
|
|
28
|
-
else:
|
|
29
|
-
return [item.embedding for item in response.data]
|
haiku/rag/graph/agui/events.py
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
"""Generic AG-UI event creation utilities for any graph."""
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
4
|
-
from uuid import uuid4
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel
|
|
7
|
-
|
|
8
|
-
from haiku.rag.graph.agui.state import compute_state_delta
|
|
9
|
-
|
|
10
|
-
# Type aliases for AG-UI events (actual types from ag_ui.core will be used at runtime)
|
|
11
|
-
AGUIEvent = dict[str, Any]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def emit_run_started(
|
|
15
|
-
thread_id: str, run_id: str, input_data: str | None = None
|
|
16
|
-
) -> dict[str, Any]:
|
|
17
|
-
"""Create a RunStarted event.
|
|
18
|
-
|
|
19
|
-
Args:
|
|
20
|
-
thread_id: Unique identifier for the conversation thread
|
|
21
|
-
run_id: Unique identifier for this run
|
|
22
|
-
input_data: Optional input that started the run
|
|
23
|
-
|
|
24
|
-
Returns:
|
|
25
|
-
RunStarted event dict
|
|
26
|
-
"""
|
|
27
|
-
event: dict[str, Any] = {
|
|
28
|
-
"type": "RUN_STARTED",
|
|
29
|
-
"threadId": thread_id,
|
|
30
|
-
"runId": run_id,
|
|
31
|
-
}
|
|
32
|
-
if input_data:
|
|
33
|
-
event["input"] = input_data
|
|
34
|
-
return event
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def emit_run_finished(thread_id: str, run_id: str, result: Any) -> dict[str, Any]:
|
|
38
|
-
"""Create a RunFinished event.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
thread_id: Unique identifier for the conversation thread
|
|
42
|
-
run_id: Unique identifier for this run
|
|
43
|
-
result: The final result of the run
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
RunFinished event dict
|
|
47
|
-
"""
|
|
48
|
-
# Convert result to dict if it's a Pydantic model
|
|
49
|
-
if hasattr(result, "model_dump"):
|
|
50
|
-
result = result.model_dump()
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
"type": "RUN_FINISHED",
|
|
54
|
-
"threadId": thread_id,
|
|
55
|
-
"runId": run_id,
|
|
56
|
-
"result": result,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def emit_run_error(message: str, code: str | None = None) -> dict[str, Any]:
|
|
61
|
-
"""Create a RunError event.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
message: Error message
|
|
65
|
-
code: Optional error code
|
|
66
|
-
|
|
67
|
-
Returns:
|
|
68
|
-
RunError event dict
|
|
69
|
-
"""
|
|
70
|
-
event: dict[str, Any] = {
|
|
71
|
-
"type": "RUN_ERROR",
|
|
72
|
-
"message": message,
|
|
73
|
-
}
|
|
74
|
-
if code:
|
|
75
|
-
event["code"] = code
|
|
76
|
-
return event
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def emit_step_started(step_name: str) -> dict[str, Any]:
|
|
80
|
-
"""Create a StepStarted event.
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
step_name: Name of the step being started
|
|
84
|
-
|
|
85
|
-
Returns:
|
|
86
|
-
StepStarted event dict
|
|
87
|
-
"""
|
|
88
|
-
return {
|
|
89
|
-
"type": "STEP_STARTED",
|
|
90
|
-
"stepName": step_name,
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def emit_step_finished(step_name: str) -> dict[str, Any]:
|
|
95
|
-
"""Create a StepFinished event.
|
|
96
|
-
|
|
97
|
-
Args:
|
|
98
|
-
step_name: Name of the step that finished
|
|
99
|
-
|
|
100
|
-
Returns:
|
|
101
|
-
StepFinished event dict
|
|
102
|
-
"""
|
|
103
|
-
return {
|
|
104
|
-
"type": "STEP_FINISHED",
|
|
105
|
-
"stepName": step_name,
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def emit_text_message(content: str, role: str = "assistant") -> dict[str, Any]:
|
|
110
|
-
"""Create a TextMessageChunk event (convenience wrapper).
|
|
111
|
-
|
|
112
|
-
This creates a complete text message in one event.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
content: The message content
|
|
116
|
-
role: The role of the sender (default: assistant)
|
|
117
|
-
|
|
118
|
-
Returns:
|
|
119
|
-
TextMessageChunk event dict
|
|
120
|
-
"""
|
|
121
|
-
message_id = str(uuid4())
|
|
122
|
-
return {
|
|
123
|
-
"type": "TEXT_MESSAGE_CHUNK",
|
|
124
|
-
"messageId": message_id,
|
|
125
|
-
"role": role,
|
|
126
|
-
"delta": content,
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def emit_text_message_start(message_id: str, role: str = "assistant") -> dict[str, Any]:
|
|
131
|
-
"""Create a TextMessageStart event.
|
|
132
|
-
|
|
133
|
-
Args:
|
|
134
|
-
message_id: Unique identifier for this message
|
|
135
|
-
role: The role of the sender
|
|
136
|
-
|
|
137
|
-
Returns:
|
|
138
|
-
TextMessageStart event dict
|
|
139
|
-
"""
|
|
140
|
-
return {
|
|
141
|
-
"type": "TEXT_MESSAGE_START",
|
|
142
|
-
"messageId": message_id,
|
|
143
|
-
"role": role,
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def emit_text_message_content(message_id: str, delta: str) -> dict[str, Any]:
|
|
148
|
-
"""Create a TextMessageContent event.
|
|
149
|
-
|
|
150
|
-
Args:
|
|
151
|
-
message_id: Identifier for the message being streamed
|
|
152
|
-
delta: Content chunk to append
|
|
153
|
-
|
|
154
|
-
Returns:
|
|
155
|
-
TextMessageContent event dict
|
|
156
|
-
"""
|
|
157
|
-
return {
|
|
158
|
-
"type": "TEXT_MESSAGE_CONTENT",
|
|
159
|
-
"messageId": message_id,
|
|
160
|
-
"delta": delta,
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def emit_text_message_end(message_id: str) -> dict[str, Any]:
|
|
165
|
-
"""Create a TextMessageEnd event.
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
message_id: Identifier for the message being completed
|
|
169
|
-
|
|
170
|
-
Returns:
|
|
171
|
-
TextMessageEnd event dict
|
|
172
|
-
"""
|
|
173
|
-
return {
|
|
174
|
-
"type": "TEXT_MESSAGE_END",
|
|
175
|
-
"messageId": message_id,
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def emit_state_snapshot(state: BaseModel) -> dict[str, Any]:
|
|
180
|
-
"""Create a StateSnapshot event.
|
|
181
|
-
|
|
182
|
-
Args:
|
|
183
|
-
state: The complete state to snapshot (any Pydantic BaseModel)
|
|
184
|
-
|
|
185
|
-
Returns:
|
|
186
|
-
StateSnapshot event dict
|
|
187
|
-
"""
|
|
188
|
-
return {
|
|
189
|
-
"type": "STATE_SNAPSHOT",
|
|
190
|
-
"snapshot": state.model_dump(),
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def emit_state_delta(old_state: BaseModel, new_state: BaseModel) -> dict[str, Any]:
|
|
195
|
-
"""Create a StateDelta event with JSON Patch operations.
|
|
196
|
-
|
|
197
|
-
Args:
|
|
198
|
-
old_state: Previous state (any Pydantic BaseModel)
|
|
199
|
-
new_state: Current state (same type as old_state)
|
|
200
|
-
|
|
201
|
-
Returns:
|
|
202
|
-
StateDelta event dict
|
|
203
|
-
"""
|
|
204
|
-
delta = compute_state_delta(old_state, new_state)
|
|
205
|
-
return {
|
|
206
|
-
"type": "STATE_DELTA",
|
|
207
|
-
"delta": delta,
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
def emit_activity(
|
|
212
|
-
message_id: str,
|
|
213
|
-
activity_type: str,
|
|
214
|
-
content: str,
|
|
215
|
-
) -> dict[str, Any]:
|
|
216
|
-
"""Create an ActivitySnapshot event.
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
message_id: Message ID to associate activity with (required)
|
|
220
|
-
activity_type: Type of activity (e.g., "planning", "searching")
|
|
221
|
-
content: Description of the activity
|
|
222
|
-
|
|
223
|
-
Returns:
|
|
224
|
-
ActivitySnapshot event dict
|
|
225
|
-
"""
|
|
226
|
-
return {
|
|
227
|
-
"type": "ACTIVITY_SNAPSHOT",
|
|
228
|
-
"messageId": message_id,
|
|
229
|
-
"activityType": activity_type,
|
|
230
|
-
"content": content,
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
def emit_activity_delta(
|
|
235
|
-
message_id: str,
|
|
236
|
-
activity_type: str,
|
|
237
|
-
patch: list[dict[str, Any]],
|
|
238
|
-
) -> dict[str, Any]:
|
|
239
|
-
"""Create an ActivityDelta event with JSON Patch operations.
|
|
240
|
-
|
|
241
|
-
Args:
|
|
242
|
-
message_id: Message ID of the activity being updated
|
|
243
|
-
activity_type: Type of activity being updated
|
|
244
|
-
patch: JSON Patch operations to apply
|
|
245
|
-
|
|
246
|
-
Returns:
|
|
247
|
-
ActivityDelta event dict
|
|
248
|
-
"""
|
|
249
|
-
return {
|
|
250
|
-
"type": "ACTIVITY_DELTA",
|
|
251
|
-
"messageId": message_id,
|
|
252
|
-
"activityType": activity_type,
|
|
253
|
-
"patch": patch,
|
|
254
|
-
}
|
haiku/rag/graph/common/models.py
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"""Common models used across different graph implementations."""
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel, Field, field_validator
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ResearchPlan(BaseModel):
|
|
7
|
-
"""A structured research plan with sub-questions to explore."""
|
|
8
|
-
|
|
9
|
-
sub_questions: list[str] = Field(
|
|
10
|
-
...,
|
|
11
|
-
description="Specific questions to research, phrased as complete questions",
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
@field_validator("sub_questions")
|
|
15
|
-
@classmethod
|
|
16
|
-
def validate_sub_questions(cls, v: list[str]) -> list[str]:
|
|
17
|
-
if len(v) < 1:
|
|
18
|
-
raise ValueError("Must have at least 1 sub-question")
|
|
19
|
-
if len(v) > 12:
|
|
20
|
-
raise ValueError("Cannot have more than 12 sub-questions")
|
|
21
|
-
return v
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class SearchAnswer(BaseModel):
|
|
25
|
-
"""Answer from a search operation with sources."""
|
|
26
|
-
|
|
27
|
-
query: str = Field(..., description="The question that was answered")
|
|
28
|
-
answer: str = Field(..., description="The comprehensive answer to the question")
|
|
29
|
-
context: list[str] = Field(
|
|
30
|
-
default_factory=list,
|
|
31
|
-
description="Relevant snippets that directly support the answer",
|
|
32
|
-
)
|
|
33
|
-
sources: list[str] = Field(
|
|
34
|
-
default_factory=list,
|
|
35
|
-
description="Source URIs or titles that contributed to this answer",
|
|
36
|
-
)
|
|
37
|
-
confidence: float = Field(
|
|
38
|
-
default=1.0,
|
|
39
|
-
description="Confidence score for this answer (0-1)",
|
|
40
|
-
ge=0.0,
|
|
41
|
-
le=1.0,
|
|
42
|
-
)
|