Skip to content

feat(ai): add opt-in chart and dashboard authoring - #43133

Open
I3eka wants to merge 10 commits into
apache:masterfrom
I3eka:native-ai-authoring-tools
Open

feat(ai): add opt-in chart and dashboard authoring#43133
I3eka wants to merge 10 commits into
apache:masterfrom
I3eka:native-ai-authoring-tools

Conversation

@I3eka

@I3eka I3eka commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

feat(ai): add opt-in chart and dashboard authoring

SUMMARY

Add opt-in native AI tools for virtual datasets, charts, and dashboards. Shipped profiles remain read-only; configured builder profiles reuse the registered MCP implementations through a real FastMCP context and normal RBAC. Prefer FastMCP structured_content over its internal data wrapper so authoring responses remain plain payloads.

Depends on #42805 and #43132. Related SIP: #42806.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Not applicable; backend behavior only.

TESTING INSTRUCTIONS

pytest -q tests/unit_tests/ai/test_authoring_tools.py tests/unit_tests/ai/test_tools.py tests/unit_tests/ai/test_mcp_tools.py tests/unit_tests/ai/test_policy.py

Result: 222 passed.

Ruff check, Ruff format check, and git diff --check pass.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@github-actions github-actions Bot added risk:db-migration PRs that require a DB migration api Related to the REST API doc Namespace | Anything related to documentation packages and removed size/XXL labels Aug 13, 2026
@netlify

netlify Bot commented Aug 13, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 333306d
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a99b57ea21a0c000892a353
😎 Deploy Preview https://deploy-preview-43133--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 40.33244% with 3123 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.12%. Comparing base (f9cedf8) to head (333306d).
⚠️ Report is 322 commits behind head on master.

Files with missing lines Patch % Lines
superset/ai/orchestrator.py 0.00% 237 Missing ⚠️
superset/ai/llm/openai_compatible.py 0.00% 219 Missing ⚠️
superset/ai/llm/anthropic.py 0.00% 216 Missing ⚠️
superset/ai/runtime/messages.py 0.00% 195 Missing ⚠️
superset/ai/page_context.py 0.00% 185 Missing ⚠️
superset/ai/api.py 37.96% 183 Missing ⚠️
...tend/src/features/ai/components/ChatChartEmbed.tsx 21.50% 157 Missing ⚠️
superset/ai/prompts/assemble.py 0.00% 147 Missing ⚠️
...erset-frontend/src/features/ai/hooks/useChatBot.ts 73.04% 138 Missing ⚠️
superset/ai/eventbus.py 0.00% 134 Missing ⚠️
... and 32 more

❗ There is a different number of reports uploaded between BASE (f9cedf8) and HEAD (333306d). Click for more details.

HEAD has 9 uploads less than BASE
Flag BASE (f9cedf8) HEAD (333306d)
javascript 10 1
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #43133      +/-   ##
==========================================
- Coverage   66.73%   57.12%   -9.62%     
==========================================
  Files        2876     2941      +65     
  Lines      164218   171642    +7424     
  Branches    37890    39170    +1280     
==========================================
- Hits       109596    98052   -11544     
- Misses      52463    72695   +20232     
+ Partials     2159      895    -1264     
Flag Coverage Δ
hive ?
javascript 74.10% <76.70%> (+0.06%) ⬆️
mysql ?
postgres ?
sqlite ?
superset-extensions-cli 90.57% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@I3eka

I3eka commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

@bsovran, keeping this draft while #42805 and #43132 are pending. I checked both failing runs: https://github.com/apache/superset/actions/runs/31779483501 and https://github.com/apache/superset/actions/runs/31779483587. They share one inherited root cause: current master and the #42805 migration produce two Alembic heads (2d6ad72e4af6 and a1c4f7e29b31), so both the single-head check and superset db upgrade fail before the authoring code is exercised. This should be resolved or rebased in #42805, then this branch can be refreshed. Please let me know once the base is ready.

@I3eka

I3eka commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Added a9960aae10 to prevent malformed AI-generated dashboard layouts from being persisted. Explicit position_json is now checked as a traversable v2 layout with valid chart references; invalid layouts fall back to the existing packed grid and return a warning.

Regression coverage reproduces the nested inline ROOT shape that caused frontend hydration to fail before chart-data requests. Validation: TestGenerateDashboard 17 passed, targeted pre-commit passed, and pylint rated the changed backend files 10/10.

@I3eka
I3eka marked this pull request as ready for review August 18, 2026 12:43
@dosubot dosubot Bot added authentication:RBAC Related to RBAC dashboard Namespace | Anything related to the Dashboard labels Aug 18, 2026
Comment thread superset/mcp_service/dashboard/tool/generate_dashboard.py
bsovran and others added 7 commits August 20, 2026 10:29
Adds an AI assistant behind the AI_ASSISTANT feature flag, off by default.
A user can ask questions about the dashboard, chart or query in front of
them and get an answer grounded in the data they already have access to.

Architecture, in layers that can each be replaced by configuration:

- Provider seam (AI_LLM_PROVIDER_CLASS): no vendor name, model identifier,
  base URL or credential appears in core. Ships an OpenAI-compatible and an
  Anthropic provider behind optional extras, so a private gateway or a
  self-hosted model is configuration rather than a fork.
- Agent runtime (AI_AGENT_RUNTIME_CLASS): a tool-use loop that streams the
  answer as the model produces it and reports each step as it completes.
- Tools over the existing MCP service, gated by per-profile allowlists and
  a policy chain that keeps generated SQL read-only.
- Prompt assembly that fails the build rather than shipping a prompt
  carrying deployment-specific tables, hostnames or stale tool names.
- Storage in Postgres: threads, messages and feedback, with client-supplied
  idempotency enforced by a unique constraint.

Execution is inline by default and can run on the Celery worker
(AI_ASSISTANT_EXECUTION_MODE), which decouples a run from any reader and
lets a client reconnect to one already in progress.

Permissions follow the existing model: the API is @Protect()-ed, the menu
is Alpha-only so Gamma and Public cannot reach it, and tools run as the
requesting user so a question can never read past that user's grants.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@I3eka
I3eka force-pushed the native-ai-authoring-tools branch from 9ec50e7 to 0c830e3 Compare August 20, 2026 05:45
@I3eka

I3eka commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

CI note: the current test-postgres-hive failure occurred before setup or tests. Docker could not start the namenode because runner port 50070 was already in use (failed to bind host port 0.0.0.0:50070/tcp). I attempted to rerun the failed job, but GitHub only permits repository admins to rerun this upstream workflow; this needs a maintainer rerun.

@I3eka

I3eka commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

@sadpandajoe, the previous review feedback is addressed, including the authoring permission boundary and dashboard-layout validation. Could you please re-review this PR when convenient?

@rusackas

Copy link
Copy Markdown
Member

CI's red across every backend on this one, test_registry_exposes_every_documented_tool and test_every_tool_publishes_a_usable_schema both fail. Looks like TestAIToolsEndToEnd.setUp builds the registry with build_registry(), which defaults to BUNDLE_READ_ONLY (7 tools), while the assertions now expect all 10 now that this PR adds the three authoring tools to ALL_TOOL_NAMES. Should just be build_registry(BUNDLE_ALL) in setUp.

@I3eka

I3eka commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Fixed in f8df855: TestAIToolsEndToEnd.setUp now builds BUNDLE_ALL, so the registry/name/schema assertions cover all 10 documented tools. I also verified that the full bundle exposes matching names and definitions, and the changed file passes formatting, Ruff, mypy, and the remaining applicable pre-commit hooks. Thanks for pinpointing it.

@I3eka

I3eka commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

