sqlsaber 0.17.0__tar.gz → 0.18.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.
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/CHANGELOG.md +7 -1
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/PKG-INFO +1 -1
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/pyproject.toml +1 -2
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/commands.py +51 -32
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/database/connection.py +4 -1
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/uv.lock +1 -1
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.github/workflows/claude-code-review.yml +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.github/workflows/claude.yml +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.github/workflows/deploy-docs.yml +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.github/workflows/publish.yml +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.github/workflows/test.yml +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.gitignore +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/.python-version +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/AGENT.md +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/CLAUDE.md +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/LICENSE +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/README.md +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/.gitignore +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/.vscode/extensions.json +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/.vscode/launch.json +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/astro.config.mjs +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/package-lock.json +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/package.json +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/public/CNAME +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/public/favicon.svg +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/assets/sqlsaber-hero.svg +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/content/docs/guides/example.md +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/content/docs/index.mdx +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/content/docs/reference/example.md +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/content.config.ts +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/src/styles/global.css +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/docs/tsconfig.json +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/pytest.ini +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/sqlsaber.gif +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/sqlsaber.svg +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/__main__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/agents/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/agents/base.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/agents/mcp.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/agents/pydantic_ai_agent.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/auth.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/completers.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/database.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/display.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/interactive.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/memory.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/models.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/streaming.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/cli/threads.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/api_keys.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/auth.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/database.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/oauth_flow.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/oauth_tokens.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/providers.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/config/settings.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/database/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/database/resolver.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/database/schema.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/mcp/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/mcp/mcp.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/memory/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/memory/manager.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/memory/storage.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/threads/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/threads/storage.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/base.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/enums.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/instructions.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/registry.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/src/sqlsaber/tools/sql_tools.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/conftest.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_cli/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_cli/test_auth_reset.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_cli/test_commands.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_cli/test_threads.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_config/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_config/test_database.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_config/test_oauth.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_config/test_providers.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_config/test_settings.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_database/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_database/test_connection.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_database_resolver.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_threads_storage.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_tools/__init__.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_tools/test_base.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_tools/test_instructions.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_tools/test_registry.py +0 -0
- {sqlsaber-0.17.0 → sqlsaber-0.18.0}/tests/test_tools/test_sql_tools.py +0 -0
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to SQLsaber will be documented
|
|
3
|
+
All notable changes to SQLsaber will be documented here.
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.18.0] - 2025-09-08
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Improved CLI startup time
|
|
12
|
+
|
|
7
13
|
## [0.17.0] - 2025-09-08
|
|
8
14
|
|
|
9
15
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sqlsaber"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.18.0"
|
|
4
4
|
description = "SQLsaber - Open-source agentic SQL assistant"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -21,7 +21,6 @@ dependencies = [
|
|
|
21
21
|
|
|
22
22
|
[tool.uv]
|
|
23
23
|
dev-dependencies = ["ruff>=0.12.0", "pytest>=8.0.0", "pytest-asyncio>=1.0.0"]
|
|
24
|
-
compile-bytecode = true
|
|
25
24
|
|
|
26
25
|
[build-system]
|
|
27
26
|
requires = ["hatchling"]
|
|
@@ -7,24 +7,8 @@ from typing import Annotated
|
|
|
7
7
|
import cyclopts
|
|
8
8
|
from rich.console import Console
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
from sqlsaber.cli.auth import create_auth_app
|
|
12
|
-
from sqlsaber.cli.database import create_db_app
|
|
13
|
-
from sqlsaber.cli.interactive import InteractiveSession
|
|
14
|
-
from sqlsaber.cli.memory import create_memory_app
|
|
15
|
-
from sqlsaber.cli.models import create_models_app
|
|
16
|
-
from sqlsaber.cli.streaming import StreamingQueryHandler
|
|
17
|
-
from sqlsaber.cli.threads import create_threads_app
|
|
10
|
+
# Lazy imports - only import what's needed for CLI parsing
|
|
18
11
|
from sqlsaber.config.database import DatabaseConfigManager
|
|
19
|
-
from sqlsaber.database.connection import (
|
|
20
|
-
CSVConnection,
|
|
21
|
-
DatabaseConnection,
|
|
22
|
-
MySQLConnection,
|
|
23
|
-
PostgreSQLConnection,
|
|
24
|
-
SQLiteConnection,
|
|
25
|
-
)
|
|
26
|
-
from sqlsaber.database.resolver import DatabaseResolutionError, resolve_database
|
|
27
|
-
from sqlsaber.threads import ThreadStorage
|
|
28
12
|
|
|
29
13
|
|
|
30
14
|
class CLIError(Exception):
|
|
@@ -108,6 +92,21 @@ def query(
|
|
|
108
92
|
"""
|
|
109
93
|
|
|
110
94
|
async def run_session():
|
|
95
|
+
# Import heavy dependencies only when actually running a query
|
|
96
|
+
# This is only done to speed up startup time
|
|
97
|
+
from sqlsaber.agents import build_sqlsaber_agent
|
|
98
|
+
from sqlsaber.cli.interactive import InteractiveSession
|
|
99
|
+
from sqlsaber.cli.streaming import StreamingQueryHandler
|
|
100
|
+
from sqlsaber.database.connection import (
|
|
101
|
+
CSVConnection,
|
|
102
|
+
DatabaseConnection,
|
|
103
|
+
MySQLConnection,
|
|
104
|
+
PostgreSQLConnection,
|
|
105
|
+
SQLiteConnection,
|
|
106
|
+
)
|
|
107
|
+
from sqlsaber.database.resolver import DatabaseResolutionError, resolve_database
|
|
108
|
+
from sqlsaber.threads import ThreadStorage
|
|
109
|
+
|
|
111
110
|
# Check if query_text is None and stdin has data
|
|
112
111
|
actual_query = query_text
|
|
113
112
|
if query_text is None and not sys.stdin.isatty():
|
|
@@ -196,25 +195,45 @@ def query(
|
|
|
196
195
|
sys.exit(e.exit_code)
|
|
197
196
|
|
|
198
197
|
|
|
199
|
-
#
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
202
227
|
|
|
203
|
-
|
|
204
|
-
db_app = create_db_app()
|
|
205
|
-
app.command(db_app, name="db")
|
|
228
|
+
return create_models_app()(*args, **kwargs)
|
|
206
229
|
|
|
207
|
-
# Add memory management commands
|
|
208
|
-
memory_app = create_memory_app()
|
|
209
|
-
app.command(memory_app, name="memory")
|
|
210
230
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
231
|
+
@app.command(name="threads")
|
|
232
|
+
def threads(*args, **kwargs):
|
|
233
|
+
"""Manage SQLsaber threads."""
|
|
234
|
+
from sqlsaber.cli.threads import create_threads_app
|
|
214
235
|
|
|
215
|
-
|
|
216
|
-
threads_app = create_threads_app()
|
|
217
|
-
app.command(threads_app, name="threads")
|
|
236
|
+
return create_threads_app()(*args, **kwargs)
|
|
218
237
|
|
|
219
238
|
|
|
220
239
|
def main():
|
|
@@ -9,7 +9,6 @@ from urllib.parse import parse_qs, urlparse
|
|
|
9
9
|
import aiomysql
|
|
10
10
|
import aiosqlite
|
|
11
11
|
import asyncpg
|
|
12
|
-
import pandas as pd
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class BaseDatabaseConnection(ABC):
|
|
@@ -324,6 +323,10 @@ class CSVConnection(BaseDatabaseConnection):
|
|
|
324
323
|
return
|
|
325
324
|
|
|
326
325
|
try:
|
|
326
|
+
# Import pandas only when needed for CSV operations
|
|
327
|
+
# This improves CLI load times
|
|
328
|
+
import pandas as pd
|
|
329
|
+
|
|
327
330
|
# Read CSV file using pandas
|
|
328
331
|
df = pd.read_csv(
|
|
329
332
|
self.csv_path,
|
|
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
|
|
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
|