@@ -375,29 +375,71 @@ func anthropicRoleToOpenAIRole(role anthropic.MessageParamRole) (string, error)
375375 }
376376}
377377
378+ // processAssistantContent processes a single ChatCompletionAssistantMessageParamContent and returns the corresponding Anthropic content block.
379+ func processAssistantContent (content openai.ChatCompletionAssistantMessageParamContent ) (* anthropic.ContentBlockParamUnion , error ) {
380+ switch content .Type {
381+ case openai .ChatCompletionAssistantMessageParamContentTypeRefusal :
382+ if content .Refusal != nil {
383+ block := anthropic .NewTextBlock (* content .Refusal )
384+ return & block , nil
385+ }
386+ case openai .ChatCompletionAssistantMessageParamContentTypeText :
387+ if content .Text != nil {
388+ textBlock := anthropic .NewTextBlock (* content .Text )
389+ if isCacheEnabled (content .AnthropicContentFields ) {
390+ textBlock .OfText .CacheControl = content .CacheControl
391+ }
392+ return & textBlock , nil
393+ }
394+ case openai .ChatCompletionAssistantMessageParamContentTypeThinking :
395+ // thinking can not be cached: https://platform.claude.com/docs/en/build-with-claude/prompt-caching
396+ if content .Text != nil && content .Signature != nil {
397+ thinkBlock := anthropic .NewThinkingBlock (* content .Text , * content .Signature )
398+ return & thinkBlock , nil
399+ }
400+ case openai .ChatCompletionAssistantMessageParamContentTypeRedactedThinking :
401+ if content .RedactedContent != nil {
402+ switch v := content .RedactedContent .Value .(type ) {
403+ case string :
404+ redactedThinkingBlock := anthropic .NewRedactedThinkingBlock (v )
405+ return & redactedThinkingBlock , nil
406+ case []byte :
407+ return nil , fmt .Errorf ("GCP Anthropic does not support []byte format for RedactedContent, expected string" )
408+ default :
409+ return nil , fmt .Errorf ("unsupported RedactedContent type: %T, expected string" , v )
410+ }
411+ }
412+ default :
413+ return nil , fmt .Errorf ("content type not supported: %v" , content .Type )
414+ }
415+ return nil , nil
416+ }
417+
378418// openAIMessageToAnthropicMessageRoleAssistant converts an OpenAI assistant message to Anthropic content blocks.
379419// The tool_use content is appended to the Anthropic message content list if tool_calls are present.
380420func openAIMessageToAnthropicMessageRoleAssistant (openAiMessage * openai.ChatCompletionAssistantMessageParam ) (anthropicMsg anthropic.MessageParam , err error ) {
381421 contentBlocks := make ([]anthropic.ContentBlockParamUnion , 0 )
382422 if v , ok := openAiMessage .Content .Value .(string ); ok && len (v ) > 0 {
383423 contentBlocks = append (contentBlocks , anthropic .NewTextBlock (v ))
384424 } else if content , ok := openAiMessage .Content .Value .(openai.ChatCompletionAssistantMessageParamContent ); ok {
385- switch content .Type {
386- case openai .ChatCompletionAssistantMessageParamContentTypeRefusal :
387- if content .Refusal != nil {
388- contentBlocks = append (contentBlocks , anthropic .NewTextBlock (* content .Refusal ))
389- }
390- case openai .ChatCompletionAssistantMessageParamContentTypeText :
391- if content .Text != nil {
392- textBlock := anthropic .NewTextBlock (* content .Text )
393- if isCacheEnabled (content .AnthropicContentFields ) {
394- textBlock .OfText .CacheControl = content .CacheControl
395- }
396- contentBlocks = append (contentBlocks , textBlock )
425+ // Handle single content object
426+ var block * anthropic.ContentBlockParamUnion
427+ block , err = processAssistantContent (content )
428+ if err != nil {
429+ return anthropicMsg , err
430+ } else if block != nil {
431+ contentBlocks = append (contentBlocks , * block )
432+ }
433+ } else if contents , ok := openAiMessage .Content .Value .([]openai.ChatCompletionAssistantMessageParamContent ); ok {
434+ // Handle array of content objects
435+ for _ , content := range contents {
436+ var block * anthropic.ContentBlockParamUnion
437+ block , err = processAssistantContent (content )
438+ if err != nil {
439+ return anthropicMsg , err
440+ } else if block != nil {
441+ contentBlocks = append (contentBlocks , * block )
397442 }
398- default :
399- err = fmt .Errorf ("content type not supported: %v" , content .Type )
400- return
401443 }
402444 }
403445
0 commit comments