Skip to content

Commit cea0433

Browse files
Update version to 0.0.19 and enhance TinyCodeAgent functionality
This commit updates the version in pyproject.toml to 0.0.19 and improves the TinyCodeAgent class by refactoring tool management. The class now inherits from TinyAgent, streamlining the initialization process and enabling better management of Python and shell execution tools. Additionally, the system prompt update logic has been centralized, enhancing maintainability and clarity in the codebase.
1 parent ef9a663 commit cea0433

2 files changed

Lines changed: 57 additions & 133 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ tinyagent = ["prompts/*.yaml"]
1212

1313
[project]
1414
name = "tinyagent-py"
15-
version = "0.0.18"
16-
description = "TinyAgent with MCP Client, Code Agent (Thinking, Planning, and Executing in Python), and Extendable Hooks, Tiny but powerful"
15+
version = "0.0.19"
16+
description = "TinyAgent with MCP Client, CodeAgent (Thinking, Planning, Interactive Python and Shell with high variaety of sandboxing(seatbelt, Modal, E2B, docker, etc) ), and Extendable Hooks, Tiny but powerful"
1717
readme = "README.md"
1818
authors = [
1919
{name="Mahdi Golchin", email="golchin@askdev.ai"}

tinyagent/code_agent/tiny_code_agent.py

Lines changed: 55 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
)
3333

34-
class TinyCodeAgent:
34+
class TinyCodeAgent(TinyAgent):
3535
"""
3636
A TinyAgent specialized for code execution tasks.
3737
@@ -141,8 +141,8 @@ def __init__(
141141
self.auto_git_checkpoint = auto_git_checkpoint # Enable/disable automatic git checkpoints
142142

143143
# Store tool enablement flags
144-
self.enable_python_tool = enable_python_tool
145-
self.enable_shell_tool = enable_shell_tool
144+
self._python_tool_enabled = enable_python_tool
145+
self._shell_tool_enabled = enable_shell_tool
146146

147147
# Set up truncation configuration with defaults
148148
default_truncation = {
@@ -166,8 +166,8 @@ def __init__(
166166

167167
self.summary_config = summary_config or {}
168168

169-
# Create the underlying TinyAgent with summary configuration
170-
self.agent = TinyAgent(
169+
# Initialize the parent TinyAgent with the built system prompt
170+
super().__init__(
171171
model=model,
172172
api_key=api_key,
173173
system_prompt=self.system_prompt,
@@ -181,7 +181,7 @@ def __init__(
181181

182182
# Add LLM tools (not code tools - those go to the provider)
183183
if self.tools:
184-
self.agent.add_tools(self.tools)
184+
self.add_tools(self.tools)
185185

186186
# Add the selected UI callback
187187
if ui:
@@ -403,24 +403,19 @@ def _build_code_tools_prompt(self) -> str:
403403
def _setup_code_execution_tools(self):
404404
"""Set up the code execution tools using the code provider."""
405405
# Clear existing default tools to avoid duplicates
406-
# We need to remove tools by name since we can't directly access the tool objects
407-
existing_tools = self.agent.tools if hasattr(self.agent, 'tools') else []
408-
409-
# Remove existing default tools if they exist
410-
tools_to_remove = []
411-
for existing_tool in existing_tools:
412-
if hasattr(existing_tool, 'name') and existing_tool.name in ['run_python', 'bash']:
413-
tools_to_remove.append(existing_tool)
414-
415-
for existing_tool in tools_to_remove:
416-
if hasattr(self.agent, 'remove_tool'):
417-
self.agent.remove_tool(existing_tool)
418-
else:
419-
# Fallback: recreate the agent without the tools
420-
# This is a bit heavy-handed but ensures clean state
421-
pass
406+
# Remove existing default tools by name if they exist
407+
if hasattr(self, 'available_tools'):
408+
tools_to_remove = []
409+
for tool_dict in self.available_tools:
410+
if 'function' in tool_dict and 'name' in tool_dict['function']:
411+
if tool_dict['function']['name'] in ['run_python', 'bash']:
412+
tools_to_remove.append(tool_dict)
413+
414+
# Remove the tools from available_tools
415+
for tool_dict in tools_to_remove:
416+
self.available_tools.remove(tool_dict)
422417

423-
if self.enable_python_tool:
418+
if self._python_tool_enabled:
424419
@tool(name="run_python", description=dedent("""
425420
This tool receives Python code and executes it in a sandboxed environment.
426421
During each intermediate step, you can use 'print()' to save important information.
@@ -483,9 +478,9 @@ async def run_python(code_lines: List[str], timeout: int = 120) -> str:
483478

484479
return json.dumps({"error": f"Error executing code: {str(e)}"})
485480

486-
self.agent.add_tool(run_python)
481+
self.add_tool(run_python)
487482

