33 * but Google's AI API defies all the established conventions
44 * so it made sense to defy them here as well.
55 */
6+
7+ const crypto = require ( 'crypto' ) ;
68module . exports = class GeminiSquareHole {
79 static process_input_messages = async ( messages ) => {
810 messages = messages . slice ( ) ;
@@ -14,6 +16,35 @@ module.exports = class GeminiSquareHole {
1416 if ( msg . role === 'assistant' ) {
1517 msg . role = 'model' ;
1618 }
19+
20+ for ( let i = 0 ; i < msg . parts . length ; i ++ ) {
21+ const part = msg . parts [ i ] ;
22+ console . log ( 'what the part is' , part ) ;
23+ if ( part . type === 'tool_use' ) {
24+ msg . parts [ i ] = {
25+ functionCall : {
26+ name : part . id ,
27+ args : part . input ,
28+ } ,
29+ } ;
30+ }
31+ if ( part . type === 'tool_result' ) {
32+ msg . parts [ i ] = {
33+ functionResponse : {
34+ name : part . tool_use_id ,
35+ response : {
36+ name : part . tool_use_id ,
37+ content : part . content ,
38+ } ,
39+ } ,
40+ } ;
41+ }
42+ if ( part . type === 'text' ) {
43+ msg . parts [ i ] = {
44+ text : part . text ,
45+ } ;
46+ }
47+ }
1748 }
1849
1950 return messages ;
@@ -46,7 +77,12 @@ module.exports = class GeminiSquareHole {
4677 usage_promise,
4778 } ) => async ( { chatStream } ) => {
4879 const message = chatStream . message ( ) ;
80+
4981 let textblock = message . contentBlock ( { type : 'text' } ) ;
82+ let toolblock = null ;
83+ let mode = 'text' ;
84+
85+
5086 let last_usage = null ;
5187 for await ( const chunk of stream ) {
5288 // This is spread across several lines so that the stack trace
@@ -56,6 +92,31 @@ module.exports = class GeminiSquareHole {
5692 const content = candidate . content ;
5793 const parts = content . parts ;
5894 for ( const part of parts ) {
95+ if ( part . functionCall ) {
96+ if ( mode === 'text' ) {
97+ mode = 'tool' ;
98+ textblock . end ( ) ;
99+ }
100+
101+ toolblock = message . contentBlock ( {
102+ type : 'tool_use' ,
103+ id : part . functionCall . name ,
104+ name : part . functionCall . name ,
105+ } ) ;
106+ toolblock . addPartialJSON ( JSON . stringify (
107+ part . functionCall . args ,
108+ ) ) ;
109+
110+ continue ;
111+ }
112+
113+ if ( mode === 'tool' ) {
114+ mode = 'text' ;
115+ toolblock . end ( ) ;
116+ textblock = message . contentBlock ( { type : 'text' } ) ;
117+ }
118+
119+ // assume text as default
59120 const text = part . text ;
60121 textblock . addText ( text ) ;
61122 }
@@ -65,7 +126,8 @@ module.exports = class GeminiSquareHole {
65126
66127 usage_promise . resolve ( last_usage ) ;
67128
68- textblock . end ( ) ;
129+ if ( mode === 'text' ) textblock . end ( ) ;
130+ if ( mode === 'tool' ) toolblock . end ( ) ;
69131 message . end ( ) ;
70132 chatStream . end ( ) ;
71133 }
0 commit comments