-module(examples@gemini_tool_call). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/examples/gemini_tool_call.gleam"). -export([main/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -file("src/examples/gemini_tool_call.gleam", 122). ?DOC(false). -spec handle_round( starlet:chat(starlet:tools_on(), starlet:free_text(), starlet:ready(), RWN), fun((starlet@tool:call()) -> {ok, starlet@tool:tool_result()} | {error, starlet@tool:tool_error()}), integer() ) -> {ok, starlet:chat(starlet:tools_on(), starlet:free_text(), starlet:ready(), RWN)} | {error, starlet:starlet_error()}. handle_round(Chat, Dispatcher, Round) -> gleam_stdlib:println( <<<<"--- Round "/utf8, (erlang:integer_to_binary(Round))/binary>>/binary, " ---"/utf8>> ), gleam@result:'try'(starlet:step(Chat), fun(Step) -> case Step of {done, Chat@1, Turn} -> gleam_stdlib:println( <<"Gemini: "/utf8, (starlet:text(Turn))/binary>> ), {ok, Chat@1}; {tool_call, Chat@2, _, Calls} -> gleam_stdlib:println(<<"Tool calls requested:"/utf8>>), gleam@list:each( Calls, fun(Call) -> gleam_stdlib:println( <<" - "/utf8, (starlet@tool:to_string(Call))/binary>> ) end ), gleam@result:'try'( starlet:apply_tool_results(Chat@2, Calls, Dispatcher), fun(Chat@3) -> gleam@result:'try'( starlet:step(Chat@3), fun(Step@1) -> case Step@1 of {done, Final_chat, Turn@1} -> gleam_stdlib:println( <<"Gemini: "/utf8, (starlet:text(Turn@1))/binary>> ), {ok, Final_chat}; {tool_call, Final_chat@1, Turn@2, _} -> gleam_stdlib:println( <<<<"Gemini (partial): "/utf8, (starlet:text(Turn@2))/binary>>/binary, " [more tools requested]"/utf8>> ), {ok, Final_chat@1} end end ) end ) end end). -file("src/examples/gemini_tool_call.gleam", 21). ?DOC(false). -spec run_example(binary()) -> nil. run_example(Api_key) -> Client = starlet@gemini:new(Api_key), Weather_tool = starlet@tool:function( <<"get_weather"/utf8>>, <<"Get the current weather for a city"/utf8>>, gleam@json:object( [{<<"type"/utf8>>, gleam@json:string(<<"object"/utf8>>)}, {<<"properties"/utf8>>, gleam@json:object( [{<<"city"/utf8>>, gleam@json:object( [{<<"type"/utf8>>, gleam@json:string(<<"string"/utf8>>)}, {<<"description"/utf8>>, gleam@json:string( <<"The city name"/utf8>> )}] )}] )}, {<<"required"/utf8>>, gleam@json:array([<<"city"/utf8>>], fun gleam@json:string/1)}] ) ), Multiply_tool = starlet@tool:function( <<"multiply"/utf8>>, <<"Multiply two integers together"/utf8>>, gleam@json:object( [{<<"type"/utf8>>, gleam@json:string(<<"object"/utf8>>)}, {<<"properties"/utf8>>, gleam@json:object( [{<<"a"/utf8>>, gleam@json:object( [{<<"type"/utf8>>, gleam@json:string( <<"integer"/utf8>> )}, {<<"description"/utf8>>, gleam@json:string( <<"The first number"/utf8>> )}] )}, {<<"b"/utf8>>, gleam@json:object( [{<<"type"/utf8>>, gleam@json:string( <<"integer"/utf8>> )}, {<<"description"/utf8>>, gleam@json:string( <<"The second number"/utf8>> )}] )}] )}, {<<"required"/utf8>>, gleam@json:array( [<<"a"/utf8>>, <<"b"/utf8>>], fun gleam@json:string/1 )}] ) ), Dispatcher = starlet@tool:dispatch( [starlet@tool:handler( <<"get_weather"/utf8>>, examples@utils:weather_decoder(), fun examples@utils:get_weather/1 ), starlet@tool:handler( <<"multiply"/utf8>>, examples@utils:multiply_decoder(), fun examples@utils:multiply/1 )] ), Result = begin Msg1 = <<"What's the weather like in Paris?"/utf8>>, Msg2 = <<"Thanks! What's 6 times 7?"/utf8>>, Msg3 = <<"Can you summarize what you told me?"/utf8>>, Chat = begin _pipe = starlet:chat(Client, <<"gemini-2.5-flash"/utf8>>), _pipe@1 = starlet:system( _pipe, <<"You are a helpful assistant. Use tools when asked about weather or multiplication."/utf8>> ), _pipe@2 = starlet:with_tools(_pipe@1, [Weather_tool, Multiply_tool]), starlet:user(_pipe@2, Msg1) end, gleam_stdlib:println(<<"User: "/utf8, Msg1/binary>>), gleam_stdlib:println(<<""/utf8>>), gleam@result:'try'( handle_round(Chat, Dispatcher, 1), fun(Chat@1) -> Chat@2 = starlet:user(Chat@1, Msg2), gleam_stdlib:println(<<"User: "/utf8, Msg2/binary>>), gleam_stdlib:println(<<""/utf8>>), gleam@result:'try'( handle_round(Chat@2, Dispatcher, 2), fun(Chat@3) -> Chat@4 = starlet:user(Chat@3, Msg3), gleam_stdlib:println(<<"User: "/utf8, Msg3/binary>>), gleam_stdlib:println(<<""/utf8>>), gleam@result:'try'( handle_round(Chat@4, Dispatcher, 3), fun(_) -> {ok, nil} end ) end ) end ) end, case Result of {ok, _} -> gleam_stdlib:println( <<"\nConversation completed successfully!"/utf8>> ); {error, Err} -> gleam_stdlib:println( <<"Error: "/utf8, (examples@utils:error_to_string(Err))/binary>> ) end. -file("src/examples/gemini_tool_call.gleam", 12). ?DOC(false). -spec main() -> nil. main() -> Api_key = begin _pipe = envoy_ffi:get(<<"GEMINI_API_KEY"/utf8>>), gleam@result:unwrap(_pipe, <<""/utf8>>) end, case Api_key of <<""/utf8>> -> gleam_stdlib:println( <<"Error: GEMINI_API_KEY environment variable not set"/utf8>> ); _ -> run_example(Api_key) end.