Skip to content

Feat/explainer story generation - #796

Draft
Creylay wants to merge 11 commits into
developfrom
feat/explainer-story-generation
Draft

Feat/explainer story generation#796
Creylay wants to merge 11 commits into
developfrom
feat/explainer-story-generation

Conversation

@Creylay

@Creylay Creylay commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds on-demand "story" generation for global and local explainers. Stories are generated only when the user explicitly clicks "Generate story"; the main explain job never computes them automatically. Text is deterministic (template-based) for now; the same job/endpoint/UI plumbing is designed to swap in an LLM later without further changes to this scaffolding.


Type of Change

  • Backend change
  • Frontend change
  • CI / Workflow change
  • Build / Packaging change
  • Bug fix
  • Documentation

Changes (by file)

Schema / migrations

  • DashAI/back/dependencies/database/models.py: adds story, story_huey_id to GlobalExplainer, and stories (JSON, keyed by instance index) to LocalExplainer.
  • DashAI/alembic/versions/6273b0d04af3_..._global_explainer.py, .../0b08a41e4dbd_..._local_explainer.py: corresponding migrations.

Job

  • DashAI/back/job/explainer_story_job.py (new): ExplainerStoryJob, one job class for both global and local (branches by scope like the existing ExplainerJob). Reloads the already-computed explanation/plot from disk — never recomputes — reinstantiates the explainer, calls story(), and persists the result.
  • DashAI/back/initial_components.py, DashAI/back/api/api_v1/schemas/job_params.py: register the new job type.

Registry

  • DashAI/back/dependencies/registry/component_registry.py: adds a supports_story flag per registered component (true only if that explainer defines its own story()), so the frontend knows when to show the button instead of guessing and failing.

API

  • DashAI/back/api/api_v1/endpoints/explainers.py: new POST /explainer/global/{id}/story and POST /explainer/local/{id}/story (with group_index) endpoints; validate the explainer exists, its explanation finished, and it supports stories.

Explainers

  • permutation_feature_importance.py: implements story() for global (ranks features by importance).
  • contrastive_shap.py, nearest_counterfactual.py, regression_kernel_shap.py, dice_counterfactual.py, token_ablation.py, grad_cam.py, occlusion_saliency.py: implement story() for local. Each of these used to build this same narrative eagerly inside plot() as a TextArtifact; that's now only built on demand by story(), from self.explanation's raw numbers, decoupled from how plot() renders.

Frontend

  • ExplainersCard.jsx: "Generate/Regenerate story" button + result, one per global explainer.
  • ExplainersPlot.jsx: same, per explained instance, for local explainers.
  • api/explainer.ts, types/explainer.ts: createGlobalExplainerStory / createLocalExplainerStory calls and types.
  • RunResults.jsx, ExplainerResultsTab.jsx, LazyExplainerCard.jsx, useRunResultsData.js: thread supportsStory down so the button only renders where the backend actually supports it.
  • i18n: new labels in en/es/pt/de/zh.

Testing

  • tests/back/api/test_explainer_story_job.py (new): end-to-end coverage of the job + both endpoints (happy path, unfinished explanation, missing explainer, explainer without story support).
  • tests/back/explainers/test_explainers.py, test_new_explainers.py, and the other per-explainer test files: unit coverage confirming plot() no longer emits the narrative and story() produces it correctly.

Creylay added 10 commits August 3, 2026 23:25
- Introduced `_summarize_instance` methods in GradCam, NearestCounterfactual, OcclusionSaliency, RegressionKernelShap, and TokenAblation classes to generate descriptive summaries based on explanation data.
- Updated `plot` methods in these classes to remove narrative summary generation, delegating it to a new `story` method that retrieves the summary when requested.
- Added `createLocalExplainerStory` API endpoint to facilitate story generation for local explainers.
- Enhanced ExplainersCard and ExplainersPlot components to manage story generation and display results using ArtifactViewer.
- Updated TypeScript types to include optional `stories` property for explainers.
@Creylay
Creylay changed the base branch from production to develop August 4, 2026 22:08
@Creylay
Creylay requested a review from Irozuku August 4, 2026 22:20
@Creylay
Creylay marked this pull request as draft August 5, 2026 13:12
…points

- Deleted the ExplainerStoryJob class to streamline story generation as part of the existing explainer job.
- Removed createGlobalExplainerStory and createLocalExplainerStory API functions from the frontend.
- Updated ExplainersCard and ExplainersPlot components to reflect the removal of story generation logic and utilize the story directly from the explainer.
- Adjusted tests to ensure stories are generated automatically during the explainer job execution, including handling cases where story generation may fail.
- Cleaned up localization files by removing story generation related strings.
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