Skip to content

Configuration

Every SQLSaber session is configured through a single SQLSaberOptions dataclass. Construct it with keyword arguments and pass it to SQLSaber(options=...).

from sqlsaber import SQLSaberOptions
options = SQLSaberOptions(
database="postgresql://user:pass@localhost:5432/analytics",
model_name="anthropic:claude-sonnet-4-5-20250929",
thinking_level="medium",
)
FieldTypeDefaultDescription
databasestr | list[str] | tuple[str, ...] | NoneNoneConnection string, file path, configured DB name, a list of CSV/Parquet paths, or a list of targets for a multi-database session.
model_namestr | NoneNoneModel in "provider:model" form. Falls back to your configured/default model.
api_keystr | NoneNoneAPI key for the model’s provider. Usually unnecessary — see Credentials.
thinking_enabledbool | NoneNoneToggle extended thinking on supported reasoning models.
thinking_levelThinkingLevel | str | NoneNone"minimal" | "low" | "medium" | "high" | "maximum". Setting a level enables thinking.
system_promptstr | Path | NoneNoneCustom system prompt text, or a path to a file containing it.
settingsConfig | NoneNoneInject a Config (e.g. Config.in_memory(...)). Defaults to file-backed Config.default().
knowledge_managerKnowledgeManager | NoneNoneInject your own knowledge base (see Advanced).
thread_managerThreadManager | NoneNonePersist conversation history across runs (see Advanced).
capabilitiesSequence[AbstractCapability[Any] | Callable]()Explicit pydantic-ai capabilities and plugin factories (see Capabilities). SQLSaber always includes SQL and knowledge tools. An embedded session includes only the listed capabilities. The CLI loads installed plugins.
artifact_storeArtifactStore | NoneNoneApplication-owned publication and retrieval for artifacts such as analysis notebooks and plots.
artifact_failure_mode"required" | "best_effort""required"Fail the tool or retain its answer when artifact publication fails.
query_result_storeQueryResultStore | NoneNoneStore for complete SQL row results. Defaults to a session-owned in-memory store. Inject application storage for durable or tenant-scoped retrieval.
workspace_input_resolverWorkspaceInputResolver | NoneNoneApplication-owned resolver for opaque, authorized inputs to the managed notebook analyst.
tool_overridesMapping[str, ModelOverides] | NoneNonePer-tool model/API-key overrides (see Advanced).
allow_dangerousboolFalseAllow write operations and a restricted subset of DDL (see Advanced).
csv_tool_resultsboolFalseOpt in to experimental CSV tables in model-facing SQL tool results. JSON remains the default.

SQL tool results use JSON by default. Opt in per session:

from sqlsaber import SQLSaber, SQLSaberOptions
saber = SQLSaber(options=SQLSaberOptions(
database="analytics.db",
csv_tool_results=True,
))

This changes the tabular portions of list_tables, introspect_schema, execute_sql, and multi-database list_dbs results sent to the model. Metadata, schema constraints, errors, and empty results remain JSON. CSV cells use standard quoting, \N for null, and escaped backslashes; nested cell values use JSON. Complete retained query results remain typed JSON. Terminal tables, plugin access, and the 12 KiB SQL preview limit are unchanged. Structured rendering data is kept in message metadata, not sent to the model as a second copy of the result.

CSV can reduce tokens for multi-row results, but tiny results can be larger and its effect on answer quality has not been established. Evaluate it with your models and queries before enabling it broadly.

The setting is available as saber.info.csv_tool_results. It is not a saved global preference or restored from thread history: pass it again in SQLSaber.resume(..., options=SQLSaberOptions(csv_tool_results=True)) to opt in for new calls. Existing messages are not rewritten. For a standalone capability, use SqlTools(csv_tool_results=True).

Embedded SQLsaber does not persist artifacts unless artifact_store is injected. The injected store is application-owned and is never closed or garbage-collected by SQLsaber. The CLI explicitly uses FilesystemArtifactStore under its private user data directory.

Cloud stores should authorize get() from the current identity in ArtifactContext.metadata, keep objects private, and return ArtifactUnavailable for both missing and unauthorized IDs. Stable descriptor URIs are locators; SQLsaber retrieves bytes through the store rather than dereferencing those URIs.

Every successful row-returning query writes its complete canonical JSON payload to query_result_store. The model and message history receive only a stable 12 KiB projection. An injected store is application-owned and SQLsaber does not close it. The SDK default is in-memory; the CLI explicitly uses private filesystem storage. A storage failure makes that row-returning tool call fail rather than silently claiming complete data is available.

For web applications, implement QueryResultStore.put/get over a private database or object store. Authorize get from current identity in QueryResultContext.metadata; do not authorize solely from possession of a result ID, filename, or historical conversation metadata.

When sqlsaber-notebook is listed in SQLSaberOptions.capabilities, workspace_input_resolver lets a host application make authorized files available to analyze_data without exposing filesystem paths, URLs, bucket names, object keys, or raw bytes to the main model. See Analyzing application-owned inputs for the resolver contract and trust boundary.

Without a resolver, SQLsaber preserves the original analyze_data(goal, files=None) schema: attachment_refs is not advertised to the model and SQL result selection is unchanged.

The database option accepts the same targets as the CLI’s -d flag.

SQLSaberOptions(database="postgresql://user:pass@host:5432/db")
SQLSaberOptions(database="mysql://user:pass@host:3306/db")
SQLSaberOptions(database="sqlite:///path/to/local.db")
SQLSaberOptions(database="duckdb:///path/to/warehouse.duckdb")

Point directly at a SQLite, DuckDB, CSV, or Parquet file:

SQLSaberOptions(database="./data/sales.db")
SQLSaberOptions(database="./customers.csv")
SQLSaberOptions(database="./orders.parquet")

Pass a list (or tuple) of CSV/Parquet paths to query across them together. All files are merged into a single in-memory database with one table per file:

SQLSaberOptions(database=["users.csv", "orders.csv"])
SQLSaberOptions(database=["users.csv", "orders.parquet"])

Pass a list including other targets (configured names, connection strings, or database file paths) to connect to several databases in one session. The agent queries each one separately and combines the results:

SQLSaberOptions(database=["sales", "postgresql://user:pass@host:5432/events"])

The resulting session exposes database metadata through saber.info:

from sqlsaber import SQLSaber
async with SQLSaber(options=options) as saber:
saber.info.database_names # ("sales", "events")

The compatibility properties saber.db_names and saber.connections remain available for callers that need the managed names or connection objects:

async with SQLSaber(options=options) as saber:
saber.db_names # ["sales", "events"]
saber.connections # {name: connection, ...}

If you’ve already registered a connection with the CLI (saber db add), refer to it by name:

SQLSaberOptions(database="prod-db")

See the Database Setup guide for details on connection strings and registering databases.