Skip to content

Commit bc8679c

Browse files
Merge pull request #45 from Mermaid-Chart/AT-416-add-new-tool-to-mcp-pr-summary-that-call-mermaid-ai-through-mermaid-sdk-and-collab
AT- 416 Added functionality to fetch PR title & description from Mermaid AI via pr-summary endpoint
2 parents a94f4a6 + 656f935 commit bc8679c

6 files changed

Lines changed: 119 additions & 0 deletions

File tree

.changeset/calm-berries-check.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@mermaidchart/sdk': patch
3+
---
4+
5+
Add a suggestPrSummary method to the SDK that generates PR details based on Mermaid diagram changes, including the branch name, title, commit message, and description.

packages/sdk/src/index.e2e.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,28 @@ describe('repairDiagram', () => {
242242
}
243243
}, 60000); // 60 seconds timeout for AI repair operations
244244
});
245+
246+
describe('suggestPrSummary', () => {
247+
it('should generate PR summary from diagram differences', async () => {
248+
const originalDiagram = `flowchart TD\n A[Start] --> B[Process]\n B --> C[End]`;
249+
const editedDiagram = `flowchart TD\n A[Start] --> B[Process]\n B --> D[Validate]\n D --> C[End]`;
250+
251+
try {
252+
const result = await client.suggestPrSummary({
253+
originalDiagram,
254+
editedDiagram,
255+
});
256+
257+
// Verify response structure
258+
expect(result).toHaveProperty('title');
259+
expect(result).toHaveProperty('description');
260+
expect(result).toHaveProperty('branchName');
261+
expect(result).toHaveProperty('commitMessage');
262+
} catch (error) {
263+
if (error instanceof AICreditsLimitExceededError) {
264+
return; // Credits exceeded is acceptable for E2E test
265+
}
266+
throw error;
267+
}
268+
}, 60000); // 60 seconds timeout for AI operations
269+
});

packages/sdk/src/index.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
22
import { MermaidChart } from './index.js';
33
import { AICreditsLimitExceededError } from './errors.js';
44
import type { AuthorizationData } from './types.js';
5+
import { URLS } from './urls.js';
56

67
import { OAuth2Client } from '@badgateway/oauth2-client';
78

@@ -171,4 +172,52 @@ describe('MermaidChart', () => {
171172
).rejects.toThrow(AICreditsLimitExceededError);
172173
});
173174
});
175+
176+
describe('#suggestPrSummary', () => {
177+
beforeEach(async () => {
178+
await client.setAccessToken('test-access-token');
179+
});
180+
181+
it('should POST to the pr-summary endpoint with the request body and return response.data', async () => {
182+
const jsonResponse = {
183+
title: 'Add validation step to flowchart',
184+
description: '## What changed\n- Added node C',
185+
branchName: 'feature/flowchart-validation',
186+
commitMessage: 'Add validation node C',
187+
};
188+
189+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
190+
const postSpy = vi.spyOn((client as any).axios, 'post').mockResolvedValue({
191+
data: jsonResponse,
192+
});
193+
194+
const requestBody = {
195+
originalDiagram: 'flowchart TD\n A --> B',
196+
editedDiagram: 'flowchart TD\n A --> B\n B --> C[Validate]',
197+
};
198+
199+
const result = await client.suggestPrSummary(requestBody);
200+
201+
expect(postSpy).toHaveBeenCalledWith(URLS.rest.openai.prSummary, requestBody);
202+
expect(result).toEqual(jsonResponse);
203+
});
204+
205+
it('should throw AICreditsLimitExceededError on 402', async () => {
206+
// Mock the underlying axios call so the error mapping in suggestPrSummary is exercised.
207+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
208+
vi.spyOn((client as any).axios, 'post').mockRejectedValue({
209+
response: {
210+
status: 402,
211+
data: 'AI credits limit exceeded',
212+
},
213+
});
214+
215+
await expect(
216+
client.suggestPrSummary({
217+
originalDiagram: 'flowchart TD\n A --> B',
218+
editedDiagram: 'flowchart TD\n A --> B\n B --> C',
219+
}),
220+
).rejects.toThrow(AICreditsLimitExceededError);
221+
});
222+
});
174223
});

packages/sdk/src/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import type {
1919
MCUser,
2020
RepairDiagramRequest,
2121
RepairDiagramResponse,
22+
PrSummaryRequest,
23+
PrSummaryResponse,
2224
AICreditsUsage,
2325
} from './types.js';
2426
import { URLS } from './urls.js';
@@ -330,6 +332,25 @@ export class MermaidChart {
330332
}
331333
}
332334

335+
/**
336+
* Suggests a pull request title and body (markdown) from a before/after diagram diff (Mermaid AI).
337+
* The response also includes `branchName` and `commitMessage`.
338+
*
339+
* @param request - `originalDiagram` and `editedDiagram` only
340+
* @throws {@link AICreditsLimitExceededError} if credits limit exceeded (HTTP 402)
341+
*/
342+
public async suggestPrSummary(request: PrSummaryRequest): Promise<PrSummaryResponse> {
343+
try {
344+
const response = await this.axios.post<PrSummaryResponse>(
345+
URLS.rest.openai.prSummary,
346+
request,
347+
);
348+
return response.data;
349+
} catch (error: unknown) {
350+
throwIfAICreditsExceeded(error);
351+
}
352+
}
353+
333354
/**
334355
* Chat with Mermaid AI about a diagram.
335356
*

packages/sdk/src/types.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ export interface RepairDiagramRequest {
9696
userID?: string;
9797
}
9898

99+
/**
100+
* Only the two diagram versions are sent; the server derives user plan and usage from the auth context provided by the access token.
101+
*/
102+
export interface PrSummaryRequest {
103+
originalDiagram: string;
104+
editedDiagram: string;
105+
}
106+
107+
/**
108+
* Public response: suggested PR title and markdown description, branch name, and commit message.
109+
*/
110+
export interface PrSummaryResponse {
111+
title: string;
112+
description: string;
113+
branchName: string;
114+
commitMessage: string;
115+
}
116+
99117
/**
100118
* Request parameters for chatting with the Mermaid AI about a diagram.
101119
*/

packages/sdk/src/urls.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const URLS = {
4141
},
4242
openai: {
4343
repair: `/rest-api/openai/repair`,
44+
prSummary: `/rest-api/openai/pr-summary`,
4445
chat: `/rest-api/openai/chat`,
4546
},
4647
},

0 commit comments

Comments
 (0)