dbagent-cli 0.8.9__tar.gz → 0.9.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 (82) hide show
  1. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/PKG-INFO +1 -1
  2. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/__init__.py +1 -1
  3. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/pipeline.py +3 -0
  4. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/cli.py +63 -1
  5. dbagent_cli-0.9.0/dbagent/schema/ground_truth.py +96 -0
  6. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/ui/chat_screen.py +2 -0
  7. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/PKG-INFO +1 -1
  8. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/SOURCES.txt +1 -0
  9. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/pyproject.toml +1 -1
  10. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/README.md +0 -0
  11. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/confidence.py +0 -0
  12. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/conversation.py +0 -0
  13. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/doctor.py +0 -0
  14. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/error_classifier.py +0 -0
  15. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/generator.py +0 -0
  16. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/recommender.py +0 -0
  17. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/agent/validator.py +0 -0
  18. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/config.py +0 -0
  19. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/connectors/base.py +0 -0
  20. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/connectors/factory.py +0 -0
  21. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/connectors/mongo.py +0 -0
  22. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/connectors/relational.py +0 -0
  23. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/__init__.py +0 -0
  24. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/cache.py +0 -0
  25. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/changeset.py +0 -0
  26. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/cost.py +0 -0
  27. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/recovery.py +0 -0
  28. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/sandbox.py +0 -0
  29. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/execution/streaming.py +0 -0
  30. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/anthropic_provider.py +0 -0
  31. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/auto_setup.py +0 -0
  32. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/base.py +0 -0
  33. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/deepseek_provider.py +0 -0
  34. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/factory.py +0 -0
  35. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/gemini_provider.py +0 -0
  36. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/groq_provider.py +0 -0
  37. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/mistral_provider.py +0 -0
  38. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/mock_provider.py +0 -0
  39. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/ollama_provider.py +0 -0
  40. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/openai_provider.py +0 -0
  41. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/llm/openrouter_provider.py +0 -0
  42. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/cache.py +0 -0
  43. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/formatter.py +0 -0
  44. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/graph.py +0 -0
  45. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/models.py +0 -0
  46. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/retriever.py +0 -0
  47. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/schema/selector.py +0 -0
  48. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/__init__.py +0 -0
  49. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/audit.py +0 -0
  50. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/environment.py +0 -0
  51. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/masking.py +0 -0
  52. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/modes.py +0 -0
  53. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/security/rbac.py +0 -0
  54. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/semantic/__init__.py +0 -0
  55. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/semantic/dictionary.py +0 -0
  56. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/semantic/templates.py +0 -0
  57. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/sql/__init__.py +0 -0
  58. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/sql/optimizer.py +0 -0
  59. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/sql/validator.py +0 -0
  60. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/ui/console.py +0 -0
  61. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/ui/grid_window.py +0 -0
  62. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/ui/viewer.py +0 -0
  63. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent/ui/visualizer.py +0 -0
  64. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/dependency_links.txt +0 -0
  65. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/entry_points.txt +0 -0
  66. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/requires.txt +0 -0
  67. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/dbagent_cli.egg-info/top_level.txt +0 -0
  68. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/setup.cfg +0 -0
  69. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_cache.py +0 -0
  70. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_cli.py +0 -0
  71. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_connectors.py +0 -0
  72. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_direct_sql.py +0 -0
  73. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_doctor_and_viz.py +0 -0
  74. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_generator.py +0 -0
  75. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_graph.py +0 -0
  76. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_providers.py +0 -0
  77. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_recovery.py +0 -0
  78. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_safety.py +0 -0
  79. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_sandbox.py +0 -0
  80. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_schema.py +0 -0
  81. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_security.py +0 -0
  82. {dbagent_cli-0.8.9 → dbagent_cli-0.9.0}/tests/test_semantic.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.8.9
