Repository navigation
Conversation
The conversation title is the first prompt truncated to 50 bytes, taken as-is. Prompts carry each @ or / reference as markup, e.g. <chat-reference>type="metricsView" metricsView="orders"</chat-reference>, which is longer than the title, so a conversation that starts with a reference gets a title like `<chat-reference>type="metricsView" metricsView=...` in the chat sidebar, its history menu and the full-page conversation list. Replace each reference with readable text before truncating: the display name of the referenced metrics view, measure, dimension or canvas when the session can access it (falling back to its name), `/name` for skills, the dates of a time range in its time zone, and the name for the other types. References of unknown types are dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
promptToTitle cut the title at byte 47 with title[:47], which can land
inside a multi-byte rune. The dangling lead byte followed by "..." is
invalid UTF-8, and protobuf refuses to marshal it ("string field contains
invalid UTF-8"), so the conversation can't be returned by the API. Titles
in languages with accents hit this, and the display names that now
replace chat references make it more likely.
Add truncateUTF8, which backs off to the previous rune boundary, and use
it for the title.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Components defined in a canvas are named after their position, e.g. sales--component-1-0, which says nothing in a conversation title. Show a component reference by the component's title, then its display name, then the display name of its canvas, and only then its name. Everyone can read a component, and access to it is decided by the canvas that shows it, as in ResolveCanvas. So the component's title is only used when it belongs to the referenced canvas and the session can access that canvas. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
542539f to
d14c123
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Preserve time-zone attributes and enforce the required ReadObjects permission before exposing resource names.
1 open issue
What changed in this PR
Updates AI conversation titles to show readable chat-reference labels and safely truncate UTF-8 text.
Changes:
- Resolves resource, skill, time-range, and component references.
- Centralizes reference attribute parsing.
- Adds UTF-8-safe truncation and title tests.
| File | Description |
|---|---|
runtime/ai/truncate.go |
Adds UTF-8-safe truncation. |
runtime/ai/skill_references.go |
Centralizes chat-reference parsing. |
runtime/ai/router_agent.go |
Generates readable reference-based titles. |
runtime/ai/router_agent_test.go |
Tests title formatting and security behavior. |
Review effort: Lite
| func (t *RouterAgent) accessibleResource(ctx context.Context, kind, name string) *runtimev1.Resource { | ||
| session := GetSession(ctx) | ||
|
|
||
| ctrl, err := t.Runtime.Controller(ctx, session.InstanceID()) | ||
| if err != nil { | ||
| return nil | ||
| } | ||
| r, err := ctrl.Get(ctx, &runtimev1.ResourceName{Kind: kind, Name: name}, false) |
There was a problem hiding this comment.
This is a one time replacement of reference => displayName, so these can go stale. While this can be replaced at runtime in Rill UI, mcp usage wont have a good path for this. But router agent is only called from Rill UI so I think an alternative can also work.
How about we cut at the end of a reference and replace the reference in Rill UI, we already have a lot of code for this there.
Edit: Actually the whole mention system is only present in Rill UI, so I think the approach of replacing during runtime is better.
|
I have merged 10047. Will be deployed in next major release. |

A conversation's title is its first prompt truncated to 50 bytes. When the prompt starts with an
@or/reference, the title shows the reference's markup, cut in the middle:<chat-reference>type="metricsView" metricsView=...<chat-reference>type="skill" skill="monthly-cl...That's what the chat sidebar header, its history menu and the full-page conversation list show, since the three render
conversation.titleas plain text.This fixes it in
promptToTitle, so the title is still stored as plain text and the UI doesn't change:<chat-reference>is replaced with readable text before truncating: the display name of the referenced metrics view, measure, dimension or canvas when the session can access it (with the same security check asGetMetricsView), falling back to its name;/namefor skills; the dates of a time range in its time zone; and a canvas component's title, then its display name, then its canvas's display name. References of unknown types are dropped.ResolveCanvas), a component's title is only used when it belongs to the referenced canvas and the session can access that canvas.title[:47]could leave a dangling lead byte, and protobuf refuses to marshal a string field with invalid UTF-8, so the conversation couldn't be returned by the API.chatReferenceAttrsis extracted fromreferencedSkills, so both parse references the same way.The text is close to the chips the UI renders, but not identical: for charts, the UI builds an English title from the chart's fields, while the conversation title uses the component's
title, which is usually in the project's language. Existing conversations keep their current titles.Tested with
TestRouterAgentTitle(one case per reference type, plus truncation), and locally with a project whose conversations start with a metrics view and a skill reference.Developed in collaboration with Claude Code