The stop button called aiCancelStream -> notify_one(), but the four
stream_*_with_tools SSE loops only `break`ed and returned Ok(token_usage)
when cancelled. run_agent_loop treated that as a normal completed turn and
kept going (often into contract-repair or the next turn), so isGenerating
stayed true and a single click did not stop the agent.
Return Err(AGENT_CANCELLED_ERROR) from the cancel branch so the existing
Err-cancel match arm sets loop_exit = Cancelled and stops the loop cleanly,
preserving whatever was streamed so far.
Additional:
- Promote AGENT_CANCELLED_ERROR to a shared `pub const` in ai.rs; agent_loop
now references ai::AGENT_CANCELLED_ERROR.
- Check cancellation before executing requested tools, so a stop landing
between stream-end and tool execution is honored.
- Wire cancellation into the text-only fallback (previously `_cancelled`,
ignored) via tokio::select! racing ai::complete against cancelled.notified().
Known limitation left: in-flight tool execution (e.g. execute_query) is
still not interruptible mid-call.
* feat(spark): add Apache Spark database driver
Spark Thrift Server speaks the HiveServer2 protocol, so the Spark driver
reuses the hive-jdbc agent runtime. Registers spark (agentKey=spark,
defaultPort=10015) across the manifest, DatabaseType enum, agent catalog,
SQL dialects, connection dialog, and a SparkAgent built on AbstractJdbcAgent.
* feat(spark): add catalog support and official logo
SparkAgent now supports Spark 3.4+ multi-catalog (Paimon, Lance, Iceberg)
via catalog=<name> in url_params, mirroring the StarRocks catalog flow:
- afterConnect switches to the configured catalog via USE <catalog>
- listDatabases returns the catalog name when SHOW DATABASES is empty
(catalogs like Lance expose tables at the catalog root with no databases)
- listTables uses SHOW TABLES IN <catalog>[.<schema>] uniformly, working
for both catalog-root tables (Lance) and catalog.schema tables (Paimon)
- setSchemaSQL qualifies USE with the catalog to prevent resetting to
spark_catalog on schema switches
- buildJdbcUrl omits database from the URL path
Also replaces the placeholder lightning icon with the official Apache Spark
logo (spark-logo.png from spark.apache.org).
* fix(spark): use catalog-qualified DESCRIBE for column retrieval
getColumnsFromDescribe used USE <schema> + DESCRIBE <table>, which
generated USE `catalog`.`catalog` when the sidebar passed the catalog
name as the schema (Lance case where the catalog is the only node).
This failed and fell back to JDBC metadata which also returned nothing,
resulting in an empty DDL (CREATE TABLE ... ()).
Now uses DESCRIBE `catalog`.`table` directly when a catalog is
configured, bypassing USE entirely. Also fixes setSchemaSQL to treat
schema == catalog as catalog-only (no .schema suffix).
* fix(ci): add spark to metadata coverage matrix and BRIDGE_REQUIRED_TYPES
- agents/metadata-constraint-coverage.tsv: register spark as
intentional-fallback (SHOW TABLES/SHOW DATABASES, like Hive/TDengine)
- packages/node-core/src/diagnostics.ts: add spark to
BRIDGE_REQUIRED_TYPES (mcpMode=bridge, matches manifest)
* fix(ci): add spark to DBX_CONNECTION_TYPE_DESCRIPTION in mcp-server
The driver-manifest test asserts every manifest dbType appears in the
MCP server's connection type description string.