Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/tools/mongodb/read/aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const genericPipelineDescription = "An array of aggregation stages to execute.";
export const getAggregateArgs = (vectorSearchEnabled: boolean) =>
({
pipeline: z
.array(vectorSearchEnabled ? z.union([AnyAggregateStage, VectorSearchStage]) : AnyAggregateStage)
.array(vectorSearchEnabled ? z.union([VectorSearchStage, AnyAggregateStage]) : AnyAggregateStage)
.describe(vectorSearchEnabled ? pipelineDescriptionWithVectorSearch : genericPipelineDescription),
responseBytesLimit: z.number().optional().default(ONE_MB).describe(`\
The maximum number of bytes to return in the response. This value is capped by the server's configured maxBytesPerQuery and cannot be exceeded. \
Expand Down
66 changes: 64 additions & 2 deletions tests/integration/tools/mongodb/read/aggregate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import * as constants from "../../../../../src/helpers/constants.js";
import { freshInsertDocuments } from "./find.test.js";
import { BSON } from "bson";
import { DOCUMENT_EMBEDDINGS } from "./vyai/embeddings.js";

describeWithMongoDB("aggregate tool", (integration) => {
afterEach(() => {
Expand Down Expand Up @@ -384,8 +385,6 @@ describeWithMongoDB(
}
);

import { DOCUMENT_EMBEDDINGS } from "./vyai/embeddings.js";

describeWithMongoDB(
"aggregate tool with atlas search enabled",
(integration) => {
Expand Down Expand Up @@ -921,6 +920,69 @@ If the user requests additional filtering, include filters in \`$vectorSearch.fi
);
});
});

describe("outputDimension transformation", () => {
it.each([
{ numDimensions: 2048, outputDimension: "2048" },
{ numDimensions: 4096, outputDimension: "4096" },
])(
"should successfully transform outputDimension string '$outputDimension' to number",
async ({ numDimensions, outputDimension }) => {
await waitUntilSearchIsReady(integration.mongoClient());

const collection = integration.mongoClient().db(integration.randomDbName()).collection("databases");
await collection.insertOne({ name: "mongodb", description_embedding: DOCUMENT_EMBEDDINGS.float });

await createVectorSearchIndexAndWait(
integration.mongoClient(),
integration.randomDbName(),
"databases",
[
{
type: "vector",
path: "description_embedding",
numDimensions,
similarity: "cosine",
quantization: "none",
},
]
);

await integration.connectMcpClient();
const response = await integration.mcpClient().callTool({
name: "aggregate",
arguments: {
database: integration.randomDbName(),
collection: "databases",
pipeline: [
{
$vectorSearch: {
index: "default",
path: "description_embedding",
queryVector: "example query",
numCandidates: 10,
limit: 10,
embeddingParameters: {
model: "voyage-3-large",
outputDimension, // Pass as string literal
},
},
},
{
$project: {
description_embedding: 0,
},
},
],
},
});

const responseContent = getResponseContent(response);
// String should succeed and be transformed to number internally
expect(responseContent).toContain("The aggregation resulted in");
}
);
});
},
{
getUserConfig: () => ({
Expand Down