Skip to content

Conversation

@mabaasit
Copy link
Collaborator

@mabaasit mabaasit commented Dec 3, 2025

Description

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • If this change could impact the load on the MongoDB cluster, please describe the expected and worst case impact
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Motivation and Context

  • Bugfix
  • New feature
  • Dependency update
  • Misc

Open Questions

Dependents

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

@mabaasit mabaasit requested a review from a team as a code owner December 3, 2025 12:44
@github-actions github-actions bot added the feat label Dec 3, 2025
@mabaasit mabaasit added feature flagged PRs labeled with this label will not be included in the release notes of the next release no release notes Fix or feature not for release notes labels Dec 3, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR integrates the chatbot API for generative AI query functionality in MongoDB Compass, replacing the previous implementation with a new endpoint. The changes introduce XML response parsing, update authentication headers for service requests, and add comprehensive E2E testing for the new chatbot integration.

Key Changes:

  • Introduces new chatbot API client using OpenAI SDK to generate MongoDB queries
  • Adds XML-to-JSON response parser to handle chatbot responses
  • Updates service providers with request origin headers for tracking

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/compass/src/app/components/entrypoint.tsx Adds 'X-Request-Origin' header for Compass desktop
packages/compass-web/src/entrypoint.tsx Adds 'X-Request-Origin' header for Atlas Data Explorer
packages/compass-generative-ai/src/utils/xml-to-mms-response.ts Implements XML parsing logic to convert chatbot responses to expected format
packages/compass-generative-ai/src/utils/xml-to-mms-response.spec.ts Adds comprehensive test coverage for XML parser
packages/compass-generative-ai/src/utils/gen-ai-response.ts Implements chatbot API response streaming handler
packages/compass-generative-ai/src/utils/gen-ai-prompt.ts Renames parameter from 'userPrompt' to 'userInput' for consistency
packages/compass-generative-ai/src/utils/gen-ai-prompt.spec.ts Updates tests to reflect parameter rename
packages/compass-generative-ai/src/chatbot-errors.ts Defines error classes for chatbot API failures
packages/compass-generative-ai/src/atlas-ai-service.ts Integrates chatbot client and adds feature flag for new endpoint
packages/compass-generative-ai/src/atlas-ai-service.spec.ts Updates mock service with assistant endpoint method
packages/compass-generative-ai/package.json Moves mongodb-query-parser to dependencies and adds AI SDK packages
packages/compass-e2e-tests/tests/collection-ai-query.test.ts Adds E2E tests for chatbot-based query generation
packages/compass-e2e-tests/helpers/assistant-service.ts Fixes header order in mock server response

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codeowners-service-app
Copy link

Assigned gagik for team compass-developers because gribnoysup is out of office.

import type { LanguageModel } from 'ai';
import { streamText } from 'ai';

export async function getAiQueryResponse(
Copy link
Contributor

Choose a reason for hiding this comment

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

I know packages/compass-assistant/src/docs-provider-transport.ts is in entirely different path of code but wondering if one or the other should live closer together since there is some tie-in there.
I'm fine as is too though

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, good point. Initially I adopted that here as well and then remove it in clean up transport. I want to do a follow-up when this project ends and use the class removed in clean up transport commit. That will be exported by this package and will be used by the assistant.

import type { Logger } from '@mongodb-js/compass-logging';
import parse, { toJSString } from 'mongodb-query-parser';

export function parseXmlToMmsJsonResponse(xmlString: string, logger: Logger) {
Copy link
Contributor

Choose a reason for hiding this comment

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

MmsJsonResponse feels like a technical detail to me; without context of the old assistant API I wouldn't understand what this meant.
Can we also add add a return type to this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added in add type

Copy link
Collaborator

@gribnoysup gribnoysup left a comment

Choose a reason for hiding this comment

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

A few nits, but otherwise LGTM. We're planning to re-export the transport later down the road so that compass-assistant can depend on it isntead of having a copy, is that right?

Comment on lines 60 to 61
export type UserPromptForQueryOptions = {
userPrompt: string;
userInput: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: naming is slightly inconsistent, if you're changing userPrompt to userInput, then the type name should also change maybe?

Comment on lines 24 to 25
const reader = response.getReader();
while (!done) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: the for await loop would be a more idiomatic way to deal with an async iterator I think

Suggested change
const reader = response.getReader();
while (!done) {
for await (const chunk of response) {

import { parseXmlToMmsJsonResponse } from './xml-to-mms-response';
import type { Logger } from '@mongodb-js/compass-logging';

const loggerMock = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: this is what we have createNoopLogger for

Comment on lines 41 to 43
for (const tag of expectedTags) {
const regex = new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`, 'i');
const match = xmlString.match(regex);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably fine to roll our own "parser" here, but just FYI DOMParser browser API exists

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added this in clean up error, names. This however requires me to add top-level tag to the string so that its parsable.


export class AiChatbotInvalidResponseError extends AiChatbotError {
constructor(message: string) {
super(500, message, 'INVALID_RESPONSE');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't we want to preserve the original server response code instead of hardcoding 500?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a bit tricky one. This is thrown when the server returns an error while streaming. I was unable to recreate this use-case locally and I am not how the server responds with error in this case (what's contained in chunk.errorText). I think its fine if we throw 500 because we are not streaming response to the query bar.

@@ -0,0 +1,20 @@
export class AiChatbotError extends Error {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a copy of AtlasServiceError that we export from the atlas-service package? This package depends on service already, can we just import it?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Naming nit: we don't usually use mms for naming in the codebase, it's an outdated term that is not really relevant here, especially as strictly speaking I guess this is not even an "mms response", it's just xml with selected fields parsed to json. There's probably a better name for that

@mabaasit
Copy link
Collaborator Author

mabaasit commented Dec 8, 2025

We're planning to re-export the transport later down the road so that compass-assistant can depend on it isntead of having a copy, is that right?

Yes that's correct. I addressed the comments. Regarding using DOMParser I also added that and it required me to wrap the string in top-level node so that parsing does now throw.

@mabaasit
Copy link
Collaborator Author

mabaasit commented Dec 9, 2025

@gribnoysup I'll merge it for now and if there's something more that needs to be addressed, I'll handle that in upcoming PR.

@mabaasit mabaasit merged commit 76e37ab into main Dec 9, 2025
107 of 109 checks passed
@mabaasit mabaasit deleted the COMPASS-10081-switch-to-edu-api branch December 9, 2025 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat feature flagged PRs labeled with this label will not be included in the release notes of the next release no release notes Fix or feature not for release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants