dbagent-cli 0.9.8__tar.gz → 0.9.9__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 (85) hide show
  1. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/PKG-INFO +1 -1
  2. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/__init__.py +1 -1
  3. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/cli.py +12 -10
  4. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/ground_truth.py +5 -3
  5. dbagent_cli-0.9.9/dbagent/ui/live_streamer.py +117 -0
  6. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/PKG-INFO +1 -1
  7. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/SOURCES.txt +1 -0
  8. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/pyproject.toml +1 -1
  9. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/README.md +0 -0
  10. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/confidence.py +0 -0
  11. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/conversation.py +0 -0
  12. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/doctor.py +0 -0
  13. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/error_classifier.py +0 -0
  14. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/generator.py +0 -0
  15. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/pipeline.py +0 -0
  16. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/recommender.py +0 -0
  17. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/agent/validator.py +0 -0
  18. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/config.py +0 -0
  19. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/connectors/base.py +0 -0
  20. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/connectors/factory.py +0 -0
  21. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/connectors/mongo.py +0 -0
  22. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/connectors/relational.py +0 -0
  23. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/__init__.py +0 -0
  24. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/cache.py +0 -0
  25. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/changeset.py +0 -0
  26. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/cost.py +0 -0
  27. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/recovery.py +0 -0
  28. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/sandbox.py +0 -0
  29. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/execution/streaming.py +0 -0
  30. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/anthropic_provider.py +0 -0
  31. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/auto_setup.py +0 -0
  32. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/base.py +0 -0
  33. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/deepseek_provider.py +0 -0
  34. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/factory.py +0 -0
  35. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/gemini_provider.py +0 -0
  36. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/groq_provider.py +0 -0
  37. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/mistral_provider.py +0 -0
  38. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/mock_provider.py +0 -0
  39. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/ollama_provider.py +0 -0
  40. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/openai_provider.py +0 -0
  41. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/llm/openrouter_provider.py +0 -0
  42. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/cache.py +0 -0
  43. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/formatter.py +0 -0
  44. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/graph.py +0 -0
  45. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/models.py +0 -0
  46. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/retriever.py +0 -0
  47. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/schema/selector.py +0 -0
  48. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/__init__.py +0 -0
  49. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/audit.py +0 -0
  50. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/environment.py +0 -0
  51. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/masking.py +0 -0
  52. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/modes.py +0 -0
  53. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/security/rbac.py +0 -0
  54. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/semantic/__init__.py +0 -0
  55. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/semantic/dictionary.py +0 -0
  56. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/semantic/knowledge.py +0 -0
  57. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/semantic/templates.py +0 -0
  58. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/sql/__init__.py +0 -0
  59. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/sql/optimizer.py +0 -0
  60. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/sql/validator.py +0 -0
  61. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/ui/chat_screen.py +0 -0
  62. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/ui/console.py +0 -0
  63. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/ui/grid_window.py +0 -0
  64. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/ui/viewer.py +0 -0
  65. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent/ui/visualizer.py +0 -0
  66. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/dependency_links.txt +0 -0
  67. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/entry_points.txt +0 -0
  68. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/requires.txt +0 -0
  69. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/dbagent_cli.egg-info/top_level.txt +0 -0
  70. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/setup.cfg +0 -0
  71. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_cache.py +0 -0
  72. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_cli.py +0 -0
  73. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_connectors.py +0 -0
  74. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_direct_sql.py +0 -0
  75. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_doctor_and_viz.py +0 -0
  76. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_generator.py +0 -0
  77. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_graph.py +0 -0
  78. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_knowledge.py +0 -0
  79. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_providers.py +0 -0
  80. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_recovery.py +0 -0
  81. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_safety.py +0 -0
  82. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_sandbox.py +0 -0
  83. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_schema.py +0 -0
  84. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_security.py +0 -0
  85. {dbagent_cli-0.9.8 → dbagent_cli-0.9.9}/tests/test_semantic.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.9.8
3
+ Version: 0.9.9
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.9.8"
5
+ __version__ = "0.9.9"
6
6
  __author__ = "Santhosh Gupta"
@@ -530,6 +530,8 @@ def ask_command(
530
530
  choice_callback=_choice_callback,
531
531
  )
532
532
 
533
+ from dbagent.ui.live_streamer import LiveMarkdownStreamer
534
+ streamer = LiveMarkdownStreamer(console)
533
535
  spinner = DynamicSpinner.for_prompt(prompt, model_name=model or getattr(llm, "default_model", None), connector=connector)
534
536
  stream_started = [False]
535
537
 