488-
if self.enable_shell_tool:
483+
if self._shell_tool_enabled:
489484
@tool(name="bash", description=dedent("""
490485
This tool executes shell commands securely in a sandboxed environment.
491486
Only a limited set of safe commands are allowed for security reasons.
@@ -637,7 +632,7 @@ async def run_shell(command: List[str], absolute_workdir: str, description: str
637632

638633
return json.dumps({"error": f"Error executing shell command: {str(e)}"})
639634

640-
self.agent.add_tool(run_shell)
635+
self.add_tool(run_shell)
641636

642637
async def _create_git_checkpoint(self, command: List[str], description: str, workdir: str) -> Dict[str, Any]:
643638
"""
@@ -735,60 +730,17 @@ def get_default_workdir(self) -> str:
735730
"""
736731
return self.default_workdir
737732

738-
async def run(self, user_input: str, max_turns: int = 10) -> str:
739-
"""
740-
Run the code agent with the given input.
741-
742-
Args:
743-
user_input: The user's request or question
744-
max_turns: Maximum number of conversation turns
745-
746-
Returns:
747-
The agent's response
748-
"""
749-
return await self.agent.run(user_input, max_turns)
733+
750734

751-
async def resume(self, max_turns: int = 10) -> str:
752-
"""
753-
Resume the conversation without adding a new user message.
754-
755-
This method continues the conversation from the current state,
756-
allowing the agent to process the existing conversation history
757-
and potentially take additional actions.
758-
759-
Args:
760-
max_turns: Maximum number of conversation turns
761-
762-
Returns:
763-
The agent's response
764-
"""
765-
return await self.agent.resume(max_turns)
735+
766736

767-
async def connect_to_server(self, command: str, args: List[str], **kwargs):
768-
"""
769-
Connect to an MCP server and fetch available tools.
770-
771-
Args:
772-
command: The command to run the server
773-
args: List of arguments for the server
774-
**kwargs: Additional keyword arguments including:
775-
- include_tools: Optional list of tool name patterns to include
776-
- exclude_tools: Optional list of tool name patterns to exclude
777-
- env: Optional dictionary of environment variables to pass to the subprocess
778-
"""
779-
return await self.agent.connect_to_server(command, args, **kwargs)
737+
780738

781-
def add_callback(self, callback):
782-
"""Add a callback to the agent."""
783-
self.agent.add_callback(callback)
739+
784740

785-
def add_tool(self, tool):
786-
"""Add a tool to the agent (LLM tool)."""
787-
self.agent.add_tool(tool)
741+
788742

789-
def add_tools(self, tools: List[Any]):
790-
"""Add multiple tools to the agent (LLM tools)."""
791-
self.agent.add_tools(tools)
743+
792744

793745
def add_code_tool(self, tool):
794746
"""
@@ -802,8 +754,8 @@ def add_code_tool(self, tool):
802754
self.code_provider.set_code_tools(self.code_tools)
803755
# Rebuild system prompt to include new code tools info
804756
self.system_prompt = self._build_system_prompt()
805-
# Update the agent's system prompt
806-
self.agent.system_prompt = self.system_prompt
757+
# Update the system prompt in messages
758+
self._update_system_prompt()
807759

808760
def add_code_tools(self, tools: List[Any]):
809761
"""
@@ -817,8 +769,8 @@ def add_code_tools(self, tools: List[Any]):
817769
self.code_provider.set_code_tools(self.code_tools)
818770
# Rebuild system prompt to include new code tools info
819771
self.system_prompt = self._build_system_prompt()
820-
# Update the agent's system prompt
821-
self.agent.system_prompt = self.system_prompt
772+
# Update the system prompt in messages
773+
self._update_system_prompt()
822774

823775
def remove_code_tool(self, tool_name: str):
824776
"""
@@ -834,8 +786,8 @@ def remove_code_tool(self, tool_name: str):
834786
self.code_provider.set_code_tools(self.code_tools)
835787
# Rebuild system prompt
836788
self.system_prompt = self._build_system_prompt()
837-
# Update the agent's system prompt
838-
self.agent.system_prompt = self.system_prompt
789+
# Update the system prompt in messages
790+
self._update_system_prompt()
839791

840792
def get_code_tools(self) -> List[Any]:
841793
"""
@@ -866,8 +818,8 @@ def set_user_variables(self, variables: Dict[str, Any]):
866818
self.code_provider.set_user_variables(self.user_variables)
867819
# Rebuild system prompt to include new variables info
868820
self.system_prompt = self._build_system_prompt()
869-
# Update the agent's system prompt
870-
self.agent.system_prompt = self.system_prompt
821+
# Update the system prompt in messages
822+
self._update_system_prompt()
871823

872824
def add_user_variable(self, name: str, value: Any):
873825
"""
@@ -882,7 +834,7 @@ def add_user_variable(self, name: str, value: Any):
882834
# Rebuild system prompt to include new variables info
883835
self.system_prompt = self._build_system_prompt()
884836
# Update the agent's system prompt
885-
self.agent.system_prompt = self.system_prompt
837+
self._update_system_prompt()
886838

887839
def remove_user_variable(self, name: str):
888840
"""
@@ -897,7 +849,7 @@ def remove_user_variable(self, name: str):
897849
# Rebuild system prompt
898850
self.system_prompt = self._build_system_prompt()
899851
# Update the agent's system prompt
900-
self.agent.system_prompt = self.system_prompt
852+
self._update_system_prompt()
901853

902854
def get_user_variables(self) -> Dict[str, Any]:
903855
"""
@@ -965,7 +917,7 @@ def add_authorized_imports(self, imports: List[str]):
965917
# Rebuild system prompt to include new authorized imports
966918
self.system_prompt = self._build_system_prompt()
967919
# Update the agent's system prompt
968-
self.agent.system_prompt = self.system_prompt
920+
self._update_system_prompt()
969921

970922
def get_authorized_imports(self) -> List[str]:
971923
"""
@@ -1012,27 +964,22 @@ def remove_authorized_import(self, import_name: str):
1012964
# Rebuild system prompt to reflect updated authorized imports
1013965
self.system_prompt = self._build_system_prompt()
1014966
# Update the agent's system prompt
1015-
self.agent.system_prompt = self.system_prompt
967+
self._update_system_prompt()
1016968

1017969
async def close(self):
1018970
"""Clean up resources."""
1019971
await self.code_provider.cleanup()
1020-
await self.agent.close()
1021-
1022-
def clear_conversation(self):
1023-
"""Clear the conversation history."""
1024-
self.agent.clear_conversation()
972+
await super().close()
1025973

1026-
@property
1027-
def messages(self):
1028-
"""Get the conversation messages."""
1029-
return self.agent.messages
974+
1030975

1031-
@property
1032-
def session_id(self):
1033-
"""Get the session ID."""
1034-
return self.agent.session_id
976+
1035977

978+
def _update_system_prompt(self):
979+
"""Update the system prompt in the messages array."""
980+
if self.messages and len(self.messages) > 0:
981+
self.messages[0]["content"] = self.system_prompt
982+
1036983
def set_check_string_obfuscation(self, enabled: bool):
1037984
"""
1038985
Enable or disable string obfuscation detection.
@@ -1047,32 +994,9 @@ def set_check_string_obfuscation(self, enabled: bool):
1047994
if hasattr(self.code_provider, 'check_string_obfuscation'):
1048995
self.code_provider.check_string_obfuscation = enabled
1049996

1050-
async def summarize(self) -> str:
1051-
"""
1052-
Generate a summary of the current conversation history.
1053-
1054-
Args:
1055-
Returns:
1056-
A string containing the conversation summary
1057-
"""
1058-
# Use the underlying TinyAgent's summarize_conversation method
1059-
return await self.agent.summarize()
1060-
1061-
async def compact(self) -> bool:
1062-
"""
1063-
Compact the conversation history by replacing it with a summary.
1064-
1065-
This method delegates to the underlying TinyAgent's compact method,
1066-
which:
1067-
1. Generates a summary of the current conversation
1068-
2. If successful, replaces the conversation with just [system, user] messages
1069-
where the user message contains the summary
1070-
3. Returns True if compaction was successful, False otherwise
997+
1071998

1072-
Returns:
1073-
Boolean indicating whether the compaction was successful
1074-
"""
1075-
return await self.agent.compact()
999+
10761000

10771001
def add_ui_callback(self, ui_type: str, optimized: bool = True):
10781002
"""
@@ -1168,8 +1092,8 @@ def enable_python_tool(self, enabled: bool = True):
11681092
Args:
11691093
enabled: If True, enable the run_python tool. If False, disable it.
11701094
"""
1171-
if enabled != self.enable_python_tool:
1172-
self.enable_python_tool = enabled
1095+
if enabled != self._python_tool_enabled:
1096+
self._python_tool_enabled = enabled
11731097
# Re-setup tools to reflect the change
11741098
self._setup_code_execution_tools()
11751099

@@ -1180,8 +1104,8 @@ def enable_shell_tool(self, enabled: bool = True):
11801104
Args:
11811105
enabled: If True, enable the bash tool. If False, disable it.
11821106
"""
1183-
if enabled != self.enable_shell_tool:
1184-
self.enable_shell_tool = enabled
1107+
if enabled != self._shell_tool_enabled:
1108+
self._shell_tool_enabled = enabled
11851109
# Re-setup tools to reflect the change
11861110
self._setup_code_execution_tools()
11871111

@@ -1192,7 +1116,7 @@ def get_python_tool_status(self) -> bool:
11921116
Returns:
11931117
True if the run_python tool is enabled, False otherwise.
11941118
"""
1195-
return self.enable_python_tool
1119+
return self._python_tool_enabled
11961120

11971121
def get_shell_tool_status(self) -> bool:
11981122
"""
@@ -1201,7 +1125,7 @@ def get_shell_tool_status(self) -> bool:
12011125
Returns:
12021126
True if the bash tool is enabled, False otherwise.
12031127
"""
1204-
return self.enable_shell_tool
1128+
return self._shell_tool_enabled
12051129

12061130
def set_environment_variables(self, env_vars: Dict[str, str]):
12071131
"""

0 commit comments

Comments
 (0)