vectorwave 0.2.9__tar.gz → 0.3.0__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.
Files changed (61) hide show
  1. {vectorwave-0.2.9 → vectorwave-0.3.0}/PKG-INFO +5 -2
  2. {vectorwave-0.2.9 → vectorwave-0.3.0}/Readme.md +4 -1
  3. {vectorwave-0.2.9 → vectorwave-0.3.0}/pyproject.toml +1 -1
  4. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/__init__.py +3 -2
  5. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/batch/batch.py +23 -5
  6. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/auto_injector.py +1 -1
  7. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/decorator.py +43 -35
  8. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/generator.py +2 -2
  9. vectorwave-0.3.0/src/vectorwave/core/initializer.py +37 -0
  10. vectorwave-0.3.0/src/vectorwave/core/llm/factory.py +10 -0
  11. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/database/dataset.py +10 -2
  12. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/database/db.py +127 -99
  13. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/database/db_search.py +4 -4
  14. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/models/db_config.py +3 -0
  15. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/tracer.py +199 -179
  16. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/search/execution_search.py +2 -20
  17. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/search/rag_search.py +2 -2
  18. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/healer.py +1 -1
  19. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/replayer.py +73 -51
  20. vectorwave-0.3.0/src/vectorwave/utils/replayer_semantic.py +130 -0
  21. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/return_caching_utils.py +2 -1
  22. vectorwave-0.3.0/src/vectorwave/utils/serialization.py +17 -0
  23. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/status.py +0 -4
  24. vectorwave-0.2.9/src/vectorwave/core/llm/factory.py +0 -13
  25. vectorwave-0.2.9/src/vectorwave/utils/replayer_semantic.py +0 -234
  26. {vectorwave-0.2.9 → vectorwave-0.3.0}/crates/Cargo.lock +0 -0
  27. {vectorwave-0.2.9 → vectorwave-0.3.0}/crates/Cargo.toml +0 -0
  28. {vectorwave-0.2.9 → vectorwave-0.3.0}/crates/src/lib.rs +0 -0
  29. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/batch/__init__.py +0 -0
  30. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/__init__.py +0 -0
  31. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/core.py +0 -0
  32. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/llm/__init__.py +0 -0
  33. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/llm/base.py +0 -0
  34. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/core/llm/openai_client.py +0 -0
  35. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/database/__init__.py +0 -0
  36. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/database/archiver.py +0 -0
  37. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/exception/__init__.py +0 -0
  38. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/exception/exceptions.py +0 -0
  39. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/models/__init__.py +0 -0
  40. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/__init__.py +0 -0
  41. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/alert/__init__.py +0 -0
  42. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/alert/base.py +0 -0
  43. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/alert/factory.py +0 -0
  44. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/alert/null_alerter.py +0 -0
  45. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/alert/webhook_alerter.py +0 -0
  46. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/monitoring/monitoring.py +0 -0
  47. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/prediction/__init__.py +0 -0
  48. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/prediction/predictor.py +0 -0
  49. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/search/__init__.py +0 -0
  50. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/search/extended_search.py +0 -0
  51. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/__init__.py +0 -0
  52. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/context.py +0 -0
  53. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/function_cache.py +0 -0
  54. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/github_pr.py +0 -0
  55. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/path_utils.py +0 -0
  56. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/utils/scheduler.py +0 -0
  57. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/vectorizer/__init__.py +0 -0
  58. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/vectorizer/base.py +0 -0
  59. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/vectorizer/factory.py +0 -0
  60. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/vectorizer/huggingface_vectorizer.py +0 -0
  61. {vectorwave-0.2.9 → vectorwave-0.3.0}/src/vectorwave/vectorizer/openai_vectorizer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectorwave
3
- Version: 0.2.9
3
+ Version: 0.3.0
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.10
6
6
  Classifier: Programming Language :: Python :: 3.11
