(msg: Api.Message, question: string, imageInfo?: MediaInfo)
| 555 | }); |
| 556 | return; |
| 557 | } |
| 558 | |
| 559 | if (!this.config.model) { |
| 560 | await msg.edit({ |
| 561 | text: `❌ 未设置模型\n使用: <code>${mainPrefix}xm set model [模型名]</code>`, |
| 562 | parseMode: 'html', |
| 563 | }); |
| 564 | return; |
| 565 | } |
| 566 | |
| 567 | try { |
| 568 | const processingText = imageInfo |
| 569 | ? '🔄 正在识别图片...' |
| 570 | : '🔄 处理中...'; |
| 571 | await msg.edit({ |
| 572 | text: processingText, |
| 573 | parseMode: 'html', |
| 574 | }); |
| 575 | |
| 576 | let answer: string; |
| 577 | if (this.config.apiMode === 'gemini') { |
| 578 | answer = await this.callGemini(question, imageInfo); |
| 579 | } else { |
| 580 | answer = await this.callOpenAI(question, imageInfo); |
| 581 | } |
| 582 | |
| 583 | // 移除think标签 |
| 584 | answer = this.removeThinkTags(answer); |
| 585 | |
| 586 | // 检查token数量 |
| 587 | const estimatedTokens = Math.ceil(answer.length / 4); |
| 588 | if (estimatedTokens > MAX_RESPONSE_TOKENS) { |
| 589 | answer = `⚠️ 回复过长(${estimatedTokens} tokens, 超过限制${MAX_RESPONSE_TOKENS})\n\n${answer.substring( |
| 590 | 0, |
| 591 | 1000 |
| 592 | )}...`; |
| 593 | } |
| 594 | |
| 595 | await msg.edit({ |
| 596 | text: answer, |
| 597 | parseMode: 'html', |
| 598 | }); |
| 599 | } catch (error: any) { |
| 600 | console.error('[xmsl] API Error:', error); |
| 601 | // 打印 API 返回的详细错误信息 |
| 602 | if (error.response?.data) { |
| 603 | console.error('[xmsl] API Response:', JSON.stringify(error.response.data, null, 2)); |
| 604 | } |
| 605 | let errorMsg = '❌ API 调用失败'; |
| 606 | |
| 607 | if (error.response?.status === 400) { |
| 608 | const apiError = error.response?.data?.error?.message || '请求格式错误'; |
| 609 | errorMsg = `❌ API 请求错误: ${htmlEscape(apiError)}`; |
| 610 | } else if (error.response?.status === 401) { |
| 611 | errorMsg = '❌ API 密钥无效'; |
| 612 | } else if (error.response?.status === 429) { |
| 613 | errorMsg = '❌ 请求过于频繁,请稍后重试'; |
| 614 | } else if (error.code === 'ECONNREFUSED') { |
no test coverage detected