Mahdiyar
Add initial implementation of TinyCodeAgent with Python code execution capabilities
ebb6a31
| import yaml | |
| from jinja2 import Template | |
| from textwrap import dedent | |
| prompt_code_example = dedent(""" | |
| User: How the following repo has implemented Logging, and how can I make it compatible with Facebook Standard Logging? github url: https://github.com/askbudi/tinyagent | |
| function_calling: run_python | |
| run_python("task='How the following repo has implemented Logging, and how can I make it compatible with Facebook Standard Logging?'", | |
| "repo_result = code_research(repo_url='https://github.com/askbudi/tinyagent',task='How the following repo has implemented Logging, and how can I make it compatible with Facebook Standard Logging?')", | |
| "print(repo_result)", | |
| "answer_for_user_review = problem_solver(task=task,context=repo_result)", | |
| "print(answer_for_user_review)", | |
| """) | |
| def load_template(path: str) -> str: | |
| """ | |
| Load the YAML file and extract its 'system_prompt' field. | |
| """ | |
| with open(path, "r") as f: | |
| data = yaml.safe_load(f) | |
| return data["system_prompt"] | |
| def render_system_prompt(template_str: str, | |
| tools: dict, | |
| managed_agents: dict, | |
| authorized_imports) -> str: | |
| """ | |
| Render the Jinja2 template with the given context. | |
| """ | |
| tmpl = Template(template_str) | |
| return tmpl.render( | |
| tools=tools, | |
| managed_agents=managed_agents, | |
| authorized_imports=authorized_imports | |
| ) | |
| from tinyagent import tool | |
| import asyncio | |
| from typing import Any, Dict | |
| import inspect | |
| from typing import get_type_hints | |
| def translate_tool_for_code_agent(tool_func_or_class: Any) -> Dict[str, Any]: | |
| """ | |
| Translate a tool decorated with @tool into a format compatible with code_agent.yaml. | |
| Args: | |
| tool_func_or_class: A function or class decorated with @tool | |
| Returns: | |
| A dictionary with the tool configuration in code_agent.yaml format | |
| """ | |
| def _get_type_as_string(type_hint: Any) -> str: | |
| """ | |
| Convert a type hint to its string representation. | |
| Args: | |
| type_hint: The type hint to convert | |
| Returns: | |
| String representation of the type | |
| """ | |
| if type_hint is Any: | |
| return "Any" | |
| # Handle common types | |
| type_map = { | |
| str: "str", | |
| int: "int", | |
| float: "float", | |
| bool: "bool", | |
| list: "List", | |
| dict: "Dict", | |
| tuple: "Tuple", | |
| None: "None" | |
| } | |
| if type_hint in type_map: | |
| return type_map[type_hint] | |
| # Try to get the name attribute | |
| if hasattr(type_hint, "__name__"): | |
| return type_hint.__name__ | |
| # For generic types like List[str], Dict[str, int], etc. | |
| return str(type_hint).replace("typing.", "") | |
| # Check if the tool has the required metadata | |
| if not hasattr(tool_func_or_class, '_tool_metadata'): | |
| raise ValueError("Tool must be decorated with @tool decorator") | |
| metadata = tool_func_or_class._tool_metadata | |
| # Check if it's an async function | |
| is_async = asyncio.iscoroutinefunction(tool_func_or_class) | |
| if metadata["is_class"] and hasattr(tool_func_or_class, "__call__"): | |
| is_async = asyncio.iscoroutinefunction(tool_func_or_class.__call__) | |
| # Get the function signature for parameter types | |
| if metadata["is_class"]: | |
| func_to_inspect = tool_func_or_class.__init__ | |
| else: | |
| func_to_inspect = tool_func_or_class | |
| sig = inspect.signature(func_to_inspect) | |
| type_hints = get_type_hints(func_to_inspect) | |
| # Build inputs dictionary | |
| inputs = {} | |
| for name, param in sig.parameters.items(): | |
| if name in ['self', 'cls']: | |
| continue | |
| param_type = type_hints.get(name, Any) | |
| param_type_str = _get_type_as_string(param_type) | |
| # Get parameter description from schema if available | |
| param_desc = "" | |
| if metadata["schema"] and "properties" in metadata["schema"]: | |
| if name in metadata["schema"]["properties"]: | |
| param_desc = metadata["schema"]["properties"][name].get("description", "") | |
| inputs[name] = { | |
| "type": param_type_str, | |
| "description": param_desc | |
| } | |
| # Determine output type | |
| output_type = "Any" | |
| if "return" in type_hints: | |
| output_type = _get_type_as_string(type_hints["return"]) | |
| # Create the tool config | |
| tool_config = { | |
| "name": metadata["name"], | |
| "description": metadata["description"], | |
| "inputs": inputs, | |
| "output_type": output_type, | |
| "is_async": is_async | |
| } | |
| return tool_config | |