@@ -26,7 +26,10 @@ Requires-Python: >=3.10
26
26
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
27
27
  Project-URL: Repository, https://github.com/cozymori/vectorwave
28
28
 
29
- Need more information? Visit [here](https://cozymori.github.io/vectorwave-docs/)
29
+
30
+ ![VectorWave Logo](./docs_kr/images/vectorwave.png)
31
+
32
+ Need more information? Visit [here](https://www.cozymori.net/vectorwave)
30
33
 
31
34
  # VectorWave
32
35
  ![Star](https://badgen.net/github/stars/cozymori/vectorwave)
@@ -1,4 +1,7 @@
1
- Need more information? Visit [here](https://cozymori.github.io/vectorwave-docs/)
1
+
2
+ ![VectorWave Logo](./docs_kr/images/vectorwave.png)
3
+
4
+ Need more information? Visit [here](https://www.cozymori.net/vectorwave)
2
5
 
3
6
  # VectorWave
4
7
  ![Star](https://badgen.net/github/stars/cozymori/vectorwave)
@@ -5,7 +5,7 @@ build-backend = "maturin"
5
5
 
6
6
  [project]
7
7
  name = "vectorwave"
8
- version = "0.2.09"
8
+ version = "0.3.0"
9
9
  authors = [
10
10
  { name = "junyeonggim", email = "junyeonggim5@gmail.com" },
11
11
  ]
@@ -1,5 +1,5 @@
1
1
  from .core.decorator import vectorize
2
- from .database.db import initialize_database
2
+ from .database.db import initialize_database, update_database_schema
3
3
  from .database.db_search import search_functions, search_executions, search_errors_by_message, search_functions_hybrid
4
4
  from .monitoring.tracer import trace_span
5
5
  from .search.rag_search import search_and_answer, analyze_trace_log
@@ -25,5 +25,6 @@ __all__ = [
25
25
  'VectorWaveReplayer',
26
26
  'SemanticReplayer',
27
27
  'VectorWaveDatasetManager',
28
- 'VectorWaveAutoInjector'
28
+ 'VectorWaveAutoInjector',
29
+ 'update_database_schema'
29
30
  ]
@@ -27,11 +27,18 @@ class WeaviateBatchManager:
27
27
  Uses High-Performance Rust Core if available, otherwise falls back to Python.
28
28
  """
29
29
 
30
- def __init__(self):
30
+ def __init__(self, host: Optional[str] = None, port: Optional[int] = None,
31
+ grpc_port: Optional[int] = None, api_key: Optional[str] = None):
31
32
  self._initialized = False
32
33
  self.settings: WeaviateSettings = get_weaviate_settings()
33
34
  self.client: Optional[weaviate.WeaviateClient] = None
34
35
 
36
+ # Store dynamic connection params
37
+ self._host = host
38
+ self._port = port
39
+ self._grpc_port = grpc_port
40
+ self._api_key = api_key
41
+
35
42
  # Batch Configuration
36
43
  self.batch_threshold = self.settings.BATCH_THRESHOLD
37
44
  self.flush_interval = self.settings.FLUSH_INTERVAL_SECONDS
@@ -60,7 +67,13 @@ class WeaviateBatchManager:
60
67
  def _connect_client(self):
61
68
  """Attempts to connect to Weaviate."""
62
69
  try:
63
- self.client = get_weaviate_client(self.settings)
70
+ if self._host is not None:
71
+ self.client = get_weaviate_client(
72
+ host=self._host, port=self._port,
73
+ grpc_port=self._grpc_port, api_key=self._api_key
74
+ )
75
+ else:
76
+ self.client = get_weaviate_client(self.settings)
64
77
  if self.client:
65
78
  self._initialized = True
66
79
  except Exception as e:
@@ -171,6 +184,11 @@ class WeaviateBatchManager:
171
184
  except:
172
185
  pass
173
186
 
174
- @lru_cache(None)
175
- def get_batch_manager() -> WeaviateBatchManager:
176
- return WeaviateBatchManager()
187
+ @lru_cache()
188
+ def get_batch_manager(
189
+ host: Optional[str] = None,
190
+ port: Optional[int] = None,
191
+ grpc_port: Optional[int] = None,
192
+ api_key: Optional[str] = None
193
+ ) -> WeaviateBatchManager:
194
+ return WeaviateBatchManager(host=host, port=port, grpc_port=grpc_port, api_key=api_key)
@@ -23,7 +23,7 @@ def create_smart_wrapper(original_func, root_wrapper):
23
23
  # Check for existing tracer at runtime
24
24
  tracer = current_tracer_var.get()
25
25
 
26
- if tracer:
26
+ if tracer is not None:
27
27
  # [Case A] Parent trace exists -> Act as Child Span
28
28
  # (Wrap original function with trace_span and execute)
29
29
  return trace_span(original_func, capture_return_value=True)(*args, **kwargs)
@@ -13,7 +13,7 @@ from ..utils.function_cache import function_cache_manager
13
13
  from ..utils.return_caching_utils import _check_and_return_cached_result
14
14
  from ..vectorizer.factory import get_vectorizer
15
15
  from ..utils.context import execution_source_context
16
- from ..utils.path_utils import get_repo_root_and_relative_path # New import
16
+ from ..utils.path_utils import get_repo_root_and_relative_path
17
17
 
18
18
  logger = logging.getLogger(__name__)
19
19
 
@@ -31,6 +31,7 @@ def vectorize(search_description: Optional[str] = None,
31
31
  capture_inputs: bool = False,
32
32
  semantic_cache_filters: Optional[Dict[str, Any]] = None,
33
33
  semantic_cache_scope: Optional[List[str]] = None,
34
+ enable_alert: bool = True,
34
35
  **execution_tags):
35
36
  """
36
37
  VectorWave Decorator with Auto-Generation support.
@@ -65,7 +66,7 @@ def vectorize(search_description: Optional[str] = None,
65
66
  if attr not in final_attributes:
66
67
  final_attributes.append(attr)
67
68
 
68
- if capture_inputs:
69
+ if capture_inputs or replay:
69
70
  try:
70
71
  sig = inspect.signature(func)
71
72
  for param_name in sig.parameters:
@@ -74,15 +75,6 @@ def vectorize(search_description: Optional[str] = None,
74
75
  except Exception as e:
75
76
  logger.warning(f"Failed to inspect signature for auto-capture in '{function_name}': {e}")
76
77
 
77
- if replay:
78
- try:
79
- sig = inspect.signature(func)
80
- for param_name in sig.parameters:
81
- if param_name not in ('self', 'cls') and param_name not in final_attributes:
82
- final_attributes.append(param_name)
83
- except Exception as e:
84
- logger.warning(f"Failed to inspect signature for replay auto-capture in '{function_name}': {e}")
85
-
86
78
  # Extract Execution Tags
87
79
  valid_execution_tags = {}
88
80
  settings = get_weaviate_settings()
@@ -110,7 +102,7 @@ def vectorize(search_description: Optional[str] = None,
110
102
  if relative_file_path:
111
103
  file_path = relative_file_path
112
104
  else:
113
- file_path = abs_file_path # Fallback to absolute path if not in a git repo
105
+ file_path = abs_file_path
114
106
  logger.warning(f"Function '{function_name}' is not in a Git repository. "
115
107
  f"PR creation might fail for absolute path: {file_path}")
116
108
  except Exception as e:
@@ -147,7 +139,7 @@ def vectorize(search_description: Optional[str] = None,
147
139
  vectorizer = get_vectorizer()
148
140
  vector_to_add = None
149
141
 
150
- if vectorizer and search_description:
142
+ if vectorizer is not None and search_description:
151
143
  try:
152
144
  vector_to_add = vectorizer.embed(search_description)
153
145
  except Exception as e:
@@ -185,9 +177,32 @@ def vectorize(search_description: Optional[str] = None,
185
177
 
186
178
  # --- Wrapper Logic ---
187
179
 
180
+ def _try_cache(args, kwargs):
181
+ """Check semantic cache. Returns cached result or None."""
182
+ if not semantic_cache:
183
+ return None
184
+ filters = resolve_semantic_filters(args, kwargs)
185
+ return _check_and_return_cached_result(
186
+ func, args, kwargs, function_name, cache_threshold,
187
+ is_async_func, filters=filters
188
+ )
189
+
190
+ def _build_full_kwargs(kwargs):
191
+ """Build kwargs with execution tags and metadata."""
192
+ full_kwargs = kwargs.copy()
193
+ full_kwargs.update(valid_execution_tags)
194
+ full_kwargs['function_uuid'] = func_uuid
195
+ full_kwargs['exec_source'] = execution_source_context.get()
196
+ return full_kwargs
197
+
188
198
  if is_async_func:
189
199
  @trace_root()
190
- @trace_span(attributes_to_capture=final_attributes, capture_return_value=capture_return_value)
200
+ @trace_span(
201
+ attributes_to_capture=final_attributes,
202
+ capture_return_value=capture_return_value,
203
+ force_sync=semantic_cache,
204
+ enable_alert=enable_alert
205
+ )
191
206
  @wraps(func)
192
207
  async def inner_wrapper(*args, **kwargs):
193
208
  clean_kwargs = {k: v for k, v in kwargs.items() if
@@ -196,23 +211,22 @@ def vectorize(search_description: Optional[str] = None,
196
211
 
197
212
  @wraps(func)
198
213
  async def outer_wrapper(*args, **kwargs):
199
- if semantic_cache:
200
- filters = resolve_semantic_filters(args, kwargs)
201
- cached = _check_and_return_cached_result(func, args, kwargs, function_name, cache_threshold, True, filters=filters)
202
- if cached is not None: return cached
203
-
204
- full_kwargs = kwargs.copy()
205
- full_kwargs.update(valid_execution_tags)
206
- full_kwargs['function_uuid'] = func_uuid
207
- full_kwargs['exec_source'] = execution_source_context.get()
208
- return await inner_wrapper(*args, **full_kwargs)
214
+ cached = _try_cache(args, kwargs)
215
+ if cached is not None:
216
+ return cached
217
+ return await inner_wrapper(*args, **_build_full_kwargs(kwargs))
209
218
 
210
219
  outer_wrapper._is_vectorized = True
211
220
  return outer_wrapper
212
221
 
213
222
  else: # Sync wrapper
214
223
  @trace_root()
215
- @trace_span(attributes_to_capture=final_attributes, capture_return_value=capture_return_value)
224
+ @trace_span(
225
+ attributes_to_capture=final_attributes,
226
+ capture_return_value=capture_return_value,
227
+ force_sync=semantic_cache,
228
+ enable_alert=enable_alert
229
+ )
216
230
  @wraps(func)
217
231
  def inner_wrapper(*args, **kwargs):
218
232
  clean_kwargs = {k: v for k, v in kwargs.items() if
@@ -221,16 +235,10 @@ def vectorize(search_description: Optional[str] = None,
221
235
 
222
236
  @wraps(func)
223
237
  def outer_wrapper(*args, **kwargs):
224
- if semantic_cache:
225
- filters = resolve_semantic_filters(args, kwargs)
226
- cached = _check_and_return_cached_result(func, args, kwargs, function_name, cache_threshold, False, filters=filters)
227
- if cached is not None: return cached
228
-
229
- full_kwargs = kwargs.copy()
230
- full_kwargs.update(valid_execution_tags)
231
- full_kwargs['function_uuid'] = func_uuid
232
- full_kwargs['exec_source'] = execution_source_context.get()
233
- return inner_wrapper(*args, **full_kwargs)
238
+ cached = _try_cache(args, kwargs)
239
+ if cached is not None:
240
+ return cached
241
+ return inner_wrapper(*args, **_build_full_kwargs(kwargs))
234
242
 
235
243
  outer_wrapper._is_vectorized = True
236
244
  return outer_wrapper
@@ -21,7 +21,7 @@ def generate_metadata_via_llm(source_code: str, func_name: str) -> Optional[Dict
21
21
  """Call LLM to generate description and narrative from source code."""
22
22
  settings = get_weaviate_settings()
23
23
  client = get_llm_client()
24
- if not client:
24
+ if client is None:
25
25
  return None
26
26
 
27
27
  prompt = f"""
@@ -121,7 +121,7 @@ def generate_and_register_metadata():
121
121
 
122
122
  # 4. Vectorize the Description
123
123
  vector_to_add = None
124
- if vectorizer and final_desc:
124
+ if vectorizer is not None and final_desc:
125
125
  try:
126
126
  vector_to_add = vectorizer.embed(final_desc)
127
127
  except Exception as e:
@@ -0,0 +1,37 @@
1
+ import threading
2
+ import logging
3
+ from ..models.db_config import get_weaviate_settings
4
+ from ..utils.scheduler import start_scheduler
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ _HEALER_STARTED = False
9
+
10
+ def initialize_vectorwave():
11
+ """
12
+ Initialize vectorwave system.
13
+ Refer to config automatically run Auto Healer System.
14
+ """
15
+ global _HEALER_STARTED
16
+ try:
17
+ settings = get_weaviate_settings()
18
+ except Exception as e:
19
+ logger.warning(f"⚠️ Failed to load settings during initialization: {e}")
20
+ return
21
+
22
+ if _HEALER_STARTED:
23
+ return
24
+
25
+ if settings.ENABLE_AUTO_HEALER:
26
+ logger.info("🔧 AutoHealer is enabled. Starting background scheduler...")
27
+
28
+ healer_thread = threading.Thread(
29
+ target=start_scheduler,
30
+ kwargs={'interval_minutes': settings.HEALER_CHECK_INTERVAL_MINUTES},
31
+ daemon=True,
32
+ name="VectorWave-AutoHealer"
33
+ )
34
+ healer_thread.start()
35
+ _HEALER_STARTED = True
36
+ else:
37
+ logger.debug("🔧 AutoHealer is disabled (ENABLE_AUTO_HEALER=False).")
@@ -0,0 +1,10 @@
1
+ from functools import lru_cache
2
+
3
+ from .base import BaseLLMClient
4
+ from .openai_client import VectorWaveOpenAIClient
5
+
6
+
7
+ @lru_cache()
8
+ def get_llm_client() -> BaseLLMClient:
9
+ """Returns the singleton LLM client instance."""
10
+ return VectorWaveOpenAIClient()
@@ -37,7 +37,7 @@ class VectorWaveDatasetManager:
37
37
  include_vector=True
38
38
  )
39
39
 
40
- if not log_obj:
40
+ if log_obj is None:
41
41
  logger.error(f"Log UUID '{log_uuid}' not found.")
42
42
  return False
43
43
 
@@ -55,9 +55,17 @@ class VectorWaveDatasetManager:
55
55
  }
56
56
 
57
57
  # 3. Save (reuse original vector)
58
+ vector = (log_obj.vector or {}).get("default")
59
+ if vector is None:
60
+ logger.error(
61
+ f"Log '{log_uuid}' has no stored vector. "
62
+ "The source function must have capture_return_value=True for vector storage."
63
+ )
64
+ return False
65
+
58
66
  self.golden_col.data.insert(
59
67
  properties=golden_props,
60
- vector=log_obj.vector["default"], # Copy vector
68
+ vector=vector,
61
69
  uuid=generate_uuid5(log_uuid) # Regenerate to avoid UUID collision, or maintain relation with original
62
70
  )
63
71
  logger.info(f"✅ Registered log {log_uuid} as Golden Data.")