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: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build output
dist/
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"clean": "turbo run clean:build",
"prepublishOnly": "npm run build",
"lint-staged": "npx lint-staged",
"test": "node scripts/test-summary.js",
"test:run": "node scripts/test-summary.js",
"test": "turbo run build && node scripts/test-summary.js",
"test:run": "turbo run build && node scripts/test-summary.js",
"test:manual": "npm run build && npm run inspector",
"test:e2e": "vitest run test/e2e/",
"test:watch": "turbo run test",
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build output
dist/
2 changes: 2 additions & 0 deletions packages/content-loader/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build output
dist/
5 changes: 4 additions & 1 deletion packages/core/.prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Build output
dist/

# Test fixtures that are intentionally malformed
src/__tests__/fixtures/malformed.yaml
src/__tests__/fixtures/invalid-*.yaml
src/__tests__/fixtures/invalid-*.yaml
2 changes: 2 additions & 0 deletions packages/mcp-server/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build output
dist/
80 changes: 60 additions & 20 deletions packages/mcp-server/src/__tests__/performance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe("Performance Requirements", () => {
version: "1.0"
docsets:
- id: "test-docs"
name: "Test Documentation"
name: "Test Documentation"
description: "Test documentation for performance tests"
local_path: "./docs"
template: "Search for '{{pattern}}' in {{local_path}}."
Expand All @@ -43,15 +43,39 @@ template: "Search for '{{pattern}}' in {{local_path}}."

describe("Response Time Requirements (<10ms after config load)", () => {
it("should create server instance quickly", async () => {
const start = process.hrtime.bigint();
const server = createAgenticKnowledgeServer();
const end = process.hrtime.bigint();
const time = Number(end - start) / 1000000; // Convert to ms
// A single cold measurement also captures module initialisation and JIT
// warm-up, which on a contended CI runner can easily exceed a 10ms
// budget and make this test flaky. Warm up first, then assert on the
// median of several samples against a threshold that is generous enough
// to survive a slow runner while still catching real regressions
// (steady-state creation is well under 1ms).
const WARMUP_RUNS = 3;
const SAMPLE_RUNS = 9;
const MAX_MEDIAN_MS = 50;

for (let i = 0; i < WARMUP_RUNS; i++) {
expect(createAgenticKnowledgeServer()).toBeDefined();
}

const samples: number[] = [];
for (let i = 0; i < SAMPLE_RUNS; i++) {
const start = process.hrtime.bigint();
const server = createAgenticKnowledgeServer();
const end = process.hrtime.bigint();

expect(server).toBeDefined();
samples.push(Number(end - start) / 1_000_000); // ns -> ms
}

samples.sort((a, b) => a - b);
const median = samples[Math.floor(samples.length / 2)]!;

expect(median).toBeLessThan(MAX_MEDIAN_MS);

expect(server).toBeDefined();
expect(time).toBeLessThan(10); // Server creation should be very fast

console.log(`Server creation time: ${time.toFixed(2)}ms`);
console.log(
`Server creation time: median ${median.toFixed(2)}ms ` +
`(min ${samples[0]!.toFixed(2)}ms, max ${samples[samples.length - 1]!.toFixed(2)}ms)`,
);
});

it("should demonstrate caching behavior improves performance", async () => {
Expand All @@ -77,19 +101,35 @@ template: "Search for '{{pattern}}' in {{local_path}}."
});

it("should meet memory usage requirements", () => {
// Basic memory usage validation
const beforeMemory = process.memoryUsage();
const server = createAgenticKnowledgeServer();
const afterMemory = process.memoryUsage();

const memoryDiff = afterMemory.heapUsed - beforeMemory.heapUsed;

expect(server).toBeDefined();
// Server creation should not use excessive memory (less than 10MB)
expect(memoryDiff).toBeLessThan(10 * 1024 * 1024);
// A heapUsed delta around a single cheap call is dominated by GC noise:
// it can come out negative, or spike if a collection happens to land
// between the two samples. Measure the aggregate growth across many
// creations instead, so the real allocation cost dominates the noise,
// and assert a per-server budget.
const SERVER_COUNT = 50;
const MAX_BYTES_PER_SERVER = 1024 * 1024; // 1MB

const servers = [];
const beforeMemory = process.memoryUsage().heapUsed;
for (let i = 0; i < SERVER_COUNT; i++) {
servers.push(createAgenticKnowledgeServer());
}
const afterMemory = process.memoryUsage().heapUsed;

// Keep the references alive so nothing is collected before we sample.
expect(servers).toHaveLength(SERVER_COUNT);
for (const server of servers) {
expect(server).toBeDefined();
}

const totalDiff = afterMemory - beforeMemory;
const perServer = totalDiff / SERVER_COUNT;

expect(perServer).toBeLessThan(MAX_BYTES_PER_SERVER);

console.log(
`Memory usage for server creation: ${(memoryDiff / 1024 / 1024).toFixed(2)}MB`,
`Memory usage for server creation: ${(perServer / 1024).toFixed(1)}KB per server ` +
`(${(totalDiff / 1024 / 1024).toFixed(2)}MB total for ${SERVER_COUNT})`,
);
});
});
Expand Down
Loading
Loading