warm-sdk 0.1.3__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.
Files changed (70) hide show
  1. warm_sdk-0.1.3.dist-info/METADATA +207 -0
  2. warm_sdk-0.1.3.dist-info/RECORD +70 -0
  3. warm_sdk-0.1.3.dist-info/WHEEL +4 -0
  4. warm_sdk-0.1.3.dist-info/entry_points.txt +2 -0
  5. writerslogic_warm_sdk/__init__.py +21 -0
  6. writerslogic_warm_sdk/_transport.py +118 -0
  7. writerslogic_warm_sdk/client.py +281 -0
  8. writerslogic_warm_sdk/crewai/__init__.py +5 -0
  9. writerslogic_warm_sdk/crewai/tools.py +44 -0
  10. writerslogic_warm_sdk/dspy/__init__.py +5 -0
  11. writerslogic_warm_sdk/dspy/retriever.py +43 -0
  12. writerslogic_warm_sdk/embedchain/__init__.py +5 -0
  13. writerslogic_warm_sdk/embedchain/vectordb.py +59 -0
  14. writerslogic_warm_sdk/evidence.py +225 -0
  15. writerslogic_warm_sdk/haystack/__init__.py +5 -0
  16. writerslogic_warm_sdk/haystack/document_store.py +44 -0
  17. writerslogic_warm_sdk/importers/__init__.py +38 -0
  18. writerslogic_warm_sdk/importers/checkpoint.py +96 -0
  19. writerslogic_warm_sdk/importers/cli.py +189 -0
  20. writerslogic_warm_sdk/importers/common.py +214 -0
  21. writerslogic_warm_sdk/importers/inventory.py +103 -0
  22. writerslogic_warm_sdk/importers/mapping.py +364 -0
  23. writerslogic_warm_sdk/importers/model.py +79 -0
  24. writerslogic_warm_sdk/importers/options.py +114 -0
  25. writerslogic_warm_sdk/importers/pipeline.py +355 -0
  26. writerslogic_warm_sdk/importers/report.py +182 -0
  27. writerslogic_warm_sdk/importers/sink.py +254 -0
  28. writerslogic_warm_sdk/importers/sources/__init__.py +61 -0
  29. writerslogic_warm_sdk/importers/sources/_fields.py +117 -0
  30. writerslogic_warm_sdk/importers/sources/_sidecar.py +108 -0
  31. writerslogic_warm_sdk/importers/sources/annoy.py +102 -0
  32. writerslogic_warm_sdk/importers/sources/base.py +169 -0
  33. writerslogic_warm_sdk/importers/sources/chroma.py +122 -0
  34. writerslogic_warm_sdk/importers/sources/elastic.py +276 -0
  35. writerslogic_warm_sdk/importers/sources/faiss.py +153 -0
  36. writerslogic_warm_sdk/importers/sources/files.py +338 -0
  37. writerslogic_warm_sdk/importers/sources/hnswlib.py +127 -0
  38. writerslogic_warm_sdk/importers/sources/lancedb.py +117 -0
  39. writerslogic_warm_sdk/importers/sources/langchain.py +207 -0
  40. writerslogic_warm_sdk/importers/sources/letta.py +148 -0
  41. writerslogic_warm_sdk/importers/sources/llamaindex.py +128 -0
  42. writerslogic_warm_sdk/importers/sources/markdown.py +202 -0
  43. writerslogic_warm_sdk/importers/sources/mem0.py +303 -0
  44. writerslogic_warm_sdk/importers/sources/milvus.py +191 -0
  45. writerslogic_warm_sdk/importers/sources/mongodb.py +162 -0
  46. writerslogic_warm_sdk/importers/sources/openai_vs.py +110 -0
  47. writerslogic_warm_sdk/importers/sources/pgvector.py +140 -0
  48. writerslogic_warm_sdk/importers/sources/pinecone.py +181 -0
  49. writerslogic_warm_sdk/importers/sources/qdrant.py +170 -0
  50. writerslogic_warm_sdk/importers/sources/redis.py +223 -0
  51. writerslogic_warm_sdk/importers/sources/sqlite_vec.py +149 -0
  52. writerslogic_warm_sdk/importers/sources/vespa.py +233 -0
  53. writerslogic_warm_sdk/importers/sources/weaviate.py +186 -0
  54. writerslogic_warm_sdk/importers/sources/zep.py +144 -0
  55. writerslogic_warm_sdk/importers/verify.py +257 -0
  56. writerslogic_warm_sdk/langchain/__init__.py +5 -0
  57. writerslogic_warm_sdk/langchain/vectorstores.py +65 -0
  58. writerslogic_warm_sdk/llamaindex/__init__.py +5 -0
  59. writerslogic_warm_sdk/llamaindex/vectorstores.py +68 -0
  60. writerslogic_warm_sdk/memory.py +756 -0
  61. writerslogic_warm_sdk/memory.pyi +139 -0
  62. writerslogic_warm_sdk/phidata/__init__.py +5 -0
  63. writerslogic_warm_sdk/phidata/vectordb.py +61 -0
  64. writerslogic_warm_sdk/py.typed +0 -0
  65. writerslogic_warm_sdk/pydantic_ai/__init__.py +7 -0
  66. writerslogic_warm_sdk/pydantic_ai/tools.py +39 -0
  67. writerslogic_warm_sdk/semantic_kernel/__init__.py +2 -0
  68. writerslogic_warm_sdk/semantic_kernel/memory_store.py +95 -0
  69. writerslogic_warm_sdk/smolagents/__init__.py +5 -0
  70. writerslogic_warm_sdk/smolagents/tools.py +51 -0
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.5
2
+ Name: warm-sdk
3
+ Version: 0.1.3
4
+ Summary: HTTP client and agent-framework adapters for a WritersLogic Adaptive Retention & Memory service
5
+ Project-URL: Homepage, https://writerslogic.com/warm/
6
+ Project-URL: Documentation, https://writerslogic.com/warm/docs/
7
+ Project-URL: Repository, https://github.com/writerslogic/warm
8
+ Author-email: WritersLogic <david@writerslogic.com>
9
+ License: Apache-2.0
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: httpx>=0.27.0
12
+ Requires-Dist: sniffio>=1.3
13
+ Provides-Extra: all
14
+ Requires-Dist: crewai>=0.28.0; extra == 'all'
15
+ Requires-Dist: dspy-ai>=2.4.0; extra == 'all'
16
+ Requires-Dist: embedchain>=0.1.114; extra == 'all'
17
+ Requires-Dist: haystack-ai>=2.0.0; extra == 'all'
18
+ Requires-Dist: langchain-core>=0.1.0; extra == 'all'
19
+ Requires-Dist: llama-index-core>=0.10.0; extra == 'all'
20
+ Requires-Dist: phidata>=2.4.0; extra == 'all'
21
+ Requires-Dist: pydantic-ai>=0.0.14; extra == 'all'
22
+ Requires-Dist: semantic-kernel>=1.39.4; extra == 'all'
23
+ Requires-Dist: smolagents>=1.0.0; extra == 'all'
24
+ Provides-Extra: crewai
25
+ Requires-Dist: crewai>=0.28.0; extra == 'crewai'
26
+ Provides-Extra: dspy
27
+ Requires-Dist: dspy-ai>=2.4.0; extra == 'dspy'
28
+ Provides-Extra: embedchain
29
+ Requires-Dist: embedchain>=0.1.114; extra == 'embedchain'
30
+ Provides-Extra: fast
31
+ Requires-Dist: orjson>=3.9; extra == 'fast'
32
+ Provides-Extra: haystack
33
+ Requires-Dist: haystack-ai>=2.0.0; extra == 'haystack'
34
+ Provides-Extra: import-annoy
35
+ Requires-Dist: annoy>=1.17; extra == 'import-annoy'
36
+ Requires-Dist: numpy>=1.26; extra == 'import-annoy'
37
+ Provides-Extra: import-chroma
38
+ Requires-Dist: chromadb>=0.5; extra == 'import-chroma'
39
+ Provides-Extra: import-faiss
40
+ Requires-Dist: faiss-cpu>=1.8; extra == 'import-faiss'
41
+ Requires-Dist: numpy>=1.26; extra == 'import-faiss'
42
+ Provides-Extra: import-files
43
+ Requires-Dist: duckdb>=1.0; extra == 'import-files'
44
+ Requires-Dist: numpy>=1.26; extra == 'import-files'
45
+ Requires-Dist: pyarrow>=15; extra == 'import-files'
46
+ Provides-Extra: import-hnswlib
47
+ Requires-Dist: hnswlib>=0.8; extra == 'import-hnswlib'
48
+ Requires-Dist: numpy>=1.26; extra == 'import-hnswlib'
49
+ Provides-Extra: import-lancedb
50
+ Requires-Dist: lancedb>=0.9; extra == 'import-lancedb'
51
+ Requires-Dist: pyarrow>=15; extra == 'import-lancedb'
52
+ Provides-Extra: import-langchain
53
+ Requires-Dist: faiss-cpu>=1.8; extra == 'import-langchain'
54
+ Requires-Dist: langchain-core>=0.2; extra == 'import-langchain'
55
+ Provides-Extra: import-letta
56
+ Requires-Dist: letta-client>=0.1; extra == 'import-letta'
57
+ Provides-Extra: import-llamaindex
58
+ Requires-Dist: llama-index-core>=0.10; extra == 'import-llamaindex'
59
+ Provides-Extra: import-mem0
60
+ Requires-Dist: mem0ai<0.2,>=0.1; extra == 'import-mem0'
61
+ Provides-Extra: import-milvus
62
+ Requires-Dist: pymilvus>=2.4; extra == 'import-milvus'
63
+ Provides-Extra: import-mongodb
64
+ Requires-Dist: pymongo>=4.6; extra == 'import-mongodb'
65
+ Provides-Extra: import-openai
66
+ Requires-Dist: openai>=1.40; extra == 'import-openai'
67
+ Provides-Extra: import-pgvector
68
+ Requires-Dist: psycopg[binary]>=3.1; extra == 'import-pgvector'
69
+ Provides-Extra: import-pinecone
70
+ Requires-Dist: pinecone>=5; extra == 'import-pinecone'
71
+ Provides-Extra: import-qdrant
72
+ Requires-Dist: qdrant-client>=1.9; extra == 'import-qdrant'
73
+ Provides-Extra: import-redis
74
+ Requires-Dist: redis>=5; extra == 'import-redis'
75
+ Provides-Extra: import-sqlite-vec
76
+ Requires-Dist: sqlite-vec>=0.1.1; extra == 'import-sqlite-vec'
77
+ Provides-Extra: import-zep
78
+ Requires-Dist: zep-cloud>=2; extra == 'import-zep'
79
+ Provides-Extra: langchain
80
+ Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
81
+ Provides-Extra: llamaindex
82
+ Requires-Dist: llama-index-core>=0.10.0; extra == 'llamaindex'
83
+ Provides-Extra: phidata
84
+ Requires-Dist: phidata>=2.4.0; extra == 'phidata'
85
+ Provides-Extra: pydantic-ai
86
+ Requires-Dist: pydantic-ai>=0.0.14; extra == 'pydantic-ai'
87
+ Provides-Extra: semantic-kernel
88
+ Requires-Dist: semantic-kernel>=1.39.4; extra == 'semantic-kernel'
89
+ Provides-Extra: smolagents
90
+ Requires-Dist: smolagents>=1.0.0; extra == 'smolagents'
91
+ Description-Content-Type: text/markdown
92
+
93
+ <a href="https://writerslogic.com/warm/"><img src="https://raw.githubusercontent.com/writerslogic/warm/main/assets/crystal-halo/crystal-detailed-static.png" width="96" alt="WARM logo" align="left"></a>
94
+
95
+ # WARM SDK
96
+
97
+ Python HTTP client and framework adapters for a WARM service.
98
+
99
+ [Website](https://writerslogic.com/warm/) · [Documentation](https://writerslogic.com/warm/docs/) · [Source](https://github.com/writerslogic/warm) · [License](https://github.com/writerslogic/warm/blob/main/LICENSE)
100
+
101
+ <br clear="left">
102
+
103
+ The client talks to `warm-server`, which ships in the WARM repository. The server
104
+ stores vectors you supply and exposes document and query endpoints. See the
105
+ [server guide](https://writerslogic.com/warm/docs/latest/SERVER/) to run it.
106
+
107
+ ## Installation
108
+
109
+ ```bash
110
+ uv add warm-sdk
111
+ ```
112
+
113
+ Framework adapters are optional extras. Install one, or all of them:
114
+
115
+ ```bash
116
+ uv add "warm-sdk[langchain]"
117
+ uv add "warm-sdk[all]"
118
+ ```
119
+
120
+ The earlier standalone `langchain-holographic` distribution is retired. For LangChain, install
121
+ `warm-sdk[langchain]` and import `WarmVectorStore` from
122
+ `writerslogic_warm_sdk.langchain`. This adapter connects to `warm-server`; update the old
123
+ `langchain_holographic` import and its local-store configuration when migrating.
124
+
125
+ The `fast` extra adds `orjson` for request encoding, which cuts the per-query cost of sending an embedding:
126
+
127
+ ```bash
128
+ uv add "warm-sdk[fast]"
129
+ ```
130
+
131
+ Requires Python 3.10 or newer.
132
+
133
+ ## Quick Start
134
+
135
+ ```python
136
+ from writerslogic_warm_sdk import WarmClient
137
+
138
+ client = WarmClient(url="http://localhost:8080", api_key="...")
139
+
140
+ client.add_documents([
141
+ {"id": "doc-1", "text": "Paris is the capital of France.", "vector": [0.12, -0.03, 0.88], "metadata": {"lang": "en"}},
142
+ ])
143
+
144
+ response = client.query(query_vector=[0.10, -0.01, 0.90], top_k=3, filter={"lang": "en"})
145
+ print(response["matches"])
146
+ client.delete_document("doc-1")
147
+ client.close()
148
+ ```
149
+
150
+ `AsyncWarmClient` has the same methods as coroutines; close it with `await client.aclose()`. Embeddings come from your own model: the SDK sends vectors, it does not compute them.
151
+
152
+ After bulk ingestion, `client.maintain_document_index()` explicitly builds the server's
153
+ exact dense document index and returns `{"documentIndexTrained": true}` when the
154
+ store is eligible. Smaller or unsupported stores return `false` and use exact scanning.
155
+ Use `await client.maintain_document_index()` with the async client. Rebuild after updates
156
+ or restart; the index is a runtime cache. Searches preserve the existing cosine results,
157
+ and metadata filters continue to apply before ranking. This method requires an
158
+ `warm-server` version exposing `POST /api/v1/index/maintain`.
159
+
160
+ ## Source Evidence
161
+
162
+ `complete_evidence` packs complete source observations in your retrieval order. Each observation contains a turn handle, session handle, observation time, role, and verbatim text. Supply opaque caller IDs as lowercase SHA-256 hex handles, and keep their association with your original records.
163
+
164
+ ```python
165
+ from hashlib import sha256
166
+ from writerslogic_warm_sdk import complete_evidence, decode_source_packet
167
+
168
+ def handle(identity):
169
+ return sha256(identity.encode("utf-8")).hexdigest()
170
+
171
+ session = handle("session-7")
172
+ candidates = [
173
+ [(handle("turn-1"), session, "2026-10-13T10:00:00Z", "user",
174
+ "I have two aquarium tanks.")],
175
+ [(handle("turn-2"), session, "2026-10-13T10:00:00Z", "assistant",
176
+ "You mentioned two aquarium tanks.")],
177
+ ]
178
+
179
+ selection = complete_evidence(candidates, selected=[0], budget_bytes=2048)
180
+ observations = decode_source_packet(selection.packet)
181
+ assert observations == [candidates[index] for index in selection.selected]
182
+ ```
183
+
184
+ The indices in `selected` are mandatory; packing raises `ValueError` if they exceed the budget. Additional complete groups fit in candidate order, with shared text and session metadata stored once. Decoding preserves every occurrence, role, observation time, and source text. The budget counts UTF-8 packet bytes; measure reader tokens separately. Packets contain source observations and no inferred answer or event date. These helpers run locally and make no service calls.
185
+
186
+ ## Integrations
187
+
188
+ | Framework | Extra | Import |
189
+ |-----------|-------|--------|
190
+ | LangChain | `langchain` | `from writerslogic_warm_sdk.langchain import WarmVectorStore` |
191
+ | LlamaIndex | `llamaindex` | `from writerslogic_warm_sdk.llamaindex import WarmVectorStore` |
192
+ | Haystack | `haystack` | `from writerslogic_warm_sdk.haystack import WarmDocumentStore` |
193
+ | Semantic Kernel | `semantic-kernel` | `from writerslogic_warm_sdk.semantic_kernel import WarmMemoryStore` |
194
+ | DSPy | `dspy` | `from writerslogic_warm_sdk.dspy import WarmRM` |
195
+ | CrewAI | `crewai` | `from writerslogic_warm_sdk.crewai import WarmSearchTool` |
196
+ | Embedchain | `embedchain` | `from writerslogic_warm_sdk.embedchain import WarmDB` |
197
+ | Phidata | `phidata` | `from writerslogic_warm_sdk.phidata import WarmVectorDb` |
198
+ | Pydantic AI | `pydantic-ai` | `from writerslogic_warm_sdk.pydantic_ai import get_warm_tool` |
199
+ | SmolAgents | `smolagents` | `from writerslogic_warm_sdk.smolagents import WarmSearchTool` |
200
+
201
+ ## Vector Masking
202
+
203
+ Passing `zero_trust_key` masks every embedding client-side with a keyed signed permutation (`VectorMask`, scrypt-derived). The server can still rank vectors because inner products and cosine similarity are preserved exactly. This is obfuscation, **not encryption**: the server learns all pairwise similarities, and known plain/masked pairs reveal the key for the coordinates they cover. Pass a per-collection `mask_salt` (at least 16 bytes) shared by all clients of that collection. Masks produced by 0.1.0/0.1.1 are not compatible and were not secure.
204
+
205
+ ## License
206
+
207
+ Apache-2.0. See the [LICENSE](https://github.com/writerslogic/warm/blob/main/LICENSE).
@@ -0,0 +1,70 @@
1
+ writerslogic_warm_sdk/__init__.py,sha256=F-9QymU9-vU4MrK7QqbPceAAVSyCxuTT27MMv8n7TNo,489
2
+ writerslogic_warm_sdk/_transport.py,sha256=mXryLv1Ad9HpYxxBYEbD-UomDyXPSId5nWAt3MHRG78,4877
3
+ writerslogic_warm_sdk/client.py,sha256=sFmZUHLI53DEG5eBotWp8NolrUgEHFFBVVhrflc8Qf4,10537
4
+ writerslogic_warm_sdk/evidence.py,sha256=lT__Mxs8nQNT7vFbZVfDplnjivYHDX2eh6KBqJvQPjQ,9896
5
+ writerslogic_warm_sdk/memory.py,sha256=s-Ewt9VnYRmKj-nY7UFoJXIix4N6vzhSus9v8bcNGdE,27445
6
+ writerslogic_warm_sdk/memory.pyi,sha256=zzoSpvBeTobI9gZOtMH4D6t8UzmW7RVlrpSgLC2LfC4,7798
7
+ writerslogic_warm_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ writerslogic_warm_sdk/crewai/__init__.py,sha256=uH8ejfkrKotkES9TL5uVoZt1znbNCmtWxOM3XXRSouU,140
9
+ writerslogic_warm_sdk/crewai/tools.py,sha256=BAIqCf2Xa1maCLKoLO07HJ1ZTAMJhFqD3QJyo_JMHZU,1553
10
+ writerslogic_warm_sdk/dspy/__init__.py,sha256=Y1XLmRhIFqFg3BfRWlujBTplxTeB8RiPO40uPpbD3BM,104
11
+ writerslogic_warm_sdk/dspy/retriever.py,sha256=HQy1EqCnuSGMHS4jFF9elEghCDZPfXGZGNpELaz5IRQ,1425
12
+ writerslogic_warm_sdk/embedchain/__init__.py,sha256=TYSIXCif4sRHMe4rpKXumcDrmwzM_mhNPqmrbCCcM2w,103
13
+ writerslogic_warm_sdk/embedchain/vectordb.py,sha256=aSEwfWEcXoUL-_sgsFYWqpcYpmZ6S4jZ1HVByJIAxYs,1846
14
+ writerslogic_warm_sdk/haystack/__init__.py,sha256=2u1HpQnc3NlefyKnA3PXRsN4KOaAIzEkrbkV2EBqZBo,164
15
+ writerslogic_warm_sdk/haystack/document_store.py,sha256=unzBhOhFD2_gc78koDsLxcJtRhRedVpETqye8yILHmU,1351
16
+ writerslogic_warm_sdk/importers/__init__.py,sha256=frLqXmUBsEz9JmZL1K6yhmfhbNXeKq-m1SQR7DSBLTs,1023
17
+ writerslogic_warm_sdk/importers/checkpoint.py,sha256=xHyI41cXlthPkNLv4r1CjbFkoYX-z-L-CceFs4QGWGA,4085
18
+ writerslogic_warm_sdk/importers/cli.py,sha256=dajPGc-D8ifoA1LFlaFotV_IbLXkWmgGSgznRZIPLXQ,10059
19
+ writerslogic_warm_sdk/importers/common.py,sha256=X4vS76a2EQhFOp5jN00_g9h3p5g4YYJzc_9Cn1GTXh0,7475
20
+ writerslogic_warm_sdk/importers/inventory.py,sha256=wphY4jlOPvPGKarhinwibsppm5buRVQrbpmwVziXoLI,5867
21
+ writerslogic_warm_sdk/importers/mapping.py,sha256=CIHP9HNdPfVlmpXIsOSuoldhps0TFuOJ6FOSRDLHwDA,15833
22
+ writerslogic_warm_sdk/importers/model.py,sha256=MxpWnrRFejSOI2oXCoG7lM3pPIoegp5_IR8cLas8WU4,2737
23
+ writerslogic_warm_sdk/importers/options.py,sha256=b45AfRQlS5Jx2Mycas3UbJU2Ceuhd3drKgQdXloJqmg,5558
24
+ writerslogic_warm_sdk/importers/pipeline.py,sha256=_XEIzb9SNxKxTvLWa00ElYHeWmNdNe68TK8m-k_omUw,14441
25
+ writerslogic_warm_sdk/importers/report.py,sha256=TLzq7WlCE_782rbeT9E-ankEJYqxn_0GP7xNmD2a9j0,7130
26
+ writerslogic_warm_sdk/importers/sink.py,sha256=Ci8ydS6xZl7KCqU8-GPLcLI2nR39BNtWzd2cQ9uVd68,10802
27
+ writerslogic_warm_sdk/importers/verify.py,sha256=n6UPiBSXC9T_CNgVinQCyxtblt7OUvJUUeVrkHKk3I0,9902
28
+ writerslogic_warm_sdk/importers/sources/__init__.py,sha256=UPb-nxwbF5DPy0Oq0oFay1st7cYs_JvOZWZvdc1iZEo,2209
29
+ writerslogic_warm_sdk/importers/sources/_fields.py,sha256=ov_X5GFdOhS2ze-fHIExXrgYivu1IC7PHlyb7vyQwaY,3987
30
+ writerslogic_warm_sdk/importers/sources/_sidecar.py,sha256=z9sM6bNTM7_NYCuMMxD560PEb1X29i7IBtyHlTZGFSY,4957
31
+ writerslogic_warm_sdk/importers/sources/annoy.py,sha256=QMq6LcyTjWM5S9zYbY2CHJpl7qafEuQA40ZsSsMLSNw,4774
32
+ writerslogic_warm_sdk/importers/sources/base.py,sha256=dAYNeKoqDjz5zuqZbQdfTV4AN10uCSmcWPp36cWMyKg,6123
33
+ writerslogic_warm_sdk/importers/sources/chroma.py,sha256=XFas-eQtVXFRtl3heaRcWfStQw0HJD72GZPUvuj43lY,5645
34
+ writerslogic_warm_sdk/importers/sources/elastic.py,sha256=kzN4Sebg8h32MLuTmFk6FnJ6WhDKZMtdFCp9uM-H9As,12119
35
+ writerslogic_warm_sdk/importers/sources/faiss.py,sha256=xaG7nu-pKiiFtjZu3YMtN4pafJ3VSgp6wTOBUhg5KpE,7255
36
+ writerslogic_warm_sdk/importers/sources/files.py,sha256=vzBJm2MIaHSXSrv9VM3M4qndW_riXfgnA8S3ltEzDYU,14613
37
+ writerslogic_warm_sdk/importers/sources/hnswlib.py,sha256=0QgMz09Om8QOQJEOrH0xyaGTE0UIzx9BmfbjNCg9cRo,6331
38
+ writerslogic_warm_sdk/importers/sources/lancedb.py,sha256=yht5yXrskDCh_glU7brCg3Ml6q9xq77zzArHGrsnpFA,5011
39
+ writerslogic_warm_sdk/importers/sources/langchain.py,sha256=HUj5TdRRM6X5m-W7MJWvYVi6OfrFswJ1dcellV9E57s,9678
40
+ writerslogic_warm_sdk/importers/sources/letta.py,sha256=Cmw_NIcb70fKqotOsNQymVyx1SgxPCH0TmWjwZs4pu0,7092
41
+ writerslogic_warm_sdk/importers/sources/llamaindex.py,sha256=7xsgWJHKmBZLWtefKX6w6OWDiLiVR7Qa5x10F8kGev0,6721
42
+ writerslogic_warm_sdk/importers/sources/markdown.py,sha256=xUMn7VldaLyRrQT_yj1EBk-SLtMSFXoGo2aPHr89rxc,8942
43
+ writerslogic_warm_sdk/importers/sources/mem0.py,sha256=Cm9G_ANaDOGwhA8IiOJt0z74o6y2ZNGII7ImUNiIEpQ,14877
44
+ writerslogic_warm_sdk/importers/sources/milvus.py,sha256=SMSY-iEy5OFo32Q6NK1rEAaOtoQ0R7X0cKNX4Rc18xU,9562
45
+ writerslogic_warm_sdk/importers/sources/mongodb.py,sha256=d38ZsZ7xV_aOy3C_v9XYK5CrdOmpfmnpx7JKxwQhiCk,7154
46
+ writerslogic_warm_sdk/importers/sources/openai_vs.py,sha256=kziGazhEHReOfwsHbK3o-lMBMOQU8gWV2aK_ymEYFBo,5529
47
+ writerslogic_warm_sdk/importers/sources/pgvector.py,sha256=J8hodWJn9e5GOnS9Dq5iRcWnN-8QfYWHQ2KuAHrBalw,6278
48
+ writerslogic_warm_sdk/importers/sources/pinecone.py,sha256=uMLrlUDVMhPLC4Mxd2AaLOKrzI4Ukw-cy3O9Xhc6Hpg,8810
49
+ writerslogic_warm_sdk/importers/sources/qdrant.py,sha256=3xeaAheL5XHb3dLbnk2A0ei5NnDsISDzowB_Sd_aBdE,8055
50
+ writerslogic_warm_sdk/importers/sources/redis.py,sha256=_YzATwkpczUDOxglRxVWsU6LJzx30-6krL3Do4PjihE,10450
51
+ writerslogic_warm_sdk/importers/sources/sqlite_vec.py,sha256=MfXisCeCi0gaMjp4e77rZaoosnUCCxUNnmK0ZP3eJ8w,7112
52
+ writerslogic_warm_sdk/importers/sources/vespa.py,sha256=swyU8B0iEofQzGoGQCQqvS5_Vm2f9uxl4HcwHQtEyyQ,11381
53
+ writerslogic_warm_sdk/importers/sources/weaviate.py,sha256=PJnoQlj5_a8EOIzrSQL8iRSsKtrgICtorl70rOKn44w,8749
54
+ writerslogic_warm_sdk/importers/sources/zep.py,sha256=jlIj9V-W-Quouf9e6NsXaMmAUIQeetZfD9sd8SF1qfE,7544
55
+ writerslogic_warm_sdk/langchain/__init__.py,sha256=jRX6kZbFQbdEnO8eyhZV4ERwBjIhtu3iWGA8PaCe7FE,152
56
+ writerslogic_warm_sdk/langchain/vectorstores.py,sha256=yYrWJvyBTDr-RYh6u91R0r8Qg1wOdoe2dC234YTc6lE,2290
57
+ writerslogic_warm_sdk/llamaindex/__init__.py,sha256=jRX6kZbFQbdEnO8eyhZV4ERwBjIhtu3iWGA8PaCe7FE,152
58
+ writerslogic_warm_sdk/llamaindex/vectorstores.py,sha256=PxgWvDeQVcXPIhTM5EOCa8iMTP5RXOkL56NxF42EFV0,2232
59
+ writerslogic_warm_sdk/phidata/__init__.py,sha256=zS_KNdVKWN2v4cpUbjZrFqeSRKQAd-0KLRJ4VvmxVhw,133
60
+ writerslogic_warm_sdk/phidata/vectordb.py,sha256=XG2Idqd8ZqwXzx-SrTRExQt2Vyg99_E8mbqjzxA8iNE,1998
61
+ writerslogic_warm_sdk/pydantic_ai/__init__.py,sha256=KWf_yRn9Uk1zjBRnlVuk4Nd-ZxskM3zcNFnTZBNj44k,220
62
+ writerslogic_warm_sdk/pydantic_ai/tools.py,sha256=1AkkJn0qwM1gSbNcq5gO4tEp4l0jUbh5ld-_O8fqSHc,1378
63
+ writerslogic_warm_sdk/semantic_kernel/__init__.py,sha256=B6Y8_TMBbv0CjhxYy914TpEd995vJdGmxNwqda6VMDU,72
64
+ writerslogic_warm_sdk/semantic_kernel/memory_store.py,sha256=jBwOmj4wjGvCWvsd6Gm-KMw3nw6_E9ordQC8OJ3aSJU,3511
65
+ writerslogic_warm_sdk/smolagents/__init__.py,sha256=uH8ejfkrKotkES9TL5uVoZt1znbNCmtWxOM3XXRSouU,140
66
+ writerslogic_warm_sdk/smolagents/tools.py,sha256=eZ5DfnAR3AwmLuJt_NHqE_oniFaqSqmISXKTz3bNGPQ,1673
67
+ warm_sdk-0.1.3.dist-info/METADATA,sha256=pvqIx5HgyAYPT7i-nTzNNnp0mF5e6NzG3QvGswyqyBw,9724
68
+ warm_sdk-0.1.3.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
69
+ warm_sdk-0.1.3.dist-info/entry_points.txt,sha256=HNtyKHRP7dGA9OGlhAWHeGXLWCpcRmi6LZMBNLDDZ6g,73
70
+ warm_sdk-0.1.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ warm-import = writerslogic_warm_sdk.importers.cli:main
@@ -0,0 +1,21 @@
1
+ from .client import AsyncWarmClient, WarmClient, WarmError, VectorMask
2
+ from .memory import AsyncMemoryClient, MemoryClient
3
+ from .evidence import (
4
+ EvidenceSelection,
5
+ complete_evidence,
6
+ decode_source_packet,
7
+ encode_source_packet,
8
+ )
9
+
10
+ __all__ = [
11
+ "WarmClient",
12
+ "AsyncWarmClient",
13
+ "WarmError",
14
+ "VectorMask",
15
+ "MemoryClient",
16
+ "AsyncMemoryClient",
17
+ "EvidenceSelection",
18
+ "complete_evidence",
19
+ "decode_source_packet",
20
+ "encode_source_packet",
21
+ ]
@@ -0,0 +1,118 @@
1
+ """Keep-alive HTTP/1.1 transport on ``http.client`` for plain-HTTP service URLs.
2
+
3
+ httpx's default transport frames each request through httpcore and h11, which costs more per
4
+ call on loopback than the server spends answering a vector query. This transport keeps one
5
+ persistent ``http.client`` connection per thread and hands httpx a complete response, so the
6
+ ``httpx.Client`` API, its errors and its response objects stay the same.
7
+ """
8
+
9
+ import http.client
10
+ import os
11
+ import select
12
+ import socket
13
+ import threading
14
+ from typing import List, Optional
15
+
16
+ import httpx
17
+
18
+ _PROXY_VARS = ("http_proxy", "https_proxy", "all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY")
19
+
20
+
21
+ def usable_for(url: str) -> bool:
22
+ """True for a plain ``http`` URL with no proxy configured in the environment.
23
+
24
+ Passing any transport to ``httpx.Client`` turns off its environment proxies, so a URL that
25
+ a proxy variable could apply to keeps httpx's own transport.
26
+ """
27
+ return httpx.URL(url).scheme == "http" and not any(os.environ.get(v) for v in _PROXY_VARS)
28
+
29
+
30
+ def _timeout(request: httpx.Request) -> Optional[float]:
31
+ timeout = request.extensions.get("timeout") or {}
32
+ values = [v for v in (timeout.get("connect"), timeout.get("read"), timeout.get("write")) if v is not None]
33
+ return max(values) if values else None
34
+
35
+
36
+ def _stale(conn: http.client.HTTPConnection) -> bool:
37
+ """An idle keep-alive socket that is readable has been closed (or poisoned) by the peer."""
38
+ sock = conn.sock
39
+ if sock is None:
40
+ return False
41
+ try:
42
+ readable, _, _ = select.select([sock], [], [], 0)
43
+ except (OSError, ValueError):
44
+ return True
45
+ return bool(readable)
46
+
47
+
48
+ class KeepAliveTransport(httpx.BaseTransport):
49
+ def __init__(self) -> None:
50
+ self._local = threading.local()
51
+ self._lock = threading.Lock()
52
+ self._conns: List[http.client.HTTPConnection] = []
53
+
54
+ def _connection(self, request: httpx.Request, timeout: Optional[float]) -> http.client.HTTPConnection:
55
+ url = request.url
56
+ key = (url.host, url.port)
57
+ conn: Optional[http.client.HTTPConnection] = getattr(self._local, "conn", None)
58
+ if conn is not None and getattr(self._local, "key", None) != key:
59
+ conn.close()
60
+ with self._lock:
61
+ self._conns.remove(conn)
62
+ conn = None
63
+ elif conn is not None and _stale(conn):
64
+ # http.client reopens a closed connection object on the next request.
65
+ conn.close()
66
+ if conn is None:
67
+ conn = http.client.HTTPConnection(url.host, url.port or 80, timeout=timeout)
68
+ self._local.conn, self._local.key = conn, key
69
+ with self._lock:
70
+ self._conns.append(conn)
71
+ elif conn.sock is not None:
72
+ conn.sock.settimeout(timeout)
73
+ conn.timeout = timeout
74
+ return conn
75
+
76
+ def handle_request(self, request: httpx.Request) -> httpx.Response:
77
+ timeout = _timeout(request)
78
+ conn = self._connection(request, timeout)
79
+ connecting = conn.sock is None
80
+ try:
81
+ conn.putrequest(request.method, request.url.raw_path.decode("ascii"), skip_host=True, skip_accept_encoding=True)
82
+ chunked = False
83
+ for name, value in request.headers.raw:
84
+ conn.putheader(name, value)
85
+ chunked = chunked or (name.lower() == b"transfer-encoding" and value.lower() == b"chunked")
86
+ body = request.read()
87
+ if chunked:
88
+ conn.endheaders([body] if body else [], encode_chunked=True)
89
+ else:
90
+ conn.endheaders(body or None)
91
+ res = conn.getresponse()
92
+ body = res.read()
93
+ except socket.timeout as exc:
94
+ conn.close()
95
+ raise (httpx.ConnectTimeout if connecting else httpx.ReadTimeout)(str(exc), request=request) from exc
96
+ except (http.client.HTTPException, ConnectionError) as exc:
97
+ conn.close()
98
+ if connecting and isinstance(exc, ConnectionRefusedError):
99
+ raise httpx.ConnectError(str(exc), request=request) from exc
100
+ raise httpx.RemoteProtocolError(str(exc) or type(exc).__name__, request=request) from exc
101
+ except OSError as exc:
102
+ conn.close()
103
+ raise (httpx.ConnectError if connecting else httpx.ReadError)(str(exc), request=request) from exc
104
+ if res.will_close:
105
+ conn.close()
106
+ return httpx.Response(
107
+ res.status,
108
+ headers=res.getheaders(),
109
+ stream=httpx.ByteStream(body),
110
+ request=request,
111
+ extensions={"http_version": b"HTTP/1.1", "reason_phrase": res.reason.encode("ascii", "replace")},
112
+ )
113
+
114
+ def close(self) -> None:
115
+ with self._lock:
116
+ conns, self._conns = self._conns, []
117
+ for conn in conns:
118
+ conn.close()