diff --git a/calculator/README.md b/calculator/README.md new file mode 100644 index 0000000..af69754 --- /dev/null +++ b/calculator/README.md @@ -0,0 +1 @@ +# calculator \ No newline at end of file diff --git a/calculator/lorem.txt b/calculator/lorem.txt new file mode 100644 index 0000000..900ea57 --- /dev/null +++ b/calculator/lorem.txt @@ -0,0 +1 @@ +wait, this isn't lorem ipsum \ No newline at end of file diff --git a/calculator/test_output.txt b/calculator/test_output.txt new file mode 100644 index 0000000..95d09f2 --- /dev/null +++ b/calculator/test_output.txt @@ -0,0 +1 @@ +hello world \ No newline at end of file diff --git a/functions/call_function.py b/functions/call_function.py new file mode 100644 index 0000000..40eb3e8 --- /dev/null +++ b/functions/call_function.py @@ -0,0 +1,57 @@ +import os +from google.genai import types + +from functions.get_files_info import get_files_info +from functions.get_file_content import get_file_content +from functions.write_file import write_file +from functions.run_python_file import run_python_file + + +def call_function(function_call_part, verbose=False): + + function_name = function_call_part.name + args = dict(function_call_part.args or {}) + + args["working_directory"] = "./calculator" + + function_map = { + "get_files_info": get_files_info, + "get_file_content": get_file_content, + "write_file": write_file, + "run_python_file": run_python_file, + } + + if verbose: + print(f"Calling function: {function_name}({args})") + else: + print(f" - Calling function: {function_name}") + + if function_name not in function_map: + return types.Content( + role="tool", + parts=[ + types.Part.from_function_response( + name=function_name, + response={"error": f"Unknown function: {function_name}"}, + ) + ], + ) + + try: + function_result = function_map[function_name](**args) + except Exception as e: + function_result = f"Error executing function: {e}" + + tool_response = types.Content( + role="tool", + parts=[ + types.Part.from_function_response( + name=function_name, response={"result": function_result} + ) + ], + ) + + if verbose: + print(f"-> {tool_response.parts[0].function_response.response}") + + return tool_response \ No newline at end of file diff --git a/main.py b/main.py index 88ad19f..42b1774 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,7 @@ import sys from dotenv import load_dotenv from google import genai from google.genai import types +from functions.call_function import call_function from functions.get_files_info import schema_get_files_info from functions.get_file_content import schema_get_file_content from functions.run_python_file import schema_run_python_file @@ -75,14 +76,17 @@ def main(): if response.candidates[0].content.parts: for part in response.candidates[0].content.parts: if part.function_call: - function_call_part = part.function_call - print(f"Calling function: {function_call_part.name}({function_call_part.args})") + function_result = call_function(part.function_call, verbose=verbose) + # validate that function call produced a response + if not ( + function_result.parts + and function_result.parts[0].function_response + and function_result.parts[0].function_response.response + ): + raise RuntimeError("Fatal: Function call returned no response.") elif part.text: reply_text = part.text - - # Add AI response to history add_message("model", reply_text) - print(reply_text) if verbose: