diff --git a/src/core/task/__tests__/apiConversationHistory.spec.ts b/src/core/task/__tests__/apiConversationHistory.spec.ts index 7313e4fa1c..bacb3c03d0 100644 --- a/src/core/task/__tests__/apiConversationHistory.spec.ts +++ b/src/core/task/__tests__/apiConversationHistory.spec.ts @@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" import { prepareApiConversationMessage } from "../apiConversationHistory.js" import { providerIdentifiers } from "@roo-code/types/provider-identifiers" +import type { ApiHandler } from "../../../api" describe("prepareApiConversationMessage", () => { beforeEach(() => { @@ -83,6 +84,40 @@ describe("prepareApiConversationMessage", () => { ]) }) + it.each(["reasoning-1", undefined])("preserves encrypted reasoning alongside its visible text (id: %s)", (id) => { + const api = { + createMessage: vi.fn(), + getModel: vi.fn(), + countTokens: vi.fn(), + getEncryptedContent: () => ({ encrypted_content: "encrypted", ...(id ? { id } : {}) }), + } + const result = prepareApiConversationMessage({ + message: { + role: "assistant", + content: [ + { type: "text", text: "Reading files" }, + { type: "tool_use", id: "call-1", name: "read_file", input: { path: "a.ts" } }, + ], + }, + reasoning: "visible reasoning", + api, + apiConfiguration: { apiProvider: providerIdentifiers.openaiCodex }, + apiConversationHistory: [], + }) + + expect(result.content).toEqual([ + { + type: "reasoning", + text: "visible reasoning", + summary: [], + encrypted_content: "encrypted", + ...(id ? { id } : {}), + }, + { type: "text", text: "Reading files" }, + { type: "tool_use", id: "call-1", name: "read_file", input: { path: "a.ts" } }, + ]) + }) + it("appends thought signatures for non-Anthropic protocols", () => { const result = prepareApiConversationMessage({ message: { role: "assistant", content: "answer" }, diff --git a/src/core/task/apiConversationHistory.ts b/src/core/task/apiConversationHistory.ts index d1e609c8dc..c75fb4f1c5 100644 --- a/src/core/task/apiConversationHistory.ts +++ b/src/core/task/apiConversationHistory.ts @@ -82,6 +82,13 @@ function prepareAssistantMessage( type: "reasoning", text: reasoning, summary: [] as any[], + // A visible summary must not discard the encrypted state needed for continuation. + ...(reasoningData?.encrypted_content + ? { + encrypted_content: reasoningData.encrypted_content, + ...(reasoningData.id ? { id: reasoningData.id } : {}), + } + : {}), } prependContentBlock(messageWithTs, reasoningBlock)