minimax-image-adapter.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * MiniMax Image Generation Adapter
  3. * Supports: text-to-image with aspect ratio control
  4. * API Docs: https://platform.minimaxi.com/docs/api-reference/image-generation-t2i
  5. */
  6. import type {
  7. ImageGenerationConfig,
  8. ImageGenerationOptions,
  9. ImageGenerationResult,
  10. } from '../types';
  11. const BASE_URL = 'https://api.minimaxi.com';
  12. export async function generateWithMiniMaxImage(
  13. config: ImageGenerationConfig,
  14. options: ImageGenerationOptions,
  15. ): Promise<ImageGenerationResult> {
  16. const baseUrl = (config.baseUrl || BASE_URL).replace(/\/$/, '');
  17. const model = config.model || 'image-01';
  18. const aspectRatio = options.aspectRatio || '1:1';
  19. const response = await fetch(`${baseUrl}/v1/image_generation`, {
  20. method: 'POST',
  21. headers: {
  22. Authorization: `Bearer ${config.apiKey}`,
  23. 'Content-Type': 'application/json; charset=utf-8',
  24. },
  25. body: JSON.stringify({
  26. model,
  27. prompt: options.prompt,
  28. negative_prompt: options.negativePrompt,
  29. aspect_ratio: aspectRatio,
  30. response_format: 'url',
  31. n: 1,
  32. prompt_optimizer: false,
  33. }),
  34. });
  35. if (!response.ok) {
  36. const errText = await response.text().catch(() => response.statusText);
  37. throw new Error(`MiniMax Image API error: ${errText}`);
  38. }
  39. const data = await response.json();
  40. // Check for error response
  41. if (data?.base_resp?.status_code !== 0 && data?.base_resp?.status_code !== undefined) {
  42. const code = data.base_resp.status_code;
  43. const msg = data.base_resp.status_msg || 'unknown error';
  44. throw new Error(`MiniMax Image API error ${code}: ${msg}`);
  45. }
  46. const imageUrls = data?.data?.image_urls;
  47. if (!imageUrls || imageUrls.length === 0) {
  48. throw new Error(`MiniMax Image: no image URLs returned. Response: ${JSON.stringify(data)}`);
  49. }
  50. const imageUrl = imageUrls[0];
  51. // Determine dimensions from aspect ratio
  52. let width = options.width || 1024;
  53. let height = options.height || 1024;
  54. if (!options.width && !options.height) {
  55. const [w, h] = aspectRatio.split(':').map(Number);
  56. if (w && h) {
  57. if (w > h) {
  58. width = 1024;
  59. height = Math.round((1024 * h) / w);
  60. } else {
  61. height = 1024;
  62. width = Math.round((1024 * w) / h);
  63. }
  64. }
  65. }
  66. return {
  67. url: imageUrl,
  68. width,
  69. height,
  70. };
  71. }
  72. export async function testMiniMaxImageConnectivity(
  73. config: ImageGenerationConfig,
  74. ): Promise<{ success: boolean; message: string }> {
  75. try {
  76. const baseUrl = (config.baseUrl || BASE_URL).replace(/\/$/, '');
  77. const response = await fetch(`${baseUrl}/v1/image_generation`, {
  78. method: 'POST',
  79. headers: {
  80. Authorization: `Bearer ${config.apiKey}`,
  81. 'Content-Type': 'application/json; charset=utf-8',
  82. },
  83. body: JSON.stringify({
  84. model: 'image-01',
  85. prompt: 'test',
  86. aspect_ratio: '1:1',
  87. n: 1,
  88. }),
  89. });
  90. if (response.ok) {
  91. return { success: true, message: 'MiniMax Image API connected' };
  92. }
  93. const errData = await response.json().catch(() => ({}));
  94. const msg = errData?.base_resp?.status_msg || response.statusText;
  95. return { success: false, message: `API error: ${msg}` };
  96. } catch (err) {
  97. return { success: false, message: `Connection failed: ${(err as Error).message}` };
  98. }
  99. }