Proposal: paradigm-aware plugin surfaces via kind: driver + paradigms
Depends on #306 (Decoupling RFC). This builds on the standardized driver /
capability contract from that RFC and should land after it. The work below is
intentionally broad — when picked up it should be split into the subtasks outlined
in Work breakdown.
Problem
Today every connector is modeled relationally: databases → tables → columns → SQL execute_query → QueryResult. Non-relational engines — search engines, document
stores, key-value, vector — don't fit this shape and have to emulate it:
QueryResult.affected_rows / pagination are SQL/DML artifacts these engines
don't have.
execute_query expects SQL, so flat stores fake it (e.g. SELECT * FROM x to
list documents) and silently ignore filters and projection.
- The connection model assumes a set of selectable databases that some engines
don't have at all.
- Their real query model — ranked search, facets, field filters — has nowhere to
live, because the host only offers the SQL grid and editor.
The root cause is that the host has a single interaction surface, but different
engines have different primary verbs: a document store filters-and-gets, a
search engine searches-and-ranks, a key-value store gets-and-sets. One UI can't
serve all of them well, and bending each engine to fit the SQL surface produces the
friction above.
Proposal
kind should describe the plugin type, not the data model. Every connector
installs the same way (a binary speaking JSON-RPC over stdio) and follows the same
lifecycle, so they all stay kind: driver. The differences between engines belong on
finer axes:
kind: driver # stable: "it's a driver"
└─ paradigms[] # primary verb → host picks the surface
└─ capabilities{} # feature flags within the driver contract
└─ optional methods # search() / facets() / query(filter) → unlock richer UI
└─ ui_extensions[] # paradigm-specific panels via slots
-
paradigms[0] is the primary verb, and it selects which surface the host
shows for a connection. Paradigms are admin-managed facets, so introducing a new
data model needs no schema release — just a new facet value.
-
Optional RPC methods are the actual unlock. A paradigm is only a hint; the
host renders a richer surface for a connection when the driver actually implements
the matching methods (e.g. search() for a search engine), and falls back to the
standard grid when it doesn't. This keeps it honest — a plugin can't claim a
paradigm it doesn't back — and lets engines adopt the new surface incrementally
(progressive enhancement, graceful degrade).
-
Surfaces are built into core and shown contextually, i.e. rendered only when
an open connection's paradigm matches. The code ships with the app, but a search
panel never appears unless you've opened a search connection. The SQL grid remains
the default and the universal fallback. We'd start with two surfaces that cover the
most engines: search (Meilisearch, Typesense, Elasticsearch) and document
(Firestore, MongoDB).
-
One surface per paradigm — no single "NoSQL" surface. "NoSQL" lumps together
incompatible verbs (document ≠ search ≠ key-value ≠ graph); each needs its own UI.
How it fits together
manifest: kind=driver, paradigms=[search,…]
│
▼
host resolves surface for a connection:
paradigms[0] + which optional methods the driver implements
│
├─ implements search()/facets() → Search surface
├─ implements query(filter)/CRUD → Document surface
└─ neither → SQL grid (fallback, unchanged)
The relational path is untouched: existing SQL drivers declare no extra paradigm or
methods and keep the grid. New surfaces are additive.
Work breakdown
When this is scheduled, split into the following subtasks. Groups are roughly
ordered; A–C are prerequisites for the surfaces in D–E.
A. Contract (backend / spec)
B. Registry / metadata
C. Host: surface resolution
D. Search surface
E. Document surface
F. Reference drivers / migration
G. Docs & examples
Scope
In scope: the model above and the first two surfaces (search, document), plus the
contract and host wiring they need.
Out of scope for now:
- A second plugin framework or a separate
kind per data model.
- Replacing the SQL grid — it stays the default and the fallback.
- Per-database UIs — surfaces are generic per paradigm.
- Long-tail paradigms (key-value, graph, time-series) and full vector UIs. They can
follow later, and could even ship as community surface plugins once the extension
API supports full custom views.
Open questions
- Method signatures and result shapes per paradigm — the filter model, facet
response, ranking score field.
- How a multi-paradigm engine (e.g. search + document + vector) exposes its
secondary surfaces: a view switcher, or primary-only?
- Whether vector search is its own paradigm and surface, or a mode inside the search
surface.
- Capability flags vs. method probing for detecting optional-method support.
Proposal: paradigm-aware plugin surfaces via
kind: driver+paradigmsProblem
Today every connector is modeled relationally:
databases → tables → columns → SQL execute_query → QueryResult. Non-relational engines — search engines, documentstores, key-value, vector — don't fit this shape and have to emulate it:
QueryResult.affected_rows/paginationare SQL/DML artifacts these enginesdon't have.
execute_queryexpects SQL, so flat stores fake it (e.g.SELECT * FROM xtolist documents) and silently ignore filters and projection.
don't have at all.
live, because the host only offers the SQL grid and editor.
The root cause is that the host has a single interaction surface, but different
engines have different primary verbs: a document store filters-and-gets, a
search engine searches-and-ranks, a key-value store gets-and-sets. One UI can't
serve all of them well, and bending each engine to fit the SQL surface produces the
friction above.
Proposal
kindshould describe the plugin type, not the data model. Every connectorinstalls the same way (a binary speaking JSON-RPC over stdio) and follows the same
lifecycle, so they all stay
kind: driver. The differences between engines belong onfiner axes:
paradigms[0]is the primary verb, and it selects which surface the hostshows for a connection. Paradigms are admin-managed facets, so introducing a new
data model needs no schema release — just a new facet value.
Optional RPC methods are the actual unlock. A paradigm is only a hint; the
host renders a richer surface for a connection when the driver actually implements
the matching methods (e.g.
search()for a search engine), and falls back to thestandard grid when it doesn't. This keeps it honest — a plugin can't claim a
paradigm it doesn't back — and lets engines adopt the new surface incrementally
(progressive enhancement, graceful degrade).
Surfaces are built into core and shown contextually, i.e. rendered only when
an open connection's paradigm matches. The code ships with the app, but a search
panel never appears unless you've opened a search connection. The SQL grid remains
the default and the universal fallback. We'd start with two surfaces that cover the
most engines: search (Meilisearch, Typesense, Elasticsearch) and document
(Firestore, MongoDB).
One surface per paradigm — no single "NoSQL" surface. "NoSQL" lumps together
incompatible verbs (document ≠ search ≠ key-value ≠ graph); each needs its own UI.
How it fits together
The relational path is untouched: existing SQL drivers declare no extra paradigm or
methods and keep the grid. New surfaces are additive.
Work breakdown
When this is scheduled, split into the following subtasks. Groups are roughly
ordered; A–C are prerequisites for the surfaces in D–E.
A. Contract (backend / spec)
search(index, q, filter, facets, sort),facets(index), andquery(collection, filter, sort, page)for document.(capability flags vs. JSON-RPC
method not foundprobing).B. Registry / metadata
search,document,vector,key-value,graph) and are documented.paradigmsordering semantics ([0]= primary).C. Host: surface resolution
paradigms[0]+ implemented methods.D. Search surface
search().facets()/ filterable fields; filter + sort controls.E. Document surface
field op value, composite) →query(collection, filter).F. Reference drivers / migration
G. Docs & examples
methods, with a minimal example per surface.
Scope
In scope: the model above and the first two surfaces (search, document), plus the
contract and host wiring they need.
Out of scope for now:
kindper data model.follow later, and could even ship as community surface plugins once the extension
API supports full custom views.
Open questions
response, ranking score field.
secondary surfaces: a view switcher, or primary-only?
surface.