vectorwave 0.2.4__tar.gz → 0.2.6__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.4 → vectorwave-0.2.6}/PKG-INFO +29 -10
- vectorwave-0.2.4/src/vectorwave.egg-info/PKG-INFO → vectorwave-0.2.6/Readme.md +18 -26
- vectorwave-0.2.6/crates/Cargo.lock +259 -0
- vectorwave-0.2.6/crates/Cargo.toml +14 -0
- vectorwave-0.2.6/crates/src/lib.rs +193 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/pyproject.toml +10 -5
- vectorwave-0.2.6/src/vectorwave/batch/batch.py +176 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/tracer.py +9 -32
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/replayer.py +2 -2
- vectorwave-0.2.4/LICENSE +0 -21
- vectorwave-0.2.4/MANIFEST.in +0 -2
- vectorwave-0.2.4/NOTICE +0 -31
- vectorwave-0.2.4/Readme.md +0 -635
- vectorwave-0.2.4/setup.cfg +0 -4
- vectorwave-0.2.4/src/tests/batch/test_batch.py +0 -161
- vectorwave-0.2.4/src/tests/conftest.py +0 -27
- vectorwave-0.2.4/src/tests/core/llm/test_token_usage.py +0 -112
- vectorwave-0.2.4/src/tests/core/test_auto_injector.py +0 -228
- vectorwave-0.2.4/src/tests/core/test_auto_injector_real.py +0 -111
- vectorwave-0.2.4/src/tests/core/test_decorator.py +0 -345
- vectorwave-0.2.4/src/tests/core/test_semantic_caching.py +0 -372
- vectorwave-0.2.4/src/tests/database/test_archiver.py +0 -232
- vectorwave-0.2.4/src/tests/database/test_dataset.py +0 -97
- vectorwave-0.2.4/src/tests/database/test_db.py +0 -471
- vectorwave-0.2.4/src/tests/database/test_db_search.py +0 -163
- vectorwave-0.2.4/src/tests/models/test_db_config.py +0 -186
- vectorwave-0.2.4/src/tests/monitoring/alert/test_alerter.py +0 -70
- vectorwave-0.2.4/src/tests/monitoring/test_async_trace.py +0 -282
- vectorwave-0.2.4/src/tests/monitoring/test_tracer.py +0 -353
- vectorwave-0.2.4/src/tests/search/test_execution_search.py +0 -145
- vectorwave-0.2.4/src/tests/utils/test_function_cahe.py +0 -127
- vectorwave-0.2.4/src/tests/utils/test_replay_source.py +0 -140
- vectorwave-0.2.4/src/tests/utils/test_replayer.py +0 -247
- vectorwave-0.2.4/src/tests/utils/test_return_caching.py +0 -213
- vectorwave-0.2.4/src/tests/utils/test_status.py +0 -126
- vectorwave-0.2.4/src/tests/vectorizer/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/batch/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/batch/batch.py +0 -176
- vectorwave-0.2.4/src/vectorwave/core/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/core/llm/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/database/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/exception/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/models/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/monitoring/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/monitoring/alert/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/prediction/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/search/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/utils/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave/vectorizer/__init__.py +0 -0
- vectorwave-0.2.4/src/vectorwave.egg-info/SOURCES.txt +0 -92
- vectorwave-0.2.4/src/vectorwave.egg-info/dependency_links.txt +0 -1
- vectorwave-0.2.4/src/vectorwave.egg-info/requires.txt +0 -5
- vectorwave-0.2.4/src/vectorwave.egg-info/top_level.txt +0 -2
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/__init__.py +0 -0
- {vectorwave-0.2.4/src/tests → vectorwave-0.2.6/src/vectorwave/batch}/__init__.py +0 -0
- {vectorwave-0.2.4/src/tests/batch → vectorwave-0.2.6/src/vectorwave/core}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/auto_injector.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/core.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/decorator.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/generator.py +0 -0
- {vectorwave-0.2.4/src/tests/core → vectorwave-0.2.6/src/vectorwave/core/llm}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/llm/base.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/llm/factory.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/core/llm/openai_client.py +0 -0
- {vectorwave-0.2.4/src/tests/core/llm → vectorwave-0.2.6/src/vectorwave/database}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/database/archiver.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/database/dataset.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/database/db.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/database/db_search.py +0 -0
- {vectorwave-0.2.4/src/tests/database → vectorwave-0.2.6/src/vectorwave/exception}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/exception/exceptions.py +0 -0
- {vectorwave-0.2.4/src/tests/exception → vectorwave-0.2.6/src/vectorwave/models}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/models/db_config.py +0 -0
- {vectorwave-0.2.4/src/tests/models → vectorwave-0.2.6/src/vectorwave/monitoring}/__init__.py +0 -0
- {vectorwave-0.2.4/src/tests/monitoring → vectorwave-0.2.6/src/vectorwave/monitoring/alert}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/alert/base.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/alert/factory.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/alert/null_alerter.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/alert/webhook_alerter.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/monitoring/monitoring.py +0 -0
- {vectorwave-0.2.4/src/tests/monitoring/alert → vectorwave-0.2.6/src/vectorwave/prediction}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/prediction/predictor.py +0 -0
- {vectorwave-0.2.4/src/tests/prediction → vectorwave-0.2.6/src/vectorwave/search}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/search/execution_search.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/search/extended_search.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/search/rag_search.py +0 -0
- {vectorwave-0.2.4/src/tests/search → vectorwave-0.2.6/src/vectorwave/utils}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/context.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/function_cache.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/healer.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/replayer_semantic.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/return_caching_utils.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/utils/status.py +0 -0
- {vectorwave-0.2.4/src/tests/utils → vectorwave-0.2.6/src/vectorwave/vectorizer}/__init__.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/vectorizer/base.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/vectorizer/factory.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/vectorizer/huggingface_vectorizer.py +0 -0
- {vectorwave-0.2.4 → vectorwave-0.2.6}/src/vectorwave/vectorizer/openai_vectorizer.py +0 -0
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vectorwave
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: VectorWave: Seamless Auto-Vectorization Framework
|
|
5
|
-
Author-email: junyeonggim <junyeonggim5@gmail.com>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Repository, https://github.com/cozymori/vectorwave
|
|
3
|
+
Version: 0.2.6
|
|
8
4
|
Classifier: Programming Language :: Python :: 3
|
|
9
5
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
6
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
7
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
8
|
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
+
Classifier: Programming Language :: Rust
|
|
13
10
|
Classifier: Operating System :: OS Independent
|
|
14
11
|
Classifier: Development Status :: 3 - Alpha
|
|
15
12
|
Classifier: Intended Audience :: Developers
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
License-File: NOTICE
|
|
20
13
|
Requires-Dist: weaviate-client>=4.0.0
|
|
21
14
|
Requires-Dist: pydantic-settings>=2.0.0
|
|
22
15
|
Requires-Dist: sentence-transformers
|
|
23
16
|
Requires-Dist: requests
|
|
24
17
|
Requires-Dist: openai
|
|
25
|
-
|
|
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
26
|
|
|
27
27
|
|
|
28
28
|
# VectorWave: Seamless Auto-Vectorization Framework
|
|
@@ -652,6 +652,24 @@ import my_service.payment
|
|
|
652
652
|
my_service.payment.process_transaction()
|
|
653
653
|
```
|
|
654
654
|
|
|
655
|
+
## 🌌 Ecosystem
|
|
656
|
+
|
|
657
|
+
VectorWave is part of a larger ecosystem designed to optimize the entire lifecycle of AI engineering, from observability to testing.
|
|
658
|
+
|
|
659
|
+
### 🏄♂️ [VectorSurfer](https://github.com/cozymori/vectorsurfer)
|
|
660
|
+
> **Visualize your AI flows instantly.**
|
|
661
|
+
**VectorSurfer** is a comprehensive dashboard for VectorWave. It allows you to visualize execution traces, monitor error rates in real-time, and manage self-healing processes through an intuitive web interface.
|
|
662
|
+
* **Trace Visualization:** View complex execution flows (Spans) and latency waterfalls at a glance.
|
|
663
|
+
* **Error Monitoring:** Track error trends and inspect detailed failure logs.
|
|
664
|
+
* **Healer Interface:** Review and apply code fixes suggested by the VectorWave Healer.
|
|
665
|
+
|
|
666
|
+
### ✅ [VectorCheck](https://github.com/cozymori/vectorcheck)
|
|
667
|
+
> **Test your AI with "Intent", not just strings.**
|
|
668
|
+
**VectorCheck** is an AI-native regression testing framework. Instead of brittle exact string matching (`assert a == b`), it uses vector similarity to validate if the AI's output matches the intended meaning ("Golden Data").
|
|
669
|
+
* **Semantic Assertions:** Pass tests if the output is *semantically* similar to the expected result, even if the wording differs.
|
|
670
|
+
* **Golden Data Replay:** Automatically fetch and replay successful production logs to verify new code changes.
|
|
671
|
+
* **CLI Dashboard:** Run tests and view results directly in your terminal with zero configuration.
|
|
672
|
+
|
|
655
673
|
## 🤝 Contributing
|
|
656
674
|
|
|
657
675
|
We welcome all forms of contributions, including bug reports, feature requests, and code contributions. Please refer to [CONTRIBUTING.md](https://www.google.com/search?q=httpsS://www.google.com/search%3Fq%3DCONTRIBUTING.md) for details.
|
|
@@ -659,3 +677,4 @@ We welcome all forms of contributions, including bug reports, feature requests,
|
|
|
659
677
|
## 📜 License
|
|
660
678
|
|
|
661
679
|
This project is distributed under the MIT License. Please check the [LICENSE](https://www.google.com/search?q=LICENSE) file for details.
|
|
680
|
+
|
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: vectorwave
|
|
3
|
-
Version: 0.2.4
|
|
4
|
-
Summary: VectorWave: Seamless Auto-Vectorization Framework
|
|
5
|
-
Author-email: junyeonggim <junyeonggim5@gmail.com>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Repository, https://github.com/cozymori/vectorwave
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
-
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Development Status :: 3 - Alpha
|
|
15
|
-
Classifier: Intended Audience :: Developers
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
License-File: NOTICE
|
|
20
|
-
Requires-Dist: weaviate-client>=4.0.0
|
|
21
|
-
Requires-Dist: pydantic-settings>=2.0.0
|
|
22
|
-
Requires-Dist: sentence-transformers
|
|
23
|
-
Requires-Dist: requests
|
|
24
|
-
Requires-Dist: openai
|
|
25
|
-
Dynamic: license-file
|
|
26
|
-
|
|
27
1
|
|
|
28
2
|
# VectorWave: Seamless Auto-Vectorization Framework
|
|
29
3
|
|
|
@@ -652,6 +626,24 @@ import my_service.payment
|
|
|
652
626
|
my_service.payment.process_transaction()
|
|
653
627
|
```
|
|
654
628
|
|
|
629
|
+
## 🌌 Ecosystem
|
|
630
|
+
|
|
631
|
+
VectorWave is part of a larger ecosystem designed to optimize the entire lifecycle of AI engineering, from observability to testing.
|
|
632
|
+
|
|
633
|
+
### 🏄♂️ [VectorSurfer](https://github.com/cozymori/vectorsurfer)
|
|
634
|
+
> **Visualize your AI flows instantly.**
|
|
635
|
+
**VectorSurfer** is a comprehensive dashboard for VectorWave. It allows you to visualize execution traces, monitor error rates in real-time, and manage self-healing processes through an intuitive web interface.
|
|
636
|
+
* **Trace Visualization:** View complex execution flows (Spans) and latency waterfalls at a glance.
|
|
637
|
+
* **Error Monitoring:** Track error trends and inspect detailed failure logs.
|
|
638
|
+
* **Healer Interface:** Review and apply code fixes suggested by the VectorWave Healer.
|
|
639
|
+
|
|
640
|
+
### ✅ [VectorCheck](https://github.com/cozymori/vectorcheck)
|
|
641
|
+
> **Test your AI with "Intent", not just strings.**
|
|
642
|
+
**VectorCheck** is an AI-native regression testing framework. Instead of brittle exact string matching (`assert a == b`), it uses vector similarity to validate if the AI's output matches the intended meaning ("Golden Data").
|
|
643
|
+
* **Semantic Assertions:** Pass tests if the output is *semantically* similar to the expected result, even if the wording differs.
|
|
644
|
+
* **Golden Data Replay:** Automatically fetch and replay successful production logs to verify new code changes.
|
|
645
|
+
* **CLI Dashboard:** Run tests and view results directly in your terminal with zero configuration.
|
|
646
|
+
|
|
655
647
|
## 🤝 Contributing
|
|
656
648
|
|
|
657
649
|
We welcome all forms of contributions, including bug reports, feature requests, and code contributions. Please refer to [CONTRIBUTING.md](https://www.google.com/search?q=httpsS://www.google.com/search%3Fq%3DCONTRIBUTING.md) for details.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.0"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "cfg-if"
|
|
13
|
+
version = "1.0.4"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "crossbeam-channel"
|
|
19
|
+
version = "0.5.15"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
|
22
|
+
dependencies = [
|
|
23
|
+
"crossbeam-utils",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "crossbeam-utils"
|
|
28
|
+
version = "0.8.21"
|
|
29
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "heck"
|
|
34
|
+
version = "0.5.0"
|
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
36
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "indoc"
|
|
40
|
+
version = "2.0.7"
|
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
43
|
+
dependencies = [
|
|
44
|
+
"rustversion",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[[package]]
|
|
48
|
+
name = "itoa"
|
|
49
|
+
version = "1.0.16"
|
|
50
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
51
|
+
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
|
52
|
+
|
|
53
|
+
[[package]]
|
|
54
|
+
name = "libc"
|
|
55
|
+
version = "0.2.178"
|
|
56
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
57
|
+
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
|
58
|
+
|
|
59
|
+
[[package]]
|
|
60
|
+
name = "memchr"
|
|
61
|
+
version = "2.7.6"
|
|
62
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
63
|
+
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
|
64
|
+
|
|
65
|
+
[[package]]
|
|
66
|
+
name = "memoffset"
|
|
67
|
+
version = "0.9.1"
|
|
68
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
69
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
70
|
+
dependencies = [
|
|
71
|
+
"autocfg",
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[[package]]
|
|
75
|
+
name = "once_cell"
|
|
76
|
+
version = "1.21.3"
|
|
77
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
78
|
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
79
|
+
|
|
80
|
+
[[package]]
|
|
81
|
+
name = "portable-atomic"
|
|
82
|
+
version = "1.12.0"
|
|
83
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
84
|
+
checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd"
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "proc-macro2"
|
|
88
|
+
version = "1.0.103"
|
|
89
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
+
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
|
91
|
+
dependencies = [
|
|
92
|
+
"unicode-ident",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[[package]]
|
|
96
|
+
name = "pyo3"
|
|
97
|
+
version = "0.23.5"
|
|
98
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
99
|
+
checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
|
|
100
|
+
dependencies = [
|
|
101
|
+
"cfg-if",
|
|
102
|
+
"indoc",
|
|
103
|
+
"libc",
|
|
104
|
+
"memoffset",
|
|
105
|
+
"once_cell",
|
|
106
|
+
"portable-atomic",
|
|
107
|
+
"pyo3-build-config",
|
|
108
|
+
"pyo3-ffi",
|
|
109
|
+
"pyo3-macros",
|
|
110
|
+
"unindent",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
[[package]]
|
|
114
|
+
name = "pyo3-build-config"
|
|
115
|
+
version = "0.23.5"
|
|
116
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
+
checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
|
|
118
|
+
dependencies = [
|
|
119
|
+
"once_cell",
|
|
120
|
+
"target-lexicon",
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
[[package]]
|
|
124
|
+
name = "pyo3-ffi"
|
|
125
|
+
version = "0.23.5"
|
|
126
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
127
|
+
checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
|
|
128
|
+
dependencies = [
|
|
129
|
+
"libc",
|
|
130
|
+
"pyo3-build-config",
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
[[package]]
|
|
134
|
+
name = "pyo3-macros"
|
|
135
|
+
version = "0.23.5"
|
|
136
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
137
|
+
checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
|
|
138
|
+
dependencies = [
|
|
139
|
+
"proc-macro2",
|
|
140
|
+
"pyo3-macros-backend",
|
|
141
|
+
"quote",
|
|
142
|
+
"syn",
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
[[package]]
|
|
146
|
+
name = "pyo3-macros-backend"
|
|
147
|
+
version = "0.23.5"
|
|
148
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
149
|
+
checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
|
|
150
|
+
dependencies = [
|
|
151
|
+
"heck",
|
|
152
|
+
"proc-macro2",
|
|
153
|
+
"pyo3-build-config",
|
|
154
|
+
"quote",
|
|
155
|
+
"syn",
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
[[package]]
|
|
159
|
+
name = "quote"
|
|
160
|
+
version = "1.0.42"
|
|
161
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
162
|
+
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
|
163
|
+
dependencies = [
|
|
164
|
+
"proc-macro2",
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
[[package]]
|
|
168
|
+
name = "rustversion"
|
|
169
|
+
version = "1.0.22"
|
|
170
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
171
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
172
|
+
|
|
173
|
+
[[package]]
|
|
174
|
+
name = "ryu"
|
|
175
|
+
version = "1.0.21"
|
|
176
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
+
checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea"
|
|
178
|
+
|
|
179
|
+
[[package]]
|
|
180
|
+
name = "serde"
|
|
181
|
+
version = "1.0.228"
|
|
182
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
183
|
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
184
|
+
dependencies = [
|
|
185
|
+
"serde_core",
|
|
186
|
+
"serde_derive",
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
[[package]]
|
|
190
|
+
name = "serde_core"
|
|
191
|
+
version = "1.0.228"
|
|
192
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
193
|
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
194
|
+
dependencies = [
|
|
195
|
+
"serde_derive",
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
[[package]]
|
|
199
|
+
name = "serde_derive"
|
|
200
|
+
version = "1.0.228"
|
|
201
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
202
|
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
203
|
+
dependencies = [
|
|
204
|
+
"proc-macro2",
|
|
205
|
+
"quote",
|
|
206
|
+
"syn",
|
|
207
|
+
]
|
|
208
|
+
|
|
209
|
+
[[package]]
|
|
210
|
+
name = "serde_json"
|
|
211
|
+
version = "1.0.145"
|
|
212
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
213
|
+
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
|
214
|
+
dependencies = [
|
|
215
|
+
"itoa",
|
|
216
|
+
"memchr",
|
|
217
|
+
"ryu",
|
|
218
|
+
"serde",
|
|
219
|
+
"serde_core",
|
|
220
|
+
]
|
|
221
|
+
|
|
222
|
+
[[package]]
|
|
223
|
+
name = "syn"
|
|
224
|
+
version = "2.0.111"
|
|
225
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
226
|
+
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
|
227
|
+
dependencies = [
|
|
228
|
+
"proc-macro2",
|
|
229
|
+
"quote",
|
|
230
|
+
"unicode-ident",
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
[[package]]
|
|
234
|
+
name = "target-lexicon"
|
|
235
|
+
version = "0.12.16"
|
|
236
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
237
|
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
238
|
+
|
|
239
|
+
[[package]]
|
|
240
|
+
name = "unicode-ident"
|
|
241
|
+
version = "1.0.22"
|
|
242
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
243
|
+
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
|
244
|
+
|
|
245
|
+
[[package]]
|
|
246
|
+
name = "unindent"
|
|
247
|
+
version = "0.2.4"
|
|
248
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
249
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
250
|
+
|
|
251
|
+
[[package]]
|
|
252
|
+
name = "vectorwave_core"
|
|
253
|
+
version = "0.1.0"
|
|
254
|
+
dependencies = [
|
|
255
|
+
"crossbeam-channel",
|
|
256
|
+
"pyo3",
|
|
257
|
+
"serde",
|
|
258
|
+
"serde_json",
|
|
259
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "vectorwave_core"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
|
|
6
|
+
[lib]
|
|
7
|
+
name = "vectorwave_core"
|
|
8
|
+
crate-type = ["cdylib"]
|
|
9
|
+
|
|
10
|
+
[dependencies]
|
|
11
|
+
pyo3 = { version = "0.23.3", features = ["extension-module"] }
|
|
12
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
13
|
+
serde_json = "1.0"
|
|
14
|
+
crossbeam-channel = "0.5"
|
|
@@ -0,0 +1,193 @@
|
|
|
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 crossbeam_channel::{bounded, Receiver, Sender, TrySendError};
|
|
7
|
+
|
|
8
|
+
struct LogItem {
|
|
9
|
+
collection: PyObject,
|
|
10
|
+
properties: Py<PyDict>,
|
|
11
|
+
uuid: Option<PyObject>,
|
|
12
|
+
vector: Option<Vec<f32>>,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#[pyclass]
|
|
16
|
+
struct RustBatchManager {
|
|
17
|
+
sender: Sender<LogItem>,
|
|
18
|
+
flush_callback: PyObject,
|
|
19
|
+
worker_handle: Option<thread::JoinHandle<()>>,
|
|
20
|
+
stop_signal: Sender<()>,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
#[pymethods]
|
|
24
|
+
impl RustBatchManager {
|
|
25
|
+
#[new]
|
|
26
|
+
fn new(
|
|
27
|
+
py: Python<'_>,
|
|
28
|
+
callback: PyObject,
|
|
29
|
+
batch_threshold: usize,
|
|
30
|
+
flush_interval_ms: u64,
|
|
31
|
+
) -> Self {
|
|
32
|
+
let (tx, rx) = bounded::<LogItem>(10000);
|
|
33
|
+
let (stop_tx, stop_rx) = bounded(1);
|
|
34
|
+
|
|
35
|
+
let worker_callback = callback.clone_ref(py);
|
|
36
|
+
|
|
37
|
+
let handle = thread::spawn(move || {
|
|
38
|
+
Self::worker_loop(rx, stop_rx, worker_callback, batch_threshold, flush_interval_ms);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
RustBatchManager {
|
|
42
|
+
sender: tx,
|
|
43
|
+
flush_callback: callback,
|
|
44
|
+
worker_handle: Some(handle),
|
|
45
|
+
stop_signal: stop_tx,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#[pyo3(signature = (collection, properties, uuid=None, vector=None))]
|
|
50
|
+
fn add_object(
|
|
51
|
+
&self,
|
|
52
|
+
collection: PyObject,
|
|
53
|
+
properties: Py<PyDict>,
|
|
54
|
+
uuid: Option<PyObject>,
|
|
55
|
+
vector: Option<Vec<f32>>,
|
|
56
|
+
) {
|
|
57
|
+
let item = LogItem {
|
|
58
|
+
collection,
|
|
59
|
+
properties,
|
|
60
|
+
uuid,
|
|
61
|
+
vector,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
match self.sender.try_send(item) {
|
|
65
|
+
Ok(_) => {},
|
|
66
|
+
Err(TrySendError::Full(_)) => {
|
|
67
|
+
eprintln!("[RustCore] 🚨 Queue Full! Dropping log item.");
|
|
68
|
+
},
|
|
69
|
+
Err(TrySendError::Disconnected(_)) => {
|
|
70
|
+
eprintln!("[RustCore] ❌ Channel disconnected.");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fn shutdown(&self) {
|
|
76
|
+
let _ = self.stop_signal.send(());
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
impl RustBatchManager {
|
|
81
|
+
fn worker_loop(
|
|
82
|
+
rx: Receiver<LogItem>,
|
|
83
|
+
stop_rx: Receiver<()>,
|
|
84
|
+
callback: PyObject,
|
|
85
|
+
threshold: usize,
|
|
86
|
+
interval_ms: u64,
|
|
87
|
+
) {
|
|
88
|
+
let mut buffer = Vec::with_capacity(threshold);
|
|
89
|
+
let mut last_flush = Instant::now();
|
|
90
|
+
let flush_interval = Duration::from_millis(interval_ms);
|
|
91
|
+
|
|
92
|
+
loop {
|
|
93
|
+
if let Ok(_) = stop_rx.try_recv() {
|
|
94
|
+
if !buffer.is_empty() {
|
|
95
|
+
Self::flush_buffer(&buffer, &callback);
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
match rx.recv_timeout(Duration::from_millis(100)) {
|
|
101
|
+
Ok(item) => buffer.push(item),
|
|
102
|
+
Err(_) => {}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let time_since_flush = last_flush.elapsed();
|
|
106
|
+
if buffer.len() >= threshold || (time_since_flush >= flush_interval && !buffer.is_empty()) {
|
|
107
|
+
Self::flush_buffer(&buffer, &callback);
|
|
108
|
+
buffer.clear();
|
|
109
|
+
last_flush = Instant::now();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fn flush_buffer(buffer: &Vec<LogItem>, callback: &PyObject) {
|
|
115
|
+
Python::with_gil(|py| {
|
|
116
|
+
let py_list = PyList::empty_bound(py);
|
|
117
|
+
|
|
118
|
+
for item in buffer {
|
|
119
|
+
let dict = PyDict::new_bound(py);
|
|
120
|
+
let _ = dict.set_item("collection", &item.collection);
|
|
121
|
+
let _ = dict.set_item("properties", &item.properties);
|
|
122
|
+
|
|
123
|
+
if let Some(uuid) = &item.uuid {
|
|
124
|
+
let _ = dict.set_item("uuid", uuid);
|
|
125
|
+
} else {
|
|
126
|
+
let _ = dict.set_item("uuid", py.None());
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if let Some(vec) = &item.vector {
|
|
130
|
+
let _ = dict.set_item("vector", vec);
|
|
131
|
+
} else {
|
|
132
|
+
let _ = dict.set_item("vector", py.None());
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let _ = py_list.append(dict);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if let Err(e) = callback.call1(py, (py_list,)) {
|
|
139
|
+
eprintln!("[RustCore] ❌ Callback failed: {}", e);
|
|
140
|
+
e.print_and_set_sys_last_vars(py);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
fn process_recursive(py: Python, value: &Bound<'_, PyAny>, sensitive_set: &HashSet<String>) -> PyResult<PyObject> {
|
|
148
|
+
if let Ok(dict_obj) = value.downcast::<PyDict>() {
|
|
149
|
+
let new_dict = PyDict::new_bound(py);
|
|
150
|
+
for (k, v) in dict_obj {
|
|
151
|
+
let k_str = k.to_string().to_lowercase();
|
|
152
|
+
if sensitive_set.contains(&k_str) {
|
|
153
|
+
new_dict.set_item(k, "[MASKED]")?;
|
|
154
|
+
} else {
|
|
155
|
+
new_dict.set_item(k, process_recursive(py, &v, sensitive_set)?)?;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
Ok(new_dict.into())
|
|
159
|
+
} else if let Ok(list_obj) = value.downcast::<PyList>() {
|
|
160
|
+
let new_list = PyList::empty_bound(py);
|
|
161
|
+
for item in list_obj {
|
|
162
|
+
new_list.append(process_recursive(py, &item, sensitive_set)?)?;
|
|
163
|
+
}
|
|
164
|
+
Ok(new_list.into())
|
|
165
|
+
} else {
|
|
166
|
+
if value.is_none()
|
|
167
|
+
|| value.is_instance_of::<PyBool>()
|
|
168
|
+
|| value.is_instance_of::<PyFloat>()
|
|
169
|
+
|| value.is_instance_of::<PyInt>()
|
|
170
|
+
|| value.is_instance_of::<PyString>() {
|
|
171
|
+
// [수정] unbind()를 사용하여 PyObject로 변환
|
|
172
|
+
Ok(value.clone().unbind())
|
|
173
|
+
} else {
|
|
174
|
+
match value.str() {
|
|
175
|
+
Ok(s) => Ok(s.into()),
|
|
176
|
+
Err(_) => Ok(PyString::new_bound(py, "[SERIALIZATION_ERROR]").into())
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#[pyfunction]
|
|
183
|
+
fn mask_and_serialize(py: Python, data: &Bound<'_, PyAny>, sensitive_keys: Vec<String>) -> PyResult<PyObject> {
|
|
184
|
+
let sensitive_set: HashSet<String> = sensitive_keys.into_iter().map(|s| s.to_lowercase()).collect();
|
|
185
|
+
process_recursive(py, data, &sensitive_set)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#[pymodule]
|
|
189
|
+
fn vectorwave_core(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
190
|
+
m.add_class::<RustBatchManager>()?;
|
|
191
|
+
m.add_function(wrap_pyfunction!(mask_and_serialize, m)?)?;
|
|
192
|
+
Ok(())
|
|
193
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["
|
|
3
|
-
build-backend = "
|
|
2
|
+
requires = ["maturin>=1.5,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
[project]
|
|
6
7
|
name = "vectorwave"
|
|
7
|
-
version = "0.2.
|
|
8
|
+
version = "0.2.06"
|
|
8
9
|
authors = [
|
|
9
10
|
{ name = "junyeonggim", email = "junyeonggim5@gmail.com" },
|
|
10
11
|
]
|
|
@@ -18,6 +19,7 @@ classifiers = [
|
|
|
18
19
|
"Programming Language :: Python :: 3.11",
|
|
19
20
|
"Programming Language :: Python :: 3.12",
|
|
20
21
|
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Rust",
|
|
21
23
|
"Operating System :: OS Independent",
|
|
22
24
|
"Development Status :: 3 - Alpha",
|
|
23
25
|
"Intended Audience :: Developers",
|
|
@@ -34,5 +36,8 @@ dependencies = [
|
|
|
34
36
|
[project.urls]
|
|
35
37
|
Repository = "https://github.com/cozymori/vectorwave"
|
|
36
38
|
|
|
37
|
-
[tool.
|
|
38
|
-
|
|
39
|
+
[tool.maturin]
|
|
40
|
+
python-source = "src"
|
|
41
|
+
module-name = "vectorwave.vectorwave_core"
|
|
42
|
+
manifest-path = "crates/Cargo.toml"
|
|
43
|
+
features = ["pyo3/extension-module"]
|