



















@@ -29,7 +29,7 @@ function requireFirstStreamOptions(mock: ReturnType<typeof vi.fn>, label: string
2929}
30303131describe("wrapCopilotAnthropicStream", () => {
32-it("adds Copilot headers and Anthropic cache markers for Claude payloads", () => {
32+it("adds Copilot headers, strips thinking replay, and marks cache for Claude payloads", () => {
3333const payloads: Array<{
3434messages: Array<Record<string, unknown>>;
3535}> = [];
@@ -39,7 +39,11 @@ describe("wrapCopilotAnthropicStream", () => {
3939{ role: "system", content: "system prompt" },
4040{
4141role: "assistant",
42-content: [{ type: "thinking", text: "draft", cache_control: { type: "ephemeral" } }],
42+content: [
43+{ type: "thinking", thinking: "draft", cache_control: { type: "ephemeral" } },
44+{ type: "redacted_thinking", data: "opaque" },
45+{ type: "text", text: "visible reply" },
46+],
4347},
4448],
4549};
@@ -98,11 +102,54 @@ describe("wrapCopilotAnthropicStream", () => {
98102},
99103{
100104role: "assistant",
101-content: [{ type: "thinking", text: "draft" }],
105+content: [{ type: "text", text: "visible reply" }],
102106},
103107]);
104108});
105109110+it("keeps a non-empty assistant turn when Copilot replay only contains thinking", () => {
111+const payloads: Array<{
112+messages: Array<Record<string, unknown>>;
113+}> = [];
114+const baseStreamFn = vi.fn((model, _context, options) => {
115+const payload = {
116+messages: [
117+{ role: "user", content: "use the tool result" },
118+{
119+role: "assistant",
120+content: [
121+{ type: "thinking", thinking: "private" },
122+{ type: "redacted_thinking", data: "opaque" },
123+],
124+},
125+{ role: "user", content: [{ type: "tool_result", content: "done" }] },
126+],
127+};
128+options?.onPayload?.(payload, model);
129+payloads.push(payload);
130+return {
131+async *[Symbol.asyncIterator]() {},
132+} as never;
133+});
134+135+const wrapped = requireStreamFn(wrapCopilotAnthropicStream(baseStreamFn));
136+void wrapped(
137+{
138+provider: "github-copilot",
139+api: "anthropic-messages",
140+id: "claude-haiku-4.5",
141+} as never,
142+{ messages: [{ role: "user", content: "hi" }] } as never,
143+{},
144+);
145+146+expect(payloads[0]?.messages).toEqual([
147+{ role: "user", content: "use the tool result" },
148+{ role: "assistant", content: [{ type: "text", text: "[assistant reasoning omitted]" }] },
149+{ role: "user", content: [{ type: "tool_result", content: "done" }] },
150+]);
151+});
152+106153it("leaves non-Anthropic Copilot models untouched", () => {
107154const baseStreamFn = vi.fn(() => ({ async *[Symbol.asyncIterator]() {} }) as never);
108155const wrapped = requireStreamFn(wrapCopilotAnthropicStream(baseStreamFn));
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。