signalpilot-ai-internal 0.4.6__py3-none-any.whl → 0.4.7__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.

Potentially problematic release.


This version of signalpilot-ai-internal might be problematic. Click here for more details.

Files changed (41) hide show
  1. signalpilot_ai_internal/_version.py +1 -1
  2. signalpilot_ai_internal/handlers.py +5 -1
  3. signalpilot_ai_internal/schema_search_config.yml +32 -0
  4. signalpilot_ai_internal/schema_search_service.py +109 -0
  5. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/package.json +2 -2
  6. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/package.json.orig +1 -1
  7. signalpilot_ai_internal-0.4.7.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.4db23bddecbec684b06c.js +1 -0
  8. signalpilot_ai_internal-0.4.6.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.61ef7b3a050c161d7a88.js → signalpilot_ai_internal-0.4.7.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/remoteEntry.2a797d447eeb725a28cf.js +1 -1
  9. {signalpilot_ai_internal-0.4.6.dist-info → signalpilot_ai_internal-0.4.7.dist-info}/METADATA +3 -2
  10. {signalpilot_ai_internal-0.4.6.dist-info → signalpilot_ai_internal-0.4.7.dist-info}/RECORD +40 -38
  11. signalpilot_ai_internal-0.4.6.data/data/share/jupyter/labextensions/signalpilot-ai-internal/static/839.0be091400e2f58fe8fd2.js +0 -1
  12. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/etc/jupyter/jupyter_server_config.d/signalpilot_ai.json +0 -0
  13. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/install.json +0 -0
  14. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/schemas/signalpilot-ai-internal/plugin.json +0 -0
  15. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js +0 -0
  16. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/104.04e170724f369fcbaf19.js.LICENSE.txt +0 -0
  17. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/122.e2dadf63dc64d7b5f1ee.js +0 -0
  18. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/220.328403b5545f268b95c6.js +0 -0
  19. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/262.726e1da31a50868cb297.js +0 -0
  20. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js +0 -0
  21. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/280.35d8c8b68815702a5238.js.LICENSE.txt +0 -0
  22. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/353.72484b768a04f89bd3dd.js +0 -0
  23. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/364.dbec4c2dc12e7b050dcc.js +0 -0
  24. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/384.fa432bdb7fb6b1c95ad6.js +0 -0
  25. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/439.37e271d7a80336daabe2.js +0 -0
  26. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/476.9b4f05a99f5003f82094.js +0 -0
  27. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/481.73c7a9290b7d35a8b9c1.js +0 -0
  28. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/512.b58fc0093d080b8ee61c.js +0 -0
  29. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js +0 -0
  30. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/553.b4042a795c91d9ff71ef.js.LICENSE.txt +0 -0
  31. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/606.90aaaae46b73dc3c08fb.js +0 -0
  32. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/635.9720593ee20b768da3ca.js +0 -0
  33. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/713.8e6edc9a965bdd578ca7.js +0 -0
  34. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/742.91e7b516c8699eea3373.js +0 -0
  35. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/785.3aa564fc148b37d1d719.js +0 -0
  36. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/888.34054db17bcf6e87ec95.js +0 -0
  37. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/923.e80ae4c5cedc1d73f2a1.js +0 -0
  38. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/style.js +0 -0
  39. {signalpilot_ai_internal-0.4.6.data → signalpilot_ai_internal-0.4.7.data}/data/share/jupyter/labextensions/signalpilot-ai-internal/static/third-party-licenses.json +0 -0
  40. {signalpilot_ai_internal-0.4.6.dist-info → signalpilot_ai_internal-0.4.7.dist-info}/WHEEL +0 -0
  41. {signalpilot_ai_internal-0.4.6.dist-info → signalpilot_ai_internal-0.4.7.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '0.4.6'
4
+ __version__ = VERSION = '0.4.7'
@@ -12,6 +12,7 @@ from .cache_service import get_cache_service
12
12
  from .cache_handlers import ChatHistoriesHandler, AppValuesHandler, CacheInfoHandler
13
13
  from .unified_database_schema_service import UnifiedDatabaseSchemaHandler, UnifiedDatabaseQueryHandler
14
14
  from .snowflake_schema_service import SnowflakeSchemaHandler, SnowflakeQueryHandler
15
+ from .schema_search_service import SchemaSearchHandler
15
16
 
16
17
 
17
18
  class HelloWorldHandler(APIHandler):
@@ -279,6 +280,7 @@ def setup_handlers(web_app):
279
280
  # Database service endpoints
280
281
  database_schema_route = url_path_join(base_url, "signalpilot-ai-internal", "database", "schema")
281
282
  database_query_route = url_path_join(base_url, "signalpilot-ai-internal", "database", "query")
283
+ database_schema_search_route = url_path_join(base_url, "signalpilot-ai-internal", "database", "schema-search")
282
284
 
283
285
  # MySQL service endpoints
284
286
  mysql_schema_route = url_path_join(base_url, "signalpilot-ai-internal", "mysql", "schema")
@@ -309,6 +311,7 @@ def setup_handlers(web_app):
309
311
  # Database service endpoints (unified for PostgreSQL and MySQL)
310
312
  (database_schema_route, UnifiedDatabaseSchemaHandler),
311
313
  (database_query_route, UnifiedDatabaseQueryHandler),
314
+ (database_schema_search_route, SchemaSearchHandler),
312
315
 
313
316
  # MySQL service endpoints (use unified handler)
314
317
  (mysql_schema_route, UnifiedDatabaseSchemaHandler),
@@ -339,7 +342,8 @@ def setup_handlers(web_app):
339
342
  print(f" - Cache Info: {cache_info_route}")
340
343
  print(f" - Database Schema: {database_schema_route}")
341
344
  print(f" - Database Query: {database_query_route}")
345
+ print(f" - Database Schema Search: {database_schema_search_route}")
342
346
  print(f" - MySQL Schema: {mysql_schema_route}")
343
347
  print(f" - MySQL Query: {mysql_query_route}")
344
348
  print(f" - Snowflake Schema: {snowflake_schema_route}")
345
- print(f" - Snowflake Query: {snowflake_query_route}")
349
+ print(f" - Snowflake Query: {snowflake_query_route}")
@@ -0,0 +1,32 @@
1
+ logging:
2
+ level: "WARNING"
3
+
4
+ embedding:
5
+ location: "memory"
6
+ model: "multi-qa-MiniLM-L6-cos-v1"
7
+ metric: "cosine"
8
+ batch_size: 32
9
+ show_progress: false
10
+ cache_dir: "/tmp/.schema_search_cache"
11
+
12
+ chunking:
13
+ strategy: "raw"
14
+ max_tokens: 256
15
+ overlap_tokens: 50
16
+ model: "gpt-4o-mini"
17
+
18
+ search:
19
+ strategy: "hybrid"
20
+ initial_top_k: 20
21
+ rerank_top_k: 5
22
+ semantic_weight: 0.67
23
+ hops: 1
24
+
25
+ reranker:
26
+ model: null
27
+
28
+ schema:
29
+ include_columns: true
30
+ include_indices: true
31
+ include_foreign_keys: true
32
+ include_constraints: true
@@ -0,0 +1,109 @@
1
+ import json
2
+ import os
3
+ import subprocess
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ from jupyter_server.base.handlers import APIHandler
9
+ import tornado
10
+ from schema_search import SchemaSearch
11
+ from sqlalchemy import create_engine
12
+
13
+
14
+ class SchemaSearchHandler(APIHandler):
15
+ CONFIG_PATH = Path(__file__).with_name("schema_search_config.yml")
16
+
17
+ def _get_database_url(self, explicit: Optional[str]) -> Optional[str]:
18
+ if isinstance(explicit, str) and explicit.strip():
19
+ return explicit.strip()
20
+
21
+ for key, value in os.environ.items():
22
+ if key.endswith("_CONNECTION_JSON") and isinstance(value, str) and value.strip().startswith("{"):
23
+ config = json.loads(value)
24
+ url = config.get("connectionUrl")
25
+ if url:
26
+ return url
27
+ return os.environ.get("DB_URL")
28
+
29
+ @tornado.web.authenticated
30
+ async def post(self):
31
+ body = self.get_json_body() or {}
32
+ queries = body.get("queries")
33
+ if isinstance(queries, str):
34
+ queries = [queries]
35
+
36
+ if not isinstance(queries, list):
37
+ self.set_status(400)
38
+ self.finish(json.dumps({"error": "queries parameter must be a list of strings"}))
39
+ return
40
+
41
+ queries = [q.strip() for q in queries if isinstance(q, str) and q.strip()]
42
+
43
+ if not queries:
44
+ self.set_status(400)
45
+ self.finish(json.dumps({"error": "queries parameter is required"}))
46
+ return
47
+
48
+ db_url = self._get_database_url(body.get("dbUrl"))
49
+ if not db_url:
50
+ self.set_status(400)
51
+ self.finish(json.dumps({"error": "Database connection URL is not configured"}))
52
+ return
53
+
54
+ db_url = db_url.strip()
55
+ db_url_lower = db_url.lower()
56
+
57
+ if db_url_lower.startswith("mysql://"):
58
+ db_url = "mysql+pymysql://" + db_url[len("mysql://"):]
59
+ db_url_lower = db_url.lower()
60
+
61
+ if db_url_lower.startswith("snowflake://"):
62
+ self._ensure_snowflake_dependencies()
63
+ elif db_url_lower.startswith("postgresql") or db_url_lower.startswith("postgres") or db_url_lower.startswith("mysql+pymysql"):
64
+ pass
65
+ else:
66
+ self.set_status(400)
67
+ self.finish(json.dumps({"error": "Schema search currently supports PostgreSQL, MySQL, or Snowflake connections"}))
68
+ return
69
+
70
+ engine = None
71
+ try:
72
+ engine = create_engine(db_url)
73
+ schema_search = SchemaSearch(engine=engine, config_path=str(self.CONFIG_PATH))
74
+ schema_search.index()
75
+
76
+ limit = body.get("limit")
77
+ if limit is not None:
78
+ limit = max(1, min(int(limit), 10))
79
+ else:
80
+ limit = 5
81
+
82
+ query_results = []
83
+ for query in queries:
84
+ result = schema_search.search(query, limit=limit)
85
+ query_results.append({
86
+ "query": query,
87
+ "results": result
88
+ })
89
+
90
+ self.finish(json.dumps({"results": query_results}))
91
+ except Exception as error:
92
+ self.set_status(500)
93
+ self.finish(json.dumps({"error": f"Schema search failed: {error}"}))
94
+ finally:
95
+ if engine is not None:
96
+ try:
97
+ engine.dispose()
98
+ except Exception:
99
+ pass
100
+
101
+ def _install_package(self, package: str) -> None:
102
+ subprocess.check_call([sys.executable, "-m", "pip", "install", package])
103
+
104
+ def _ensure_snowflake_dependencies(self) -> None:
105
+ try:
106
+ import snowflake.sqlalchemy # type: ignore # noqa: F401
107
+ except ImportError:
108
+ self._install_package("snowflake-sqlalchemy")
109
+ import snowflake.sqlalchemy # type: ignore # noqa: F401
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalpilot-ai-internal",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "SignalPilot Agent - Your Jupyter Notebook Assistant",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -133,7 +133,7 @@
133
133
  "outputDir": "signalpilot_ai_internal/labextension",
134
134
  "schemaDir": "schema",
135
135
  "_build": {
136
- "load": "static/remoteEntry.61ef7b3a050c161d7a88.js",
136
+ "load": "static/remoteEntry.2a797d447eeb725a28cf.js",
137
137
  "extension": "./extension",
138
138
  "style": "./style"
139
139
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalpilot-ai-internal",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "SignalPilot Agent - Your Jupyter Notebook Assistant",
5
5
  "keywords": [
6
6
  "jupyter",