Skip to content

Commit 645124e

Browse files
fix(dashboards): Send current dashboard state on Seer follow-up messages (#112601)
- Fixes a bug where manual dashboard edits (add/move/edit widgets) made during an edit session get overwritten when Seer responds to a follow-up message - The root cause is that follow-up messages to the Seer chat endpoint only sent `{query: message}` without including the current dashboard state, so Seer generated a complete dashboard based on stale context - Now sends the current `modifiedDashboard` as `on_page_context` on follow-up messages, matching how initial session creation already sends `current_dashboard`
1 parent 6e1004f commit 645124e

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

static/app/views/dashboards/useSeerDashboardSession.spec.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,68 @@ describe('useSeerDashboardSession', () => {
121121
);
122122
});
123123

124+
it('sends current dashboard state as on_page_context with follow-up messages', async () => {
125+
const dashboard = {
126+
title: 'My Dashboard',
127+
widgets: [
128+
{
129+
title: 'Count',
130+
displayType: DisplayType.LINE,
131+
interval: '1h',
132+
queries: [
133+
{
134+
name: '',
135+
conditions: '',
136+
fields: ['count()'],
137+
columns: [],
138+
aggregates: ['count()'],
139+
orderby: '',
140+
},
141+
],
142+
},
143+
],
144+
};
145+
146+
MockApiClient.addMockResponse({
147+
url: apiUrl,
148+
body: COMPLETED_SESSION,
149+
});
150+
151+
const postMock = MockApiClient.addMockResponse({
152+
url: apiUrl,
153+
method: 'POST',
154+
body: {},
155+
});
156+
157+
const onDashboardUpdate = jest.fn();
158+
159+
const {result} = renderHookWithProviders(
160+
() =>
161+
useSeerDashboardSession({
162+
seerRunId: SEER_RUN_ID,
163+
dashboard,
164+
onDashboardUpdate,
165+
}),
166+
{organization}
167+
);
168+
169+
await act(async () => {
170+
await result.current.sendFollowUpMessage('Add an error rate widget');
171+
});
172+
173+
expect(postMock).toHaveBeenCalledWith(
174+
apiUrl,
175+
expect.objectContaining({
176+
method: 'POST',
177+
data: expect.objectContaining({
178+
query: 'Add an error rate widget',
179+
on_page_context:
180+
'The user is editing an existing dashboard. The current dashboard state is:\n\n{"title":"My Dashboard","widgets":[{"title":"Count","displayType":"line","interval":"1h","queries":[{"name":"","conditions":"","fields":["count()"],"columns":[],"aggregates":["count()"],"orderby":""}]}]}\n\nThis session must ONLY modify the dashboard artifact. Produce a COMPLETE dashboard artifact that incorporates the requested changes while preserving widgets the user did not ask to change.',
181+
}),
182+
})
183+
);
184+
});
185+
124186
it('starts a new session via the generate endpoint when dashboard is provided without seerRunId', async () => {
125187
const dashboard = {
126188
title: 'My Dashboard',

static/app/views/dashboards/useSeerDashboardSession.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import type {DashboardDetails, Widget} from './types';
1515
const POLL_INTERVAL_MS = 500;
1616
const POST_COMPLETE_POLL_MS = 5000;
1717

18+
function buildEditOnPageContext(
19+
dashboard: Pick<DashboardDetails, 'title' | 'widgets'>
20+
): string {
21+
return `The user is editing an existing dashboard. The current dashboard state is:\n\n${JSON.stringify({title: dashboard.title, widgets: dashboard.widgets})}\n\nThis session must ONLY modify the dashboard artifact. Produce a COMPLETE dashboard artifact that incorporates the requested changes while preserving widgets the user did not ask to change.`;
22+
}
23+
1824
async function startDashboardEditSession(
1925
orgSlug: string,
2026
message: string,
@@ -169,7 +175,10 @@ export function useSeerDashboardSession({
169175
await fetchMutation({
170176
url,
171177
method: 'POST',
172-
data: {query: message},
178+
data: {
179+
query: message,
180+
...(dashboard ? {on_page_context: buildEditOnPageContext(dashboard)} : {}),
181+
},
173182
});
174183
queryClient.invalidateQueries({queryKey});
175184
}

0 commit comments

Comments
 (0)