Skip to content

NL2SQL 0.5.0

Configuration v2: one nl2sql.yaml configures the engine, the CLI, nl2sql-api and the demo, an extension registry loads adapters, LLM, embeddings and secret providers by name, and every engine owns its config. This is a clean break from 0.4, with no compatibility layer: read Upgrading before you install it.

Released 2026-10-14.

Highlights

  • One config file. nl2sql.yaml replaces the 0.4 files and about 48 environment variables. It can be one file or split into datasources/, llm.yaml, embeddings.yaml, policies.yaml and storage.yaml. nl2sql init writes that layout for you (--demo adds the demo databases). nl2sql config check checks every file, name, driver and secret without starting the engine, and with --connect it also connects to each datasource. It fits a CI job.
  • An extension registry. Registry.default() finds adapters, LLM providers, embeddings providers and secret providers through entry points, and imports none of them until the config uses one. Register your own with add_adapter, add_llm, add_embeddings, add_secrets or a decorator (@registry.adapter("name")). A wrong interface version, a missing driver or a misspelled name is reported when the engine is built, with the fix. The SDK they build against is now nl2sql-sdk (import nl2sql_sdk).
  • A tidier Python API, with a model switch at runtime. run_query and stream_query stay at the top level. Everything else is in namespaces: engine.datasources, index, llm, policies, curated, results, traces and feedback, plus about(), check() and close() (or with). engine.llm.replace(...) and the admin-only PUT /api/v1/settings/llm swap the model in a running engine. Queries already running finish on the old model, and the change is logged without keys.
  • Each engine owns its config. There are no process-wide settings and nothing writes os.environ, so two engines in one process share nothing. import nl2sql takes about 15 ms instead of about 2.2 s, because it loads no heavy library.

What's included

