11import { Anthropic } from "@anthropic-ai/sdk"
2- import {
3- Content ,
4- EnhancedGenerateContentResponse ,
5- FunctionCallPart ,
6- FunctionDeclaration ,
7- FunctionResponsePart ,
8- InlineDataPart ,
9- Part ,
10- SchemaType ,
11- TextPart ,
12- } from "@google/generative-ai"
2+ import { Content , EnhancedGenerateContentResponse , InlineDataPart , Part , TextPart } from "@google/generative-ai"
133
144export function convertAnthropicContentToGemini ( content : string | Anthropic . ContentBlockParam [ ] ) : Part [ ] {
155 if ( typeof content === "string" ) {
@@ -29,55 +19,6 @@ export function convertAnthropicContentToGemini(content: string | Anthropic.Cont
2919 mimeType : block . source . media_type ,
3020 } ,
3121 } as InlineDataPart
32- case "tool_use" :
33- return {
34- functionCall : {
35- name : block . name ,
36- args : block . input ,
37- } ,
38- } as FunctionCallPart
39- case "tool_result" :
40- const name = block . tool_use_id . split ( "-" ) [ 0 ]
41- if ( ! block . content ) {
42- return [ ]
43- }
44- if ( typeof block . content === "string" ) {
45- return {
46- functionResponse : {
47- name,
48- response : {
49- name,
50- content : block . content ,
51- } ,
52- } ,
53- } as FunctionResponsePart
54- } else {
55- // The only case when tool_result could be array is when the tool failed and we're providing ie user feedback potentially with images
56- const textParts = block . content . filter ( ( part ) => part . type === "text" )
57- const imageParts = block . content . filter ( ( part ) => part . type === "image" )
58- const text = textParts . length > 0 ? textParts . map ( ( part ) => part . text ) . join ( "\n\n" ) : ""
59- const imageText = imageParts . length > 0 ? "\n\n(See next part for image)" : ""
60- return [
61- {
62- functionResponse : {
63- name,
64- response : {
65- name,
66- content : text + imageText ,
67- } ,
68- } ,
69- } as FunctionResponsePart ,
70- ...imageParts . map (
71- ( part ) =>
72- ( {
73- inlineData : {
74- data : part . source . data ,
75- mimeType : part . source . media_type ,
76- } ,
77- } ) as InlineDataPart ,
78- ) ,
79- ]
80- }
8122 default :
8223 throw new Error ( `Unsupported content block type: ${ ( block as any ) . type } ` )
8324 }
@@ -91,26 +32,6 @@ export function convertAnthropicMessageToGemini(message: Anthropic.Messages.Mess
9132 }
9233}
9334
94- export function convertAnthropicToolToGemini ( tool : Anthropic . Messages . Tool ) : FunctionDeclaration {
95- return {
96- name : tool . name ,
97- description : tool . description || "" ,
98- parameters : {
99- type : SchemaType . OBJECT ,
100- properties : Object . fromEntries (
101- Object . entries ( tool . input_schema . properties || { } ) . map ( ( [ key , value ] ) => [
102- key ,
103- {
104- type : ( value as any ) . type . toUpperCase ( ) ,
105- description : ( value as any ) . description || "" ,
106- } ,
107- ] ) ,
108- ) ,
109- required : ( tool . input_schema . required as string [ ] ) || [ ] ,
110- } ,
111- }
112- }
113-
11435/*
11536It looks like gemini likes to double escape certain characters when writing file contents: https://discuss.ai.google.dev/t/function-call-string-property-is-double-escaped/37867
11637*/
@@ -127,22 +48,6 @@ export function convertGeminiResponseToAnthropic(response: EnhancedGenerateConte
12748 content . push ( { type : "text" , text, citations : null } )
12849 }
12950
130- // Add function calls as tool_use blocks
131- const functionCalls = response . functionCalls ( )
132- if ( functionCalls ) {
133- functionCalls . forEach ( ( call , index ) => {
134- if ( "content" in call . args && typeof call . args . content === "string" ) {
135- call . args . content = unescapeGeminiContent ( call . args . content )
136- }
137- content . push ( {
138- type : "tool_use" ,
139- id : `${ call . name } -${ index } -${ Date . now ( ) } ` ,
140- name : call . name ,
141- input : call . args ,
142- } )
143- } )
144- }
145-
14651 // Determine stop reason
14752 let stop_reason : Anthropic . Messages . Message [ "stop_reason" ] = null
14853 const finishReason = response . candidates ?. [ 0 ] ?. finishReason
0 commit comments