sqlsaber 0.19.0__tar.gz → 0.20.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.

Potentially problematic release.


This version of sqlsaber might be problematic. Click here for more details.

Files changed (104) hide show
  1. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/PKG-INFO +1 -1
  2. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/changelog.md +8 -0
  3. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/pyproject.toml +1 -1
  4. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/commands.py +11 -41
  5. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/database.py +3 -1
  6. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/interactive.py +24 -19
  7. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/threads.py +14 -7
  8. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_cli/test_threads.py +12 -8
  9. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/uv.lock +1 -1
  10. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.github/workflows/claude-code-review.yml +0 -0
  11. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.github/workflows/claude.yml +0 -0
  12. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.github/workflows/deploy-docs.yml +0 -0
  13. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.github/workflows/publish.yml +0 -0
  14. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.github/workflows/test.yml +0 -0
  15. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.gitignore +0 -0
  16. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/.python-version +0 -0
  17. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/AGENT.md +0 -0
  18. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/CLAUDE.md +0 -0
  19. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/LICENSE +0 -0
  20. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/README.md +0 -0
  21. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/.gitignore +0 -0
  22. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/.vscode/extensions.json +0 -0
  23. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/.vscode/launch.json +0 -0
  24. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/CLAUDE.md +0 -0
  25. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/astro.config.mjs +0 -0
  26. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/package-lock.json +0 -0
  27. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/package.json +0 -0
  28. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/public/CNAME +0 -0
  29. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/public/favicon.svg +0 -0
  30. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/assets/sqlsaber-hero.svg +0 -0
  31. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/authentication.mdx +0 -0
  32. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/database-setup.mdx +0 -0
  33. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/getting-started.mdx +0 -0
  34. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/memory.mdx +0 -0
  35. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/models.mdx +0 -0
  36. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/queries.mdx +0 -0
  37. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/guides/threads.md +0 -0
  38. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/index.mdx +0 -0
  39. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/installation.mdx +0 -0
  40. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content/docs/reference/commands.md +0 -0
  41. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/content.config.ts +0 -0
  42. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/src/styles/global.css +0 -0
  43. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/docs/tsconfig.json +0 -0
  44. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/legislators.db +0 -0
  45. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/pytest.ini +0 -0
  46. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/sqlsaber.gif +0 -0
  47. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/sqlsaber.svg +0 -0
  48. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/__init__.py +0 -0
  49. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/__main__.py +0 -0
  50. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/agents/__init__.py +0 -0
  51. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/agents/base.py +0 -0
  52. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/agents/mcp.py +0 -0
  53. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/agents/pydantic_ai_agent.py +0 -0
  54. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/__init__.py +0 -0
  55. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/auth.py +0 -0
  56. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/completers.py +0 -0
  57. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/display.py +0 -0
  58. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/memory.py +0 -0
  59. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/models.py +0 -0
  60. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/cli/streaming.py +0 -0
  61. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/__init__.py +0 -0
  62. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/api_keys.py +0 -0
  63. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/auth.py +0 -0
  64. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/database.py +0 -0
  65. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/oauth_flow.py +0 -0
  66. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/oauth_tokens.py +0 -0
  67. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/providers.py +0 -0
  68. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/config/settings.py +0 -0
  69. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/database/__init__.py +0 -0
  70. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/database/connection.py +0 -0
  71. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/database/resolver.py +0 -0
  72. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/database/schema.py +0 -0
  73. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/mcp/__init__.py +0 -0
  74. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/mcp/mcp.py +0 -0
  75. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/memory/__init__.py +0 -0
  76. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/memory/manager.py +0 -0
  77. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/memory/storage.py +0 -0
  78. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/threads/__init__.py +0 -0
  79. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/threads/storage.py +0 -0
  80. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/__init__.py +0 -0
  81. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/base.py +0 -0
  82. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/enums.py +0 -0
  83. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/instructions.py +0 -0
  84. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/registry.py +0 -0
  85. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/src/sqlsaber/tools/sql_tools.py +0 -0
  86. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/__init__.py +0 -0
  87. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/conftest.py +0 -0
  88. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_cli/__init__.py +0 -0
  89. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_cli/test_auth_reset.py +0 -0
  90. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_cli/test_commands.py +0 -0
  91. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_config/__init__.py +0 -0
  92. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_config/test_database.py +0 -0
  93. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_config/test_oauth.py +0 -0
  94. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_config/test_providers.py +0 -0
  95. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_config/test_settings.py +0 -0
  96. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_database/__init__.py +0 -0
  97. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_database/test_connection.py +0 -0
  98. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_database_resolver.py +0 -0
  99. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_threads_storage.py +0 -0
  100. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_tools/__init__.py +0 -0
  101. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_tools/test_base.py +0 -0
  102. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_tools/test_instructions.py +0 -0
  103. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_tools/test_registry.py +0 -0
  104. {sqlsaber-0.19.0 → sqlsaber-0.20.0}/tests/test_tools/test_sql_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlsaber
