-
Notifications
You must be signed in to change notification settings - Fork 245
chore(compass-assistant): add explain plan entry point COMPASS-9606 #7208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
261bfbc
efc4c44
8ac11d5
0e82ba8
b6bb19f
d030b3d
8c1436e
54dd010
8831559
bc1906e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,29 +5,73 @@ import { createContext, useContext } from 'react'; | |||||
| import { registerCompassPlugin } from '@mongodb-js/compass-app-registry'; | ||||||
| import { atlasServiceLocator } from '@mongodb-js/atlas-service/provider'; | ||||||
| import { DocsProviderTransport } from './docs-provider-transport'; | ||||||
| import { useDrawerActions } from '@mongodb-js/compass-components'; | ||||||
| import { buildExplainPlanPrompt } from './prompts'; | ||||||
| import { usePreference } from 'compass-preferences-model/provider'; | ||||||
|
|
||||||
| export const ASSISTANT_DRAWER_ID = 'compass-assistant-drawer'; | ||||||
|
|
||||||
| type AssistantContextType = Chat<UIMessage>; | ||||||
| export type AssistantMessage = UIMessage & { | ||||||
| metadata?: { | ||||||
| /** The text to display instead of the message text. */ | ||||||
| displayText?: string; | ||||||
| }; | ||||||
| }; | ||||||
|
|
||||||
| type AssistantContextType = Chat<AssistantMessage>; | ||||||
|
|
||||||
| export const AssistantContext = createContext<AssistantContextType | null>( | ||||||
| null | ||||||
| ); | ||||||
|
|
||||||
| type AssistantActionsContextType = unknown; | ||||||
| type AssistantActionsContextType = { | ||||||
| interpretExplainPlan: ({ | ||||||
| namespace, | ||||||
| explainPlan, | ||||||
| }: { | ||||||
| namespace: string; | ||||||
| explainPlan: string; | ||||||
| }) => void; | ||||||
| }; | ||||||
| export const AssistantActionsContext = | ||||||
| createContext<AssistantActionsContextType>({}); | ||||||
| createContext<AssistantActionsContextType>({ | ||||||
| interpretExplainPlan: () => {}, | ||||||
| }); | ||||||
|
|
||||||
| export function useAssistantActions(): AssistantActionsContextType { | ||||||
| return useContext(AssistantActionsContext); | ||||||
| export function useAssistantActions(): AssistantActionsContextType & { | ||||||
| isAssistantEnabled: boolean; | ||||||
| } { | ||||||
| const isAssistantEnabled = usePreference('enableAIAssistant'); | ||||||
|
|
||||||
| return { | ||||||
| ...useContext(AssistantActionsContext), | ||||||
| isAssistantEnabled, | ||||||
| }; | ||||||
| } | ||||||
|
|
||||||
| export const AssistantProvider: React.FunctionComponent< | ||||||
| PropsWithChildren<{ | ||||||
| chat: Chat<UIMessage>; | ||||||
| chat: Chat<AssistantMessage>; | ||||||
| }> | ||||||
| > = ({ chat, children }) => { | ||||||
| const assistantActionsContext = useRef<AssistantActionsContextType>(); | ||||||
| const assistantActionsContext = useRef<AssistantActionsContextType>({ | ||||||
| interpretExplainPlan: ({ explainPlan }) => { | ||||||
| openDrawer(ASSISTANT_DRAWER_ID); | ||||||
| const { prompt, displayText } = buildExplainPlanPrompt({ | ||||||
| explainPlan, | ||||||
| }); | ||||||
| void chat.sendMessage( | ||||||
|
||||||
| void chat.sendMessage( | |
| chat.sendMessage( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will be followed up later and handled with onError on useChat hook
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| export { CompassAssistantProvider } from './compass-assistant-provider'; | ||
| export { CompassAssistantDrawer } from './compass-assistant-drawer'; | ||
| export { useAssistantActions } from './compass-assistant-provider'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| export const buildExplainPlanPrompt = ({ | ||
| explainPlan, | ||
| }: { | ||
| explainPlan: string; | ||
| }) => { | ||
| return { | ||
| prompt: `Given the MongoDB explain plan output below, provide a concise human readable explanation that explains the query execution plan and highlights aspects of the plan that might impact query performance. Respond with as much concision and clarity as possible. | ||
| If a clear optimization should be made, please suggest the optimization and describe how it can be accomplished in MongoDB Compass. Do not advise users to create indexes without weighing the pros and cons. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm so skeptical about this 😆 |
||
| Explain output: | ||
| ${explainPlan}`, | ||
| displayText: 'Provide an explanation of this explain plan.', | ||
| }; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| import type { UIMessage } from 'ai'; | ||
| import { Chat } from '../src/@ai-sdk/react/chat-react'; | ||
| import sinon from 'sinon'; | ||
| import type { AssistantMessage } from '../src/compass-assistant-provider'; | ||
|
|
||
| export const createMockChat = ({ messages }: { messages: UIMessage[] }) => { | ||
| const newChat = new Chat<UIMessage>({ | ||
| export const createMockChat = ({ | ||
| messages, | ||
| }: { | ||
| messages: AssistantMessage[]; | ||
| }) => { | ||
| const newChat = new Chat<AssistantMessage>({ | ||
| messages, | ||
| }); | ||
| sinon.replace(newChat, 'sendMessage', sinon.stub()); | ||
| return newChat as unknown as Chat<UIMessage> & { | ||
| return newChat as unknown as Chat<AssistantMessage> & { | ||
| sendMessage: sinon.SinonStub; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The display logic uses a complex ternary expression that could be simplified for better readability. Consider extracting this into a helper function or variable to make the intent clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I would do this, but it is indeed nitpicky.