CI follow-up: the rerun is blocked before any backend tests execute because this stacked branch carries Alembic head a1c4f7e29b31 from base PR #42805 while master now has head 39097d124752; superset db upgrade exits on the two heads. The pre-commit job is likewise failing in the stacked base, on superset.ai imports whose sanitization APIs changed in master and on existing frontend default imports now rejected by Oxlint; none of those failures touches f8df855. I have not added downstream compatibility or a merge revision here because that ownership belongs to #42805 and this PR must be refreshed after the base is updated or merged. The requested registry fix itself is in f8df855.

request.assistant_message_uuid,
content=_terminal_content(result, outcome),
status=_status_of(outcome),
extra={

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successful turns discard the reasoning that was streamed to the browser, so reopening a completed conversation shows a different thought process than the live run. Could this persist the bounded result.thoughts here, as the abnormal-run path does?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Successful-turn thought persistence is inherited unchanged from the parent Native AI PR #42805; this authoring PR does not modify the finalization path. The parent should persist the same bounded field on every outcome, then this branch can be rebased. I am leaving the thread open pending that change.

pip install "apache-superset[ai-anthropic]" # or [ai-openai]
```

Then run `superset init` so the assistant's permissions are created and assigned

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following these enablement steps on an existing deployment leaves the new ai_chat_* tables absent, because superset init does not apply the migration. Could this also require superset db upgrade before the assistant is used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The reviewed enablement sequence is inherited unchanged from #42805. This authoring PR adds tool-specific documentation but does not own the base migration runbook. The parent docs should add superset db upgrade once, after which this branch will be rebased. I am leaving this open until then.


## Retention

Conversations are kept for `AI_ASSISTANT_MESSAGE_RETENTION_DAYS` (default 30).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retention setting is not enforced by this branch: the only added Celery task is ai.run_turn, so there is no pruning task or scheduler hook for an operator to schedule. Could this provide the pruning mechanism or document that the setting is currently inert?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The retention contract and missing pruning task are inherited unchanged from #42805, where the root issue is already tracked: #42805 (comment). This child PR will be rebased after the parent resolves it; I am leaving the thread open meanwhile.

| { status: 'loaded'; formData: QueryFormData }
| { status: 'error'; message: string };

const exploreUrlFor = (formDataKey: string): string =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This absolute Explore URL drops the application root. Deployments served under a prefix therefore send the new “View in Explore” link to /explore/… instead of the mounted route. Could this use the existing application-root-aware URL helper?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The reviewed Explore-link construction is inherited unchanged from the parent Native AI PR #42805 and is not introduced by the authoring adapters. The application-root-aware fix belongs in the parent UI implementation, then this branch can be rebased. I am leaving the thread open pending that fix.

</ActionButton>
{/* A conversation with messages is confirmed before deletion; an
empty one is discarded without a prompt. */}
{tab.messages.length > 0 ? (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thread-list tabs are deliberately created with messages: [] until first selection, so deleting an unopened conversation bypasses this confirmation even when it has persisted messages. Could the list retain/use the server message count for this decision?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Unopened-thread deletion behavior is inherited unchanged from #42805 and is already tracked on the parent: #42805 (comment). This authoring PR should not duplicate the parent state-model fix, so the thread remains open until rebase.


const PillLabel = styled.span`
overflow: hidden;
text-overflow: ellipsis;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answer deltas update liveAnswer, but it is absent from this effect’s dependencies. After tool activity stops, a long streamed answer can grow below the viewport without the transcript following it. Could this depend on liveAnswer too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The auto-scroll effect is inherited unchanged from the parent Native AI PR #42805; the authoring commits do not modify this panel behavior. The dependency fix should land once in the parent UI, then be rebased here. I am leaving this thread open pending that update.

);

