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.
- warm_sdk-0.1.3.dist-info/METADATA +207 -0
- warm_sdk-0.1.3.dist-info/RECORD +70 -0
- warm_sdk-0.1.3.dist-info/WHEEL +4 -0
- warm_sdk-0.1.3.dist-info/entry_points.txt +2 -0
- writerslogic_warm_sdk/__init__.py +21 -0
- writerslogic_warm_sdk/_transport.py +118 -0
- writerslogic_warm_sdk/client.py +281 -0
- writerslogic_warm_sdk/crewai/__init__.py +5 -0
- writerslogic_warm_sdk/crewai/tools.py +44 -0
- writerslogic_warm_sdk/dspy/__init__.py +5 -0
- writerslogic_warm_sdk/dspy/retriever.py +43 -0
- writerslogic_warm_sdk/embedchain/__init__.py +5 -0
- writerslogic_warm_sdk/embedchain/vectordb.py +59 -0
- writerslogic_warm_sdk/evidence.py +225 -0
- writerslogic_warm_sdk/haystack/__init__.py +5 -0
- writerslogic_warm_sdk/haystack/document_store.py +44 -0
- writerslogic_warm_sdk/importers/__init__.py +38 -0
- writerslogic_warm_sdk/importers/checkpoint.py +96 -0
- writerslogic_warm_sdk/importers/cli.py +189 -0
- writerslogic_warm_sdk/importers/common.py +214 -0
- writerslogic_warm_sdk/importers/inventory.py +103 -0
- writerslogic_warm_sdk/importers/mapping.py +364 -0
- writerslogic_warm_sdk/importers/model.py +79 -0
- writerslogic_warm_sdk/importers/options.py +114 -0
- writerslogic_warm_sdk/importers/pipeline.py +355 -0
- writerslogic_warm_sdk/importers/report.py +182 -0
- writerslogic_warm_sdk/importers/sink.py +254 -0
- writerslogic_warm_sdk/importers/sources/__init__.py +61 -0
- writerslogic_warm_sdk/importers/sources/_fields.py +117 -0
- writerslogic_warm_sdk/importers/sources/_sidecar.py +108 -0
- writerslogic_warm_sdk/importers/sources/annoy.py +102 -0
- writerslogic_warm_sdk/importers/sources/base.py +169 -0
- writerslogic_warm_sdk/importers/sources/chroma.py +122 -0
- writerslogic_warm_sdk/importers/sources/elastic.py +276 -0
- writerslogic_warm_sdk/importers/sources/faiss.py +153 -0
- writerslogic_warm_sdk/importers/sources/files.py +338 -0
- writerslogic_warm_sdk/importers/sources/hnswlib.py +127 -0
- writerslogic_warm_sdk/importers/sources/lancedb.py +117 -0
- writerslogic_warm_sdk/importers/sources/langchain.py +207 -0
- writerslogic_warm_sdk/importers/sources/letta.py +148 -0
- writerslogic_warm_sdk/importers/sources/llamaindex.py +128 -0
- writerslogic_warm_sdk/importers/sources/markdown.py +202 -0
- writerslogic_warm_sdk/importers/sources/mem0.py +303 -0
- writerslogic_warm_sdk/importers/sources/milvus.py +191 -0
- writerslogic_warm_sdk/importers/sources/mongodb.py +162 -0
- writerslogic_warm_sdk/importers/sources/openai_vs.py +110 -0
- writerslogic_warm_sdk/importers/sources/pgvector.py +140 -0
- writerslogic_warm_sdk/importers/sources/pinecone.py +181 -0
- writerslogic_warm_sdk/importers/sources/qdrant.py +170 -0
- writerslogic_warm_sdk/importers/sources/redis.py +223 -0
- writerslogic_warm_sdk/importers/sources/sqlite_vec.py +149 -0
- writerslogic_warm_sdk/importers/sources/vespa.py +233 -0
- writerslogic_warm_sdk/importers/sources/weaviate.py +186 -0
- writerslogic_warm_sdk/importers/sources/zep.py +144 -0
- writerslogic_warm_sdk/importers/verify.py +257 -0
- writerslogic_warm_sdk/langchain/__init__.py +5 -0
- writerslogic_warm_sdk/langchain/vectorstores.py +65 -0
- writerslogic_warm_sdk/llamaindex/__init__.py +5 -0
- writerslogic_warm_sdk/llamaindex/vectorstores.py +68 -0
- writerslogic_warm_sdk/memory.py +756 -0
- writerslogic_warm_sdk/memory.pyi +139 -0
- writerslogic_warm_sdk/phidata/__init__.py +5 -0
- writerslogic_warm_sdk/phidata/vectordb.py +61 -0
- writerslogic_warm_sdk/py.typed +0 -0
- writerslogic_warm_sdk/pydantic_ai/__init__.py +7 -0
- writerslogic_warm_sdk/pydantic_ai/tools.py +39 -0
- writerslogic_warm_sdk/semantic_kernel/__init__.py +2 -0
- writerslogic_warm_sdk/semantic_kernel/memory_store.py +95 -0
- writerslogic_warm_sdk/smolagents/__init__.py +5 -0
- 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,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()
|