3
- Version: 0.19.0
3
+ Version: 0.20.0
4
4
  Summary: SQLsaber - Open-source agentic SQL assistant
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -9,6 +9,14 @@ All notable changes to SQLsaber will be documented here.
9
9
 
10
10
  ---
11
11
 
12
+ ### v0.20.0 - 2025-09-10
13
+
14
+ #### Fixed
15
+
16
+ - Subcommand help visibility for nested apps
17
+ - Removed mouse support for user prompt
18
+ - Enabling mouse support disables terminal scrolling when user prompt is focused
19
+
12
20
  ### v0.19.0 - 2025-09-09
13
21
 
14
22
  #### Added
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sqlsaber"
3
- version = "0.19.0"
3
+ version = "0.20.0"
4
4
  description = "SQLsaber - Open-source agentic SQL assistant"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -7,6 +7,12 @@ from typing import Annotated
7
7
  import cyclopts
8
8
  from rich.console import Console
9
9
 
10
+ from sqlsaber.cli.auth import create_auth_app
11
+ from sqlsaber.cli.database import create_db_app
12
+ from sqlsaber.cli.memory import create_memory_app
13
+ from sqlsaber.cli.models import create_models_app
14
+ from sqlsaber.cli.threads import create_threads_app
15
+
10
16
  # Lazy imports - only import what's needed for CLI parsing
11
17
  from sqlsaber.config.database import DatabaseConfigManager
12
18
 
@@ -24,6 +30,11 @@ app = cyclopts.App(
24
30
  help="SQLsaber - Open-source agentic SQL assistant for your database",
25
31
  )
26
32
 
33
+ app.command(create_auth_app(), name="auth")
34
+ app.command(create_db_app(), name="db")
35
+ app.command(create_memory_app(), name="memory")
36
+ app.command(create_models_app(), name="models")
37
+ app.command(create_threads_app(), name="threads")
27
38
 
28
39
  console = Console()
29
40
  config_manager = DatabaseConfigManager()
