Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions static/app/components/commandPalette/ui/commandPalette.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,54 @@ describe('CommandPalette', () => {
).toBeInTheDocument();
});

it('tells Seer a Tab handoff came from the command palette', async () => {
const openSeerExplorer = jest.fn();
render(
<CommandPaletteProvider>
<CMDKAction to="/known/" display={{label: 'Known Action'}} />
<CommandPalette
{...makeRenderProps(jest.fn())}
openSeerExplorer={openSeerExplorer}
/>
</CommandPaletteProvider>
);

await userEvent.type(
screen.getByRole('searchbox', {name: 'Search commands'}),
'dsn'
);
await userEvent.keyboard('{Tab}');

expect(openSeerExplorer).toHaveBeenCalledWith({
initialQuery: 'dsn',
initialQueryReferrer: 'command_palette.tab',
});
});

it('tells Seer a no-results handoff came from the command palette', async () => {
const openSeerExplorer = jest.fn();
render(
<CommandPaletteProvider>
<CMDKAction to="/known/" display={{label: 'Known Action'}} />
<CommandPalette
{...makeRenderProps(jest.fn())}
openSeerExplorer={openSeerExplorer}
/>
</CommandPaletteProvider>
);

await userEvent.type(
screen.getByRole('searchbox', {name: 'Search commands'}),
'xyzzy'
);
await userEvent.click(await screen.findByRole('option', {name: 'Ask Seer: xyzzy'}));

expect(openSeerExplorer).toHaveBeenCalledWith({
initialQuery: 'xyzzy',
initialQueryReferrer: 'command_palette.no_results',
});
});

it('clearing the query restores all top-level items', async () => {
render(
<GlobalActionsComponent>
Expand Down
12 changes: 10 additions & 2 deletions static/app/components/commandPalette/ui/commandPalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {fzf} from 'sentry/utils/search/fzf';
import {normalizeUrl} from 'sentry/utils/url/normalizeUrl';
import {useFeedbackForm} from 'sentry/utils/useFeedbackForm';
import {useNavigate} from 'sentry/utils/useNavigate';
import type {SeerExplorerChatReferrer} from 'sentry/views/seerExplorer/types';

import type {CMDKActionData} from './cmdk';
import {CMDKCollection} from './cmdk';
Expand Down Expand Up @@ -91,7 +92,10 @@ interface CommandPaletteScore {
}

interface CommandPaletteProps extends ModalRenderProps {
openSeerExplorer?: (options?: {initialQuery?: string}) => void;
openSeerExplorer?: (options?: {
initialQuery?: string;
initialQueryReferrer?: SeerExplorerChatReferrer;
}) => void;
}

export function CommandPalette({
Expand Down Expand Up @@ -201,7 +205,10 @@ export function CommandPalette({
listItemType: 'action',
display: {label: t('Ask Seer: %s', state.query), icon: <IconSeer />},
onAction: () =>
openSeerExplorer?.({initialQuery: state.query.trim() || undefined}),
openSeerExplorer?.({
initialQuery: state.query.trim() || undefined,
initialQueryReferrer: 'command_palette.no_results',
}),
},
...(openForm
? [
Expand Down Expand Up @@ -422,6 +429,7 @@ export function CommandPalette({
closeModal?.();
openSeerExplorer({
initialQuery: state.query.trim() || undefined,
initialQueryReferrer: 'command_palette.tab',
});
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ describe('SeerDrawerNextStep', () => {
setSidebarPosition: jest.fn(),
sidebarAppendInitialQuery: false,
sidebarInitialQuery: undefined,
sidebarInitialQueryReferrer: undefined,
sidebarKey: 0,
sidebarPosition: 'auto',
toggleSeerExplorer: jest.fn(),
Expand Down
7 changes: 6 additions & 1 deletion static/app/utils/analytics/seerAnalyticsEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import type {
PullRequestReviewStatus,
} from 'sentry/types/integrations';
import type {Organization} from 'sentry/types/organization';
import type {SeerExplorerRunId} from 'sentry/views/seerExplorer/types';
import type {
SeerExplorerChatReferrer,
SeerExplorerRunId,
} from 'sentry/views/seerExplorer/types';

type InvestigationActionRequestEvent = {
action_kind: string;
Expand Down Expand Up @@ -227,6 +230,8 @@ export type SeerAnalyticsEventsParameters = {
'seer.explorer.session_created': {
referrer: string;
surface: 'global_panel';
/** The UI entry point that started the chat, when it was recorded. */
entry_point?: SeerExplorerChatReferrer;
};
'seer.explorer.session_link_copied': Record<string, unknown>;
'seer.explorer.sidebar.position_changed': {
Expand Down
1 change: 1 addition & 0 deletions static/app/views/navigation/topBar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ describe('TopBar', () => {
setSidebarPosition: jest.fn(),
sidebarAppendInitialQuery: false,
sidebarInitialQuery: undefined,
sidebarInitialQueryReferrer: undefined,
sidebarKey: 0,
sidebarPosition: 'auto',
toggleSeerExplorer: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {DrawerHeader, useDrawerContentContext} from '@sentry/scraps/drawer';

import {SeerExplorerContent} from 'sentry/views/seerExplorer/components/seerExplorerContent';
import type {SeerExplorerChatReferrer} from 'sentry/views/seerExplorer/types';

/**
* Drawer surface for Seer Explorer: renders the shared content with the drawer's
Expand All @@ -15,18 +16,21 @@ import {SeerExplorerContent} from 'sentry/views/seerExplorer/components/seerExpl
export function ExplorerDrawerContent({
getPageReferrer,
initialQuery,
initialQueryReferrer,
appendInitialQuery,
}: {
getPageReferrer: () => string;
appendInitialQuery?: boolean;
initialQuery?: string;
initialQueryReferrer?: SeerExplorerChatReferrer;
}) {
const {onClose = () => {}} = useDrawerContentContext();

return (
<SeerExplorerContent
getPageReferrer={getPageReferrer}
initialQuery={initialQuery}
initialQueryReferrer={initialQueryReferrer}
appendInitialQuery={appendInitialQuery}
onClose={onClose}
renderHeader={({children, isPoppedOut}) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {isSeerExplorerEnabled} from 'sentry/utils/seer/isSeerExplorerEnabled';
import {useOrganization} from 'sentry/utils/useOrganization';
import type {ChatPrompt} from 'sentry/views/seerExplorer/chatPrompt';
import {useSeerExplorerChatDispatch} from 'sentry/views/seerExplorer/seerExplorerChatStateContext';
import type {SeerExplorerRunId} from 'sentry/views/seerExplorer/types';
import type {
SeerExplorerChatReferrer,
SeerExplorerRunId,
} from 'sentry/views/seerExplorer/types';
import {usePageReferrer} from 'sentry/views/seerExplorer/utils';

import {ExplorerDrawerContent} from './explorerDrawerContent';
Expand All @@ -32,6 +35,8 @@ export type OpenSeerExplorerDrawerOptions = {
* an empty session, or the open one with `appendToOpenRun`.
*/
initialQuery?: string;
/** Where `initialQuery` came from, recorded on the run it starts. */
initialQueryReferrer?: SeerExplorerChatReferrer;
/**
* Optional run ID to open. If provided, opens an existing session.
*/
Expand Down Expand Up @@ -75,7 +80,12 @@ export const useSeerExplorerDrawer = (options?: {onClose?: () => void}) => {

const openSeerExplorerDrawer = useCallback(
(drawerOptions?: OpenSeerExplorerDrawerOptions) => {
const {runId: openRunId, initialQuery, appendToOpenRun} = drawerOptions ?? {};
const {
runId: openRunId,
initialQuery,
initialQueryReferrer,
appendToOpenRun,
} = drawerOptions ?? {};

if (initialQuery) {
// A forwarded query starts a fresh session unless the caller asked to
Expand All @@ -94,6 +104,7 @@ export const useSeerExplorerDrawer = (options?: {onClose?: () => void}) => {
<ExplorerDrawerContent
getPageReferrer={getPageReferrer}
initialQuery={initialQuery}
initialQueryReferrer={initialQueryReferrer}
appendInitialQuery={appendToOpenRun}
/>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,13 @@ describe('SeerExplorerContent', () => {
// The explicit null run id is what forces a fresh run rather than a post
// into the run that just failed.
await waitFor(() => {
expect(sendMessage).toHaveBeenCalledWith('why is this slow?', 0, null);
expect(sendMessage).toHaveBeenCalledWith(
'why is this slow?',
0,
null,
undefined,
undefined
);
});
});
});
Expand Down Expand Up @@ -2225,7 +2231,13 @@ describe('SeerExplorerContent', () => {
renderContent({initialQuery: 'why is this slow?'});

await waitFor(() => {
expect(sendMessage).toHaveBeenCalledWith('why is this slow?', 0);
expect(sendMessage).toHaveBeenCalledWith(
'why is this slow?',
0,
undefined,
undefined,
undefined
);
});
expect(creditCheck).toHaveBeenCalledTimes(1);
expect(
Expand Down Expand Up @@ -2260,7 +2272,13 @@ describe('SeerExplorerContent', () => {
answerCreditCheck();

await waitFor(() => {
expect(sendMessage).toHaveBeenCalledWith('why is this slow?', 0);
expect(sendMessage).toHaveBeenCalledWith(
'why is this slow?',
0,
undefined,
undefined,
undefined
);
});
expect(sendMessage).toHaveBeenCalledTimes(1);
expect(textarea).toHaveTextContent('my own question');
Expand Down Expand Up @@ -2316,7 +2334,13 @@ describe('SeerExplorerContent', () => {
answerCreditCheck();

await waitFor(() => {
expect(sendMessage).toHaveBeenCalledWith('why is this slow?', 0);
expect(sendMessage).toHaveBeenCalledWith(
'why is this slow?',
0,
undefined,
undefined,
undefined
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import type {
Block,
ChatSuggestion,
PendingUserInput,
SeerExplorerChatReferrer,
SeerExplorerRunId,
SeerExplorerSidebarPosition,
} from 'sentry/views/seerExplorer/types';
Expand Down Expand Up @@ -141,6 +142,7 @@ function SidebarHeaderShell({
export function SeerExplorerContent({
getPageReferrer,
initialQuery,
initialQueryReferrer,
appendInitialQuery,
onClose,
renderHeader,
Expand All @@ -153,6 +155,8 @@ export function SeerExplorerContent({
/** Submit `initialQuery` into the open run rather than only an empty one. */
appendInitialQuery?: boolean;
initialQuery?: string;
/** Where `initialQuery` came from, recorded on the run it starts. */
initialQueryReferrer?: SeerExplorerChatReferrer;
onSidebarPositionChange?: (position: SeerExplorerSidebarPosition) => void;
/** Surface chrome for the header. Defaults to the sidebar shell. */
renderHeader?: RenderHeader;
Expand Down Expand Up @@ -502,12 +506,13 @@ export function SeerExplorerContent({
if (showLoadError) {
// The open run failed to load, so appending to it would post into a dead run.
// A forwarded query still deserves an answer: start it in a fresh one.
sendMessage(query, 0, null);
sendMessage(query, 0, null, undefined, initialQueryReferrer);
return;
}
sendMessage(query, blocks.length);
sendMessage(query, blocks.length, undefined, undefined, initialQueryReferrer);
}, [
initialQuery,
initialQueryReferrer,
appendInitialQuery,
isEmptyState,
isCheckingCredits,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function SeerExplorerPanel() {
sidebarPosition,
setSidebarPosition,
sidebarInitialQuery,
sidebarInitialQueryReferrer,
sidebarAppendInitialQuery,
sidebarKey,
} = useSeerExplorerContext();
Expand All @@ -29,6 +30,7 @@ export function SeerExplorerPanel() {
key={sidebarKey}
getPageReferrer={getPageReferrer}
initialQuery={sidebarInitialQuery}
initialQueryReferrer={sidebarInitialQueryReferrer}
appendInitialQuery={sidebarAppendInitialQuery}
onClose={closeSeerExplorer}
sidebarPosition={sidebarPosition}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,15 +401,21 @@ describe('SeerExplorerSidebarLayout', () => {

it('auto-submits an initialQuery when opened (command palette)', async () => {
mockWideScreen(true);
renderSidebar(orgWithSidebar, {initialQuery: 'find the bug'});
renderSidebar(orgWithSidebar, {
initialQuery: 'find the bug',
initialQueryReferrer: 'command_palette.tab',
});

await userEvent.click(screen.getByText('open-seer'));

expect(await screen.findByTestId('seer-explorer-input')).toBeInTheDocument();
await waitFor(() =>
expect(defaultHookReturn.sendMessage).toHaveBeenCalledWith(
'find the bug',
expect.any(Number)
expect.any(Number),
undefined,
undefined,
'command_palette.tab'
)
);
});
Expand Down
Loading
Loading