Feat/explainer story generation - #796
Draft
Creylay wants to merge 11 commits into
Draft
Conversation
…elated request body
…tory method and caching explanation
- 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.
…xplainersPlot components
…ove unused artifact types
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
Changes (by file)
Schema / migrations
DashAI/back/dependencies/database/models.py: addsstory,story_huey_idtoGlobalExplainer, andstories(JSON, keyed by instance index) toLocalExplainer.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 existingExplainerJob). Reloads the already-computed explanation/plot from disk — never recomputes — reinstantiates the explainer, callsstory(), 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 asupports_storyflag per registered component (true only if that explainer defines its ownstory()), so the frontend knows when to show the button instead of guessing and failing.API
DashAI/back/api/api_v1/endpoints/explainers.py: newPOST /explainer/global/{id}/storyandPOST /explainer/local/{id}/story(withgroup_index) endpoints; validate the explainer exists, its explanation finished, and it supports stories.Explainers
permutation_feature_importance.py: implementsstory()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: implementstory()for local. Each of these used to build this same narrative eagerly insideplot()as aTextArtifact; that's now only built on demand bystory(), fromself.explanation's raw numbers, decoupled from howplot()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/createLocalExplainerStorycalls and types.RunResults.jsx,ExplainerResultsTab.jsx,LazyExplainerCard.jsx,useRunResultsData.js: threadsupportsStorydown so the button only renders where the backend actually supports it.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 confirmingplot()no longer emits the narrative andstory()produces it correctly.