(params: {
model: string;
contents: any[];
})
| 661 | } |
| 662 | |
| 663 | async generateImage(params: { |
| 664 | model: string; |
| 665 | contents: any[]; |
| 666 | }): Promise<{ text?: string; imageData?: Buffer }> { |
| 667 | const url = `${this.baseUrl}/v1beta/models/${params.model}:generateContent`; |
| 668 | |
| 669 | const headers: Record<string, string> = { |
| 670 | 'x-goog-api-key': this.apiKey |
| 671 | }; |
| 672 | |
| 673 | const requestData = { |
| 674 | contents: params.contents, |
| 675 | generationConfig: { |
| 676 | responseModalities: ['TEXT', 'IMAGE'] |
| 677 | } |
| 678 | }; |
| 679 | |
| 680 | const response = await HttpClient.makeRequest(url, { |
| 681 | method: 'POST', |
| 682 | headers, |
| 683 | data: requestData |
| 684 | }); |
| 685 | |
| 686 | if (response.status !== 200 || response.data?.error) { |
| 687 | const errorMsg = response.data?.error?.message || JSON.stringify(response.data); |
| 688 | // 隐藏可能包含API密钥的敏感信息 |
| 689 | const sanitizedMsg = errorMsg.replace(/api_key:[A-Za-z0-9_-]+/g, 'api_key:***'); |
| 690 | throw new Error(`API Error: ${response.status} - ${sanitizedMsg}`); |
| 691 | } |
| 692 | |
| 693 | const parts = response.data?.candidates?.[0]?.content?.parts || []; |
| 694 | let text: string | undefined; |
| 695 | let imageData: Buffer | undefined; |
| 696 | |
| 697 | for (const part of parts) { |
| 698 | if (part?.text) { |
| 699 | text = HttpClient.cleanResponseText(part.text); |
| 700 | } else if (part?.inlineData?.data) { |
| 701 | imageData = Buffer.from(part.inlineData.data, 'base64'); |
| 702 | } |
| 703 | } |
| 704 | |
| 705 | return { text, imageData }; |
| 706 | } |
| 707 | |
| 708 | async generateTTS(params: { |
| 709 | model: string; |
no test coverage detected