dbagent-cli 0.3.1__tar.gz → 0.3.2__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 (73) hide show
  1. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/PKG-INFO +2 -2
  2. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/__init__.py +1 -1
  3. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/pipeline.py +44 -11
  4. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/cli.py +22 -10
  5. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/PKG-INFO +2 -2
  6. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/pyproject.toml +2 -2
  7. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/README.md +0 -0
  8. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/confidence.py +0 -0
  9. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/conversation.py +0 -0
  10. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/doctor.py +0 -0
  11. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/error_classifier.py +0 -0
  12. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/generator.py +0 -0
  13. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/recommender.py +0 -0
  14. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/validator.py +0 -0
  15. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/config.py +0 -0
  16. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/base.py +0 -0
  17. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/factory.py +0 -0
  18. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/mongo.py +0 -0
  19. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/relational.py +0 -0
  20. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/__init__.py +0 -0
  21. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/cache.py +0 -0
  22. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/changeset.py +0 -0
  23. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/cost.py +0 -0
  24. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/recovery.py +0 -0
  25. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/sandbox.py +0 -0
  26. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/streaming.py +0 -0
  27. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/auto_setup.py +0 -0
  28. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/base.py +0 -0
  29. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/factory.py +0 -0
  30. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/gemini_provider.py +0 -0
  31. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/groq_provider.py +0 -0
  32. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/mock_provider.py +0 -0
  33. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/ollama_provider.py +0 -0
  34. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/openrouter_provider.py +0 -0
  35. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/cache.py +0 -0
  36. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/formatter.py +0 -0
  37. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/graph.py +0 -0
  38. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/models.py +0 -0
  39. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/retriever.py +0 -0
  40. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/selector.py +0 -0
  41. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/__init__.py +0 -0
  42. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/audit.py +0 -0
  43. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/environment.py +0 -0
  44. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/masking.py +0 -0
  45. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/modes.py +0 -0
  46. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/rbac.py +0 -0
  47. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/__init__.py +0 -0
  48. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/dictionary.py +0 -0
  49. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/templates.py +0 -0
  50. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/__init__.py +0 -0
  51. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/optimizer.py +0 -0
  52. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/validator.py +0 -0
  53. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/console.py +0 -0
  54. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/viewer.py +0 -0
  55. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/visualizer.py +0 -0
  56. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/SOURCES.txt +0 -0
  57. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/dependency_links.txt +0 -0
  58. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/entry_points.txt +0 -0
  59. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/requires.txt +0 -0
  60. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/top_level.txt +0 -0
  61. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/setup.cfg +0 -0
  62. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_cache.py +0 -0
  63. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_cli.py +0 -0
  64. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_connectors.py +0 -0
  65. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_doctor_and_viz.py +0 -0
  66. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_generator.py +0 -0
  67. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_graph.py +0 -0
  68. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_recovery.py +0 -0
  69. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_safety.py +0 -0
  70. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_sandbox.py +0 -0
  71. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_schema.py +0 -0
  72. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_security.py +0 -0
  73. {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_semantic.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.3.1
4
- Summary: Enterprise AI Database Copilot with Long-Term Change Recovery (CLI)
3
+ Version: 0.3.2
4
+ Summary: Enterprise AI Database Copilot with High-Speed Schema Caching & Long-Term Recovery (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
@@ -2,5 +2,5 @@
2
2
  DB-Agent: Universal Database Introspection and Script Generation AI Agent (CLI).
3
3
  """
4
4
 
5
- __version__ = "0.3.1"
5
+ __version__ = "0.3.2"
6
6
  __author__ = "Santhosh Gupta"
@@ -129,6 +129,40 @@ class QueryPipeline:
129
129
  self.db_name = "database"
130
130
  if hasattr(connector, "engine") and connector.engine:
131
131
  self.db_name = connector.engine.url.database or "database"
132
+ self.db_id = str(connector.engine.url)
133
+ else:
134
+ self.db_id = self.db_name
135
+ self.cache_mgr = SchemaCacheManager()
136
+
137
+ def _get_fast_schema_context(
138
+ self,
139
+ user_prompt: str,
140
+ exact: List[str],
141
+ fuzzy: List[str],
142
+ ) -> Tuple[DatabaseSchema, List[JoinStep]]:
143
+ """Fast schema sub-graph retrieval using cache (<5ms) or targeted introspection (<50ms)."""
144
+ # 1. Try local schema cache (< 5ms)
145
+ cached = self.cache_mgr.load_cached_schema(self.db_id)
146
+ if cached:
147
+ retriever = ContextRetriever(cached)
148
+ return retriever.retrieve_context(
149
+ user_prompt=user_prompt,
150
+ exact_tables=exact,
151
+ fuzzy_tables=fuzzy,
152
+ max_tables=8,
153
+ )
154
+
155
+ # 2. Targeted on-demand table introspection (~50ms instead of 5000ms for full scan)
156
+ target_names = list(set(exact + fuzzy))
157
+ if target_names:
158
+ targeted = self.connector.inspect_schema(table_names=target_names, include_samples=False, max_samples=0)
159
+ retriever = ContextRetriever(targeted)
160
+ return retriever.retrieve_context(user_prompt, exact_tables=exact, fuzzy_tables=fuzzy, max_tables=8)
161
+
162
+ # 3. Fallback: inspect targeted
163
+ targeted = self.connector.inspect_targeted(user_prompt, max_tables=8)
164
+ retriever = ContextRetriever(targeted)
165
+ return retriever.retrieve_context(user_prompt, exact_tables=exact, fuzzy_tables=fuzzy, max_tables=8)
132
166
 
133
167
  def run(self, user_prompt: str, force: bool = False, bypass_cache: bool = False) -> PipelineResult:
134
168
  """
@@ -138,10 +172,16 @@ class QueryPipeline:
138
172
  result = PipelineResult()
139
173
  result.intent = ScriptGenerator.classify_intent(user_prompt)
140
174
 
141
- # --- 1. Conversational Chat Fast-Path ---
175
+ # --- 1. Conversational Chat Fast-Path (<10ms schema load) ---
142
176
  if result.intent == "chat":
143
177
  try:
144
- schema = self.connector.inspect_schema(include_samples=False, max_samples=0, include_row_counts=False)
178
+ cached = self.cache_mgr.load_cached_schema(self.db_id)
179
+ if cached:
180
+ schema = cached
181
+ else:
182
+ quick_tables = self.connector.get_table_names()[:25]
183
+ schema = self.connector.inspect_schema(table_names=quick_tables, include_samples=False, max_samples=0)
184
+
145
185
  result.schema = schema
146
186
  result.message = self.generator.generate_chat_response(
147
187
  schema=schema,
@@ -177,16 +217,9 @@ class QueryPipeline:
177
217
  result.error = "Ambiguous table reference — please specify table name."
178
218
  return result
179
219
 
180
- # --- 3. Fast AI Context Retrieval (Minimal sub-graph) ---
220
+ # --- 3. Fast AI Context Retrieval (Minimal sub-graph < 5ms) ---
181
221
  try:
182
- full_schema = self.connector.inspect_schema(include_samples=False, max_samples=0, include_row_counts=False)
183
- retriever = ContextRetriever(full_schema)
184
- sub_schema, join_steps = retriever.retrieve_context(
185
- user_prompt=user_prompt,
186
- exact_tables=exact,
187
- fuzzy_tables=fuzzy,
188
- max_tables=8,
189
- )
222
+ sub_schema, join_steps = self._get_fast_schema_context(user_prompt, exact, fuzzy)
190
223
  result.schema = sub_schema
191
224
  result.join_steps = join_steps
192
225
  except Exception as e:
@@ -357,11 +357,15 @@ def chat_command(
357
357
  console.print(f"[bold cyan]AI:[/bold cyan] {llm.name} | [bold yellow]Mode:[/bold yellow] {current_mode.value}")
358
358
  console.print("[dim]Type your question in plain English or use colon commands (e.g. :help, :tables, :doctor).[/dim]")
359
359
 
360
- # Display AI recommendations on connect
360
+ # Display AI recommendations on connect (instant via cache or top tables)
361
361
  try:
362
- with console.status("[dim]Analyzing schema recommendations...[/dim]"):
363
- full_schema = connector.inspect_schema(include_samples=False, max_samples=0, include_row_counts=False)
364
- recs = QueryRecommender.generate_recommendations(full_schema, max_suggestions=3)
362
+ cached_schema = cache_mgr.load_cached_schema(db_url)
363
+ if cached_schema:
364
+ recs = QueryRecommender.generate_recommendations(cached_schema, max_suggestions=3)
365
+ else:
366
+ quick_tables = table_names[:10]
367
+ quick_schema = connector.inspect_schema(table_names=quick_tables, include_samples=False, max_samples=0)
368
+ recs = QueryRecommender.generate_recommendations(quick_schema, max_suggestions=3)
365
369
  if recs:
366
370
  console.print("\n[bold cyan]💡 Try asking:[/bold cyan]")
367
371
  for r in recs:
@@ -443,8 +447,12 @@ def chat_command(
443
447
  continue
444
448
  exact, fuzzy = connector.resolve_tables(cmd_arg)
445
449
  target = exact[0] if exact else (fuzzy[0] if fuzzy else cmd_arg)
446
- with console.status(f"[bold cyan]Finding relationships for {target}...[/bold cyan]"):
447
- full_schema = connector.inspect_schema(include_samples=False, max_samples=0)
450
+ cached = cache_mgr.load_cached_schema(db_url)
451
+ if cached:
452
+ full_schema = cached
453
+ else:
454
+ with console.status(f"[bold cyan]Finding relationships for {target}...[/bold cyan]"):
455
+ full_schema = connector.inspect_schema(include_samples=False, max_samples=0)
448
456
 
449
457
  tmodel = full_schema.get_table(target)
450
458
  outgoing = tmodel.foreign_keys if tmodel else []
@@ -473,10 +481,14 @@ def chat_command(
473
481
  if len(args) < 2:
474
482
  print_warning("Usage: :path <start_table> <end_table> (e.g. :path users events)")
475
483
  continue
476
- with console.status("[bold cyan]Traversing relationship graph...[/bold cyan]"):
477
- full_schema = connector.inspect_schema(include_samples=False, max_samples=0)
478
- graph = RelationshipGraph(full_schema)
479
- path = graph.find_shortest_path(args[0], args[1])
484
+ cached = cache_mgr.load_cached_schema(db_url)
485
+ if cached:
486
+ full_schema = cached
487
+ else:
488
+ with console.status("[bold cyan]Traversing relationship graph...[/bold cyan]"):
489
+ full_schema = connector.inspect_schema(include_samples=False, max_samples=0)
490
+ graph = RelationshipGraph(full_schema)
491
+ path = graph.find_shortest_path(args[0], args[1])
480
492
  if path:
481
493
  console.print(f"\n[bold cyan]Shortest Relationship Path:[/bold cyan]\n{path.format_visual_path()}\n")
482
494
  else:
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.3.1
4
- Summary: Enterprise AI Database Copilot with Long-Term Change Recovery (CLI)
3
+ Version: 0.3.2
4
+ Summary: Enterprise AI Database Copilot with High-Speed Schema Caching & Long-Term Recovery (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dbagent-cli"
7
- version = "0.3.1"
8
- description = "Enterprise AI Database Copilot with Long-Term Change Recovery (CLI)"
7
+ version = "0.3.2"
8
+ description = "Enterprise AI Database Copilot with High-Speed Schema Caching & Long-Term Recovery (CLI)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  authors = [
File without changes
File without changes