/** Resolved when the user answers a checkpoint; see `streamRun`. */
const checkpointGateRef = useRef<{ resolve: () => void } | null>(null);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runs are tracked per tab, but this single checkpoint resolver is shared by every stream. If two tabs reach checkpoints, continuing one can resolve the other run and leave the selected run blocked. Could the gate be keyed by tab/run like activeRunsByTab?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. The single checkpoint resolver is inherited unchanged from the parent Native AI PR #42805 and is not part of the authoring tool change. The gate needs to be keyed in the parent run-state implementation, then rebased here. I am leaving the thread open until that is resolved.

Comment thread superset/ai/tools/authoring.py Outdated
Comment thread superset/ai/api.py
except (AIChatMessageInvalidError, AIChatThreadInvalidError) as ex:
return self.response_422(message=str(ex))

run_id = new_run_id()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A replay with the same request ID reuses the existing message rows, but this still creates a new run ID, overwrites their run context, and starts inference again. A lost POST response can therefore produce two paid runs racing on one assistant message. Could this return the original run when the append command reports created == false?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Duplicate request handling is inherited unchanged from #42805 and is already tracked at #42805 (comment). This authoring PR does not alter request claiming, so I am leaving the thread open pending the parent fix and rebase.

Comment thread superset/ai/eventbus.py
# A failure to publish must not kill the run that is producing useful
# work; the reader will time out and the answer is still persisted.
try:
self._cache.xadd(self._stream(run_id), payload, "*", 10_000)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates Redis streams without a TTL; expiration is only installed by a reader calling close(). If no stream reader connects, every abandoned run retains up to 10,000 events indefinitely. Could publishing set or refresh the stream expiry?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Producer-side stream expiry is inherited unchanged from #42805 and is already tracked at #42805 (comment). It is outside the authoring adapter change; this thread remains open until the parent fix is rebased.

Comment thread superset/ai/api.py
return self.response_404()

turn = None
if current_app.config.get("AI_ASSISTANT_EXECUTION_MODE") != "worker":

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline-mode reconnects construct and execute a new turn for any matching message without claiming the pending row or checking its status. Two stream GETs—or a retry after completion—can therefore run the same request twice and repeat authoring side effects. Could this make the run claim idempotent before starting it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Inline run claiming and terminal replay are inherited unchanged from #42805. The duplicate-side-effect issue is already tracked at #42805 (comment). I am leaving this open and will rebase the child after the parent fix.

