Skip to content

Conversation

@djbarnwal
Copy link
Member

@djbarnwal djbarnwal commented Nov 18, 2025

Adds project wide theme.

  • Adds theme in rill.yaml
  • AI Viz uses the project theme
  • For dashboards, inline theme -> referenced theme -> rill.yaml defaults -> theme in rill.yaml

Closes https://linear.app/rilldata/issue/ENG-960/add-theme-support-for-ai-generated-charts

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

@djbarnwal djbarnwal requested a review from mindspank November 18, 2025 01:50
@mindspank
Copy link
Contributor

@ericpgreen2 slight change to our Viz for AI. We will pick a theme of it has been defined, you think that's too aggressive?

@ericpgreen2
Copy link
Contributor

ericpgreen2 commented Nov 18, 2025

@ericpgreen2 slight change to our Viz for AI. We will pick a theme of it has been defined, you think that's too aggressive?

I'd advocate for consistency. Since Explore dashboards require a theme be set explicitly, I'd expect the same of inline AI visualizations. I'd expect:

# rill.yaml
ai_theme: my_theme

// or refactored to be nested under a top-level "ai" key
ai:
  theme: my_theme
  connector: my_openai
  instructions: ...

@mindspank
Copy link
Contributor

I'd advocate for consistency. Since Explore dashboards require a theme be set explicitly, I'd expect the same of inline AI visualizations. I'd expect:

@ericpgreen2 @djbarnwal lets go with ai_theme then to stay consistent with our existing implementation since we dont have a top level key for that today (and at that point perhaps it's own resource?)

@mindspank mindspank changed the title feat: add theme support for viz in chat feat: project level themes Nov 26, 2025
map<string, string> variables = 7;
map<string, string> annotations = 9;
string frontend_url = 18;
string theme = 19;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you remove the option here? Since the field gets populated from rill.yaml, it should not be possible to pass it over the APIs CreateInstance or EditInstance (because the YAML parser runs continuously and would quickly overwrite anything passed through the API)

map<string, string> variables = 15;
map<string, string> annotations = 10;
optional string frontend_url = 19;
optional string theme = 20;
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above

Comment on lines -300 to -308
// Set an error without returning to mark if there are parse errors (if not, force error to nil in case there previously were parse errors)
var parseErrsErr error
if len(parser.Errors) > 0 {
parseErrsErr = ErrParserHasParseErrors
}
err = r.C.UpdateError(ctx, self.Meta.Name, parseErrsErr)
if err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think moving this is safe – it will prevent parse errors from showing up in Rill Developer

Comment on lines +314 to +340
// Check if theme referenced theme changed
themeChanged := false
if parser.RillYAML.Theme != "" && diff != nil {
referencedTheme := parserpkg.ResourceName{Kind: parserpkg.ResourceKindTheme, Name: parser.RillYAML.Theme}
for _, n := range diff.Added {
if n.Normalized() == referencedTheme.Normalized() {
themeChanged = true
break
}
}
if !themeChanged {
for _, n := range diff.Modified {
if n.Normalized() == referencedTheme.Normalized() {
themeChanged = true
break
}
}
}
if !themeChanged {
for _, n := range diff.Deleted {
if n.Normalized() == referencedTheme.Normalized() {
themeChanged = true
break
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is needed? It does a full re-parse of the project when rill.yaml is changed, so I don't think any further changes here should be necessary (unless I'm missing something?)

Comment on lines 186 to +197
inst.ProjectAIConnector = rillYAML.AIConnector

// Validate theme references an existing theme resource
if rillYAML.Theme != "" {
// Check if theme exists in parsed resources using normalized name (case-insensitive)
themeName := parser.ResourceName{Kind: parser.ResourceKindTheme, Name: rillYAML.Theme}
if _, ok := p.Resources[themeName.Normalized()]; !ok {
return fmt.Errorf("theme references theme %q which does not exist", rillYAML.Theme)
}
}

inst.Theme = rillYAML.Theme
Copy link
Contributor

Choose a reason for hiding this comment

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

It should just assign the expressed theme without doing validation. This is not a safe place to do validation – validation has to be done when parsing or when reconciling/consuming the value.

It'll be difficult to validate this at parse time because rill.yaml is parsed before any other file is parsed, so it won't know if the theme exists or not. Due to unpredictable parse order, we generally don't validate references in the parser – we do that in reconciles. But for AI themes, there is no resource to reconcile.

So I suggest you validate this when consuming the setting in the AI chat UI. I.e. show an error if the theme doesn't exist.

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.

5 participants