vectorwave 0.2.6__tar.gz → 0.2.7__tar.gz
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.
- vectorwave-0.2.7/PKG-INFO +60 -0
- vectorwave-0.2.7/Readme.md +33 -0
- vectorwave-0.2.7/crates/src/lib.rs +171 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/pyproject.toml +1 -1
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/tracer.py +2 -2
- vectorwave-0.2.6/PKG-INFO +0 -680
- vectorwave-0.2.6/Readme.md +0 -653
- vectorwave-0.2.6/crates/src/lib.rs +0 -193
- {vectorwave-0.2.6 → vectorwave-0.2.7}/crates/Cargo.lock +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/crates/Cargo.toml +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/batch/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/batch/batch.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/auto_injector.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/core.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/decorator.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/generator.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/llm/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/llm/base.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/llm/factory.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/core/llm/openai_client.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/database/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/database/archiver.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/database/dataset.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/database/db.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/database/db_search.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/exception/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/exception/exceptions.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/models/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/models/db_config.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/alert/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/alert/base.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/alert/factory.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/alert/null_alerter.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/alert/webhook_alerter.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/monitoring/monitoring.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/prediction/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/prediction/predictor.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/search/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/search/execution_search.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/search/extended_search.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/search/rag_search.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/context.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/function_cache.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/healer.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/replayer.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/replayer_semantic.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/return_caching_utils.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/utils/status.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/vectorizer/__init__.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/vectorizer/base.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/vectorizer/factory.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/vectorizer/huggingface_vectorizer.py +0 -0
- {vectorwave-0.2.6 → vectorwave-0.2.7}/src/vectorwave/vectorizer/openai_vectorizer.py +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vectorwave
|
|
3
|
+
Version: 0.2.7
|
|
4
|
+
Classifier: Programming Language :: Python :: 3
|
|
5
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
+
Classifier: Programming Language :: Rust
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Requires-Dist: weaviate-client>=4.0.0
|
|
14
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
15
|
+
Requires-Dist: sentence-transformers
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Requires-Dist: openai
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
License-File: NOTICE
|
|
20
|
+
Summary: VectorWave: Seamless Auto-Vectorization Framework
|
|
21
|
+
Author-email: junyeonggim <junyeonggim5@gmail.com>
|
|
22
|
+
License-Expression: MIT
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
25
|
+
Project-URL: Repository, https://github.com/cozymori/vectorwave
|
|
26
|
+
|
|
27
|
+
Need more information? Visit [here](https://cozymori.github.io/vectorwave-docs/)
|
|
28
|
+
|
|
29
|
+
# VectorWave
|
|
30
|
+

|
|
31
|
+

|
|
32
|
+

|
|
33
|
+

|
|
34
|
+

|
|
35
|
+

|
|
36
|
+

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+
<br>**Seamless Auto-Vectorization Framework**
|
|
40
|
+
|
|
41
|
+
We transform volatile data that disappears the moment code is executed into a Searchable and Reusable permanent knowledge asset.
|
|
42
|
+
|
|
43
|
+
### Requirements
|
|
44
|
+
|
|
45
|
+
* **Python**: 3.10 ~ 3.13
|
|
46
|
+
* **Docker**: Required to run the Weaviate database.
|
|
47
|
+
* (Optional) **OpenAI API Key**: Required for AI auto-documentation and high-performance embedding.
|
|
48
|
+
|
|
49
|
+
### How to reach us
|
|
50
|
+
|
|
51
|
+
Have questions or found a bug? Please join our community.
|
|
52
|
+
|
|
53
|
+
* **GitHub Issues**: [https://github.com/cozymori/vectorwave/issues](https://github.com/cozymori/vectorwave/issues)
|
|
54
|
+
|
|
55
|
+
### Contributors
|
|
56
|
+
[See the contributors of vectorwave](https://github.com/Cozymori/VectorWave/graphs/contributors)<br>
|
|
57
|
+
VectorWave is an open-source project and we welcome your contributions.
|
|
58
|
+
Please refer to [CONTRIBUTING.md](https://www.google.com/search?q=https://github.com/cozymori/vectorwave/blob/main/CONTRIBUTING.md) in the GitHub repository.
|
|
59
|
+
|
|
60
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Need more information? Visit [here](https://cozymori.github.io/vectorwave-docs/)
|
|
2
|
+
|
|
3
|
+
# VectorWave
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
<br>**Seamless Auto-Vectorization Framework**
|
|
14
|
+
|
|
15
|
+
We transform volatile data that disappears the moment code is executed into a Searchable and Reusable permanent knowledge asset.
|
|
16
|
+
|
|
17
|
+
### Requirements
|
|
18
|
+
|
|
19
|
+
* **Python**: 3.10 ~ 3.13
|
|
20
|
+
* **Docker**: Required to run the Weaviate database.
|
|
21
|
+
* (Optional) **OpenAI API Key**: Required for AI auto-documentation and high-performance embedding.
|
|
22
|
+
|
|
23
|
+
### How to reach us
|
|
24
|
+
|
|
25
|
+
Have questions or found a bug? Please join our community.
|
|
26
|
+
|
|
27
|
+
* **GitHub Issues**: [https://github.com/cozymori/vectorwave/issues](https://github.com/cozymori/vectorwave/issues)
|
|
28
|
+
|
|
29
|
+
### Contributors
|
|
30
|
+
[See the contributors of vectorwave](https://github.com/Cozymori/VectorWave/graphs/contributors)<br>
|
|
31
|
+
VectorWave is an open-source project and we welcome your contributions.
|
|
32
|
+
Please refer to [CONTRIBUTING.md](https://www.google.com/search?q=https://github.com/cozymori/vectorwave/blob/main/CONTRIBUTING.md) in the GitHub repository.
|
|
33
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
use pyo3::prelude::*;
|
|
2
|
+
use pyo3::types::{PyDict, PyList, PyString, PyBool, PyFloat, PyInt};
|
|
3
|
+
use std::collections::HashSet;
|
|
4
|
+
use std::thread;
|
|
5
|
+
use std::time::{Duration, Instant};
|
|
6
|
+
use std::sync::Mutex;
|
|
7
|
+
use crossbeam_channel::{bounded, Receiver, Sender, TrySendError};
|
|
8
|
+
|
|
9
|
+
struct LogItem {
|
|
10
|
+
collection: PyObject,
|
|
11
|
+
properties: Py<PyDict>,
|
|
12
|
+
uuid: Option<PyObject>,
|
|
13
|
+
vector: Option<Vec<f32>>,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#[pyclass]
|
|
17
|
+
struct RustBatchManager {
|
|
18
|
+
sender: Sender<LogItem>,
|
|
19
|
+
#[allow(dead_code)]
|
|
20
|
+
flush_callback: PyObject,
|
|
21
|
+
worker_handle: Mutex<Option<thread::JoinHandle<()>>>,
|
|
22
|
+
stop_signal: Sender<()>,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[pymethods]
|
|
26
|
+
impl RustBatchManager {
|
|
27
|
+
#[new]
|
|
28
|
+
fn new(
|
|
29
|
+
py: Python<'_>,
|
|
30
|
+
callback: PyObject,
|
|
31
|
+
batch_threshold: usize,
|
|
32
|
+
flush_interval_ms: u64,
|
|
33
|
+
) -> Self {
|
|
34
|
+
let (tx, rx) = bounded::<LogItem>(10000);
|
|
35
|
+
let (stop_tx, stop_rx) = bounded(1);
|
|
36
|
+
let worker_callback = callback.clone_ref(py);
|
|
37
|
+
|
|
38
|
+
let handle = thread::spawn(move || {
|
|
39
|
+
Self::worker_loop(rx, stop_rx, worker_callback, batch_threshold, flush_interval_ms);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
RustBatchManager {
|
|
43
|
+
sender: tx,
|
|
44
|
+
flush_callback: callback,
|
|
45
|
+
worker_handle: Mutex::new(Some(handle)),
|
|
46
|
+
stop_signal: stop_tx,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#[pyo3(signature = (collection, properties, uuid=None, vector=None))]
|
|
51
|
+
fn add_object(&self, collection: PyObject, properties: Py<PyDict>, uuid: Option<PyObject>, vector: Option<Vec<f32>>) {
|
|
52
|
+
let item = LogItem { collection, properties, uuid, vector };
|
|
53
|
+
let _ = self.sender.try_send(item);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn shutdown(&self, py: Python<'_>) {
|
|
57
|
+
let _ = self.stop_signal.send(());
|
|
58
|
+
py.allow_threads(|| {
|
|
59
|
+
if let Ok(mut handle_guard) = self.worker_handle.lock() {
|
|
60
|
+
if let Some(handle) = handle_guard.take() {
|
|
61
|
+
let _ = handle.join();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
impl RustBatchManager {
|
|
69
|
+
fn worker_loop(rx: Receiver<LogItem>, stop_rx: Receiver<()>, callback: PyObject, threshold: usize, interval_ms: u64) {
|
|
70
|
+
let mut buffer = Vec::with_capacity(threshold);
|
|
71
|
+
let mut last_flush = Instant::now();
|
|
72
|
+
let flush_interval = Duration::from_millis(interval_ms);
|
|
73
|
+
|
|
74
|
+
loop {
|
|
75
|
+
crossbeam_channel::select! {
|
|
76
|
+
recv(stop_rx) -> msg => {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
recv(rx) -> msg => {
|
|
80
|
+
match msg {
|
|
81
|
+
Ok(item) => buffer.push(item),
|
|
82
|
+
Err(_) => break,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
default(Duration::from_millis(100)) => {}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
if stop_rx.is_empty() && (buffer.len() >= threshold || (last_flush.elapsed() >= flush_interval && !buffer.is_empty())) {
|
|
90
|
+
|
|
91
|
+
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
|
92
|
+
Self::flush_buffer(&buffer, &callback);
|
|
93
|
+
}));
|
|
94
|
+
buffer.clear();
|
|
95
|
+
last_flush = Instant::now();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
fn flush_buffer(buffer: &Vec<LogItem>, callback: &PyObject) {
|
|
101
|
+
Python::with_gil(|py| {
|
|
102
|
+
let py_list = PyList::empty(py);
|
|
103
|
+
|
|
104
|
+
for item in buffer {
|
|
105
|
+
let dict = PyDict::new(py);
|
|
106
|
+
let mut set_field = |key: &str, val: PyObject| -> bool {
|
|
107
|
+
if let Err(_) = dict.set_item(key, val) { return false; }
|
|
108
|
+
true
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if !set_field("collection", item.collection.clone_ref(py)) { continue; }
|
|
112
|
+
if !set_field("properties", item.properties.to_object(py)) { continue; }
|
|
113
|
+
let uuid_val = item.uuid.as_ref().map_or(py.None(), |u| u.clone_ref(py));
|
|
114
|
+
if !set_field("uuid", uuid_val) { continue; }
|
|
115
|
+
let vector_val = item.vector.as_ref().map_or(py.None(), |v| v.to_object(py));
|
|
116
|
+
if !set_field("vector", vector_val) { continue; }
|
|
117
|
+
|
|
118
|
+
if let Err(e) = py_list.append(dict) {
|
|
119
|
+
eprintln!("[RustCore] ⚠️ Failed to append item: {}", e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if let Err(e) = callback.call1(py, (py_list,)) {
|
|
124
|
+
eprintln!("[RustCore] ⚠️ Flush failed: {}", e);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fn process_recursive(py: Python, value: &Bound<'_, PyAny>, sensitive_set: &HashSet<String>) -> PyResult<PyObject> {
|
|
131
|
+
if let Ok(dict_obj) = value.downcast::<PyDict>() {
|
|
132
|
+
let new_dict = PyDict::new(py);
|
|
133
|
+
for (k, v) in dict_obj {
|
|
134
|
+
let k_str = k.to_string().to_lowercase();
|
|
135
|
+
if sensitive_set.contains(&k_str) {
|
|
136
|
+
new_dict.set_item(k, "[MASKED]")?;
|
|
137
|
+
} else {
|
|
138
|
+
new_dict.set_item(k, process_recursive(py, &v, sensitive_set)?)?;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
Ok(new_dict.into())
|
|
142
|
+
} else if let Ok(list_obj) = value.downcast::<PyList>() {
|
|
143
|
+
let new_list = PyList::empty(py);
|
|
144
|
+
for item in list_obj {
|
|
145
|
+
new_list.append(process_recursive(py, &item, sensitive_set)?)?;
|
|
146
|
+
}
|
|
147
|
+
Ok(new_list.into())
|
|
148
|
+
} else {
|
|
149
|
+
if value.is_none() || value.is_instance_of::<PyBool>() || value.is_instance_of::<PyFloat>() || value.is_instance_of::<PyInt>() || value.is_instance_of::<PyString>() {
|
|
150
|
+
Ok(value.clone().unbind())
|
|
151
|
+
} else {
|
|
152
|
+
match value.str() {
|
|
153
|
+
Ok(s) => Ok(s.into()),
|
|
154
|
+
Err(_) => Ok(PyString::new(py, "[SERIALIZATION_ERROR]").into())
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#[pyfunction]
|
|
161
|
+
fn mask_and_serialize(py: Python, data: &Bound<'_, PyAny>, sensitive_keys: Vec<String>) -> PyResult<PyObject> {
|
|
162
|
+
let sensitive_set: HashSet<String> = sensitive_keys.into_iter().map(|s| s.to_lowercase()).collect();
|
|
163
|
+
process_recursive(py, data, &sensitive_set)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#[pymodule]
|
|
167
|
+
fn vectorwave_core(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
168
|
+
m.add_class::<RustBatchManager>()?;
|
|
169
|
+
m.add_function(wrap_pyfunction!(mask_and_serialize, m)?)?;
|
|
170
|
+
Ok(())
|
|
171
|
+
}
|
|
@@ -332,7 +332,7 @@ def trace_span(
|
|
|
332
332
|
result=return_value_log
|
|
333
333
|
)
|
|
334
334
|
|
|
335
|
-
if tracer.settings.DRIFT_DETECTION_ENABLED and vector_to_add:
|
|
335
|
+
if tracer.settings.DRIFT_DETECTION_ENABLED and vector_to_add and status == "SUCCESS":
|
|
336
336
|
is_drift, dist, nearest_id = check_semantic_drift(
|
|
337
337
|
vector=vector_to_add,
|
|
338
338
|
function_name=func.__name__,
|
|
@@ -465,7 +465,7 @@ def trace_span(
|
|
|
465
465
|
result=return_value_log
|
|
466
466
|
)
|
|
467
467
|
|
|
468
|
-
if tracer.settings.DRIFT_DETECTION_ENABLED and vector_to_add:
|
|
468
|
+
if tracer.settings.DRIFT_DETECTION_ENABLED and vector_to_add and status == "SUCCESS":
|
|
469
469
|
is_drift, dist, nearest_id = check_semantic_drift(
|
|
470
470
|
vector=vector_to_add,
|
|
471
471
|
function_name=func.__name__,
|