Features

  • nl2sql-adapter-sdk is renamed nl2sql-sdk, with the import package nl2sql_sdk (#262).
  • import nl2sql loads no database driver, vector store or model library, and a test holds it under budget (#263).
  • The typed config models, load_config, file: includes, ${env:...} references, strict keys with "did you mean", and one ConfigError that lists every problem (#264).
  • The SDK defines the adapter and secret provider interfaces, with interface versions, driver lists and install hints. Secret provider settings are checked strictly (#265).
  • The extension registry: Registry.default(), add_*, decorators, and the entry point groups nl2sql.adapters, nl2sql.llms, nl2sql.embeddings and nl2sql.secrets (#266).
  • nl2sql init [DIR] [--demo] [--provider NAME] [--force] writes the split config layout and checks it (#267).
  • The engine is built from a Config: NL2SQL(config), NL2SQL.from_config(path), NL2SQL.demo(), check() and close(). Building never connects, and all results are written under storage.path (#268).
  • The pipeline reads its settings from its own engine, so two engines in one process each keep their own row limit, plan cache and model (#269).
  • engine.llm.replace, with LLM clients cached per engine, and a plan cache key that includes the planner's model (#270).
  • Indexing, tracing, replay and benchmarks run on run-scoped settings and never change the engine they run on (#271).
  • The CLI, nl2sql-api and the demo start from nl2sql.yaml with a single --config flag. nl2sql setup and every 0.4 config path are removed (#272).
  • nl2sql config check [--connect], which is also callable from Python as nl2sql.config.check.check_config (#273).
  • The namespaced facade and PUT /api/v1/settings/llm. The CLI now uses only the public API (#274).
  • engine.feedback, engine.traces.get, engine.about() and engine.llm.providers(). The playground now uses only the public API (#275).
  • The process-wide settings object is deleted. The library writes no environment variables and reads only an allow-list of them (#276).

Fixes

  • Secrets in the config are masked when it is printed, NL2SQL_LOG_LEVEL set in .env takes effect, and the scripts no longer write the environment (#277).

Docs

  • The design for Configuration v2 and the extension registry (#260). The Configuration pages are rewritten for nl2sql.yaml in the PRs above.

Known limits

  • Running several nl2sql-api replicas is not supported for a model switch. PUT /api/v1/settings/llm changes only the process that receives it, and the change is not saved: a restart reads llm.yaml again.
  • There is no migration command. You map 0.4 files and variables by hand, using the table.
  • Results are stored locally only. The S3 and ADLS backends are gone until the results-store interface in Phase 2.
  • nl2sql init is not interactive, and its --provider accepts openai, anthropic and openrouter only (Ollama has no default model). The guided setup flow comes in Phase 4.
  • A datasource's connection block is checked by the adapter only, not by a typed model, and check() gives a generic reason when a connection fails. Typed connection models and connection-test stages come with SDK v2 in Phase 2.
  • After engine.datasources.remove(id), the datasource's index entries stay until the next full index.build or index.clear.
  • This release is Phase 1 of five. Phase 2 brings SDK v2, storage interfaces and policy globs, Phase 3 the event bus and evals, Phase 4 the guided setup and the web app on nl2sql-api, and Phase 5 glossaries and knowledge sources.

Upgrading

pip install --upgrade "nl2sql-engine[demo]==0.5.0"

Adapter and secret provider authors: pip install "nl2sql-sdk==0.5.0" and uninstall nl2sql-adapter-sdk.

Breaking changes: many. 0.5 is a clean break with no compatibility layer, and the engine refuses a 0.4 config. Start with nl2sql init, then move your values across with the 0.4 to 0.5 mapping.

  • One config file (#264, #272). configs/datasources.yaml, llm.yaml, policies.json, secrets.yaml, curated.yaml, sample_questions.yaml and about 48 environment variables are no longer read. What to do: run nl2sql init (or nl2sql init --demo) and move each value to its new place using the mapping table. Sample questions now sit on each datasource, policies are YAML, and LLM agents are keyed by node name (ast_planner).
  • Environment variables (#276). Only NL2SQL_CONFIG, NL2SQL_LOG_LEVEL and the provider keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, OPENROUTER_API_KEY) are read directly. What to do: write any other value in the YAML, as ${env:VAR} where it should come from the environment.
  • .env loading (#272). Only the CLI, nl2sql-api and nl2sql demo load a .env, and only the one next to nl2sql.yaml. They never override a variable that is already set. The library never reads .env. --env, --env-file, ENV, APP_ENV and ENV_FILE_PATH are gone. What to do: put .env next to nl2sql.yaml. From Python, call nl2sql.load_env_file(path) before building the engine.
  • nl2sql setup is removed (#272). What to do: use nl2sql init, or nl2sql init --demo in place of setup --demo.
  • One CLI flag (#272). nl2sql --config PATH/nl2sql.yaml <command> (or NL2SQL_CONFIG, or ./nl2sql.yaml) replaces every per-command path flag (--llm-config, --secrets-config, --policies-config, --vector-store, and the curated and policy path flags). What to do: pass --config once, before the command.
  • nl2sql-api settings (#272). The NL2SQL_API_* variables are removed. What to do: set api.role_header, api.role, api.trust_body_role and api.cors_origins (a list) in an api: section, and the admin roles in policies.admin_roles. The API image reads NL2SQL_CONFIG=/etc/nl2sql/nl2sql.yaml, so mount your config folder there.
  • REST LLM route (#274). POST /api/v1/llm is replaced by the admin-only PUT /api/v1/settings/llm, whose body is the llm section as JSON. A bad body gets a 422 with the config error. POST /api/v1/datasource takes the datasource in the nl2sql.yaml shape, and the datasource routes return DatasourceInfo. What to do: update your clients.
  • Result storage (#268). The S3 and ADLS backends and the RESULT_ARTIFACT_* settings are removed. Results are written under storage.path/results/. What to do: set storage.path and copy anything you need from a remote store yourself.
  • Secret providers (#265). hashi is renamed hashicorp, with no alias. The VAULT_ADDR, VAULT_TOKEN and AZURE_KEYVAULT_URL fallbacks are removed, and an unknown provider setting is an error. What to do: write type: hashicorp and give url and token (for example token: "${env:VAULT_TOKEN}"), or vault_url for Azure, in the provider's block.
  • The SDK package (#262). nl2sql-adapter-sdk / nl2sql_adapter_sdk is now nl2sql-sdk / nl2sql_sdk. Adapters also declare interface_version, driver_modules and install_hint (#265). What to do: rename the dependency and the imports, add the three class attributes, and register through the nl2sql.adapters entry point or Registry.add_adapter.
  • The Python facade (#274, #275). The flat methods, engine.context, engine.query, get_adapter, configure_llm, reload_llm_config, the auth, settings, policy, indexing and datasource sub-APIs, and the QueryAPI/DatasourceAPI/LLM_API/... exports are removed. NL2SQL() is built from a Config or NL2SQL.from_config(path). What to do: call the namespaces (engine.datasources.add, engine.index.build, engine.llm.replace, engine.policies.validate, ...). The public facade page lists them.
  • Hosted demo (#276). nl2sql demo --hosted refuses to start if OPENAI_API_KEY, OPENROUTER_API_KEY or ANTHROPIC_API_KEY is set in its environment. NL2SQL_DEMO_HOSTED and NL2SQL_DEMO_QUESTIONS_* are replaced by --hosted, --questions-per-minute and --questions-per-session, and the demo's key file is <dir>/.env instead of .env.demo (#272). What to do: remove provider keys from the hosted server's environment and use the flags.
  • Startup errors (#268). Anything wrong that can be found without connecting is now a ConfigError when the engine is built. This includes an unknown datasource type and a secret that does not resolve, which in 0.4 only marked that datasource unavailable. A datasource that cannot connect still runs degraded unless it is required: true. What to do: run nl2sql config check before you deploy.

What's next

Next: 0.6, datasources and adapter SDK v2, then the web app on the API and Docker Compose.

Full changelog: v0.4.1...v0.5.0