generator cannot do both; it has the same shape either way, so callers do
not branch on which path ran.
"""
completion = CompletionRequest(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requested exact model is recorded on the run but this completion request only carries model_alias, so the provider cannot receive the pin. A request for model B can run the alias default A while telemetry reports B. Could this pass the resolved exact model through the runtime?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Exact-model propagation is inherited unchanged from #42805 and is tracked at #42805 (comment). The authoring commits do not change completion request construction, so the thread remains open pending the parent fix and rebase.

tools=tuple(request.tools.definitions()) if request.tools else (),
)

if not self.provider.supports_streaming:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The providers disable SDK retries in favor of superset.ai.llm.retry, but these calls invoke the provider directly and never apply that middleware. A transient 429/5xx therefore fails the turn on its first attempt despite the configured retry policy. Could the runtime wrap both completion paths with the retry policy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Runtime retry integration is inherited unchanged from #42805 and is already tracked at #42805 (comment). This authoring PR does not touch provider invocation; I am leaving the thread open until the parent implements and validates the retry semantics.

Comment thread superset/ai/tools/authoring.py
Comment thread superset/ai/tools/authoring.py Outdated
Comment thread docs/static/feature-flags.json Outdated
Copilot AI lite review requested due to automatic review settings September 3, 2026 17:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are at least two concrete correctness issues in the current diff (suggestions parsing vs tests, and a race where AI actions can be lost before the panel attaches its event listener).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds an opt-in AI assistant extension to Superset, including backend APIs, storage, prompts, tool plumbing, and frontend registration, with guardrails for RBAC and safe UX defaults (off-by-default, chromeless render suppression, read-only profiles by default).

Changes:

  • Adds AI assistant backend building blocks (types, commands, schemas, suggestions, runtime interfaces, retry/circuit breaker utilities) and wires the AI REST API behind the AI_ASSISTANT feature flag.
  • Improves dashboard authoring safety by validating supplied position_json layouts and falling back to an auto-generated layout with a warning when invalid.
  • Registers the assistant in the frontend chat host (flag-gated), adds UI components/hooks/tests for assistant UX, and documents/configures optional provider extras.
File summaries
File Description
tests/unit_tests/mcp_service/dashboard/tool/test_dashboard_generation.py Updates layout override test shape and adds coverage for invalid layout fallback warnings.
tests/unit_tests/ai/test_tools_result_shape.py Adds unit tests for SQL tool result normalization and row limit validation.
tests/unit_tests/ai/test_tools_display.py Adds tests ensuring LLM prompt-framing delimiters are stripped from UI display only.
tests/unit_tests/ai/test_suggestions.py Adds tests for suggested prompt parsing and “never raise” behavior.
tests/unit_tests/ai/init.py Adds package init (license header).
tests/integration_tests/superset_test_config.py Enables AI flag for integration tests and pins to an offline scripted provider.
tests/integration_tests/ai/init.py Adds package init (license header).
superset/security/manager.py Restricts the AI assistant menu to Alpha by default (avoids Gamma/Public by inheritance).
superset/migrations/versions/2026-08-04_00-00_a1c4f7e29b31_add_ai_chat_tables.py Adds DB tables for AI threads/messages/feedback with indexes and rollback.
superset/mcp_service/dashboard/tool/generate_dashboard.py Validates position_json layouts; invalid inputs fall back to packed grid + warning.
superset/mcp_service/dashboard/schemas.py Updates dashboard generation schema docs to reflect fallback-on-invalid behavior.
superset/mcp_service/auth.py Adds an in-process user override context for MCP calls and adjusts auth priority order.
superset/initialization/init.py Registers AI REST API only when AI_ASSISTANT flag is enabled.
superset/commands/ai/thread.py Adds commands for AI thread create/update/delete with validation and ownership scoping.
superset/commands/ai/submit_feedback.py Adds command to upsert thumbs up/down feedback scoped to thread ownership.
superset/commands/ai/exceptions.py Introduces AI command exception types with “missing, not forbidden” semantics.
superset/commands/ai/append_message.py Adds idempotent message append command with role/status validation.
superset/commands/ai/init.py Exposes AI command entry points.
superset/ai/types.py Defines shared enums and typed dicts for runs, messages, SSE event vocabulary.
superset/ai/tools/init.py Exposes tool registry entry points and bundles for runtime consumption.
superset/ai/tasks.py Adds Celery task wrapper for worker-mode assistant execution.
superset/ai/suggestions.py Implements opt-in model-generated opening suggestions (never-raise fallback).
superset/ai/schemas.py Adds Marshmallow request/response schemas for AI API endpoints.
superset/ai/runtime/base.py Defines runtime contract (events + results) and tool dispatcher protocols.
superset/ai/runtime/init.py Adds runtime package init and module docstring.
superset/ai/prompts/core/superset_product.py Adds core “Superset behavior” prompt section for grounding and correct guidance.
superset/ai/prompts/core/sql_conventions.py Adds portable SQL craft prompt section (no dialect-specific syntax).
superset/ai/prompts/core/safety.py Adds safety prompt section emphasizing injection resistance and scope limits.
superset/ai/prompts/core/persona.py Adds persona + grounding prompt section and response-shaping guidance.
superset/ai/prompts/core/init.py Assembles the set of core prompt sections including a time anchor.
superset/ai/prompts/init.py Exposes prompt assembly helpers and validation utilities.
superset/ai/mcp/init.py Documents external MCP server extension seam and trust boundary notes.
superset/ai/llm/retry.py Adds retry/backoff and context-local circuit breaker for provider calls.
superset/ai/llm/init.py Adds LLM package init.
superset/ai/knowledge.py Adds knowledge-provider interface for deployment-specific domains and prompt sections.
superset/ai/factories.py Adds runtime/provider/profile/tool registry resolution from configuration.
superset/ai/events.py Defines SSE event framing and canonical encoding helpers.
superset/ai/init.py Adds AI package init with “no vendor imports at module scope” contract.
superset-frontend/src/setup/setupApp.ts Imports AI feature registration as a setup side effect (flag-gated module).
superset-frontend/src/features/ai/index.ts Registers assistant as a chat provider; suppresses chromeless renders; exposes register/unregister.
superset-frontend/src/features/ai/index.test.tsx Adds tests for registration gating, chromeless suppression, and host mounting behavior.
superset-frontend/src/features/ai/hooks/useChatBot.test.ts Adds tests for transcript merge logic and page-context construction behavior.
superset-frontend/src/features/ai/hooks/useAIAction.ts Adds DOM-event-based action triggering API for other app areas to invoke the assistant.
superset-frontend/src/features/ai/hooks/useAIAction.test.ts Adds tests validating event dispatch and prompt builders.
superset-frontend/src/features/ai/hooks/quickPrompts.ts Adds client-side derived opening prompt suggestions (free fallback).
superset-frontend/src/features/ai/hooks/chatThreadsApi.ts Adds thread/message CRUD API helpers and mapping to chat tab/message shapes.
superset-frontend/src/features/ai/components/ChatTabsMenu.test.tsx Adds tests for conversation list UI behaviors (rename/delete/relative timestamps).
superset-frontend/src/features/ai/components/chatMarkdown.test.tsx Adds tests for fenced-block handling, SQL actions, and chart-embed fences.
superset-frontend/src/features/ai/components/ChatAgentSelect.tsx Adds agent profile dropdown (preserves server order; shows descriptions).
superset-frontend/src/features/ai/components/ChatAgentSelect.test.tsx Adds tests ensuring order stability and selection behavior.
superset-frontend/src/features/ai/AiAssistantTrigger.tsx Adds trigger button component tied to chat open/close state.
superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts Adds AiAssistant feature flag constant.
superset-frontend/packages/superset-ui-core/src/components/Icons/AntdEnhanced.tsx Adds additional icons used by assistant UI (like/dislike/send/message).
pyproject.toml Adds optional extras for AI providers and external MCP client.
docs/static/feature-flags.json Documents the AI_ASSISTANT flag and its safety/enablement semantics.
docker/pythonpath_dev/superset_config.py Adds local-dev configuration for AI assistant and worker-mode settings.
docker/.env-local.example Documents optional AI-related env vars for local development.
Review details
  • Files reviewed: 65/116 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +50 to +58
export const triggerAIAction = (payload: AIActionPayload): void => {
if (!payload.prompt.trim()) {
return;
}
chat.open();
window.dispatchEvent(
new CustomEvent<AIActionPayload>(AI_ACTION_EVENT, { detail: payload }),
);
};

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed: chat.open() updates the external store synchronously, but React mounts the panel and installs its useEffect listener later, so a closed panel can miss this event. This code is inherited unchanged from the owning base PR #42805 (including at its current head), not introduced by the #43133 authoring layer. I am leaving this thread open and keeping the root fix on #42805 rather than duplicating it across stacked PRs.

Comment thread superset/ai/suggestions.py
@I3eka

I3eka commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@rusackas, the authoring-specific human feedback is addressed. The remaining newly reported action-event race is inherited from #42805 and is tracked there rather than duplicated in this stack. Could you confirm whether this PR should remain parked until the base is updated or whether the focused authoring diff can be reviewed now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API authentication:RBAC Related to RBAC dashboard Namespace | Anything related to the Dashboard doc Namespace | Anything related to documentation packages risk:db-migration PRs that require a DB migration risk:many-files Change has too many files size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants