feat: Kimi k2.5参数适配+AI日志导出完善(20260419_2249)

- Kimi k2.5 强制传参拦截: 当 provider=kimi 且 model 包含 k2.5 时,
  从请求体中 delete temperature/top_p/presence_penalty/frequency_penalty,
  彻底解决 HTTP 400 报错
- 完善导出AI日志: 新增 lastExchangeLog 状态, 记录每次调用的
  完整请求体(requestPayload)、原始响应(responsePayload)、
  错误详情(errorDetail含status/statusText/responseText)、模型配置
- 更新导出按钮 JSON 结构, 包含 lastExchange 字段
This commit is contained in:
2026-04-19 22:54:00 +08:00
parent 2e634ff832
commit 3bec69986e
4 changed files with 269 additions and 9 deletions

View File

@@ -0,0 +1,117 @@
# 功能变更实现方案文档20260419_2249
## 实现方案 AKimi k2.5 参数拦截
### 变更点
`ReportEditor.tsx``handleAIGenerate` 函数的请求体构建部分(当前行号约 948-962
### 具体实现
1. 在构建 `body` 前,先创建一个 `payload` 对象:
```ts
const payload: any = {
model: modelName,
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: messageContent }
],
temperature: 0.3
};
```
2. 增加条件判断:
```ts
const isKimiK25 = settings.activeAiProvider === 'kimi' && /k2\.5/i.test(modelName);
if (isKimiK25) {
delete payload.temperature;
delete payload.top_p;
delete payload.presence_penalty;
delete payload.frequency_penalty;
}
```
3. `fetch` 的 `body: JSON.stringify(payload)`
### 设计理由
- 使用 `delete` 而非覆盖为固定值,是因为 Kimi 官方文档明确禁止这些参数出现;即使设为 `1.0` 仍可能触发校验失败
- 条件判断放在 `settings` 读取后立即执行,确保使用用户实际配置的 provider 和 modelName
- 正则 `/k2\.5/i` 兼容可能的模型 ID 变体(如 `kimi-k2.5`、`kimi-k2.5-preview` 等)
---
## 实现方案 B完善 AI 日志导出
### 变更点 1新增 `lastExchangeLog` 状态
在 `ReportEditor.tsx` 的 state 定义区(`chatMessages` 附近)新增:
```ts
const [lastExchangeLog, setLastExchangeLog] = useState<{
startTime: string;
modelConfig: { provider: string; endpoint: string; modelName: string };
requestPayload: any;
responsePayload: any | null;
errorDetail: { status: number; statusText: string; responseText: string; message: string } | null;
} | null>(null);
```
### 变更点 2在 `handleAIGenerate` 中记录日志
将函数重构为在关键节点捕获数据:
**A. 请求前记录:**
```ts
const logEntry = {
startTime: new Date().toISOString(),
modelConfig: { provider: settings.activeAiProvider || 'kimi', endpoint: apiEndpoint, modelName },
requestPayload: { ...payload },
responsePayload: null,
errorDetail: null
};
```
**B. 错误处理增强:**
当前错误处理只有:
```ts
if (!response.ok) throw new Error(`API 请求失败: ${response.status}`);
```
改为:
```ts
if (!response.ok) {
const errorText = await response.text();
logEntry.errorDetail = {
status: response.status,
statusText: response.statusText,
responseText: errorText,
message: `API 请求失败: ${response.status}`
};
setLastExchangeLog(logEntry);
throw new Error(`API 请求失败: ${response.status} - ${errorText}`);
}
```
**C. 成功响应记录:**
在解析 `responseJson` 后:
```ts
logEntry.responsePayload = responseJson;
setLastExchangeLog(logEntry);
```
### 变更点 3更新导出按钮
在「导出 AI 日志」按钮的 `onClick` 中,将 `lastExchangeLog` 加入导出数据:
```ts
const data = {
exportAt: new Date().toISOString(),
url: window.location.href,
messages: chatMessages,
lastExchange: lastExchangeLog,
metadata: { ... }
};
```
### 设计理由
- `lastExchangeLog` 只记录最后一次调用,避免无限增长导致内存/状态膨胀
- 错误时捕获 `response.text()` 获取 Kimi 官方返回的详细错误 JSON通常包含 `error.code` 和 `error.message`
- `requestPayload` 深拷贝防止后续 `delete` 操作污染日志记录
- 使用 `useState` 而非 `useRef`,因为导出按钮需要读取最新值并触发重渲染显示状态
---
## 依赖与兼容性
- 无新增 npm 依赖
- TypeScript 类型在组件内部定义,不影响 `src/types.ts`
- 向后兼容:旧数据无 `lastExchangeLog`,导出时字段为 `null`