fix(kiro): 动态压缩 tools 解决 Claude Code 发送过多工具信息导致的 500 错误

问题:
  - Claude Code 发送过多工具信息,超出 Kiro API 请求限制导致 500 错误
  - 工具包括:内置工具、MCP 工具、Skills

  解决方案:
  - 先尝试原始大小,超过 20KB 才进行压缩
  - 第一步:简化 input_schema,只保留 type/enum/required
  - 第二步:按比例缩短 description(最短 50 字符)
  - 保留全部工具和 skills 可调用,不丢弃任何工具

  效果:
  - 80KB+ tools 压缩至 ~15KB
This commit is contained in:
Done-0 2026-01-10 21:15:08 +08:00
parent 3642afe9dd
commit 8b018b562e

View file

@ -631,17 +631,80 @@ async initializeAuth(forceRefresh = false) {
const codewhispererModel = MODEL_MAPPING[model] || MODEL_MAPPING[this.modelName];
// 动态压缩 tools保留全部工具
let toolsContext = {};
if (tools && Array.isArray(tools) && tools.length > 0) {
toolsContext = {
tools: tools.map(tool => ({
toolSpecification: {
name: tool.name,
description: tool.description || "",
inputSchema: { json: tool.input_schema || {} }
const TARGET_SIZE = 20000;
const simplifySchema = (schema) => {
if (!schema || typeof schema !== 'object') return { type: 'object' };
const result = { type: schema.type || 'object' };
if (schema.properties && typeof schema.properties === 'object') {
result.properties = {};
for (const [key, value] of Object.entries(schema.properties)) {
result.properties[key] = { type: value.type || 'string' };
if (value.enum) result.properties[key].enum = value.enum;
}
}))
}
if (schema.required && Array.isArray(schema.required) && schema.required.length > 0) {
result.required = schema.required;
}
return result;
};
const buildTools = (maxDescLen, useSimplifiedSchema) => {
return tools.map(tool => {
let desc = tool.description || "";
if (maxDescLen !== null && desc.length > maxDescLen) {
desc = desc.substring(0, maxDescLen) + "...";
}
return {
toolSpecification: {
name: tool.name,
description: desc,
inputSchema: {
json: useSimplifiedSchema
? simplifySchema(tool.input_schema)
: (tool.input_schema || {})
}
}
};
});
};
// 先尝试原始大小
let kiroTools = buildTools(null, false);
let size = JSON.stringify(kiroTools).length;
const originalSize = size;
// 超过限制则压缩
if (size > TARGET_SIZE) {
// 简化 schema
kiroTools = buildTools(null, true);
size = JSON.stringify(kiroTools).length;
// 缩短描述
if (size > TARGET_SIZE) {
const ratio = TARGET_SIZE / size;
const totalDescLen = tools.reduce((sum, t) => sum + (t.description || "").length, 0);
const avgDescLen = totalDescLen / tools.length;
let targetDescLen = Math.floor(avgDescLen * ratio * 0.8);
targetDescLen = Math.max(50, Math.min(500, targetDescLen));
kiroTools = buildTools(targetDescLen, true);
size = JSON.stringify(kiroTools).length;
while (size > TARGET_SIZE && targetDescLen > 50) {
targetDescLen = Math.floor(targetDescLen * 0.7);
targetDescLen = Math.max(50, targetDescLen);
kiroTools = buildTools(targetDescLen, true);
size = JSON.stringify(kiroTools).length;
}
}
console.log(`[Kiro] Tools compressed: ${originalSize} -> ${size} bytes (${tools.length} tools)`);
}
toolsContext = { tools: kiroTools };
}
const history = [];
@ -926,7 +989,7 @@ async initializeAuth(forceRefresh = false) {
if (this.authMethod === KIRO_CONSTANTS.AUTH_METHOD_SOCIAL) {
request.profileArn = this.profileArn;
}
// fs.writeFile('claude-kiro-request'+Date.now()+'.json', JSON.stringify(request));
return request;
}