@@ -754,3 +754,167 @@ describe("usage_metadata serialized", () => {
754754 expect ( jsonConcatenatedAIMessageChunk ) . toContain ( "total_tokens" ) ;
755755 } ) ;
756756} ) ;
757+
758+ describe ( "toFormattedString" , ( ) => {
759+ describe ( "BaseMessage (HumanMessage)" , ( ) => {
760+ it ( "formats a simple string message" , ( ) => {
761+ const message = new HumanMessage ( "Hello, world!" ) ;
762+ const output = message . toFormattedString ( ) ;
763+ expect ( output ) . toContain ( "Human Message" ) ;
764+ expect ( output ) . toContain ( "Hello, world!" ) ;
765+ expect ( output ) . toMatch ( / = { 30 , } / ) ; // Check for separator line
766+ } ) ;
767+
768+ it ( "formats a message with empty content" , ( ) => {
769+ const message = new HumanMessage ( "" ) ;
770+ const output = message . toFormattedString ( ) ;
771+ expect ( output ) . toContain ( "Human Message" ) ;
772+ expect ( output ) . not . toContain ( "\n\n" ) ; // No blank line before content
773+ } ) ;
774+
775+ it ( "formats a message with whitespace-only content" , ( ) => {
776+ const message = new HumanMessage ( " " ) ;
777+ const output = message . toFormattedString ( ) ;
778+ expect ( output ) . toContain ( "Human Message" ) ;
779+ // Whitespace-only content should be treated as empty
780+ expect ( output . split ( "\n" ) . length ) . toBe ( 1 ) ;
781+ } ) ;
782+ } ) ;
783+
784+ describe ( "AIMessage" , ( ) => {
785+ it ( "formats an AI message without tool calls" , ( ) => {
786+ const message = new AIMessage ( "I can help with that!" ) ;
787+ const output = message . toFormattedString ( ) ;
788+ expect ( output ) . toContain ( "Ai Message" ) ;
789+ expect ( output ) . toContain ( "I can help with that!" ) ;
790+ } ) ;
791+
792+ it ( "formats an AI message with tool calls" , ( ) => {
793+ const message = new AIMessage ( {
794+ content : "Let me check the weather" ,
795+ tool_calls : [
796+ {
797+ id : "call_123" ,
798+ name : "get_weather" ,
799+ args : { location : "San Francisco" , unit : "celsius" } ,
800+ type : "tool_call" ,
801+ } ,
802+ ] ,
803+ } ) ;
804+ const output = message . toFormattedString ( ) ;
805+ expect ( output ) . toContain ( "Ai Message" ) ;
806+ expect ( output ) . toContain ( "Tool Calls:" ) ;
807+ expect ( output ) . toContain ( "get_weather (call_123)" ) ;
808+ expect ( output ) . toContain ( "Call ID: call_123" ) ;
809+ expect ( output ) . toContain ( "Args:" ) ;
810+ expect ( output ) . toContain ( "location: San Francisco" ) ;
811+ expect ( output ) . toContain ( "unit: celsius" ) ;
812+ } ) ;
813+
814+ it ( "formats an AI message with multiple tool calls" , ( ) => {
815+ const message = new AIMessage ( {
816+ content : "" ,
817+ tool_calls : [
818+ {
819+ id : "call_1" ,
820+ name : "search" ,
821+ args : { query : "test" } ,
822+ type : "tool_call" ,
823+ } ,
824+ {
825+ id : "call_2" ,
826+ name : "calculator" ,
827+ args : { expression : "2+2" } ,
828+ type : "tool_call" ,
829+ } ,
830+ ] ,
831+ } ) ;
832+ const output = message . toFormattedString ( ) ;
833+ expect ( output ) . toContain ( "search (call_1)" ) ;
834+ expect ( output ) . toContain ( "calculator (call_2)" ) ;
835+ } ) ;
836+
837+ it ( "formats an AI message with empty tool calls array" , ( ) => {
838+ const message = new AIMessage ( {
839+ content : "Just a message" ,
840+ tool_calls : [ ] ,
841+ } ) ;
842+ const output = message . toFormattedString ( ) ;
843+ expect ( output ) . toContain ( "Ai Message" ) ;
844+ expect ( output ) . not . toContain ( "Tool Calls:" ) ;
845+ expect ( output ) . toContain ( "Just a message" ) ;
846+ } ) ;
847+ } ) ;
848+
849+ describe ( "ToolMessage" , ( ) => {
850+ it ( "formats a tool message with name" , ( ) => {
851+ const message = new ToolMessage ( {
852+ content : '{"temperature": 72}' ,
853+ tool_call_id : "call_123" ,
854+ name : "get_weather" ,
855+ } ) ;
856+ const output = message . toFormattedString ( ) ;
857+ expect ( output ) . toContain ( "Tool Message" ) ;
858+ expect ( output ) . toContain ( "Name: get_weather" ) ;
859+ expect ( output ) . toContain ( '{"temperature": 72}' ) ;
860+ } ) ;
861+
862+ it ( "formats a tool message without name" , ( ) => {
863+ const message = new ToolMessage ( {
864+ content : "Success" ,
865+ tool_call_id : "call_456" ,
866+ } ) ;
867+ const output = message . toFormattedString ( ) ;
868+ expect ( output ) . toContain ( "Tool Message" ) ;
869+ expect ( output ) . not . toContain ( "Name:" ) ;
870+ expect ( output ) . toContain ( "Success" ) ;
871+ } ) ;
872+ } ) ;
873+
874+ describe ( "SystemMessage" , ( ) => {
875+ it ( "formats a system message" , ( ) => {
876+ const message = new SystemMessage ( "You are a helpful assistant." ) ;
877+ const output = message . toFormattedString ( ) ;
878+ expect ( output ) . toContain ( "System Message" ) ;
879+ expect ( output ) . toContain ( "You are a helpful assistant." ) ;
880+ } ) ;
881+ } ) ;
882+
883+ describe ( "Message formatting consistency" , ( ) => {
884+ it ( "maintains consistent separator length for different message types" , ( ) => {
885+ const human = new HumanMessage ( "Hi" ) ;
886+ const ai = new AIMessage ( "Hello" ) ;
887+ const system = new SystemMessage ( "System" ) ;
888+
889+ const humanOutput = human . toFormattedString ( ) ;
890+ const aiOutput = ai . toFormattedString ( ) ;
891+ const systemOutput = system . toFormattedString ( ) ;
892+
893+ const humanSep = humanOutput . split ( "\n" ) [ 0 ] ;
894+ const aiSep = aiOutput . split ( "\n" ) [ 0 ] ;
895+ const systemSep = systemOutput . split ( "\n" ) [ 0 ] ;
896+
897+ expect ( humanSep . length ) . toBe ( 80 ) ;
898+ expect ( aiSep . length ) . toBe ( 80 ) ;
899+ expect ( systemSep . length ) . toBe ( 80 ) ;
900+ } ) ;
901+
902+ it ( "adds blank line before content when details are present" , ( ) => {
903+ const messageWithDetails = new AIMessage ( {
904+ content : "Response" ,
905+ tool_calls : [
906+ {
907+ id : "call_1" ,
908+ name : "tool" ,
909+ args : { } ,
910+ type : "tool_call" ,
911+ } ,
912+ ] ,
913+ } ) ;
914+ const output = messageWithDetails . toFormattedString ( ) ;
915+ const lines = output . split ( "\n" ) ;
916+ // Should have: title, Tool Calls:, tool info, blank line, content
917+ expect ( lines ) . toContain ( "" ) ;
918+ } ) ;
919+ } ) ;
920+ } ) ;
0 commit comments