vector-inspector 0.3.9__py3-none-any.whl → 0.3.11__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.
- vector_inspector/__init__.py +10 -1
- vector_inspector/core/connections/pgvector_connection.py +1 -1
- vector_inspector/extensions/__init__.py +6 -0
- vector_inspector/extensions/telemetry_settings_panel.py +25 -0
- vector_inspector/main.py +16 -0
- vector_inspector/services/settings_service.py +8 -0
- vector_inspector/services/telemetry_service.py +88 -0
- {vector_inspector-0.3.9.dist-info → vector_inspector-0.3.11.dist-info}/METADATA +5 -36
- {vector_inspector-0.3.9.dist-info → vector_inspector-0.3.11.dist-info}/RECORD +11 -9
- {vector_inspector-0.3.9.dist-info → vector_inspector-0.3.11.dist-info}/WHEEL +1 -1
- {vector_inspector-0.3.9.dist-info → vector_inspector-0.3.11.dist-info}/entry_points.txt +0 -0
vector_inspector/__init__.py
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
"""Vector Inspector - A comprehensive desktop application for vector database visualization."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.
|
|
3
|
+
__version__ = "0.3.11" # Keep in sync with pyproject.toml for dev mode fallback
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_version():
|
|
7
|
+
try:
|
|
8
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
9
|
+
|
|
10
|
+
return version("vector-inspector")
|
|
11
|
+
except Exception:
|
|
12
|
+
return __version__
|
|
@@ -1045,7 +1045,7 @@ class PgVectorConnection(VectorDBConnection):
|
|
|
1045
1045
|
Returns:
|
|
1046
1046
|
List of floats
|
|
1047
1047
|
"""
|
|
1048
|
-
log_info("[pgvector] _parse_vector raw value: %r (type: %s)", vector_str, type(vector_str))
|
|
1048
|
+
# log_info("[pgvector] _parse_vector raw value: %r (type: %s)", vector_str, type(vector_str))
|
|
1049
1049
|
if isinstance(vector_str, list):
|
|
1050
1050
|
log_info("[pgvector] _parse_vector: already list, len=%d", len(vector_str))
|
|
1051
1051
|
return vector_str
|
|
@@ -103,3 +103,9 @@ class SettingsPanelHook:
|
|
|
103
103
|
|
|
104
104
|
# Global singleton instance
|
|
105
105
|
settings_panel_hook = SettingsPanelHook()
|
|
106
|
+
|
|
107
|
+
# Register built-in settings panel extensions
|
|
108
|
+
try:
|
|
109
|
+
import vector_inspector.extensions.telemetry_settings_panel
|
|
110
|
+
except Exception:
|
|
111
|
+
pass
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from PySide6.QtWidgets import QCheckBox, QHBoxLayout
|
|
2
|
+
from vector_inspector.extensions import settings_panel_hook
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def add_telemetry_section(parent_layout, settings_service, dialog=None):
|
|
6
|
+
telemetry_checkbox = QCheckBox("Enable anonymous telemetry (app launch events)")
|
|
7
|
+
# Default to checked if not set
|
|
8
|
+
checked = settings_service.get("telemetry.enabled")
|
|
9
|
+
if checked is None:
|
|
10
|
+
checked = True
|
|
11
|
+
telemetry_checkbox.setChecked(checked)
|
|
12
|
+
telemetry_checkbox.setToolTip(
|
|
13
|
+
"Allow the app to send anonymous launch events to help improve reliability. No personal or document data is sent."
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def on_state_changed(state):
|
|
17
|
+
settings_service.set_telemetry_enabled(bool(state))
|
|
18
|
+
|
|
19
|
+
telemetry_checkbox.stateChanged.connect(on_state_changed)
|
|
20
|
+
layout = QHBoxLayout()
|
|
21
|
+
layout.addWidget(telemetry_checkbox)
|
|
22
|
+
parent_layout.addLayout(layout)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
settings_panel_hook.register(add_telemetry_section)
|
vector_inspector/main.py
CHANGED
|
@@ -4,6 +4,7 @@ import sys
|
|
|
4
4
|
import os
|
|
5
5
|
from PySide6.QtWidgets import QApplication
|
|
6
6
|
from vector_inspector.ui.main_window import MainWindow
|
|
7
|
+
from vector_inspector.core.logging import log_error
|
|
7
8
|
|
|
8
9
|
# Ensures the app looks in its own folder for the raw libraries
|
|
9
10
|
sys.path.append(os.path.dirname(sys.executable))
|
|
@@ -15,6 +16,21 @@ def main():
|
|
|
15
16
|
app.setApplicationName("Vector Inspector")
|
|
16
17
|
app.setOrganizationName("Vector Inspector")
|
|
17
18
|
|
|
19
|
+
# Telemetry: send launch ping if enabled
|
|
20
|
+
try:
|
|
21
|
+
from vector_inspector.services.telemetry_service import TelemetryService
|
|
22
|
+
from vector_inspector import get_version, __version__
|
|
23
|
+
|
|
24
|
+
app_version = None
|
|
25
|
+
try:
|
|
26
|
+
app_version = get_version()
|
|
27
|
+
except Exception:
|
|
28
|
+
app_version = __version__
|
|
29
|
+
telemetry = TelemetryService()
|
|
30
|
+
telemetry.send_launch_ping(app_version=app_version)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
log_error(f"[Telemetry] Failed to send launch ping: {e}")
|
|
33
|
+
|
|
18
34
|
window = MainWindow()
|
|
19
35
|
window.show()
|
|
20
36
|
|
|
@@ -137,6 +137,14 @@ class SettingsService:
|
|
|
137
137
|
else:
|
|
138
138
|
cache.disable()
|
|
139
139
|
|
|
140
|
+
def get_telemetry_enabled(self) -> bool:
|
|
141
|
+
"""Get whether telemetry is enabled (default: True)."""
|
|
142
|
+
return bool(self.settings.get("telemetry.enabled", True))
|
|
143
|
+
|
|
144
|
+
def set_telemetry_enabled(self, enabled: bool):
|
|
145
|
+
"""Set whether telemetry is enabled."""
|
|
146
|
+
self.set("telemetry.enabled", bool(enabled))
|
|
147
|
+
|
|
140
148
|
def set(self, key: str, value: Any):
|
|
141
149
|
"""Set a setting value."""
|
|
142
150
|
self.settings[key] = value
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import platform
|
|
3
|
+
import uuid
|
|
4
|
+
import requests
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from vector_inspector.services.settings_service import SettingsService
|
|
7
|
+
from vector_inspector.core.logging import log_info, log_error
|
|
8
|
+
|
|
9
|
+
TELEMETRY_ENDPOINT = "https://api.divinedevops.com/api/v1/telemetry"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TelemetryService:
|
|
13
|
+
def __init__(self, settings_service=None):
|
|
14
|
+
self.settings = settings_service or SettingsService()
|
|
15
|
+
self.queue_file = Path.home() / ".vector-inspector" / "telemetry_queue.json"
|
|
16
|
+
self._load_queue()
|
|
17
|
+
|
|
18
|
+
def _load_queue(self):
|
|
19
|
+
if self.queue_file.exists():
|
|
20
|
+
try:
|
|
21
|
+
with open(self.queue_file, encoding="utf-8") as f:
|
|
22
|
+
self.queue = json.load(f)
|
|
23
|
+
except Exception:
|
|
24
|
+
self.queue = []
|
|
25
|
+
else:
|
|
26
|
+
self.queue = []
|
|
27
|
+
|
|
28
|
+
def _save_queue(self):
|
|
29
|
+
self.queue_file.parent.mkdir(parents=True, exist_ok=True)
|
|
30
|
+
with open(self.queue_file, "w", encoding="utf-8") as f:
|
|
31
|
+
json.dump(self.queue, f, indent=2)
|
|
32
|
+
|
|
33
|
+
def is_enabled(self):
|
|
34
|
+
return bool(self.settings.get("telemetry.enabled", True))
|
|
35
|
+
|
|
36
|
+
def get_hwid(self):
|
|
37
|
+
# Use a persistent UUID for this client
|
|
38
|
+
hwid = self.settings.get("telemetry.hwid")
|
|
39
|
+
if not hwid:
|
|
40
|
+
hwid = str(uuid.uuid4())
|
|
41
|
+
self.settings.set("telemetry.hwid", hwid)
|
|
42
|
+
return hwid
|
|
43
|
+
|
|
44
|
+
def queue_event(self, event):
|
|
45
|
+
self.queue.append(event)
|
|
46
|
+
self._save_queue()
|
|
47
|
+
|
|
48
|
+
def send_batch(self):
|
|
49
|
+
if not self.is_enabled() or not self.queue:
|
|
50
|
+
return
|
|
51
|
+
sent = []
|
|
52
|
+
for event in self.queue:
|
|
53
|
+
try:
|
|
54
|
+
log_info(
|
|
55
|
+
f"[Telemetry] Sending to {TELEMETRY_ENDPOINT}\nPayload: {json.dumps(event, indent=2)}"
|
|
56
|
+
)
|
|
57
|
+
resp = requests.post(TELEMETRY_ENDPOINT, json=event, timeout=5)
|
|
58
|
+
log_info(f"[Telemetry] Response: {resp.status_code} {resp.text}")
|
|
59
|
+
if resp.status_code in (200, 201):
|
|
60
|
+
sent.append(event)
|
|
61
|
+
except Exception as e:
|
|
62
|
+
log_error(f"[Telemetry] Exception: {e}")
|
|
63
|
+
# Remove sent events
|
|
64
|
+
self.queue = [e for e in self.queue if e not in sent]
|
|
65
|
+
self._save_queue()
|
|
66
|
+
|
|
67
|
+
def send_launch_ping(self, app_version, client_type="vector-inspector"):
|
|
68
|
+
log_info("[Telemetry] send_launch_ping called")
|
|
69
|
+
if not self.is_enabled():
|
|
70
|
+
log_info("[Telemetry] Telemetry is not enabled; skipping launch ping.")
|
|
71
|
+
return
|
|
72
|
+
event = {
|
|
73
|
+
"hwid": self.get_hwid(),
|
|
74
|
+
"event_name": "app_launch",
|
|
75
|
+
"app_version": app_version,
|
|
76
|
+
"client_type": client_type,
|
|
77
|
+
"metadata": {"os": platform.system() + "-" + platform.release()},
|
|
78
|
+
}
|
|
79
|
+
log_info(f"[Telemetry] Launch event payload: {json.dumps(event, indent=2)}")
|
|
80
|
+
self.queue_event(event)
|
|
81
|
+
self.send_batch()
|
|
82
|
+
|
|
83
|
+
def purge(self):
|
|
84
|
+
self.queue = []
|
|
85
|
+
self._save_queue()
|
|
86
|
+
|
|
87
|
+
def get_queue(self):
|
|
88
|
+
return list(self.queue)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vector-inspector
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.11
|
|
4
4
|
Summary: A comprehensive desktop application for visualizing, querying, and managing vector database data
|
|
5
5
|
Author-Email: Anthony Dawson <anthonypdawson+github@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -8,7 +8,7 @@ Project-URL: Homepage, https://vector-inspector.divinedevops.com
|
|
|
8
8
|
Project-URL: Source, https://github.com/anthonypdawson/vector-inspector
|
|
9
9
|
Project-URL: Issues, https://github.com/anthonypdawson/vector-inspector/issues
|
|
10
10
|
Project-URL: Documentation, https://github.com/anthonypdawson/vector-inspector#readme
|
|
11
|
-
Requires-Python:
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
12
|
Requires-Dist: chromadb>=0.4.22
|
|
13
13
|
Requires-Dist: qdrant-client>=1.7.0
|
|
14
14
|
Requires-Dist: pyside6>=6.6.0
|
|
@@ -32,39 +32,8 @@ Description-Content-Type: text/markdown
|
|
|
32
32
|
|
|
33
33
|
# Latest updates
|
|
34
34
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- MainWindow is reusable as a widget; tab system is pluggable so Studio can extend or override tabs
|
|
38
|
-
|
|
39
|
-
- Data browser improvements
|
|
40
|
-
- Added Generate embeddings on edit (persisted per user)
|
|
41
|
-
|
|
42
|
-
- Settings / Preferences
|
|
43
|
-
- SettingsService persists preferences and exposes typed accessors (breadcrumb, search defaults, auto-embed, window geometry)
|
|
44
|
-
- SettingsService emits a setting_changed Qt signal so UI reacts immediately
|
|
45
|
-
- SettingsDialog (modal) added with add_section API and hook integration for extension panels
|
|
46
|
-
- Breadcrumb controls moved out of core so Pro (Vector Studio) injects them via the settings_panel_hook
|
|
47
|
-
|
|
48
|
-
- Extension hook for settings panels
|
|
49
|
-
- *settings_panel_hook* added to *vector_inspector.extensions*; Vector Studio registers breadcrumb controls at startup
|
|
50
|
-
|
|
51
|
-
- Breadcrumb and UI improvements
|
|
52
|
-
- Breadcrumb label now elides long trails (left/middle) and shows full trail on hover
|
|
53
|
-
- SearchView supports runtime elide-mode changes and responds to settings signals
|
|
54
|
-
|
|
55
|
-
- Window geometry persistence
|
|
56
|
-
- Main window saves/restores geometry when window.restore_geometry is enabled
|
|
57
|
-
|
|
58
|
-
- Pro (Vector Studio) features
|
|
59
|
-
- *Search Similar* (Pro): right-click any row in Data Browser or Search Results to run a vector-to-vector similarity search
|
|
60
|
-
- *table_context_menu* handler hardened for many embedding/id formats and includes fallbacks
|
|
61
|
-
- Vector Studio injects breadcrumb controls into Settings dialog via *settings_panel_hook*
|
|
62
|
-
|
|
63
|
-
- Tests and CI
|
|
64
|
-
- Added *tests/test_settings_injection.py* to assert settings panel hook registration
|
|
65
|
-
- Updated context-menu tests to use *log_info* and *assert* for pytest
|
|
66
|
-
- Local test run: 5 tests passed; GUI-heavy suite ~9s due to PySide6 startup
|
|
67
|
-
|
|
35
|
+
- Added optional telemetry opt-in in settings panel (File -> Preferences -> Telemetry). See docs/telemetry/model_telemetry_and_registry.md and docs/telemetry/unified_telemetry_architecture.md for details.
|
|
36
|
+
- Currently only 'launch' telemetry is sent. Model registry telemetry will be added later.
|
|
68
37
|
---
|
|
69
38
|
|
|
70
39
|
# Vector Inspector
|
|
@@ -72,7 +41,7 @@ Description-Content-Type: text/markdown
|
|
|
72
41
|
> **Disclaimer:** This tool is currently under active development and is **not production ready**. Not all features have been thoroughly tested and code is released frequently. Use with caution in critical or production environments.
|
|
73
42
|
|
|
74
43
|
[](https://github.com/anthonypdawson/vector-inspector/actions/workflows/ci-tests.yml)
|
|
75
|
-
[](https://github.com/anthonypdawson/vector-inspector/actions/workflows/release-and-publish.yml)
|
|
76
45
|
|
|
77
46
|
[](https://pypi.org/project/vector-inspector/)
|
|
78
47
|
[](https://pepy.tech/projects/vector-inspector)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
vector_inspector-0.3.
|
|
2
|
-
vector_inspector-0.3.
|
|
3
|
-
vector_inspector-0.3.
|
|
4
|
-
vector_inspector/__init__.py,sha256=
|
|
1
|
+
vector_inspector-0.3.11.dist-info/METADATA,sha256=UJw5xL019__f7EIgTcIxAqQ4Wq7SjTXxZJfNLNRwVtY,10781
|
|
2
|
+
vector_inspector-0.3.11.dist-info/WHEEL,sha256=Wb0ASbVj8JvWHpOiIpPi7ucfIgJeCi__PzivviEAQFc,90
|
|
3
|
+
vector_inspector-0.3.11.dist-info/entry_points.txt,sha256=u96envMI2NFImZUJDFutiiWl7ZoHrrev9joAgtyvTxo,80
|
|
4
|
+
vector_inspector/__init__.py,sha256=gBFBsYQUOvdcns7nbI7_gtyUyzNgU6O7XqppKmCQ8f0,370
|
|
5
5
|
vector_inspector/__main__.py,sha256=Vdhw8YA1K3wPMlbJQYL5WqvRzAKVeZ16mZQFO9VRmCo,62
|
|
6
6
|
vector_inspector/config/__init__.py,sha256=vHkVsXSUdInsfzWSOLPZzaaELa3SGenAgfpY5EYbsYA,95
|
|
7
7
|
vector_inspector/config/known_embedding_models.json,sha256=tnTWI3OvdL2z0YreL_iBzbceIXR69NDj-0tBcEV6NVM,15701
|
|
@@ -11,7 +11,7 @@ vector_inspector/core/connection_manager.py,sha256=xNmgSXqJcMC-iaOY33-Xnfxq4QjUN
|
|
|
11
11
|
vector_inspector/core/connections/__init__.py,sha256=lDZ-Qv-CbBvVcSlT8K2824zojovEIKhykHVSLARHZWs,345
|
|
12
12
|
vector_inspector/core/connections/base_connection.py,sha256=jDA1cEeNbTghqcCZYoLRpRPXIUteU5mSdpKcjvr4JQI,12236
|
|
13
13
|
vector_inspector/core/connections/chroma_connection.py,sha256=Mks17olaHIxvJAdCVB6EoQa5Tj7ScoD3_b2--Ra0Owk,21006
|
|
14
|
-
vector_inspector/core/connections/pgvector_connection.py,sha256=
|
|
14
|
+
vector_inspector/core/connections/pgvector_connection.py,sha256=7Iq6b1pWB5Rz-zva7ZvDQj098ZVMz0WUkVgarSgTpA4,44940
|
|
15
15
|
vector_inspector/core/connections/pinecone_connection.py,sha256=V6nHLB6DXfQJG8LiH1uPtWFs6otACkaNxeYrM0uY0AQ,26954
|
|
16
16
|
vector_inspector/core/connections/qdrant_connection.py,sha256=GkLmnwnswakSMRM16pmtjkR6QXBszDhvg-aKhmI9jxw,31958
|
|
17
17
|
vector_inspector/core/connections/qdrant_helpers/__init__.py,sha256=u2YNjiW4sbNtqhTNOQr4hmOFqirlNlllsyBK2gWs9eU,262
|
|
@@ -27,8 +27,9 @@ vector_inspector/core/embedding_utils.py,sha256=UCnJllDS_YPqbOPVo_kxSCUxM64C5tmc
|
|
|
27
27
|
vector_inspector/core/logging.py,sha256=HQ6_OZgZmaS3OMFOTAqc0oRbZujqo1W0w8OU4viXP1g,845
|
|
28
28
|
vector_inspector/core/model_registry.py,sha256=fdofceD3iyNpECVC7djTEAaDYgHX_7JQ3ROh5A0plpY,6269
|
|
29
29
|
vector_inspector/core/provider_factory.py,sha256=QFDpJTOBJVYAdOLlY0GxSWl87Yj_UT9ZzOm9cjVsGMU,3924
|
|
30
|
-
vector_inspector/extensions/__init__.py,sha256=
|
|
31
|
-
vector_inspector/
|
|
30
|
+
vector_inspector/extensions/__init__.py,sha256=cbN22B89XQT7uZRXBujqfbXDWm5w4rao0UHgMsUJqu0,3303
|
|
31
|
+
vector_inspector/extensions/telemetry_settings_panel.py,sha256=uYvxnjBj_sqD18TpxeZP1f1VRbYhSjQV5boVc53dx40,934
|
|
32
|
+
vector_inspector/main.py,sha256=XhoVqZJm49X5n5dGNcuTCJagU3WgCckgO0TifxAhl5A,1182
|
|
32
33
|
vector_inspector/services/__init__.py,sha256=QLgH7oybjHuEYDFNiBgmJxvSpgAzHEuBEPXa3SKJb_I,67
|
|
33
34
|
vector_inspector/services/backup_helpers.py,sha256=aX1ONFegERq6dpoNM1eJrbyE1gWCV3SuUHMyPpnxrYM,2005
|
|
34
35
|
vector_inspector/services/backup_restore_service.py,sha256=8e64C4v8v-5Sw0upC4YaJWlLFkqAkspNt0k7yZjf_zk,7625
|
|
@@ -36,7 +37,8 @@ vector_inspector/services/credential_service.py,sha256=Ui4JzivQ5YCytQYsKdzpLs5nZ
|
|
|
36
37
|
vector_inspector/services/filter_service.py,sha256=xDrMxNWsYzRcR1n0Fd-yp6Fo-4aLbVIDkhj2GKmrw5o,2370
|
|
37
38
|
vector_inspector/services/import_export_service.py,sha256=4NOfAa6ZyvMyj5cDM4xu0Wqx0pgnK3cCNBGo3E6j4LE,10200
|
|
38
39
|
vector_inspector/services/profile_service.py,sha256=AMeC6XOfI6Qumi0bKlTbqU-czMcle0rrHYK68ceK5r8,12856
|
|
39
|
-
vector_inspector/services/settings_service.py,sha256=
|
|
40
|
+
vector_inspector/services/settings_service.py,sha256=Li1JR_6Ihuta9ifo_heqbjT5e3e26kjcxR8OxPDiN58,10798
|
|
41
|
+
vector_inspector/services/telemetry_service.py,sha256=eWOmQxZjW2v_IK_HQ_uIRi4ostQyvo4ptxK3BB1cdq8,3066
|
|
40
42
|
vector_inspector/services/update_service.py,sha256=B_l0qQUe0L_rYWNYnqvXET4UNf6bCSsl2LTkINtp0GE,2771
|
|
41
43
|
vector_inspector/services/visualization_service.py,sha256=9TOK1S1u1U74wLpF5NdDiryyrjOzFnvE8kwjugf95Wk,4208
|
|
42
44
|
vector_inspector/ui/__init__.py,sha256=262ZiXO6Luk8vZnhCIoYxOtGiny0bXK-BTKjxUNBx-w,43
|
|
@@ -71,4 +73,4 @@ vector_inspector/ui/views/visualization_view.py,sha256=wgkSkOM-ShOHDj1GCUtKnqH87
|
|
|
71
73
|
vector_inspector/utils/__init__.py,sha256=jhHBQC8C8bfhNlf6CAt07ejjStp_YAyleaYr2dm0Dk0,38
|
|
72
74
|
vector_inspector/utils/lazy_imports.py,sha256=2XZ3ZnwTvZ5vvrh36nJ_TUjwwkgjoAED6i6P9yctvt0,1211
|
|
73
75
|
vector_inspector/utils/version.py,sha256=2Xk9DEKlDRGEszNNiYnK7ps1i3OH56H2uZhR0_yZORs,382
|
|
74
|
-
vector_inspector-0.3.
|
|
76
|
+
vector_inspector-0.3.11.dist-info/RECORD,,
|
|
File without changes
|