Skip to content

feat: add DuckDB as a supported query engine (closes #40)#70

Merged
shirshanka merged 3 commits into
mainfrom
feat/duckdb-connector
May 31, 2026
Merged

feat: add DuckDB as a supported query engine (closes #40)#70
shirshanka merged 3 commits into
mainfrom
feat/duckdb-connector

Conversation

@shirshanka
Copy link
Copy Markdown
Contributor

Summary

  • Wires DuckDB into the engine factory as a SQLAlchemyQueryEngine dialect — duckdb-engine was already a declared dependency, so no new packages needed
  • Adds the frontend connection plugin (duckdb.tsx) with a single "database file path" field, matching the sqlite pattern
  • Registers the plugin in the connection list (displays between SQLite and the custom-MCP wildcard)
  • Adds a full end-to-end integration test with a temp DuckDB file containing Olist-like tables (orders, order_items, products)

Changes

File What
engines/factory.py Add "duckdb" to _engine_cls() and get_secret_env_vars()
plugins/duckdb.tsx New frontend connection form
connections/index.ts Register duckdbPlugin
test_duckdb_e2e.py Integration test: engine tools + full agent pipeline

Test plan

  • test_engine_list_tableslist_tables returns all 3 tables from a temp DuckDB file
  • test_engine_execute_sqlexecute_sql returns correct row counts (45 delivered, 5 canceled)
  • test_top_categories_by_revenue — full agent pipeline: context lookup → SQL → ranked answer with chart
  • test_delivered_vs_canceled_order_count — full agent pipeline: catalog fallback → SQL → correct counts
  • Lint, mypy, frontend typecheck all pass

🤖 Generated with Claude Code

shirshanka and others added 3 commits May 31, 2026 08:58
Wire DuckDB into the engine factory (SQLAlchemy dialect via duckdb-engine,
already a declared dependency). Add the frontend connection plugin and
register it in the plugin list. Add an end-to-end integration test covering
list_tables, execute_sql, and the full agent pipeline against a temp DuckDB
file with Olist-like sample tables.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ngs UI

- Add "duckdb" to the elif branch that renders connection fields so a
  configured DuckDB connection shows "connected" rather than "unconfigured"
- File-based engines (sqlite, duckdb) only need database path to be
  considered configured; server engines still require host
- Add "duckdb" to _KNOWN_TOOLS so the tool toggle panel renders correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tatus helper

Every engine type must be wired through several touchpoints — factory dispatch,
secret_env_vars, _KNOWN_TOOLS, the status renderer, and the frontend plugin
index. Forgetting any one of them silently degrades the UX (empty tool
toggles, connections stuck as 'unconfigured', missing from the picker)
without failing CI.

The contract test enumerates every known engine type and asserts each
touchpoint handles it. Adding a new connector means adding one entry to
MINIMAL_CONFIGS — the rest of the wiring is then enforced.

Extract _compute_engine_status as a small pure helper so the status check
is unit-testable without DB setup. Use it everywhere list_connections
computes a status (snowflake, bigquery, sqlalchemy-family, fallback).

The new tests caught three pre-existing gaps: hive, postgresql, and sqlite
were all missing from _KNOWN_TOOLS — their tool-toggles panel was empty in
the Settings UI. Fixed all three.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shirshanka shirshanka merged commit e8123d9 into main May 31, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant