ruvector-ruvllm 0.2.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.
@@ -0,0 +1,68 @@
1
+ """Bounded full precision token caches backed by native ruvllm Rust code."""
2
+ from __future__ import annotations
3
+
4
+ import numpy as np
5
+ from numpy.typing import ArrayLike, NDArray
6
+ from ruvector import KVCache
7
+
8
+ __all__ = ["KVCache", "TokenCache"]
9
+
10
+
11
+ class TokenCache:
12
+ """Row-shaped interface to the native KVCache.
13
+
14
+ append accepts (tokens, dimensions) arrays. Attention is a single
15
+ flattened head, not a model inference or text generation API.
16
+ """
17
+
18
+ def __init__(self, dimensions: int, max_tokens: int = 4096) -> None:
19
+ if isinstance(dimensions, bool) or isinstance(max_tokens, bool):
20
+ raise ValueError("dimensions and max_tokens must be integers, not booleans")
21
+ self._cache = KVCache(dimensions, max_tokens)
22
+
23
+ @property
24
+ def dimensions(self) -> int:
25
+ return self._cache.dimensions
26
+
27
+ @property
28
+ def max_tokens(self) -> int:
29
+ return self._cache.max_tokens
30
+
31
+ def __len__(self) -> int:
32
+ return len(self._cache)
33
+
34
+ def append(self, keys: ArrayLike, values: ArrayLike) -> None:
35
+ """Append matching token matrices, without eviction or quantization.
36
+
37
+ Finite values must have magnitude at most 1e10. Conversion to
38
+ float32 may copy input arrays. Invalid input never changes the cache.
39
+ """
40
+ k = np.asarray(keys)
41
+ v = np.asarray(values)
42
+ if k.ndim != 2 or v.shape != k.shape or k.shape[1] != self.dimensions:
43
+ raise ValueError("keys and values must share shape (tokens, dimensions)")
44
+ if k.shape[0] == 0 or k.shape[0] > self.max_tokens - len(self):
45
+ raise ValueError("empty batch or cache capacity exceeded")
46
+ for data in (k, v):
47
+ if data.dtype.kind not in "iuf" or not np.isfinite(data).all() or (np.abs(data.astype(np.float64)) > 1e10).any():
48
+ raise ValueError("coordinates must be finite real numbers with magnitude <= 1e10")
49
+ self._cache.append(k.astype(np.float32).ravel().tolist(), v.astype(np.float32).ravel().tolist())
50
+
51
+ def attend(self, query: ArrayLike, scale: float | None = None) -> NDArray[np.float32]:
52
+ """Return softmax attention output; default scale = 1/sqrt(dimensions)."""
53
+ q = np.asarray(query)
54
+ if q.shape != (self.dimensions,) or q.dtype.kind not in "iuf":
55
+ raise ValueError("query must be a real vector with shape (dimensions,)")
56
+ if not np.isfinite(q).all() or (np.abs(q.astype(np.float64)) > 1e10).any():
57
+ raise ValueError("query must be finite with magnitude <= 1e10")
58
+ return np.asarray(self._cache.attend(q.astype(np.float32).tolist(), scale), dtype=np.float32)
59
+
60
+ def get_all(self) -> tuple[NDArray[np.float32], NDArray[np.float32]]:
61
+ """Return copied (keys, values) matrices in insertion order."""
62
+ keys, values = self._cache.get_all()
63
+ return (np.asarray(keys, dtype=np.float32).reshape(-1, self.dimensions),
64
+ np.asarray(values, dtype=np.float32).reshape(-1, self.dimensions))
65
+
66
+ def clear(self) -> None:
67
+ """Discard all cached tokens."""
68
+ self._cache.clear()
File without changes
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: ruvector-ruvllm
3
+ Version: 0.2.0
4
+ Summary: Bounded native Rust key value cache and attention primitives for Python LLM pipelines
5
+ Project-URL: Homepage, https://github.com/ruvnet/RuVector
6
+ Project-URL: Documentation, https://github.com/ruvnet/RuVector/tree/main/python/portfolio/ruvector-ruvllm
7
+ Project-URL: Repository, https://github.com/ruvnet/RuVector
8
+ Project-URL: Issues, https://github.com/ruvnet/RuVector/issues
9
+ Project-URL: Changelog, https://github.com/ruvnet/RuVector/blob/main/python/portfolio/CHANGELOG.md
10
+ Author: RuVector Team
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: attention,kv-cache,llm,rust,ruvector
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Rust
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: numpy>=1.21
20
+ Requires-Dist: ruvector==0.1.3
21
+ Description-Content-Type: text/markdown
22
+
23
+ # ruvector-ruvllm: Native Rust KV cache for Python
24
+
25
+ ![Animated ruvllm token cache and attention overview](https://raw.githubusercontent.com/ruvnet/RuVector/main/docs/python-portfolio/ruvllm.svg)
26
+
27
+ ## What is ruvector-ruvllm?
28
+
29
+ A bounded CPU key/value cache and attention primitive for Python LLM pipelines, backed by the actual `ruvllm` Rust crate. Store key/value token vectors and query them with scaled dot product attention. This focused Python package exposes cache operations, **not text generation or full npm ruvllm feature parity**. No model weights or hosted services are required.
30
+
31
+ ## Getting started
32
+
33
+ Requires Python 3.10 or newer and a platform supported by `ruvector==0.1.3` native wheels.
34
+
35
+ ```bash
36
+ pip install ruvector-ruvllm==0.2.0
37
+ ```
38
+
39
+ This version requires publication of both the package and its pinned native runtime before that command works. In a source checkout, build/install the native SDK first, then install `./python/portfolio/ruvector-ruvllm`.
40
+
41
+ ```python
42
+ from ruvector_ruvllm import TokenCache
43
+
44
+ cache = TokenCache(dimensions=2, max_tokens=128)
45
+ cache.append(keys=[[1.0, 0.0], [0.0, 1.0]],
46
+ values=[[2.0, 4.0], [8.0, 10.0]])
47
+ answer = cache.attend([1.0, 0.0])
48
+ assert answer.shape == (2,)
49
+ assert len(cache) == 2
50
+ keys, values = cache.get_all()
51
+ assert keys.shape == values.shape == (2, 2)
52
+ cache.clear()
53
+ assert len(cache) == 0
54
+ ```
55
+
56
+ ## Architecture
57
+
58
+ ```mermaid
59
+ flowchart TD
60
+ A[Python token matrices] --> B[Shape and finite value validation]
61
+ B --> C[PyO3 KVCache]
62
+ C --> D[ruvllm full precision cache]
63
+ D --> E[Scaled softmax attention output]
64
+ ```
65
+
66
+ The shared runtime keeps computation in Rust. The row-shaped Python interface converts inputs to float32. For flat inputs, `from ruvector_ruvllm import KVCache` exposes the native class directly.
67
+
68
+ ## API and limits
69
+
70
+ | Operation | Behavior |
71
+ | --- | --- |
72
+ | `TokenCache(dimensions, max_tokens=4096)` | Create an empty bounded cache |
73
+ | `append(keys, values)` | Add matching matrices shaped `(tokens, dimensions)` |
74
+ | `attend(query, scale=None)` | Return float32 vector; default scale is `1/sqrt(dimensions)` |
75
+ | `get_all()` | Copy all keys and values into matrices |
76
+ | `clear()` | Remove all tokens |
77
+ | `len(cache)` | Number of stored tokens |
78
+
79
+ Attention treats each token as one vector, not independent attention heads. The implementation retains full float32 precision, with no quantization, sliding window or automatic eviction. Capacity errors leave the cache unchanged. Empty-cache attention returns zeros.
80
+
81
+ Dimensions are limited to 4096, tokens to 65536, and their product to 8388608. Raw keys and values therefore occupy at most 64 MiB, excluding objects, conversion buffers and returned copies. Coordinates must be finite and have absolute value at most `1e10`. Isolate untrusted workloads with process memory limits because Python conversion can allocate before native validation.
82
+
83
+ ## Relationship to npm and Rust
84
+
85
+ Inspired by the popular npm `ruvllm` package, using the repository's real Rust cache implementation. This release does not expose model loading, tokenization, GPU inference, serving, learning or text generation. It ships a focused wrapper over the shared `ruvector` native runtime rather than a separate binary engine.
86
+
87
+ Source: [RuVector](https://github.com/ruvnet/RuVector). [Security policy](https://github.com/ruvnet/RuVector/blob/main/python/portfolio/SECURITY.md). License: MIT.
@@ -0,0 +1,6 @@
1
+ ruvector_ruvllm/__init__.py,sha256=yw3LdI7yOzzghDAlOKm7IVpvQLE_FwSpf3k_2hKCIR8,3092
2
+ ruvector_ruvllm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ ruvector_ruvllm-0.2.0.dist-info/METADATA,sha256=RDwBAq_jzyt1esDPiqlaG67caht1IYCnhib34UpSZDA,4382
4
+ ruvector_ruvllm-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
5
+ ruvector_ruvllm-0.2.0.dist-info/licenses/LICENSE,sha256=UP77k1YK9EITacmck8whTNg1sxgat_FjI_nm8t7YcOM,1060
6
+ ruvector_ruvllm-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 rUv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.