@@ -195,47 +206,6 @@ def query(
195
206
  sys.exit(e.exit_code)
196
207
 
197
208
 
198
- # Use lazy imports for fast CLI startup time
199
- @app.command(name="auth")
200
- def auth(*args, **kwargs):
201
- """Manage authentication configuration."""
202
- from sqlsaber.cli.auth import create_auth_app
203
-
204
- return create_auth_app()(*args, **kwargs)
205
-
206
-
207
- @app.command(name="db")
208
- def db(*args, **kwargs):
209
- """Manage database connections."""
210
- from sqlsaber.cli.database import create_db_app
211
-
212
- return create_db_app()(*args, **kwargs)
213
-
214
-
215
- @app.command(name="memory")
216
- def memory(*args, **kwargs):
217
- """Manage database-specific memories."""
218
- from sqlsaber.cli.memory import create_memory_app
219
-
220
- return create_memory_app()(*args, **kwargs)
221
-
222
-
223
- @app.command(name="models")
224
- def models(*args, **kwargs):
225
- """Select and manage models."""
226
- from sqlsaber.cli.models import create_models_app
227
-
228
- return create_models_app()(*args, **kwargs)
229
-
230
-
231
- @app.command(name="threads")
232
- def threads(*args, **kwargs):
233
- """Manage SQLsaber threads."""
234
- from sqlsaber.cli.threads import create_threads_app
235
-
236
- return create_threads_app()(*args, **kwargs)
237
-
238
-
239
209
  def main():
240
210
  """Entry point for the CLI application."""
241
211
  app()
@@ -12,7 +12,6 @@ from rich.console import Console
12
12
  from rich.table import Table
13
13
 
14
14
  from sqlsaber.config.database import DatabaseConfig, DatabaseConfigManager
15
- from sqlsaber.database.connection import DatabaseConnection
16
15
 
17
16
  # Global instances for CLI commands
18
17
  console = Console()
@@ -343,6 +342,9 @@ def test(
343
342
  """Test a database connection."""
344
343
 
345
344
  async def test_connection():
345
+ # Lazy import to keep CLI startup fast
346
+ from sqlsaber.database.connection import DatabaseConnection
347
+
346
348
  if name:
347
349
  db_config = config_manager.get_database(name)
348
350
  if not db_config:
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
  import platformdirs
7
7
  from prompt_toolkit import PromptSession
8
8
  from prompt_toolkit.history import FileHistory
9
+ from prompt_toolkit.patch_stdout import patch_stdout
9
10
  from prompt_toolkit.styles import Style
10
11
  from pydantic_ai import Agent
11
12
  from rich.console import Console
@@ -118,6 +119,15 @@ class InteractiveSession:
118
119
  if self._thread_id:
119
120
  self.console.print(f"[dim]Resuming thread:[/dim] {self._thread_id}\n")
120
121
 
122
+ async def _end_thread_and_display_resume_hint(self):
123
+ """End thread and display command to resume thread"""
124
+ # Print resume hint if there is an active thread
125
+ if self._thread_id:
126
+ await self._threads.end_thread(self._thread_id)
127
+ self.console.print(
128
+ f"[dim]You can continue this thread using:[/dim] saber threads resume {self._thread_id}"
129
+ )
130
+
121
131
  async def _update_table_cache(self):
122
132
  """Update the table completer cache with fresh data."""
123
133
  try:
@@ -215,33 +225,27 @@ class InteractiveSession:
215
225
 
216
226
  while True:
217
227
  try:
218
- # with patch_stdout():
219
- user_query = await session.prompt_async(
220
- "",
221
- multiline=True,
222
- mouse_support=True,
223
- completer=CompositeCompleter(
224
- SlashCommandCompleter(), self.table_completer
225
- ),
226
- show_frame=True,
227
- bottom_toolbar=bottom_toolbar,
228
- style=style,
229
- )
228
+ with patch_stdout():
229
+ user_query = await session.prompt_async(
230
+ "",
231
+ multiline=True,
232
+ completer=CompositeCompleter(
233
+ SlashCommandCompleter(), self.table_completer
234
+ ),
235
+ show_frame=True,
236
+ bottom_toolbar=bottom_toolbar,
237
+ style=style,
238
+ )
230
239
 
231
240
  if not user_query:
232
241
  continue
233
242
 
234
243
  if (
235
- user_query in ["/exit", "/quit"]
244
+ user_query in ["/exit", "/quit", "exit", "quit"]
236
245
  or user_query.startswith("/exit")
237
246
  or user_query.startswith("/quit")
238
247
  ):
239
- # Print resume hint if there is an active thread
240
- if self._thread_id:
241
- await self._threads.end_thread(self._thread_id)
242
- self.console.print(
243
- f"[dim]You can continue this thread using:[/dim] saber threads resume {self._thread_id}"
244
- )
248
+ await self._end_thread_and_display_resume_hint()
245
249
  break
246
250
 
247
251
  if user_query == "/clear":
@@ -313,6 +317,7 @@ class InteractiveSession:
313
317
  )
314
318
  except EOFError:
315
319
  # Exit when Ctrl+D is pressed
320
+ await self._end_thread_and_display_resume_hint()
316
321
  break
317
322
  except Exception as e:
318
323
  self.console.print(f"[bold red]Error:[/bold red] {str(e)}")
@@ -12,17 +12,10 @@ from rich.markdown import Markdown
12
12
  from rich.panel import Panel
13
13
  from rich.table import Table
14
14
 
15
- from sqlsaber.agents import build_sqlsaber_agent
16
- from sqlsaber.cli.display import DisplayManager
17
- from sqlsaber.cli.interactive import InteractiveSession
18
- from sqlsaber.config.database import DatabaseConfigManager
19
- from sqlsaber.database.connection import DatabaseConnection
20
- from sqlsaber.database.resolver import DatabaseResolutionError, resolve_database
21
15
  from sqlsaber.threads import ThreadStorage
22
16
 
23
17
  # Globals consistent with other CLI modules
24
18
  console = Console()
25
- config_manager = DatabaseConfigManager()
26
19
 
27
20
 
28
21
  threads_app = cyclopts.App(
@@ -41,6 +34,9 @@ def _render_transcript(
41
34
  console: Console, all_msgs: list[ModelMessage], last_n: int | None = None
42
35
  ) -> None:
43
36
  """Render conversation turns from ModelMessage[] using DisplayManager."""
37
+ # Lazy import to avoid pulling UI helpers at startup
38
+ from sqlsaber.cli.display import DisplayManager
39
+
44
40
  dm = DisplayManager(console)
45
41
 
46
42
  # Locate indices of user prompts
@@ -237,6 +233,16 @@ def resume(
237
233
  store = ThreadStorage()
238
234
 
239
235
  async def _run() -> None:
236
+ # Lazy imports to avoid heavy modules at CLI startup
237
+ from sqlsaber.agents import build_sqlsaber_agent
238
+ from sqlsaber.cli.interactive import InteractiveSession
239
+ from sqlsaber.config.database import DatabaseConfigManager
240
+ from sqlsaber.database.connection import DatabaseConnection
241
+ from sqlsaber.database.resolver import (
242
+ DatabaseResolutionError,
243
+ resolve_database,
244
+ )
245
+
240
246
  thread = await store.get_thread(thread_id)
241
247
  if not thread:
242
248
  console.print(f"[red]Thread not found:[/red] {thread_id}")
@@ -248,6 +254,7 @@ def resume(
248
254
  )
249
255
  return
250
256
  try:
257
+ config_manager = DatabaseConfigManager()
251
258
  resolved = resolve_database(db_selector, config_manager)
252
259
  connection_string = resolved.connection_string
253
260
  db_name = resolved.name
@@ -17,9 +17,9 @@ from rich.console import Console
17
17
  from sqlsaber.cli.threads import (
18
18
  _human_readable,
19
19
  _render_transcript,
20
- config_manager,
21
20
  create_threads_app,
22
21
  )
22
+ from sqlsaber.config.database import DatabaseConfigManager
23
23
  from sqlsaber.threads.storage import Thread, ThreadStorage
24
24
 
25
25
 
@@ -220,7 +220,7 @@ class TestThreadsCLI:
220
220
  ),
221
221
  ]
222
222
 
223
- with patch("sqlsaber.cli.threads.DisplayManager") as mock_dm_class:
223
+ with patch("sqlsaber.cli.display.DisplayManager") as mock_dm_class:
224
224
  mock_dm = MagicMock()
225
225
  mock_dm_class.return_value = mock_dm
226
226
 
@@ -253,7 +253,7 @@ class TestThreadsCLI:
253
253
  ),