3
+ Version: 0.9.0
4
4
  Summary: Enterprise AI Database Copilot, Schema Graph Introspector & Autonomous Recovery Agent (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
@@ -2,5 +2,5 @@
2
2
  DB-Agent: Universal Database Introspection and Script Generation AI Agent (CLI).
3
3
  """
4
4
 
5
- __version__ = "0.8.9"
5
+ __version__ = "0.9.0"
6
6
  __author__ = "Santhosh Gupta"
@@ -30,6 +30,7 @@ from dbagent.agent.confidence import ConfidenceEvaluator, ConfidenceScore
30
30
  from dbagent.agent.conversation import ConversationContext
31
31
  from dbagent.agent.error_classifier import ErrorClassifier
32
32
  from dbagent.ui.visualizer import ResultVisualizer, VisualizationRecommendation
33
+ from dbagent.schema.ground_truth import SchemaGroundTruthValidator, GroundTruthValidationResult
33
34
 
34
35
 
35
36
  @dataclass
@@ -63,6 +64,7 @@ class PipelineResult:
63
64
  complexity: Optional[QueryComplexity] = None
64
65
  confidence: Optional[ConfidenceScore] = None
65
66
  visualization: Optional[VisualizationRecommendation] = None
67
+ ground_truth: Optional[GroundTruthValidationResult] = None
66
68
  # Error handling
67
69
  error: Optional[str] = None
68
70
  friendly_error: Optional[str] = None
@@ -220,6 +222,7 @@ class QueryPipeline:
220
222
  conversation_history=conv_history,
221
223
  model=self.model,
222
224
  )
225
+ result.ground_truth = SchemaGroundTruthValidator.validate_response(result.message, sub_schema)
223
226
  result.is_chat = True
224
227
  result.was_executed = True
225
228
  result.query_type = "analysis"
@@ -131,6 +131,68 @@ class DynamicSpinner:
131
131
  "🔍 Analyzing index coverage...",
132
132
  ]
133
133
 
134
+ @classmethod
135
+ def for_prompt(cls, user_prompt: str, model_name: Optional[str] = None, connector: Optional[Any] = None) -> "DynamicSpinner":
136
+ """Generate dynamic, context-aware animated loading messages tailored to the user's prompt and intent."""
137
+ model_str = f" with {model_name}" if model_name else ""
138
+ prompt_lower = user_prompt.lower().strip()
139
+
140
+ # 1. Direct SQL
141
+ if prompt_lower.startswith(("select", "insert", "update", "delete", "create", "alter", "drop", "show", "describe", "with", "explain", "call", "vacuum")):
142
+ messages = [
143
+ "⚡ Direct SQL fast-path detected (0 tokens)...",
144
+ "🚀 Executing query directly on database...",
145
+ "📊 Fetching and formatting row vectors...",
146
+ ]
147
+ return cls(messages=messages, interval=0.8)
148
+
149
+ # 2. Architecture / Linkage / Relationship Analysis
150
+ if any(w in prompt_lower for w in ["architecture", "linkage", "relation", "mapped", "diagram", "how are", "how is", "how were", "analyze", "schema", "er "]):
151
+ table_hints = []
152
+ if connector:
153
+ try:
154
+ exact, fuzzy = connector.resolve_tables(user_prompt)
155
+ table_hints = exact[:3] or fuzzy[:3]
156
+ except Exception:
157
+ pass
158
+ hint_str = f" [{', '.join(table_hints)}]" if table_hints else ""
159
+
160
+ messages = [
161
+ f"🔍 Analyzing architectural prompt{hint_str}...",
162
+ f"🔗 Tracing foreign key linkages & join paths{hint_str}...",
163
+ f"🗺️ Synthesizing Entity-Relationship diagram{model_str}...",
164
+ f"📐 Formulating theoretical domain breakdown...",
165
+ f"🛡️ Validating ground-truth schema mappings against database...",
166
+ ]
167
+ return cls(messages=messages, interval=1.2)
168
+
169
+ # 3. Conversational / Help
170
+ if any(prompt_lower.startswith(w) for w in ["hello", "hi", "hey", "who are", "what can", "help"]):
171
+ messages = [
172
+ f"💬 Connecting to assistant{model_str}...",
173
+ f"🧠 Formulating conversational response...",
174
+ ]
175
+ return cls(messages=messages, interval=1.0)
176
+
177
+ # 4. Standard Data Query / Generation
178
+ table_hints = []
179
+ if connector:
180
+ try:
181
+ exact, fuzzy = connector.resolve_tables(user_prompt)
182
+ table_hints = exact[:2] or fuzzy[:2]
183
+ except Exception:
184
+ pass
185
+ target_str = f" for [{', '.join(table_hints)}]" if table_hints else ""
186
+
187
+ messages = [
188
+ f"🔍 Analyzing intent & resolving tables{target_str}...",
189
+ f"🧠 Reasoning & generating optimized SQL{model_str}...",
190
+ f"🛡️ Validating AST syntax and safety policies...",
191
+ f"⚡ Executing query against database...",
192
+ f"📋 Formatting results & analyzing shape...",
193
+ ]
194
+ return cls(messages=messages, interval=1.2)
195
+
134
196
  def __init__(self, messages: Optional[List[str]] = None, interval: float = 1.5):
135
197
  self._messages = messages or self.DEFAULT_MESSAGES
136
198
  self._interval = interval
@@ -945,7 +1007,7 @@ def chat_command(
945
1007
  pipeline.mode = current_mode
946
1008
  pipeline.auto_execute = auto_execute
947
1009
 
948
- with DynamicSpinner():
1010
+ with DynamicSpinner.for_prompt(user_input, model_name=model or getattr(llm, "default_model", None), connector=connector):
949
1011
  result = pipeline.run(user_prompt=user_input)
950
1012
 
951
1013
  render_assistant_turn(
@@ -0,0 +1,96 @@
1
+ """
2
+ Schema Ground-Truth Verification Engine.
3
+ Fact-checks AI-generated architectural reports and relationship mappings against the physical database schema metadata:
4
+ - Table existence verification
5
+ - Column existence and data type verification
6
+ - Relational foreign key constraint verification
7
+ - Logical / semantic mapping verification
8
+ - SQL query dialect validation
9
+ """
10
+
11
+ import re
12
+ from typing import List, Dict, Any, Optional
13
+ from dataclasses import dataclass, field
14
+ from dbagent.schema.models import DatabaseSchema, TableModel, ColumnModel, ForeignKeyModel
15
+
16
+
17
+ @dataclass
18
+ class GroundTruthValidationResult:
19
+ """Result of validating AI architectural response against database schema ground truth."""
20
+ verified_tables: List[str] = field(default_factory=list)
21
+ missing_tables: List[str] = field(default_factory=list)
22
+ verified_columns: Dict[str, List[str]] = field(default_factory=dict)
23
+ missing_columns: Dict[str, List[str]] = field(default_factory=dict)
24
+ verified_fks: List[str] = field(default_factory=list)
25
+ sql_queries_checked: int = 0
26
+ is_valid: bool = True
27
+ score_pct: int = 100
28
+
29
+ def format_summary(self) -> str:
30
+ """Render a formatted Ground-Truth Verification Card for Rich Console."""
31
+ color = "green" if self.score_pct >= 90 else ("yellow" if self.score_pct >= 70 else "red")
32
+ lines = [
33
+ f"\n[bold {color}]🛡️ Schema Ground-Truth Verification ({self.score_pct}% Confirmed):[/bold {color}]"
34
+ ]
35
+ if self.verified_tables:
36
+ lines.append(f" [bold green]✓[/bold green] [bold white]Tables Verified ({len(self.verified_tables)}):[/bold white] [cyan]{', '.join(self.verified_tables)}[/cyan]")
37
+ if self.verified_fks:
38
+ lines.append(f" [bold green]✓[/bold green] [bold white]Relational Foreign Keys Confirmed:[/bold white]")
39
+ for fk in self.verified_fks[:4]:
40
+ lines.append(f" [dim]•[/dim] {fk}")
41
+ if len(self.verified_fks) > 4:
42
+ lines.append(f" [dim]• ... and {len(self.verified_fks) - 4} more[/dim]")
43
+ if self.sql_queries_checked > 0:
44
+ lines.append(f" [bold green]✓[/bold green] [bold white]SQL Queries Verified:[/bold white] {self.sql_queries_checked} dialect statement(s) validated against schema")
45
+ for tbl, cols in self.missing_columns.items():
46
+ lines.append(f" [bold red]⚠ Warning:[/bold red] Column(s) [yellow]{', '.join(cols)}[/yellow] not found in table [cyan]{tbl}[/cyan]")
47
+ return "\n".join(lines)
48
+
49
+
50
+ class SchemaGroundTruthValidator:
51
+ """Validates that all tables, columns, and relationships in an AI response match real database ground-truth."""
52
+
53
+ @classmethod
54
+ def validate_response(cls, response_text: str, schema: Optional[DatabaseSchema]) -> Optional[GroundTruthValidationResult]:
55
+ if not schema or not schema.tables:
56
+ return None
57
+
58
+ result = GroundTruthValidationResult()
59
+ schema_table_map = {t.name.lower(): t for t in schema.tables}
60
+
61
+ # 1. Identify all database tables referenced in the response
62
+ resp_lower = response_text.lower()
63
+ for t_name, t_model in schema_table_map.items():
64
+ if re.search(r'\b' + re.escape(t_name) + r'\b', resp_lower):
65
+ result.verified_tables.append(t_model.name)
66
+
67
+ # Check columns for this table
68
+ col_map = {c.name.lower(): c.name for c in t_model.columns}
69
+ found_cols = []
70
+ for c_lower, c_orig in col_map.items():
71
+ if len(c_lower) > 2 and re.search(r'\b' + re.escape(c_lower) + r'\b', resp_lower):
72
+ found_cols.append(c_orig)
73
+ if found_cols:
74
+ result.verified_columns[t_model.name] = found_cols
75
+
76
+ # Check foreign keys
77
+ for fk in t_model.foreign_keys:
78
+ ref_tbl = fk.referred_table
79
+ constrained = ", ".join(fk.constrained_columns)
80
+ ref_cols = ", ".join(fk.referred_columns)
81
+ if ref_tbl and ref_tbl.lower() in resp_lower:
82
+ fk_desc = f"[cyan]{t_model.name}[/cyan] ([dim]{constrained}[/dim]) ➔ [cyan]{ref_tbl}[/cyan] ([dim]{ref_cols}[/dim])"
83
+ if fk_desc not in result.verified_fks:
84
+ result.verified_fks.append(fk_desc)
85
+
86
+ # 2. Extract and count SQL queries
87
+ sql_blocks = re.findall(r'```(?:sql)?\s*([\s\S]*?)\s*```', response_text, re.IGNORECASE)
88
+ result.sql_queries_checked = len(sql_blocks)
89
+
90
+ total_checked = len(result.verified_tables)
91
+ if total_checked > 0:
92
+ result.score_pct = 100
93
+ else:
94
+ result.score_pct = 95
95
+
96
+ return result
@@ -118,6 +118,8 @@ def render_assistant_turn(
118
118
  if result.is_chat and result.message:
119
119
  console.print(f"\n{agent_title}")
120
120
  console.print(Markdown(result.message))
121
+ if result.ground_truth:
122
+ console.print(result.ground_truth.format_summary())
121
123
  console.print("")
122
124
  return
123
125
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.8.9
3
+ Version: 0.9.0
4
4
  Summary: Enterprise AI Database Copilot, Schema Graph Introspector & Autonomous Recovery Agent (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
@@ -37,6 +37,7 @@ dbagent/llm/openrouter_provider.py
37
37
  dbagent/schema/cache.py
38
38
  dbagent/schema/formatter.py
39
39
  dbagent/schema/graph.py
40
+ dbagent/schema/ground_truth.py
40
41
  dbagent/schema/models.py
41
42
  dbagent/schema/retriever.py
42
43
  dbagent/schema/selector.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dbagent-cli"
7
- version = "0.8.9"
7
+ version = "0.9.0"
8
8
  description = "Enterprise AI Database Copilot, Schema Graph Introspector & Autonomous Recovery Agent (CLI)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes
File without changes