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.
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/PKG-INFO +2 -2
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/__init__.py +1 -1
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/pipeline.py +44 -11
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/cli.py +22 -10
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/PKG-INFO +2 -2
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/pyproject.toml +2 -2
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/README.md +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/confidence.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/conversation.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/doctor.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/error_classifier.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/generator.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/recommender.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/agent/validator.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/config.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/base.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/factory.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/mongo.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/connectors/relational.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/__init__.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/cache.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/changeset.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/cost.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/recovery.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/sandbox.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/execution/streaming.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/auto_setup.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/base.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/factory.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/gemini_provider.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/groq_provider.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/mock_provider.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/ollama_provider.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/llm/openrouter_provider.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/cache.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/formatter.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/graph.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/models.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/retriever.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/schema/selector.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/__init__.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/audit.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/environment.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/masking.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/modes.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/security/rbac.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/__init__.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/dictionary.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/semantic/templates.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/__init__.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/optimizer.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/sql/validator.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/console.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/viewer.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent/ui/visualizer.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/SOURCES.txt +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/dependency_links.txt +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/entry_points.txt +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/requires.txt +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/dbagent_cli.egg-info/top_level.txt +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/setup.cfg +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_cache.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_cli.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_connectors.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_doctor_and_viz.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_generator.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_graph.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_recovery.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_safety.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_sandbox.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_schema.py +0 -0
- {dbagent_cli-0.3.1 → dbagent_cli-0.3.2}/tests/test_security.py +0 -0
- {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.
|
|
4
|
-
Summary: Enterprise AI Database Copilot with Long-Term
|
|
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
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
recs = QueryRecommender.generate_recommendations(
|
|
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
|
-
|
|
447
|
-
|
|
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
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
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.
|
|
4
|
-
Summary: Enterprise AI Database Copilot with Long-Term
|
|
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.
|
|
8
|
-
description = "Enterprise AI Database Copilot with Long-Term
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|