kiro-proxy 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/q-client.js +26 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiro-proxy",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Kiro API proxy with OpenAI and Anthropic compatible endpoints",
5
5
  "type": "module",
6
6
  "bin": {
package/q-client.js CHANGED
@@ -165,6 +165,25 @@ function extractText(content) {
165
165
  .join('');
166
166
  }
167
167
 
168
+ /**
169
+ * 从 assistant content blocks 中提取 thinking → CodeWhisperer reasoningContent
170
+ * Anthropic 格式: { type: "thinking", thinking: "...", signature: "..." }
171
+ * CodeWhisperer 格式: { reasoningText: { text, signature? } }
172
+ */
173
+ function extractReasoning(content) {
174
+ if (!Array.isArray(content)) return undefined;
175
+ const thinkingBlocks = content.filter(b => b.type === 'thinking' && typeof b.thinking === 'string' && b.thinking.length > 0);
176
+ if (thinkingBlocks.length === 0) return undefined;
177
+ const text = thinkingBlocks.map(b => b.thinking).join('');
178
+ const sig = thinkingBlocks.map(b => b.signature).find(s => typeof s === 'string' && s.length > 0);
179
+ return {
180
+ reasoningText: {
181
+ text,
182
+ ...(sig && { signature: sig }),
183
+ },
184
+ };
185
+ }
186
+
168
187
  /**
169
188
  * 从 assistant content blocks 中提取 tool_use 调用
170
189
  */
@@ -233,10 +252,12 @@ export function convertMessages(messages, { modelId, system, tools } = {}) {
233
252
  const images = extractImages(msg.content);
234
253
 
235
254
  if (toolResults.length > 0) {
236
- // tool_result 消息:content 为空,结果放在 userInputMessageContext.toolResults
255
+ // tool_result 消息:text block 作为 content,tool_result 放在 userInputMessageContext
256
+ // 关键:Claude Code 的 ESC 中断会把 tool_result + [Request interrupted] + 新 prompt 打包成同一条 user message 的多个 content block,
257
+ // 如果这里把 content 写死成 '',中断标记和新 prompt 会被静默丢弃,模型无法感知中断
237
258
  history.push({
238
259
  userInputMessage: {
239
- content: '',
260
+ content: text,
240
261
  modelId: validModelId,
241
262
  origin: 'AI_EDITOR',
242
263
  userInputMessageContext: { toolResults },
@@ -254,10 +275,12 @@ export function convertMessages(messages, { modelId, system, tools } = {}) {
254
275
  } else if (msg.role === 'assistant') {
255
276
  const text = extractText(msg.content);
256
277
  const toolUses = extractToolUses(msg.content);
278
+ const reasoningContent = extractReasoning(msg.content);
257
279
  history.push({
258
280
  assistantResponseMessage: {
259
281
  content: text,
260
282
  toolUses: toolUses.length > 0 ? toolUses : undefined,
283
+ ...(reasoningContent && { reasoningContent }),
261
284
  },
262
285
  });
263
286
  }
@@ -265,7 +288,7 @@ export function convertMessages(messages, { modelId, system, tools } = {}) {
265
288
  }
266
289
 
267
290
  // 确保 history 以 user→assistant 交替,末尾是 user
268
- // 如果末尾是 assistant(不应该发生),追加空 user
291
+ // 桥接后末尾仍可能是 assistant;CW 要求 currentMessage 必须是 userInputMessage
269
292
  const last = history.at(-1);
270
293
  if (last?.assistantResponseMessage) {
271
294
  history.push({