dbagent-cli 0.9.6__tar.gz → 0.9.8__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.9.6 → dbagent_cli-0.9.8}/PKG-INFO +1 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/__init__.py +1 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/generator.py +4 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/pipeline.py +23 -4
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/cli.py +43 -7
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/connectors/relational.py +5 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/ui/chat_screen.py +8 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/PKG-INFO +1 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/pyproject.toml +1 -1
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_cli.py +19 -2
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/README.md +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/confidence.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/conversation.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/doctor.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/error_classifier.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/recommender.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/agent/validator.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/config.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/connectors/base.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/connectors/factory.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/connectors/mongo.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/__init__.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/cache.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/changeset.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/cost.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/recovery.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/sandbox.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/execution/streaming.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/anthropic_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/auto_setup.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/base.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/deepseek_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/factory.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/gemini_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/groq_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/mistral_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/mock_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/ollama_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/openai_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/llm/openrouter_provider.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/cache.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/formatter.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/graph.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/ground_truth.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/models.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/retriever.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/schema/selector.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/__init__.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/audit.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/environment.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/masking.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/modes.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/security/rbac.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/semantic/__init__.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/semantic/dictionary.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/semantic/knowledge.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/semantic/templates.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/sql/__init__.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/sql/optimizer.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/sql/validator.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/ui/console.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/ui/grid_window.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/ui/viewer.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent/ui/visualizer.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/SOURCES.txt +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/dependency_links.txt +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/entry_points.txt +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/requires.txt +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/dbagent_cli.egg-info/top_level.txt +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/setup.cfg +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_cache.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_connectors.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_direct_sql.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_doctor_and_viz.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_generator.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_graph.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_knowledge.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_providers.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_recovery.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_safety.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_sandbox.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_schema.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_security.py +0 -0
- {dbagent_cli-0.9.6 → dbagent_cli-0.9.8}/tests/test_semantic.py +0 -0
|
@@ -247,6 +247,7 @@ class ScriptGenerator:
|
|
|
247
247
|
user_prompt: str,
|
|
248
248
|
conversation_history: Optional[str] = None,
|
|
249
249
|
model: Optional[str] = None,
|
|
250
|
+
stream_callback: Optional[Callable[[str], None]] = None,
|
|
250
251
|
) -> str:
|
|
251
252
|
"""Generate a natural conversational response to the user's message with full session memory."""
|
|
252
253
|
table_names = [t.name for t in schema.tables]
|
|
@@ -268,6 +269,7 @@ class ScriptGenerator:
|
|
|
268
269
|
prompt=full_prompt,
|
|
269
270
|
system_prompt=system_prompt,
|
|
270
271
|
model=model,
|
|
272
|
+
stream_callback=stream_callback,
|
|
271
273
|
)
|
|
272
274
|
|
|
273
275
|
def generate_analysis_response(
|
|
@@ -276,6 +278,7 @@ class ScriptGenerator:
|
|
|
276
278
|
user_prompt: str,
|
|
277
279
|
conversation_history: Optional[str] = None,
|
|
278
280
|
model: Optional[str] = None,
|
|
281
|
+
stream_callback: Optional[Callable[[str], None]] = None,
|
|
279
282
|
) -> str:
|
|
280
283
|
"""Generate a comprehensive architectural analysis report with ASCII diagrams, theory, and SQL queries."""
|
|
281
284
|
# 1. Filter relevant tables including foreign keys and junction tables
|
|
@@ -301,6 +304,7 @@ class ScriptGenerator:
|
|
|
301
304
|
prompt=full_prompt,
|
|
302
305
|
system_prompt=system_prompt,
|
|
303
306
|
model=model,
|
|
307
|
+
stream_callback=stream_callback,
|
|
304
308
|
)
|
|
305
309
|
|
|
306
310
|
# --- Full generation (for `generate` command) ---
|
|
@@ -56,6 +56,7 @@ class PipelineResult:
|
|
|
56
56
|
# Conversational chat response
|
|
57
57
|
is_chat: bool = False
|
|
58
58
|
is_direct_sql: bool = False
|
|
59
|
+
was_streamed: bool = False
|
|
59
60
|
message: str = ""
|
|
60
61
|
# Query classification
|
|
61
62
|
query_type: str = "unknown" # read, write, ddl, chat, unknown
|
|
@@ -192,7 +193,13 @@ class QueryPipeline:
|
|
|
192
193
|
retriever = ContextRetriever(targeted)
|
|
193
194
|
return retriever.retrieve_context(user_prompt, exact_tables=exact, fuzzy_tables=fuzzy, max_tables=12)
|
|
194
195
|
|
|
195
|
-
def run(
|
|
196
|
+
def run(
|
|
197
|
+
self,
|
|
198
|
+
user_prompt: str,
|
|
199
|
+
force: bool = False,
|
|
200
|
+
bypass_cache: bool = False,
|
|
201
|
+
stream_callback: Optional[Callable[[str], None]] = None,
|
|
202
|
+
) -> PipelineResult:
|
|
196
203
|
"""
|
|
197
204
|
Executes end-to-end pipeline: Prompt -> Security/Semantics -> SQL -> Safe Exec -> Results.
|
|
198
205
|
"""
|
|
@@ -217,7 +224,10 @@ class QueryPipeline:
|
|
|
217
224
|
user_prompt=user_prompt,
|
|
218
225
|
conversation_history=conv_history,
|
|
219
226
|
model=self.model,
|
|
227
|
+
stream_callback=stream_callback,
|
|
220
228
|
)
|
|
229
|
+
if stream_callback:
|
|
230
|
+
result.was_streamed = True
|
|
221
231
|
result.is_chat = True
|
|
222
232
|
result.was_executed = True
|
|
223
233
|
result.query_type = "chat"
|
|
@@ -238,12 +248,18 @@ class QueryPipeline:
|
|
|
238
248
|
exact, fuzzy = [], []
|
|
239
249
|
|
|
240
250
|
# Inherit active tables from conversation context if follow-up prompt doesn't name tables explicitly
|
|
251
|
+
is_inherited = False
|
|
241
252
|
if not exact and not fuzzy:
|
|
242
253
|
inherited = self.conversation.get_active_tables()
|
|
243
254
|
if inherited:
|
|
244
255
|
exact = inherited[:8]
|
|
256
|
+
is_inherited = True
|
|
257
|
+
|
|
258
|
+
effective_prompt = user_prompt
|
|
259
|
+
if is_inherited and exact:
|
|
260
|
+
effective_prompt = f"Focus strictly on the architecture, linkages, and data flow between {', '.join(exact[:5])}. User request: {user_prompt}"
|
|
245
261
|
|
|
246
|
-
sub_schema, join_steps = self._get_fast_schema_context(
|
|
262
|
+
sub_schema, join_steps = self._get_fast_schema_context(effective_prompt, exact, fuzzy)
|
|
247
263
|
result.schema = sub_schema
|
|
248
264
|
result.join_steps = join_steps
|
|
249
265
|
|
|
@@ -258,16 +274,19 @@ class QueryPipeline:
|
|
|
258
274
|
source="user_guidance",
|
|
259
275
|
)
|
|
260
276
|
|
|
261
|
-
kb_context = self.knowledge_base.format_prompt_context(self.db_name,
|
|
277
|
+
kb_context = self.knowledge_base.format_prompt_context(self.db_name, effective_prompt, exact + fuzzy)
|
|
262
278
|
conv_history = self.conversation.format_context_for_prompt()
|
|
263
|
-
analysis_prompt = f"{kb_context}\n\n{
|
|
279
|
+
analysis_prompt = f"{kb_context}\n\n{effective_prompt}" if kb_context else effective_prompt
|
|
264
280
|
|
|
265
281
|
result.message = self.generator.generate_analysis_response(
|
|
266
282
|
schema=sub_schema,
|
|
267
283
|
user_prompt=analysis_prompt,
|
|
268
284
|
conversation_history=conv_history,
|
|
269
285
|
model=self.model,
|
|
286
|
+
stream_callback=stream_callback,
|
|
270
287
|
)
|
|
288
|
+
if stream_callback:
|
|
289
|
+
result.was_streamed = True
|
|
271
290
|
result.ground_truth = SchemaGroundTruthValidator.validate_response(result.message, sub_schema)
|
|
272
291
|
result.is_chat = True
|
|
273
292
|
result.was_executed = True
|
|
@@ -339,7 +339,10 @@ def _display_pipeline_result(result: PipelineResult, show_sql: bool = True) -> N
|
|
|
339
339
|
|
|
340
340
|
if result.is_chat and result.message:
|
|
341
341
|
console.print("")
|
|
342
|
-
|
|
342
|
+
if not result.was_streamed:
|
|
343
|
+
console.print(Markdown(result.message))
|
|
344
|
+
if result.ground_truth:
|
|
345
|
+
console.print(result.ground_truth.format_summary())
|
|
343
346
|
if result.execution_time_ms > 0:
|
|
344
347
|
print_timing(result.execution_time_ms)
|
|
345
348
|
console.print("")
|
|
@@ -527,8 +530,25 @@ def ask_command(
|
|
|
527
530
|
choice_callback=_choice_callback,
|
|
528
531
|
)
|
|
529
532
|
|
|
530
|
-
|
|
531
|
-
|
|
533
|
+
spinner = DynamicSpinner.for_prompt(prompt, model_name=model or getattr(llm, "default_model", None), connector=connector)
|
|
534
|
+
stream_started = [False]
|
|
535
|
+
|
|
536
|
+
def _query_stream_callback(chunk: str) -> None:
|
|
537
|
+
if not stream_started[0]:
|
|
538
|
+
stream_started[0] = True
|
|
539
|
+
spinner.pause()
|
|
540
|
+
timing_str = f"⚡ {spinner.elapsed_ms / 1000:.2f}s" if spinner.elapsed_ms > 0 else ""
|
|
541
|
+
active_model = model or getattr(llm, "default_model", None)
|
|
542
|
+
model_display = f" ({active_model})" if active_model else ""
|
|
543
|
+
console.print(f"\n[bold cyan]● DB-Agent{model_display}[/bold cyan] [dim]{timing_str}[/dim]")
|
|
544
|
+
try:
|
|
545
|
+
sys.stdout.write(chunk)
|
|
546
|
+
sys.stdout.flush()
|
|
547
|
+
except Exception:
|
|
548
|
+
pass
|
|
549
|
+
|
|
550
|
+
with spinner:
|
|
551
|
+
result = pipeline.run(user_prompt=prompt, force=force, bypass_cache=no_cache, stream_callback=_query_stream_callback)
|
|
532
552
|
|
|
533
553
|
_display_pipeline_result(result, show_sql=True)
|
|
534
554
|
connector.close()
|
|
@@ -1094,14 +1114,30 @@ def chat_command(
|
|
|
1094
1114
|
console.print("[bold cyan]Goodbye![/bold cyan]")
|
|
1095
1115
|
break
|
|
1096
1116
|
|
|
1097
|
-
# --- Natural language query via pipeline ---
|
|
1098
|
-
# Update pipeline settings in-place (pipeline was created once before the loop)
|
|
1117
|
+
# --- Natural language query via pipeline with live streaming ---
|
|
1099
1118
|
pipeline.model = model
|
|
1100
1119
|
pipeline.mode = current_mode
|
|
1101
1120
|
pipeline.auto_execute = auto_execute
|
|
1102
1121
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1122
|
+
spinner = DynamicSpinner.for_prompt(user_input, model_name=model or getattr(llm, "default_model", None), connector=connector)
|
|
1123
|
+
stream_started = [False]
|
|
1124
|
+
|
|
1125
|
+
def _live_stream_callback(chunk: str) -> None:
|
|
1126
|
+
if not stream_started[0]:
|
|
1127
|
+
stream_started[0] = True
|
|
1128
|
+
spinner.pause()
|
|
1129
|
+
timing_str = f"⚡ {spinner.elapsed_ms / 1000:.2f}s" if spinner.elapsed_ms > 0 else ""
|
|
1130
|
+
active_model = model or getattr(llm, "default_model", None)
|
|
1131
|
+
model_display = f" ({active_model})" if active_model else ""
|
|
1132
|
+
console.print(f"\n[bold cyan]● DB-Agent{model_display}[/bold cyan] [dim]{timing_str}[/dim]")
|
|
1133
|
+
try:
|
|
1134
|
+
sys.stdout.write(chunk)
|
|
1135
|
+
sys.stdout.flush()
|
|
1136
|
+
except Exception:
|
|
1137
|
+
pass
|
|
1138
|
+
|
|
1139
|
+
with spinner:
|
|
1140
|
+
result = pipeline.run(user_prompt=user_input, stream_callback=_live_stream_callback)
|
|
1105
1141
|
|
|
1106
1142
|
render_assistant_turn(
|
|
1107
1143
|
result,
|
|
@@ -47,7 +47,7 @@ def _fuzzy_match_tables(table_names: List[str], user_prompt: str) -> Tuple[List[
|
|
|
47
47
|
exact: List[str] = []
|
|
48
48
|
fuzzy: List[str] = []
|
|
49
49
|
|
|
50
|
-
# Extract meaningful words from the prompt (3+ chars, skip SQL keywords)
|
|
50
|
+
# Extract meaningful words from the prompt (3+ chars, skip SQL keywords and diagram meta-terms)
|
|
51
51
|
sql_keywords = {
|
|
52
52
|
"select", "from", "where", "join", "left", "right", "inner", "outer",
|
|
53
53
|
"order", "group", "having", "limit", "offset", "insert", "update",
|
|
@@ -57,6 +57,10 @@ def _fuzzy_match_tables(table_names: List[str], user_prompt: str) -> Tuple[List[
|
|
|
57
57
|
"drop", "index", "primary", "foreign", "key", "null", "default",
|
|
58
58
|
"hour", "minute", "day", "week", "month", "year", "ago", "today",
|
|
59
59
|
"give", "tell", "want", "need", "please", "display", "fetch",
|
|
60
|
+
"flow", "diagram", "chart", "graph", "link", "links", "structure",
|
|
61
|
+
"design", "model", "blueprint", "mapping", "mappings", "overview",
|
|
62
|
+
"query", "code", "script", "report", "summary", "relation",
|
|
63
|
+
"relations", "relationship", "relationships", "architecture", "check",
|
|
60
64
|
}
|
|
61
65
|
prompt_words = set()
|
|
62
66
|
for word in re.findall(r"\b[a-z_][a-z0-9_]*\b", prompt_lower):
|
|
@@ -114,8 +114,15 @@ def render_assistant_turn(
|
|
|
114
114
|
model_display = f" ({ai_model})" if ai_model else ""
|
|
115
115
|
agent_title = f"[bold cyan]● DB-Agent{model_display}[/bold cyan] [dim]{timing_str}[/dim]"
|
|
116
116
|
|
|
117
|
-
# Conversational Chat Response
|
|
117
|
+
# Conversational Chat / Architectural Analysis Response
|
|
118
118
|
if result.is_chat and result.message:
|
|
119
|
+
if result.was_streamed:
|
|
120
|
+
console.print("")
|
|
121
|
+
if result.ground_truth:
|
|
122
|
+
console.print(result.ground_truth.format_summary())
|
|
123
|
+
console.print("")
|
|
124
|
+
return
|
|
125
|
+
|
|
119
126
|
console.print(f"\n{agent_title}")
|
|
120
127
|
console.print(Markdown(result.message))
|
|
121
128
|
if result.ground_truth:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dbagent-cli"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.8"
|
|
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"
|
|
@@ -481,6 +481,25 @@ def test_cli_changes_and_audit_commands():
|
|
|
481
481
|
assert res_audit.exit_code == 0
|
|
482
482
|
|
|
483
483
|
|
|
484
|
+
def test_pipeline_streaming_callback(sample_db: str):
|
|
485
|
+
from dbagent.connectors.factory import create_connector
|
|
486
|
+
from dbagent.llm.mock_provider import MockProvider
|
|
487
|
+
from dbagent.agent.pipeline import QueryPipeline
|
|
488
|
+
|
|
489
|
+
connector = create_connector(sample_db)
|
|
490
|
+
llm = MockProvider()
|
|
491
|
+
pipeline = QueryPipeline(connector=connector, llm=llm)
|
|
492
|
+
|
|
493
|
+
chunks = []
|
|
494
|
+
def callback(token: str):
|
|
495
|
+
chunks.append(token)
|
|
496
|
+
|
|
497
|
+
result = pipeline.run("hello assistant", stream_callback=callback)
|
|
498
|
+
assert result.was_streamed is True
|
|
499
|
+
assert result.is_chat is True
|
|
500
|
+
connector.close()
|
|
501
|
+
|
|
502
|
+
|
|
484
503
|
def test_cli_recovery_commands():
|
|
485
504
|
res_list = runner.invoke(app, ["recovery", "list"])
|
|
486
505
|
assert res_list.exit_code == 0
|
|
@@ -491,5 +510,3 @@ def test_cli_recovery_commands():
|
|
|
491
510
|
|
|
492
511
|
res_cleanup = runner.invoke(app, ["recovery", "cleanup"])
|
|
493
512
|
assert res_cleanup.exit_code == 0
|
|
494
|
-
|
|
495
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|