@@ -372,7 +372,7 @@ describe('tool messages', () => {
372
372
} ) ;
373
373
} ) ;
374
374
375
- it ( 'should combine tool and user messages with tool_result first ' , async ( ) => {
375
+ it ( 'should combine user and tool messages' , async ( ) => {
376
376
const result = await convertToAnthropicMessagesPrompt ( {
377
377
prompt : [
378
378
{
@@ -409,13 +409,8 @@ describe('tool messages', () => {
409
409
tool_use_id : 'tool-call-1' ,
410
410
is_error : undefined ,
411
411
content : JSON . stringify ( { test : 'This is a tool message' } ) ,
412
- cache_control : undefined ,
413
- } ,
414
- {
415
- type : 'text' ,
416
- text : 'This is a user message' ,
417
- cache_control : undefined ,
418
412
} ,
413
+ { type : 'text' , text : 'This is a user message' } ,
419
414
] ,
420
415
} ,
421
416
] ,
@@ -425,84 +420,6 @@ describe('tool messages', () => {
425
420
} ) ;
426
421
} ) ;
427
422
428
- it ( 'should place tool_result before user text in combined messages' , async ( ) => {
429
- // Ensures tool_result parts appear first in combined user messages
430
- const result = await convertToAnthropicMessagesPrompt ( {
431
- prompt : [
432
- {
433
- role : 'user' ,
434
- content : [ { type : 'text' , text : 'generate 10 items' } ] ,
435
- } ,
436
- {
437
- role : 'assistant' ,
438
- content : [
439
- {
440
- type : 'tool-call' ,
441
- toolCallId : 'tool-example-123' ,
442
- toolName : 'json' ,
443
- input : {
444
- message : 'generate 10 items' ,
445
- } ,
446
- } ,
447
- {
448
- type : 'text' ,
449
- text : 'I generated code for 10 items.' ,
450
- } ,
451
- ] ,
452
- } ,
453
- {
454
- role : 'tool' ,
455
- content : [
456
- {
457
- type : 'tool-result' ,
458
- toolCallId : 'tool-example-123' ,
459
- toolName : 'json' ,
460
- output : {
461
- type : 'json' ,
462
- value : {
463
- code : 'export const code = () => [...]' ,
464
- packageJson : '{}' ,
465
- } ,
466
- } ,
467
- } ,
468
- ] ,
469
- } ,
470
- {
471
- role : 'user' ,
472
- content : [ { type : 'text' , text : 'generate 100 items' } ] ,
473
- } ,
474
- ] ,
475
- sendReasoning : true ,
476
- warnings : [ ] ,
477
- } ) ;
478
-
479
- // The key fix: tool_result and user content are combined in a single message
480
- // but tool_result appears FIRST to satisfy Claude's validation requirements
481
- expect ( result . prompt . messages ) . toHaveLength ( 3 ) ;
482
- expect ( result . prompt . messages [ 0 ] . role ) . toBe ( 'user' ) ;
483
- expect ( result . prompt . messages [ 1 ] . role ) . toBe ( 'assistant' ) ;
484
- expect ( result . prompt . messages [ 2 ] . role ) . toBe ( 'user' ) ; // combined tool_result + user message
485
-
486
- // Verify tool_result comes before user text in the combined message
487
- expect ( result . prompt . messages [ 2 ] . content ) . toEqual ( [
488
- {
489
- type : 'tool_result' ,
490
- tool_use_id : 'tool-example-123' ,
491
- is_error : undefined ,
492
- content : JSON . stringify ( {
493
- code : 'export const code = () => [...]' ,
494
- packageJson : '{}' ,
495
- } ) ,
496
- cache_control : undefined ,
497
- } ,
498
- {
499
- type : 'text' ,
500
- text : 'generate 100 items' ,
501
- cache_control : undefined ,
502
- } ,
503
- ] ) ;
504
- } ) ;
505
-
506
423
it ( 'should handle tool result with content parts' , async ( ) => {
507
424
const result = await convertToAnthropicMessagesPrompt ( {
508
425
prompt : [
@@ -573,170 +490,6 @@ describe('tool messages', () => {
573
490
}
574
491
` ) ;
575
492
} ) ;
576
-
577
- it ( 'should place tool_result before user text in combined message' , async ( ) => {
578
- // Combines tool_result and user text in a single message (preserving role alternation)
579
- // but tool_result parts appear first, satisfying Claude's validation requirements
580
-
581
- const result = await convertToAnthropicMessagesPrompt ( {
582
- prompt : [
583
- {
584
- role : 'tool' ,
585
- content : [
586
- {
587
- type : 'tool-result' ,
588
- toolName : 'analyze-tool' ,
589
- toolCallId : 'tool-call-123' ,
590
- output : {
591
- type : 'json' ,
592
- value : { analysis : 'Tool execution completed' } ,
593
- } ,
594
- } ,
595
- ] ,
596
- } ,
597
- {
598
- role : 'user' ,
599
- content : [
600
- { type : 'text' , text : 'Thanks! Now please provide more details.' } ,
601
- ] ,
602
- } ,
603
- ] ,
604
- sendReasoning : true ,
605
- warnings : [ ] ,
606
- } ) ;
607
-
608
- // Fixed behavior: still combines in single message, but tool_result comes first
609
- // This satisfies Claude's "tool_result immediately after tool_use" requirement
610
- expect ( result ) . toEqual ( {
611
- prompt : {
612
- messages : [
613
- {
614
- role : 'user' ,
615
- content : [
616
- {
617
- type : 'tool_result' ,
618
- tool_use_id : 'tool-call-123' ,
619
- is_error : undefined ,
620
- content : JSON . stringify ( {
621
- analysis : 'Tool execution completed' ,
622
- } ) ,
623
- } ,
624
- {
625
- type : 'text' ,
626
- text : 'Thanks! Now please provide more details.' ,
627
- } ,
628
- ] ,
629
- } ,
630
- ] ,
631
- system : undefined ,
632
- } ,
633
- betas : new Set ( ) ,
634
- } ) ;
635
- } ) ;
636
-
637
- it ( 'should place multiple tool_result parts before user text in correct order' , async ( ) => {
638
- // Test multiple tool_use scenario: tool_result parts should appear first
639
- // and maintain the same order as their corresponding tool_use ids
640
- const result = await convertToAnthropicMessagesPrompt ( {
641
- prompt : [
642
- {
643
- role : 'tool' ,
644
- content : [
645
- {
646
- type : 'tool-result' ,
647
- toolName : 'search-tool' ,
648
- toolCallId : 'search-123' ,
649
- output : { type : 'text' , value : 'Search result' } ,
650
- } ,
651
- {
652
- type : 'tool-result' ,
653
- toolName : 'analyze-tool' ,
654
- toolCallId : 'analyze-456' ,
655
- output : { type : 'json' , value : { status : 'complete' } } ,
656
- } ,
657
- ] ,
658
- } ,
659
- {
660
- role : 'user' ,
661
- content : [
662
- {
663
- type : 'text' ,
664
- text : 'Great! What do you think about these results?' ,
665
- } ,
666
- ] ,
667
- } ,
668
- ] ,
669
- sendReasoning : false ,
670
- warnings : [ ] ,
671
- } ) ;
672
-
673
- expect ( result . prompt . messages ) . toHaveLength ( 1 ) ;
674
- expect ( result . prompt . messages [ 0 ] ) . toEqual ( {
675
- role : 'user' ,
676
- content : [
677
- {
678
- type : 'tool_result' ,
679
- tool_use_id : 'search-123' ,
680
- content : 'Search result' ,
681
- is_error : undefined ,
682
- } ,
683
- {
684
- type : 'tool_result' ,
685
- tool_use_id : 'analyze-456' ,
686
- content : JSON . stringify ( { status : 'complete' } ) ,
687
- is_error : undefined ,
688
- } ,
689
- { type : 'text' , text : 'Great! What do you think about these results?' } ,
690
- ] ,
691
- } ) ;
692
- } ) ;
693
-
694
- it ( 'should place error tool_result parts before user text' , async ( ) => {
695
- // Test error tool results: should also appear first even when is_error: true
696
- const result = await convertToAnthropicMessagesPrompt ( {
697
- prompt : [
698
- {
699
- role : 'tool' ,
700
- content : [
701
- {
702
- type : 'tool-result' ,
703
- toolName : 'failing-tool' ,
704
- toolCallId : 'fail-789' ,
705
- output : { type : 'error-text' , value : 'Tool execution failed' } ,
706
- } ,
707
- ] ,
708
- } ,
709
- {
710
- role : 'user' ,
711
- content : [
712
- {
713
- type : 'text' ,
714
- text : 'The tool failed. Can you try a different approach?' ,
715
- } ,
716
- ] ,
717
- } ,
718
- ] ,
719
- sendReasoning : false ,
720
- warnings : [ ] ,
721
- } ) ;
722
-
723
- expect ( result . prompt . messages ) . toHaveLength ( 1 ) ;
724
- expect ( result . prompt . messages [ 0 ] ) . toEqual ( {
725
- role : 'user' ,
726
- content : [
727
- {
728
- type : 'tool_result' ,
729
- tool_use_id : 'fail-789' ,
730
- content : 'Tool execution failed' ,
731
- is_error : true ,
732
- } ,
733
- {
734
- type : 'text' ,
735
- text : 'The tool failed. Can you try a different approach?' ,
736
- } ,
737
- ] ,
738
- } ) ;
739
- } ) ;
740
493
} ) ;
741
494
742
495
describe ( 'assistant messages' , ( ) => {
0 commit comments