fix: build hvPlotAgent response model explicitly and add colormap options - #1935
Draft
ghostiee-11 wants to merge 4 commits into
Draft
fix: build hvPlotAgent response model explicitly and add colormap options#1935ghostiee-11 wants to merge 4 commits into
ghostiee-11 wants to merge 4 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1935 +/- ##
==========================================
+ Coverage 71.37% 71.47% +0.09%
==========================================
Files 199 199
Lines 34686 34755 +69
==========================================
+ Hits 24758 24841 +83
+ Misses 9928 9914 -14 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ahuang11
reviewed
Jul 21, 2026
ahuang11
reviewed
Jul 21, 2026
Comment on lines
+32
to
+117
| class hvPlotSpec(BaseModel): | ||
| """Fields that do not depend on the data schema.""" | ||
|
|
||
| chain_of_thought: str = Field( | ||
| description="Your thought process behind the plot." | ||
| ) | ||
|
|
||
| cmap: Literal["linear", "diverging", "categorical", "cyclic"] | None = Field( | ||
| default=None, | ||
| description=( | ||
| "Colormap to use when a column is mapped to colour. Pick 'diverging' " | ||
| "for values around a meaningful centre such as anomalies or deviations, " | ||
| "'categorical' for unordered categories, 'cyclic' for wrapping values " | ||
| "such as wind direction or hour of day, and 'linear' otherwise." | ||
| ), | ||
| ) | ||
|
|
||
| cnorm: Literal["linear", "log", "eq_hist"] | None = Field( | ||
| default=None, | ||
| description="Colour scale normalization. Use 'log' for values spanning orders of magnitude.", | ||
| ) | ||
|
|
||
| colorbar: bool | None = Field( | ||
| default=None, | ||
| description="Whether to show a colorbar. Leave unset to let hvPlot decide.", | ||
| ) | ||
|
|
||
| geo: bool = Field( | ||
| default=False, | ||
| description="Whether the data is geographic and should be plotted on a map.", | ||
| ) | ||
|
|
||
| limit: int | None = Field( | ||
| default=None, | ||
| ge=0, | ||
| description="Maximum number of rows to plot. Leave unset to plot all rows.", | ||
| ) | ||
|
|
||
| title: str | None = Field( | ||
| default=None, | ||
| description="Title describing what the plot shows.", | ||
| ) | ||
|
|
||
|
|
||
| def make_hvplot_model(view_type: type[hvPlotUIView], schema: dict[str, Any]) -> type[BaseModel]: | ||
| """ | ||
| Build the structured-output model for a given view type and data schema. | ||
|
|
||
| The column fields are restricted to the columns actually present so the | ||
| model cannot reference a column that does not exist, and `kind` is derived | ||
| from the view's own Selector so the two cannot drift apart. | ||
| """ | ||
| kinds = tuple(view_type.param["kind"].objects) | ||
| columns = tuple(schema) | ||
| # Literal[()] is not a valid annotation, so fall back to a plain string | ||
| # when the schema is empty. | ||
| column = Literal[columns] if columns else str | ||
|
|
||
| return create_model( | ||
| "hvPlotSpecWithColumns", | ||
| by=( | ||
| list[column] | None, | ||
| Field(default=None, description="Columns to split into separate series."), | ||
| ), | ||
| color=( | ||
| column | None, | ||
| Field(default=None, description="Column to map onto colour."), | ||
| ), | ||
| groupby=( | ||
| list[column] | None, | ||
| Field(default=None, description="Columns to group by into widgets."), | ||
| ), | ||
| kind=( | ||
| Literal[kinds], | ||
| Field(description="The kind of plot to generate."), | ||
| ), | ||
| x=( | ||
| column | None, | ||
| Field(default=None, description="Column to plot on the x-axis."), | ||
| ), | ||
| y=( | ||
| column | None, | ||
| Field(default=None, description="Column to plot on the y-axis."), | ||
| ), | ||
| __base__=hvPlotSpec, | ||
| ) |
Contributor
There was a problem hiding this comment.
Is there a better way? Rather than duplicating the args, can we read the signature from https://github.com/holoviz/hvplot/blob/451910e7a17ba9e9ecd4115b30d529cc2cb9dfbb/hvplot/converter.py#L866
It's missing typing at this moment, but maybe could add typing?
ahuang11
marked this pull request as draft
July 21, 2026 22:45
ghostiee-11
force-pushed
the
fix/hvplot-agent-model-and-colors
branch
from
July 22, 2026 05:00
55eb30a to
7b8a9c1
Compare
…ions param_to_pydantic walks parent classes and every subclass transitively, so starting from hvPlotUIView it reached panel.viewable.Viewer and from there the whole Panel class graph. Since the subclass set is iterated in id-hash order the conversion failed differently on each run, with NotImplementedError, PydanticSchemaGenerationError or RecursionError. _get_model is called on every response, so the agent raised rather than degraded. Build the model with create_model instead, listing the fields explicitly and deriving kind from the view's own Selector so the two cannot drift. The reasoning field is now dropped from the spec, which previously reached the view and raised in the explorer. While the model was being rebuilt, add cmap, cnorm, colorbar and color. The colormap is offered as linear/diverging/categorical/cyclic, which is easier to choose from than the full list of colormaps, and resolved to a concrete name before it reaches the view because hvplot.ui.Colormapping.cmap is a Selector that rejects the semantic names. Colouring by a non-numeric column also picks a named categorical colormap, since hvPlot would otherwise default to a list of colours that the same Selector rejects. Fixes holoviz#1931
Each of these fails if its guard is removed: the semantic colormap has to be resolved to a concrete name, the reasoning field has to be dropped before the spec reaches the view, colouring by a non-numeric column needs a named colormap, and the large-data branch must not overwrite a normalization the model asked for.
Moves the hvplot.ui import up top and takes the cmap kinds and cnorm options from DEFAULT_CMAPS and Colormapping.cnorm, so they cannot drift from hvPlot. The rest of the fields stay written out: HoloViewsConverter.__init__ has 77 arguments and no type annotations, so its signature cannot type a structured output model, and only a small subset is worth putting in front of an LLM.
ghostiee-11
force-pushed
the
fix/hvplot-agent-model-and-colors
branch
from
July 22, 2026 05:05
41acca4 to
6e0245f
Compare
ghostiee-11
marked this pull request as ready for review
July 22, 2026 07:19
Contributor
|
Do you have a solution for #1935 (comment) |
ahuang11
marked this pull request as draft
July 22, 2026 23:00
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.
hvPlotAgentcould not build its structured-output model at all:param_to_pydanticwalks parent classes and every subclass transitively, so fromhvPlotUIViewit reached Panel's whole class graph and failed differently on each run._get_modelis called on every response, so the agent raised rather than degraded.This builds the model with
create_modelinstead, listing fields explicitly and derivingkindfrom the view's own Selector. Since the model was being rebuilt anyway it also addscmap,cnorm,colorbarandcolor, with the colormap offered as linear/diverging/categorical/cyclic and resolved to a concrete name before it reaches the view.Fixes #1931