Repository navigation
Conversation
Writing a PromQL query means knowing which metric exists on this data source
and what its labels are called. The assistant already knows; reaching it meant
opening the chat drawer, which covers the chart the query is written for, and
then copying the answer back by hand.
The panel sits under the query box instead. It shows what the assistant did to
check its answer, writes the verified expression into the field on arrival —
the field runs it, and Undo puts back whatever the user had — and keeps one
chat so a follow-up ("group it by pod") carries the context.
It reads the message rather than the stream: message/detail is the durable
source of truth, and a panel showing a handful of steps does not need
token-level updates.
Nothing is claimed that was not delivered. When the assistant looked and found
nothing usable, the panel says so and leaves the field alone.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
A reset the panel never calls, a placeholder override no caller passes, and an `any` on a ref antd already types. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
message/detail never returns a bare `tool` segment. GetData runs every response through AggregateToolCallResponses, which folds each run of consecutive tool calls into one `tool_group` carrying the counts. The panel was matching on `tool`, so its "what the assistant did" list would have been empty on every real answer — and the tests said otherwise only because they mocked a wire shape the server does not produce. Read the counts instead, and say them as counts: eight rows all reading "ran a command" tell the reader less than one row reading "ran 8 commands". Also drop panelKey from the panel's page params. It reaches nothing: the backend's PageInfoParam has no such field, and the comparison that would use it reads a chat context this panel never touches. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
A turn can end on a question rather than an answer — the data source the page names is ambiguous, say. It finishes clean: no error, no query. The panel read that as "nothing usable was delivered", which is true and useless; what the user needs is the question. Show it, and say to answer below — which is all it takes, verified against the running assistant: a plain follow-up on the same chat answers the request and the turn goes on to deliver its query. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
The slot the panel sits in is a flex column, so the panel was a shrinkable item: it got 71px for 98px of content, and the rounded clip cut whatever did not fit. Focusing the input on open then scrolled that clipped box down by the missing 19px, which moved the cut to the top — the header came up sliced in half, and the panel read as broken before it had done anything. Keep the panel at its own height, and focus without scrolling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
It was shouting. The raw Go failure — dial address, chat id, seq id — was set as body text at the same weight as the sentence above it, inside a full red box, under a red "failed" tag, stretched across the whole monitor. Three signals for one fact, and the loudest one was a stack address. Now: one status tag, an accent rule instead of a second red outline, and the raw failure kept but demoted to small muted monospace under its own label — still the first thing an SRE wants, no longer the first thing anyone reads. Prose wraps at a readable measure instead of running the full width. The body collapses entirely before the first answer, so an idle panel is a quiet strip rather than a hollow frame. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
A design review of the panel found the stack order was the order the machine produced things — process, artifact, result — not the order someone reading it mid-incident needs. The line that says "your query box was just overwritten, here is the way back" sat last, inside a 240px scroll box, where it was the most likely thing to be clipped. Now the result card comes first and the write-back is that card's own footer, so what happened and what it happened to cannot drift apart. The tallies stop being a checklist of green ticks and become one footnote; while a run is in flight they are the progress, under the assistant's own sentence about what it is doing right now. A run could not be stopped: for up to five minutes the input, send and regenerate were all disabled. It can now, and the backend is told too, so a retry does not race a run that is still working. Failure was one bucket. "Nothing usable came back" and "the request never reached the assistant" take different fixes, and telling a user the assistant looked and found nothing — when nothing ran — sends them off rewriting a good question. Each case now has its own title and one actionable line, the raw error is behind a toggle, and a single dropped poll no longer kills a run. Also: the panel asks the field what it holds rather than assuming, so a hand edit is noticed instead of being reverted by a stale undo; refilling after an undo is a local write rather than another model run; the header keeps the name of the task across follow-ups; Esc is scoped to the panel instead of the whole document; and the lavender fill is opacity-derived so it survives dark mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
The panel decided what to say about the field by asking whether it was empty, which meant that after an undo it told the user they had edited something. It also armed an undo when the assistant returned exactly the query already in the box — pressing it would have wiped the user's own text and re-run nothing. And having undone, asking again for the same answer filled nothing, because the write-once guard was never cleared. All three were the same missing fact: what the field held when the run started. The panel now remembers that, so it can tell "we wrote this" from "you got your text back" from "you edited it", and can stay quiet when it changed nothing. A follow-up that ends on a question, a miss or an error no longer takes the previous answer off the screen with it — the field still holds that query, so it keeps its card and its undo. Dropped the scratch-file tally from the verification line: the assistant writing its own notes is not evidence about the query, and reading "wrote 2 files" on a page that touches production invites a question nobody wants to be asking mid-incident. Dropped "another way" too — it re-asked for an equivalent phrasing, which is a thing the follow-up box does better and nobody asked for. Closing or stopping now cancels the run rather than leaving the model working on an answer no one will see, and the panel says so up front when no data source is selected instead of spending a minute to ask. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
…hows Sitting in the page flow costs height, and on this page the chart pays for it — the panel is not pushed above the chart, it takes its space. A settled panel was spending its largest block on a copy of the query that is legible in the box forty pixels above. So it shows the query only while the field does not hold it — after an undo, or a hand edit, which is exactly when it has to be read to decide. The explanation clamps to two lines with the whole of it on hover. Together that is a third of the chart handed back, with no collapse toggle and no new state: a rule instead of a mechanism. Three seams three rounds of patching had left: The status chip and the card ranked outcomes differently, so a run that changed nothing was labelled 已填入 beside a card reading 未做改动. The chip is gone — every label it carried was repeated one row below it. A follow-up that ended on a question or an error still led with the previous turn's green tick, and offered two re-run buttons thirty pixels apart aimed at different things. Whatever this turn produced now leads; a card carried over from an earlier turn follows it, dimmed, and keeps quiet about regenerating. Retry re-ran the ask without refreshing what the field held, so undoing after retrying could delete text the user typed while waiting. Retry goes through the same door as everything else now — which is also the door that stops Enter from sending with no data source selected. The evidence line claimed verification and reported tool-call tallies, counting files the user cannot see. It now says the one thing that is evidence and names what it was run against. Timeouts and dropped polls cancel the backend run instead of leaving it racing the retry. Undo became another write of the value the field started with, so the page keeps no second copy of that fact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
The panel asks the page what the field holds so it can tell its own writes from the user's. On this page the answer was stale: PromGraphCpt keeps the live value and reports edits through onChange, which the page forwarded without ever updating its own copy. So someone who typed a query by hand, then asked the assistant, had that query recorded as empty — and undo handed them back an empty box. The page now keeps its copy in step, and the prop says it must. Two more ways a wrong value could reach the field. A follow-up carried the previous answer forward under the same name as this turn's, so a turn that only asked a clarifying question looked like a delivery: the value the user had just undone was written back and re-run, underneath a block inviting them to answer. Carried values now have their own name and are never mistaken for an answer. And the undo target was re-snapshotted every turn, so after two refinements it pointed at the assistant's own earlier answer rather than at the user's text. It is snapshotted once per task now — before the assistant touched anything, which is what the prop always claimed it was. Failures showed whatever the assistant happened to be narrating when the request died, in place of the one line that says what to do about it. That line is the body now. And a turn that delivered nothing puts the question back in the box, so Send is the retry — editable first, which is what the timeout copy already advises. Three re-run buttons became none. Polling and cancellation no longer raise a global toast: the hook tolerates dropped polls on purpose, and cancels fire as the panel unmounts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
A query someone else wrote deserves a beat before it hits the data source. The panel wrote into the field and the chart fetched immediately, because the field and the query were the same piece of state: every change to the box was a change to what the panes fetched. They are separate now. The box holds what is being written; the panes fetch what has been submitted. Everything that means "run this" still submits — the query button, committing an edit with blur or enter, a query arriving from the URL or from an alert event — but a value filled in on the user's behalf only fills, and waits for them to press 查询. The banner slot can now be given a function instead of a node, receiving the field's live content and a way to fill it. That is how the assistant panel both knows what the box holds and writes to it without running, and it replaces the page-level copy of the query that existed only to answer the first question. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NifGUSCA6tmXym3k8B12Lu
The follow-up box used a fixed "group by pod" example regardless of what was just delivered. The backend now sends a follow_up phrase with each query segment; the panel reads it into run.suggestion and shows it as the placeholder, falling back to a plain "keep going" when a turn brought none.
|
Added in 4b000f4: the follow-up box's placeholder now comes from the assistant ( |
…s it ran
The panel showed "tried N times against <source>" under the spinner and
under the card. The count included the agent's own ls and --help calls,
and read as unrelated to the query. The backend already names each step
for a reader ("检索指标名"), so the running line now shows the current
step, the finished card says the answer was checked against the source,
and the explanation keeps only what was said after the query was
delivered rather than the narration of the search.
The follow-up hint the assistant wrote can now be accepted with Tab: it
fills the box and leaves sending to the user.
|
Added in the latest commit: the running line shows the backend's name for the current step ("查询指标序列…") instead of a command tally; the finished card says "checked against |
|
Superseded: the panel drew its own transcript and filled the box through a callback. The replacement mounts the ordinary ChatPanel in a slim variant under the query box and writes the query through the ai-kit page-action channel. See the PR opened from feat/ai-query-dock. |
Why
Writing a PromQL query means knowing which metric exists on this data source and what its labels are called. The assistant already knows. Reaching it meant opening the chat drawer — which covers the chart the query is written for — and then copying the answer back by hand.
What
A panel that sits under the query box instead of over the chart.
tool_groupsegments the backend sends.It reads
message/detailrather than the stream: that endpoint is the durable source of truth the chat itself falls back on, and a panel showing a handful of steps does not need token-level updates.The old icon entry point is unchanged — the icon now toggles this panel.
Notes for review
fix/ai-chat-page-params; retarget tomainonce that merges.present_metric_querytool for the metric explorer page type. Without it the assistant has no way to deliver a query segment.tscis at the repo baseline (52 pre-existing errors, none in touched files), but the local integrated dev environment's session expired and its login page hangs, so the rendered panel has not been exercised end to end.Tests
npx jest src/components/AiQueryPanel src/components/AiChatNG— 106 passed.