(params: {
model: string;
contents: any[];
systemInstruction?: string;
safetySettings?: any[];
maxOutputTokens?: number;
tools?: any[];
})
| 601 | } |
| 602 | |
| 603 | async generateContent(params: { |
| 604 | model: string; |
| 605 | contents: any[]; |
| 606 | systemInstruction?: string; |
| 607 | safetySettings?: any[]; |
| 608 | maxOutputTokens?: number; |
| 609 | tools?: any[]; |
| 610 | }): Promise<{ text: string; candidates: any[] }> { |
| 611 | const url = `${this.baseUrl}/v1beta/models/${params.model}:generateContent`; |
| 612 | |
| 613 | const headers: Record<string, string> = { |
| 614 | 'x-goog-api-key': this.apiKey |
| 615 | }; |
| 616 | |
| 617 | const requestData: any = { |
| 618 | contents: params.contents, |
| 619 | generationConfig: {} |
| 620 | }; |
| 621 | |
| 622 | if (params.systemInstruction) { |
| 623 | requestData.systemInstruction = { parts: [{ text: params.systemInstruction }] }; |
| 624 | } |
| 625 | |
| 626 | if (params.safetySettings) { |
| 627 | requestData.safetySettings = params.safetySettings; |
| 628 | } |
| 629 | |
| 630 | if (params.maxOutputTokens && params.maxOutputTokens > 0) { |
| 631 | requestData.generationConfig.maxOutputTokens = params.maxOutputTokens; |
| 632 | } |
| 633 | |
| 634 | if (params.tools) { |
| 635 | requestData.tools = params.tools; |
| 636 | } |
| 637 | |
| 638 | const response = await HttpClient.makeRequest(url, { |
| 639 | method: 'POST', |
| 640 | headers, |
| 641 | data: requestData |
| 642 | }); |
| 643 | |
| 644 | if (response.status !== 200 || response.data?.error) { |
| 645 | |
| 646 | |
| 647 | const errorMessage = response.data?.error?.message || |
| 648 | response.data?.error || |
| 649 | `HTTP错误: ${response.status} Bad Request`; |
| 650 | // 隐藏可能包含API密钥的敏感信息 |
| 651 | const sanitizedMsg = String(errorMessage).replace(/api_key:[A-Za-z0-9_-]+/g, 'api_key:***'); |
| 652 | throw new Error(sanitizedMsg); |
| 653 | } |
| 654 | |
| 655 | const rawText = response.data?.candidates?.[0]?.content?.parts?.[0]?.text || ''; |
| 656 | const text = HttpClient.cleanResponseText(rawText); |
| 657 | return { |
| 658 | text, |
| 659 | candidates: response.data?.candidates || [] |
| 660 | }; |
no test coverage detected