@@ -541,15 +543,14 @@ def ask_command(
541
543
  active_model = model or getattr(llm, "default_model", None)
542
544
  model_display = f" ({active_model})" if active_model else ""
543
545
  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
546
+ streamer.feed(chunk)
549
547
 
550
548
  with spinner:
551
549
  result = pipeline.run(user_prompt=prompt, force=force, bypass_cache=no_cache, stream_callback=_query_stream_callback)
552
550
 
551
+ if stream_started[0]:
552
+ streamer.finalize()
553
+
553
554
  _display_pipeline_result(result, show_sql=True)
554
555
  connector.close()
555
556
 
@@ -1119,6 +1120,8 @@ def chat_command(
1119
1120
  pipeline.mode = current_mode
1120
1121
  pipeline.auto_execute = auto_execute
1121
1122
 
1123
+ from dbagent.ui.live_streamer import LiveMarkdownStreamer
1124
+ streamer = LiveMarkdownStreamer(console)
1122
1125
  spinner = DynamicSpinner.for_prompt(user_input, model_name=model or getattr(llm, "default_model", None), connector=connector)
1123
1126
  stream_started = [False]
1124
1127
 
@@ -1130,15 +1133,14 @@ def chat_command(
1130
1133
  active_model = model or getattr(llm, "default_model", None)
1131
1134
  model_display = f" ({active_model})" if active_model else ""
1132
1135
  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
1136
+ streamer.feed(chunk)
1138
1137
 
1139
1138
  with spinner:
1140
1139
  result = pipeline.run(user_prompt=user_input, stream_callback=_live_stream_callback)
1141
1140
 
1141
+ if stream_started[0]:
1142
+ streamer.finalize()
1143
+
1142
1144
  render_assistant_turn(
1143
1145
  result,
1144
1146
  show_sql=True,
@@ -85,17 +85,19 @@ class SchemaGroundTruthValidator:
85
85
  if fk_desc not in result.verified_fks:
86
86
  result.verified_fks.append(fk_desc)
87
87
 
88
- # 2. Extract and validate SQL queries against physical schema
89
- sql_blocks = re.findall(r'```(?:sql)?\s*([\s\S]*?)\s*```', response_text, re.IGNORECASE)
88
+ # 2. Extract and validate only actual SQL queries against physical schema
89
+ sql_blocks = re.findall(r'```(?:sql)\s*([\s\S]*?)\s*```', response_text, re.IGNORECASE)
90
90
  result.sql_queries_checked = len(sql_blocks)
91
91
  sql_referenced_tables = set()
92
+ sql_ignore_keywords = {"via", "lateral", "on", "using", "where", "select", "table", "as", "and", "or", "values"}
92
93
 
93
94
  for block in sql_blocks:
94
95
  # Extract FROM and JOIN table references
95
96
  matches = re.findall(r'\b(?:FROM|JOIN)\s+([a-zA-Z0-9_]+)', block, re.IGNORECASE)
96
97
  for m in matches:
97
98
  m_clean = m.strip().lower()
98
- sql_referenced_tables.add(m_clean)
99
+ if m_clean not in sql_ignore_keywords:
100
+ sql_referenced_tables.add(m_clean)
99
101
 
100
102
  for sql_tbl in sql_referenced_tables:
101
103
  if sql_tbl in schema_table_map:
@@ -0,0 +1,117 @@
1
+ """
2
+ Real-Time Line-Buffered Rich Markdown Streamer for DB-Agent CLI.
3
+ Renders markdown headers, formatted diagram panels, syntax-highlighted SQL blocks,
4
+ and sleek bulleted lists dynamically as tokens stream in from LLM providers.
5
+ """
6
+
7
+ import re
8
+ import sys
9
+ from typing import List, Optional
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.syntax import Syntax
13
+ from rich.rule import Rule
14
+
15
+
16
+ class LiveMarkdownStreamer:
17
+ """
18
+ Line-buffered dynamic terminal renderer for streaming LLM responses.
19
+ Renders syntax-highlighted code blocks, bordered ASCII diagrams,
20
+ styled markdown headers, and clean bullet lists live as tokens arrive.
21
+ """
22
+
23
+ def __init__(self, console: Optional[Console] = None):
24
+ self.console = console or Console()
25
+ self.buffer = ""
26
+ self.in_code_block = False
27
+ self.code_lang = ""
28
+ self.code_lines: List[str] = []
29
+ self._has_started = False
30
+
31
+ def feed(self, chunk: str) -> None:
32
+ """Feed a token chunk from the LLM stream."""
33
+ self._has_started = True
34
+ self.buffer += chunk
35
+ while "\n" in self.buffer:
36
+ line, self.buffer = self.buffer.split("\n", 1)
37
+ self._process_line(line)
38
+
39
+ def _process_line(self, line: str) -> None:
40
+ line_strip = line.strip()
41
+
42
+ # Code block fence (```sql, ```text, ```)
43
+ if line_strip.startswith("```"):
44
+ if self.in_code_block:
45
+ # Close code block
46
+ self.in_code_block = False
47
+ code_text = "\n".join(self.code_lines)
48
+ lang = self.code_lang or "sql"
49
+ if lang in ["sql", "postgres", "postgresql", "mysql", "sqlite", "tsql"]:
50
+ syntax = Syntax(code_text, "sql", theme="monokai", line_numbers=False)
51
+ self.console.print(Panel(syntax, title="[dim]SQL Statement[/dim]", title_align="left", border_style="dim", padding=(0, 1)))
52
+ else:
53
+ syntax = Syntax(code_text, "text", theme="monokai", line_numbers=False)
54
+ self.console.print(Panel(syntax, title="[dim]Architecture Flow Diagram[/dim]", title_align="left", border_style="cyan", padding=(0, 1)))
55
+ self.code_lines = []
56
+ self.code_lang = ""
57
+ else:
58
+ # Open code block
59
+ self.in_code_block = True
60
+ self.code_lang = line_strip[3:].strip().lower()
61
+ self.code_lines = []
62
+ return
63
+
64
+ if self.in_code_block:
65
+ self.code_lines.append(line)
66
+ return
67
+
68
+ # Markdown Section Headers (#, ##, ###)
69
+ if line_strip.startswith("#"):
70
+ header_text = line_strip.lstrip("#").strip()
71
+ self.console.print("")
72
+ self.console.print(f"[bold cyan]{header_text}[/bold cyan]")
73
+ return
74
+
75
+ # Markdown Horizontal Rules (---, ***, ___)
76
+ if line_strip in ["---", "***", "___"]:
77
+ self.console.print(Rule(style="dim cyan"))
78
+ return
79
+
80
+ # Markdown Bullet Points (- , * , • )
81
+ if line_strip.startswith(("- ", "* ", "• ")):
82
+ content = line_strip[2:].strip()
83
+ styled = re.sub(r'\*\*(.*?)\*\*', r'[bold cyan]\1[/bold cyan]', content)
84
+ styled = re.sub(r'`(.*?)`', r'[bold white]\1[/bold white]', styled)
85
+ self.console.print(f" [dim]•[/dim] {styled}")
86
+ return
87
+
88
+ # Numbered List items (1. , 2. )
89
+ num_match = re.match(r'^(\d+[\.\)])\s+(.*)', line_strip)
90
+ if num_match:
91
+ num_prefix, content = num_match.groups()
92
+ styled = re.sub(r'\*\*(.*?)\*\*', r'[bold cyan]\1[/bold cyan]', content)
93
+ styled = re.sub(r'`(.*?)`', r'[bold white]\1[/bold white]', styled)
94
+ self.console.print(f" [bold yellow]{num_prefix}[/bold yellow] {styled}")
95
+ return
96
+
97
+ # Blank Line
98
+ if not line_strip:
99
+ self.console.print("")
100
+ return
101
+
102
+ # Regular Markdown paragraph text with bold and inline code styling
103
+ styled_line = re.sub(r'\*\*(.*?)\*\*', r'[bold cyan]\1[/bold cyan]', line)
104
+ styled_line = re.sub(r'`(.*?)`', r'[bold white]\1[/bold white]', styled_line)
105
+ self.console.print(styled_line)
106
+
107
+ def finalize(self) -> None:
108
+ """Flush remaining buffer and close any dangling open blocks."""
109
+ if self.buffer.strip():
110
+ self._process_line(self.buffer)
111
+ if self.in_code_block and self.code_lines:
112
+ code_text = "\n".join(self.code_lines)
113
+ syntax = Syntax(code_text, self.code_lang or "sql", theme="monokai", line_numbers=False)
114
+ self.console.print(Panel(syntax, border_style="dim", padding=(0, 1)))
115
+ self.buffer = ""
116
+ self.code_lines = []
117
+ self.in_code_block = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.9.8
3
+ Version: 0.9.9
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
@@ -57,6 +57,7 @@ dbagent/sql/validator.py
57
57
  dbagent/ui/chat_screen.py
58
58
  dbagent/ui/console.py
59
59
  dbagent/ui/grid_window.py
60
+ dbagent/ui/live_streamer.py
60
61
  dbagent/ui/viewer.py
61
62
  dbagent/ui/visualizer.py
62
63
  dbagent_cli.egg-info/PKG-INFO
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dbagent-cli"
7
- version = "0.9.8"
7
+ version = "0.9.9"
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