|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +describe DiscourseAi::Completions::AnthropicMessageProcessor do |
| 4 | + it "correctly handles and combines partial thinking chunks into complete thinking objects" do |
| 5 | + processor = |
| 6 | + DiscourseAi::Completions::AnthropicMessageProcessor.new( |
| 7 | + streaming_mode: true, |
| 8 | + partial_tool_calls: false, |
| 9 | + output_thinking: true, |
| 10 | + ) |
| 11 | + |
| 12 | + # Simulate streaming thinking output in multiple chunks |
| 13 | + result1 = |
| 14 | + processor.process_streamed_message( |
| 15 | + { type: "content_block_start", content_block: { type: "thinking", thinking: "" } }, |
| 16 | + ) |
| 17 | + |
| 18 | + result2 = |
| 19 | + processor.process_streamed_message( |
| 20 | + { |
| 21 | + type: "content_block_delta", |
| 22 | + delta: { |
| 23 | + type: "thinking_delta", |
| 24 | + thinking: "First part of thinking", |
| 25 | + }, |
| 26 | + }, |
| 27 | + ) |
| 28 | + |
| 29 | + result3 = |
| 30 | + processor.process_streamed_message( |
| 31 | + { |
| 32 | + type: "content_block_delta", |
| 33 | + delta: { |
| 34 | + type: "thinking_delta", |
| 35 | + thinking: " and second part", |
| 36 | + }, |
| 37 | + }, |
| 38 | + ) |
| 39 | + |
| 40 | + _result4 = |
| 41 | + processor.process_streamed_message( |
| 42 | + { |
| 43 | + type: "content_block_delta", |
| 44 | + delta: { |
| 45 | + type: "signature_delta", |
| 46 | + signature: "thinking-sig-123", |
| 47 | + }, |
| 48 | + }, |
| 49 | + ) |
| 50 | + |
| 51 | + # Finish the thinking block |
| 52 | + final_result = processor.process_streamed_message({ type: "content_block_stop" }) |
| 53 | + |
| 54 | + # Verify the partial thinking chunks |
| 55 | + expect(result1).to be_a(DiscourseAi::Completions::Thinking) |
| 56 | + expect(result1.message).to eq("") |
| 57 | + expect(result1.partial?).to eq(true) |
| 58 | + |
| 59 | + expect(result2).to be_a(DiscourseAi::Completions::Thinking) |
| 60 | + expect(result2.message).to eq("First part of thinking") |
| 61 | + expect(result2.partial?).to eq(true) |
| 62 | + |
| 63 | + expect(result3).to be_a(DiscourseAi::Completions::Thinking) |
| 64 | + expect(result3.message).to eq(" and second part") |
| 65 | + expect(result3.partial?).to eq(true) |
| 66 | + |
| 67 | + # Verify the final complete thinking object |
| 68 | + expect(final_result).to be_a(DiscourseAi::Completions::Thinking) |
| 69 | + expect(final_result.message).to eq("First part of thinking and second part") |
| 70 | + expect(final_result.signature).to eq("thinking-sig-123") |
| 71 | + expect(final_result.partial?).to eq(false) |
| 72 | + end |
| 73 | +end |
0 commit comments