Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export type AssistantMessage = UIMessage & {
* Used for warning messages in cases like using non-genuine MongoDB.
*/
isPermanent?: boolean;
/** The source of the message (i.e. the entry point used) */
source?: 'explain plan' | 'performance insights' | 'connection error';
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if we should treat normal typed prompts as an "entry point" and then this becomes required and we can easily segment all messages. Like I'm worried about the "ergonomics" of filtering by no source and the ambiguity introduced by a field that's not there. Maybe a question for the analytics team?

Copy link
Contributor

Choose a reason for hiding this comment

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

Similar question for spaces in the value. Wondering if that's going to be annoying to filter on in their interface. But that's a super minor nit.

/** Information for confirmation messages. */
confirmation?: {
description: string;
Expand Down Expand Up @@ -182,7 +184,10 @@ export const AssistantProvider: React.FunctionComponent<
void assistantActionsContext.current.ensureOptInAndSend(
{
text: prompt,
metadata,
metadata: {
...metadata,
source: entryPointName,
},
},
{},
() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ describe('AssistantChat', function () {
sourceId: '1',
},
],
metadata: {
source: 'performance insights',
},
},
];

Expand Down Expand Up @@ -440,6 +443,7 @@ describe('AssistantChat', function () {
feedback: 'positive',
text: undefined,
request_id: null,
source: 'performance insights',
});
});
});
Expand All @@ -466,6 +470,7 @@ describe('AssistantChat', function () {
feedback: 'negative',
text: undefined,
request_id: null,
source: 'performance insights',
});
});
});
Expand Down Expand Up @@ -502,12 +507,14 @@ describe('AssistantChat', function () {
feedback: 'negative',
text: undefined,
request_id: null,
source: 'performance insights',
});

expect(track).to.have.been.calledWith('Assistant Feedback Submitted', {
feedback: 'negative',
text: 'This response was not helpful',
request_id: null,
source: 'performance insights',
});
});
});
Expand Down Expand Up @@ -547,6 +554,7 @@ describe('AssistantChat', function () {
state: 'pending',
description: 'Are you sure you want to proceed with this action?',
},
source: 'performance insights',
},
};
});
Expand Down Expand Up @@ -763,6 +771,42 @@ describe('AssistantChat', function () {
expect(screen.queryByText('Cancel')).to.not.exist;
expect(screen.getByText('This is a regular message')).to.exist;
});

it('tracks confirmation submitted when confirm button is clicked', async function () {
const { result } = renderWithChat([mockConfirmationMessage]);
const { track } = result;

const confirmButton = screen.getByText('Confirm');
userEvent.click(confirmButton);

await waitFor(() => {
expect(track).to.have.been.calledWith(
'Assistant Confirmation Submitted',
{
status: 'confirmed',
source: 'performance insights',
}
);
});
});

it('tracks confirmation submitted when cancel button is clicked', async function () {
const { result } = renderWithChat([mockConfirmationMessage]);
const { track } = result;

const cancelButton = screen.getByText('Cancel');
userEvent.click(cancelButton);

await waitFor(() => {
expect(track).to.have.been.calledWith(
'Assistant Confirmation Submitted',
{
status: 'rejected',
source: 'performance insights',
}
);
});
});
});

describe('related sources', function () {
Expand Down
24 changes: 18 additions & 6 deletions packages/compass-assistant/src/components/assistant-chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,11 @@ export const AssistantChat: React.FunctionComponent<AssistantChatProps> = ({
);

const handleFeedback = useCallback(
(
event,
({
state,
message,
}: {
message: AssistantMessage;
state:
| {
feedback: string;
Expand All @@ -205,8 +208,8 @@ export const AssistantChat: React.FunctionComponent<AssistantChatProps> = ({
| {
rating: string;
}
| undefined
) => {
| undefined;
}) => {
if (!state) {
return;
}
Expand All @@ -219,6 +222,7 @@ export const AssistantChat: React.FunctionComponent<AssistantChatProps> = ({
feedback,
text: textFeedback,
request_id: null,
source: message.metadata?.source,
});
},
[track]
Expand Down Expand Up @@ -262,6 +266,10 @@ export const AssistantChat: React.FunctionComponent<AssistantChatProps> = ({
}
return newMessages;
});
track('Assistant Confirmation Submitted', {
status: newState,
source: confirmedMessage.metadata?.source,
});
if (newState === 'confirmed') {
// Force the new message request to be sent
void ensureOptInAndSend?.(undefined, {}, () => {});
Expand Down Expand Up @@ -336,8 +344,12 @@ export const AssistantChat: React.FunctionComponent<AssistantChatProps> = ({
>
{isSender === false && (
<Message.Actions
onRatingChange={handleFeedback}
onSubmitFeedback={handleFeedback}
onRatingChange={(event, state) =>
handleFeedback({ message, state })
}
onSubmitFeedback={(event, state) =>
handleFeedback({ message, state })
}
/>
)}
{sources.length > 0 && <Message.Links links={sources} />}
Expand Down
23 changes: 19 additions & 4 deletions packages/compass-telemetry/src/telemetry-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,18 @@ type AssistantPromptSubmittedEvent = CommonEvent<{
};
}>;

/**
* This event is fired when a user uses an assistant entry point.
*
* @category Gen AI
*/
type AssistantEntryPointUsedEvent = CommonEvent<{
name: 'Assistant Entry Point Used';
payload: {
source: 'explain plan' | 'performance insights' | 'connection error';
};
}>;

/**
* This event is fired when a user submits feedback for the assistant.
*
Expand All @@ -1482,18 +1494,20 @@ type AssistantFeedbackSubmittedEvent = CommonEvent<{
feedback: 'positive' | 'negative';
text: string | undefined;
request_id: string | null;
source: AssistantEntryPointUsedEvent['payload']['source'] | undefined;
};
}>;

/**
* This event is fired when a user uses an assistant entry point.
* This event is fired when a user confirms a confirmation message in the assistant chat.
*
* @category Gen AI
*/
type AssistantEntryPointUsedEvent = CommonEvent<{
name: 'Assistant Entry Point Used';
type AssistantConfirmationSubmittedEvent = CommonEvent<{
name: 'Assistant Confirmation Submitted';
payload: {
source: 'explain plan' | 'performance insights' | 'connection error';
status: 'confirmed' | 'rejected';
source: AssistantEntryPointUsedEvent['payload']['source'] | undefined;
};
}>;

Expand Down Expand Up @@ -3032,6 +3046,7 @@ export type TelemetryEvent =
| AssistantResponseFailedEvent
| AssistantFeedbackSubmittedEvent
| AssistantEntryPointUsedEvent
| AssistantConfirmationSubmittedEvent
| AiOptInModalShownEvent
| AiOptInModalDismissedEvent
| AiGenerateQueryClickedEvent
Expand Down
Loading