254
254
  ]
255
255
 
256
- with patch("sqlsaber.cli.threads.DisplayManager") as mock_dm_class:
256
+ with patch("sqlsaber.cli.display.DisplayManager") as mock_dm_class:
257
257
  mock_dm = MagicMock()
258
258
  mock_dm_class.return_value = mock_dm
259
259
 
@@ -307,10 +307,14 @@ class TestThreadsCLI:
307
307
 
308
308
  with (
309
309
  patch("sqlsaber.cli.threads.ThreadStorage", return_value=store),
310
- patch("sqlsaber.cli.threads.resolve_database") as mock_resolve,
311
- patch("sqlsaber.cli.threads.DatabaseConnection") as mock_db_conn_class,
312
- patch("sqlsaber.cli.threads.build_sqlsaber_agent") as mock_build_agent,
313
- patch("sqlsaber.cli.threads.InteractiveSession") as mock_session_class,
310
+ patch("sqlsaber.database.resolver") as mock_resolve,
311
+ patch("sqlsaber.database.DatabaseConnection") as mock_db_conn_class,
312
+ patch(
313
+ "sqlsaber.agents.pydantic_ai_agent.build_sqlsaber_agent"
314
+ ) as mock_build_agent,
315
+ patch(
316
+ "sqlsaber.cli.interactive.InteractiveSession"
317
+ ) as mock_session_class,
314
318
  ):
315
319
  # Mock database resolution
316
320
  mock_resolved = MagicMock()
@@ -333,7 +337,7 @@ class TestThreadsCLI:
333
337
  assert resolved_thread == thread
334
338
 
335
339
  db_selector = resolved_thread.database_name
336
- resolved = mock_resolve(db_selector, config_manager)
340
+ resolved = mock_resolve(db_selector, DatabaseConfigManager())
337
341
  assert resolved.name == "prod_db"
338
342
 
339
343
  await mock_resume_run()
@@ -1910,7 +1910,7 @@ wheels = [
1910
1910
 
1911
1911
  [[package]]
1912
1912
  name = "sqlsaber"
1913
- version = "0.19.0"
1913
+ version = "0.20.0"
1914
1914
  source = { editable = "." }
1915
1915
  dependencies = [
1916
1916
  { name = "aiomysql" },
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