1717package agenticopenai
1818
1919import (
20+ "encoding/json"
2021 "fmt"
2122 "strings"
2223 "sync"
2324
2425 "github.com/bytedance/sonic"
26+ "github.com/cloudwego/eino/components/model"
2527 "github.com/cloudwego/eino/schema"
2628 "github.com/cloudwego/eino/schema/openai"
2729 "github.com/eino-contrib/jsonschema"
@@ -554,6 +556,12 @@ func toUserRoleInputItems(msg *schema.AgenticMessage) (items []responses.Respons
554556 return nil , fmt .Errorf ("failed to convert function tool result to input item: %w" , err )
555557 }
556558
559+ case schema .ContentBlockTypeToolSearchResult :
560+ item , err = toolSearchToolResultToInputItem (block .ToolSearchFunctionToolResult )
561+ if err != nil {
562+ return nil , fmt .Errorf ("failed to convert tool search function tool result to input item: %w" , err )
563+ }
564+
557565 case schema .ContentBlockTypeMCPToolApprovalResponse :
558566 item , err = mcpToolApprovalResponseToInputItem (block .MCPToolApprovalResponse )
559567 if err != nil {
@@ -664,6 +672,25 @@ func userInputFileToInputItem(role responses.EasyInputMessageRole, block *schema
664672 return item , nil
665673}
666674
675+ func toolSearchToolResultToInputItem (block * schema.ToolSearchFunctionToolResult ) (item responses.ResponseInputItemUnionParam , err error ) {
676+ if block .Result == nil {
677+ return item , fmt .Errorf ("tool search result should not be nil" )
678+ }
679+ tools , err := toDeferredFunctionTools (block .Result .Tools )
680+ if err != nil {
681+ return item , err
682+ }
683+ item = responses.ResponseInputItemUnionParam {
684+ OfToolSearchOutput : & responses.ResponseToolSearchOutputItemParam {
685+ Tools : tools ,
686+ CallID : param .NewOpt (block .CallID ),
687+ Status : responses .ResponseToolSearchOutputItemParamStatusCompleted ,
688+ Execution : responses .ResponseToolSearchOutputItemParamExecutionClient ,
689+ },
690+ }
691+ return item , nil
692+ }
693+
667694func functionToolResultToInputItem (block * schema.FunctionToolResult ) (item responses.ResponseInputItemUnionParam , err error ) {
668695 item = responses.ResponseInputItemUnionParam {
669696 OfFunctionCallOutput : & responses.ResponseInputItemFunctionCallOutputParam {
@@ -789,6 +816,20 @@ func functionToolCallToInputItem(block *schema.ContentBlock) (item responses.Res
789816 id , _ := getItemID (block )
790817 status , _ := GetItemStatus (block )
791818
819+ if GetToolSearchToolCall (block ) {
820+ // client tool search call
821+ item = responses.ResponseInputItemUnionParam {
822+ OfToolSearchCall : & responses.ResponseInputItemToolSearchCallParam {
823+ Arguments : json .RawMessage (content .Arguments ),
824+ ID : newOpenaiStrOpt (id ),
825+ CallID : param .NewOpt (content .CallID ),
826+ Status : status ,
827+ Execution : "client" ,
828+ },
829+ }
830+ return item , nil
831+ }
832+
792833 item = responses.ResponseInputItemUnionParam {
793834 OfFunctionCall : & responses.ResponseFunctionToolCallParam {
794835 ID : newOpenaiStrOpt (id ),
@@ -847,6 +888,19 @@ func serverToolCallToInputItem(block *schema.ContentBlock) (item responses.Respo
847888 return imageGenerationToolCallToInputItem (arguments .ImageGeneration , block )
848889 case arguments .Shell != nil :
849890 return shellToolCallToInputItem (arguments .Shell , block )
891+ case arguments .ToolSearch != nil :
892+ var action * responses.ResponseInputItemToolSearchCallParam
893+ action , err = getToolSearchCallActionParam (arguments .ToolSearch )
894+ if err != nil {
895+ return item , err
896+ }
897+ action .CallID = param .NewOpt (content .CallID )
898+ action .ID = param .NewOpt (id )
899+ action .Status = status
900+
901+ item = responses.ResponseInputItemUnionParam {
902+ OfToolSearchCall : action ,
903+ }
850904 default :
851905 return item , fmt .Errorf ("server tool call arguments are nil" )
852906 }
@@ -1000,6 +1054,13 @@ func shellToolCallToInputItem(args *ShellArguments, block *schema.ContentBlock)
10001054 return item , nil
10011055}
10021056
1057+ func getToolSearchCallActionParam (ts * ToolSearchCall ) (* responses.ResponseInputItemToolSearchCallParam , error ) {
1058+ return & responses.ResponseInputItemToolSearchCallParam {
1059+ Arguments : ts .Arguments ,
1060+ Execution : "server" ,
1061+ }, nil
1062+ }
1063+
10031064func serverToolResultToInputItem (block * schema.ContentBlock ) (item responses.ResponseInputItemUnionParam , err error ) {
10041065 content := block .ServerToolResult
10051066 if content == nil {
@@ -1022,6 +1083,19 @@ func serverToolResultToInputItem(block *schema.ContentBlock) (item responses.Res
10221083 return imageGenerationToolResultToInputItem (result .ImageGeneration , block )
10231084 case result .Shell != nil :
10241085 return shellToolResultToInputItem (result .Shell , block )
1086+ case result .ToolSearch != nil :
1087+ var action * responses.ResponseToolSearchOutputItemParam
1088+ action , err = getToolSearchResultActionParam (result .ToolSearch )
1089+ if err != nil {
1090+ return item , err
1091+ }
1092+ action .CallID = param .NewOpt (content .CallID )
1093+ action .ID = param .NewOpt (id )
1094+ action .Status = responses .ResponseToolSearchOutputItemParamStatus (status )
1095+
1096+ item = responses.ResponseInputItemUnionParam {
1097+ OfToolSearchOutput : action ,
1098+ }
10251099 default :
10261100 return item , fmt .Errorf ("server tool result is nil" )
10271101 }
@@ -1209,6 +1283,17 @@ func shellToolResultToInputItem(result *ShellResult, block *schema.ContentBlock)
12091283 return item , nil
12101284}
12111285
1286+ func getToolSearchResultActionParam (ts * ToolSearchResult ) (* responses.ResponseToolSearchOutputItemParam , error ) {
1287+ tools , err := toDeferredFunctionTools (ts .Tools )
1288+ if err != nil {
1289+ return nil , err
1290+ }
1291+ return & responses.ResponseToolSearchOutputItemParam {
1292+ Tools : tools ,
1293+ Execution : "server" ,
1294+ }, nil
1295+ }
1296+
12121297func mcpToolApprovalRequestToInputItem (block * schema.ContentBlock ) (item responses.ResponseInputItemUnionParam , err error ) {
12131298 content := block .MCPToolApprovalRequest
12141299 if content == nil {
@@ -1323,7 +1408,7 @@ func mcpToolResultToInputItem(block *schema.ContentBlock) (item responses.Respon
13231408 return item , nil
13241409}
13251410
1326- func toOutputMessage (resp * responses.Response ) (msg * schema.AgenticMessage , err error ) {
1411+ func toOutputMessage (resp * responses.Response , options * model. Options ) (msg * schema.AgenticMessage , err error ) {
13271412 blocks := make ([]* schema.ContentBlock , 0 , len (resp .Output ))
13281413
13291414 for _ , item := range resp .Output {
@@ -1411,6 +1496,19 @@ func toOutputMessage(resp *responses.Response) (msg *schema.AgenticMessage, err
14111496 return nil , fmt .Errorf ("failed to convert function shell output to content block: %w" , err )
14121497 }
14131498 tmpBlocks = []* schema.ContentBlock {block }
1499+ case responses.ResponseToolSearchCall :
1500+ block , err := toolSearchToolCallToContentBlock (variant , options )
1501+ if err != nil {
1502+ return nil , fmt .Errorf ("failed to convert tool search call to content block: %w" , err )
1503+ }
1504+ tmpBlocks = append (tmpBlocks , block )
1505+
1506+ case responses.ResponseToolSearchOutputItem :
1507+ block , err := toolSearchToolResultToContentBlock (variant )
1508+ if err != nil {
1509+ return nil , fmt .Errorf ("failed to convert tool search output item to content block: %w" , err )
1510+ }
1511+ tmpBlocks = append (tmpBlocks , block )
14141512
14151513 default :
14161514 return nil , fmt .Errorf ("unknown output item type: %T" , variant )
@@ -1631,6 +1729,64 @@ func webSearchToContentBlocks(item responses.ResponseFunctionWebSearch) (blocks
16311729 return blocks , nil
16321730}
16331731
1732+ func toolSearchToolCallToContentBlock (item responses.ResponseToolSearchCall , options * model.Options ) (* schema.ContentBlock , error ) {
1733+ args , err := json .Marshal (item .Arguments )
1734+ if err != nil {
1735+ return nil , fmt .Errorf ("failed to marshal tool search arguments: %w" , err )
1736+ }
1737+
1738+ switch item .Execution {
1739+ case responses .ResponseToolSearchCallExecutionClient :
1740+ if options .ToolSearchTool == nil {
1741+ return nil , fmt .Errorf ("haven't set client tool search tool, but get a client tool search tool call" )
1742+ }
1743+ block := schema .NewContentBlock (& schema.FunctionToolCall {
1744+ CallID : item .CallID ,
1745+ Name : options .ToolSearchTool .Name ,
1746+ Arguments : string (args ),
1747+ })
1748+ setItemID (block , item .ID )
1749+ setItemStatus (block , string (item .Status ))
1750+ setToolSearchToolCall (block )
1751+ return block , nil
1752+
1753+ case responses .ResponseToolSearchCallExecutionServer :
1754+ // server tool call
1755+ block := schema .NewContentBlock (& schema.ServerToolCall {
1756+ CallID : item .CallID ,
1757+ Arguments : & ServerToolCallArguments {
1758+ ToolSearch : & ToolSearchCall {
1759+ Arguments : args ,
1760+ },
1761+ },
1762+ })
1763+ setItemID (block , item .ID )
1764+ setItemStatus (block , string (item .Status ))
1765+ return block , nil
1766+
1767+ default :
1768+ return nil , fmt .Errorf ("invalid tool search execution type: %s" , item .Execution )
1769+ }
1770+ }
1771+
1772+ func toolSearchToolResultToContentBlock (item responses.ResponseToolSearchOutputItem ) (blocks * schema.ContentBlock , err error ) {
1773+ tools , err := fromFunctionTools (item .Tools )
1774+ if err != nil {
1775+ return nil , err
1776+ }
1777+ block := schema .NewContentBlock (& schema.ServerToolResult {
1778+ CallID : item .CallID ,
1779+ Result : & ServerToolResult {
1780+ ToolSearch : & ToolSearchResult {
1781+ Tools : tools ,
1782+ },
1783+ },
1784+ })
1785+ setItemID (block , item .ID )
1786+ setItemStatus (block , string (item .Status ))
1787+ return block , nil
1788+ }
1789+
16341790func fileSearchToContentBlocks (item responses.ResponseFileSearchToolCall ) (blocks []* schema.ContentBlock , err error ) {
16351791 args := & ServerToolCallArguments {
16361792 FileSearch : & FileSearchArguments {
0 commit comments