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
5 changes: 5 additions & 0 deletions .changeset/smart-nails-mix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mermaidchart/sdk': patch
---

Add a regenerate method to the SDK that complements our Mermaid Diagram Sync GitHub App functionality. This method should accept the existing Mermaid diagram content along with source file changes, and regenerate the diagram based on those updates while preserving the overall diagram structure and intent.
43 changes: 43 additions & 0 deletions packages/sdk/src/index.e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,46 @@ describe('suggestPrSummary', () => {
}
}, 60000); // 60 seconds timeout for AI operations
});

describe('regenerateDiagram', () => {
it('should regenerate a diagram from updated source files', async () => {
const code = `flowchart TD\n A[Start] --> B[Process]\n B --> C[End]`;
const sourceFiles = [
'function processOrder(order) {\n validateOrder(order);\n shipOrder(order);\n}',
];

try {
const creditsBefore = await client.getAICredits();

const result = await client.regenerateDiagram({
code,
sourceFiles,
});

// Verify response structure
expect(result).toHaveProperty('result');
expect(result).toHaveProperty('code');
expect(['ok', 'fail']).toContain(result.result);
Comment thread
aloisklink marked this conversation as resolved.

// When the AI successfully regenerates the diagram, creditUsage should be present
// and credits should have been deducted
if (result.result === 'ok' && result.solved === true) {
expect(result.creditUsage).toMatchObject({
creditsToDeduct: expect.any(Number),
baseCost: expect.any(Number),
reason: expect.any(String),
});

const creditsAfter = await client.getAICredits();
expect(creditsAfter.aiCredits.remaining).toBe(
creditsBefore.aiCredits.remaining - result.creditUsage!.creditsToDeduct,
);
}
} catch (error) {
if (error instanceof AICreditsLimitExceededError) {
return; // Credits exceeded is acceptable for E2E test
}
throw error;
}
}, 60000); // 60 seconds timeout for AI operations
});
22 changes: 22 additions & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import type {
RepairDiagramResponse,
PrSummaryRequest,
PrSummaryResponse,
RegenerateDiagramRequest,
RegenerateDiagramResponse,
AICreditsUsage,
} from './types.js';
import { URLS } from './urls.js';
Expand Down Expand Up @@ -351,6 +353,26 @@ export class MermaidChart {
}
}

/**
* Regenerates a Mermaid diagram based on updated source files using AI.
*
* @param request - `code` (current diagram source) and `sourceFiles` (full contents of related source files)
* @throws {@link AICreditsLimitExceededError} if credits limit exceeded (HTTP 402)
*/
public async regenerateDiagram(
request: RegenerateDiagramRequest,
): Promise<RegenerateDiagramResponse> {
try {
const response = await this.axios.post<RegenerateDiagramResponse>(
URLS.rest.openai.regenerate,
request,
Comment thread
Prashant-7718 marked this conversation as resolved.
);
return response.data;
} catch (error: unknown) {
throwIfAICreditsExceeded(error);
}
}

/**
* Chat with Mermaid AI about a diagram.
*
Expand Down
36 changes: 36 additions & 0 deletions packages/sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,42 @@ export interface PrSummaryResponse {
commitMessage: string;
}

/**
* Request parameters for regenerating a Mermaid diagram from updated source files.
*/
export interface RegenerateDiagramRequest {
/** The current Mermaid diagram source to be regenerated. */
code: string;
/** Ordered full contents of the source files that the diagram is based on. */
sourceFiles: string[];
}

/**
* Response from regenerating a Mermaid diagram.
*/
export interface RegenerateDiagramResponse {
/**
* The status of the regeneration: 'ok' if a valid mermaid code block was generated, 'fail' otherwise.
*/
result: 'ok' | 'fail';
/**
* Markdown message that may contain a valid mermaid code block.
*/
code: string;
/**
* Whether the diagram regeneration was successful.
*/
solved?: boolean;
/**
* Credit usage for client-side deduction (only present when solved).
*/
creditUsage?: {
creditsToDeduct: number;
baseCost: number;
reason: string;
};
}

/**
* Request parameters for chatting with the Mermaid AI about a diagram.
*/
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const URLS = {
openai: {
repair: `/rest-api/openai/repair`,
prSummary: `/rest-api/openai/pr-summary`,
regenerate: `/rest-api/openai/regenerate`,
chat: `/rest-api/openai/chat`,
},
},
Expand Down
Loading