tinyagent-py 0.0.11__tar.gz → 0.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tinyagent_py-0.0.11/tinyagent_py.egg-info → tinyagent_py-0.0.12}/PKG-INFO +1 -1
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/pyproject.toml +1 -1
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/modal_sandbox.py +3 -1
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/providers/modal_provider.py +45 -13
- tinyagent_py-0.0.12/tinyagent/code_agent/safety.py +546 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/tiny_code_agent.py +91 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/utils.py +59 -10
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/hooks/gradio_callback.py +97 -33
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/tiny_agent.py +4 -7
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12/tinyagent_py.egg-info}/PKG-INFO +1 -1
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent_py.egg-info/SOURCES.txt +1 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/LICENSE +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/README.md +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/setup.cfg +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/example.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/helper.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/providers/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/providers/base.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/tools/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/tools/example_tools.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/hooks/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/hooks/logging_manager.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/hooks/rich_code_ui_callback.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/hooks/rich_ui_callback.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/mcp_client.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/memory_manager.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/prompts/code_agent.yaml +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/__init__.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/base.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/json_file_storage.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/postgres_storage.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/redis_storage.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/storage/sqlite_storage.py +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent_py.egg-info/dependency_links.txt +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent_py.egg-info/requires.txt +0 -0
- {tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent_py.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: tinyagent-py
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.12
|
4
4
|
Summary: TinyAgent with MCP Client, Code Agent (Thinking, Planning, and Executing in Python), and Extendable Hooks, Tiny but powerful
|
5
5
|
Author-email: Mahdi Golchin <golchin@askdev.ai>
|
6
6
|
Project-URL: Homepage, https://github.com/askbudi/tinyagent
|
@@ -12,7 +12,7 @@ tinyagent = ["prompts/*.yaml"]
|
|
12
12
|
|
13
13
|
[project]
|
14
14
|
name = "tinyagent-py"
|
15
|
-
version = "0.0.
|
15
|
+
version = "0.0.12"
|
16
16
|
description = "TinyAgent with MCP Client, Code Agent (Thinking, Planning, and Executing in Python), and Extendable Hooks, Tiny but powerful"
|
17
17
|
readme = "README.md"
|
18
18
|
authors = [
|
@@ -63,6 +63,7 @@ def create_sandbox(
|
|
63
63
|
pip_install: Sequence[str] | None = None,
|
64
64
|
image_name: str = "tinyagent-sandbox-image",
|
65
65
|
app_name: str = "persistent-code-session",
|
66
|
+
force_build: bool = False,
|
66
67
|
**sandbox_kwargs,
|
67
68
|
) -> Tuple[modal.Sandbox, modal.App]:
|
68
69
|
"""Create (or lookup) a `modal.Sandbox` pre-configured for code execution.
|
@@ -99,7 +100,7 @@ def create_sandbox(
|
|
99
100
|
|
100
101
|
# Build image -----------------------------------------------------------
|
101
102
|
agent_image = (
|
102
|
-
modal.Image.debian_slim(python_version=python_version)
|
103
|
+
modal.Image.debian_slim(python_version=python_version,force_build=force_build)
|
103
104
|
.apt_install(*apt_packages)
|
104
105
|
.pip_install(*full_pip_list)
|
105
106
|
)
|
@@ -196,6 +197,7 @@ class SandboxSession:
|
|
196
197
|
modal_secrets: modal.Secret,
|
197
198
|
*,
|
198
199
|
timeout: int = 5 * 60,
|
200
|
+
|
199
201
|
**create_kwargs,
|
200
202
|
) -> None:
|
201
203
|
self.modal_secrets = modal_secrets
|
{tinyagent_py-0.0.11 → tinyagent_py-0.0.12}/tinyagent/code_agent/providers/modal_provider.py
RENAMED
@@ -26,6 +26,7 @@ class ModalProvider(CodeExecutionProvider):
|
|
26
26
|
default_packages: Optional[List[str]] = None,
|
27
27
|
apt_packages: Optional[List[str]] = None,
|
28
28
|
python_version: Optional[str] = None,
|
29
|
+
authorized_imports: list[str] | None = None,
|
29
30
|
modal_secrets: Dict[str, Union[str, None]] | None = None,
|
30
31
|
lazy_init: bool = True,
|
31
32
|
sandbox_name: str = "tinycodeagent-sandbox",
|
@@ -48,6 +49,7 @@ class ModalProvider(CodeExecutionProvider):
|
|
48
49
|
(git, curl, …) so you only need to specify the extras.
|
49
50
|
python_version: Python version used for the sandbox image. If
|
50
51
|
``None`` the current interpreter version is used.
|
52
|
+
authorized_imports: Optional allow-list of modules the user code is permitted to import. Supports wildcard patterns (e.g. "pandas.*"). If ``None`` the safety layer blocks only the predefined dangerous modules.
|
51
53
|
"""
|
52
54
|
|
53
55
|
# Resolve default values ------------------------------------------------
|
@@ -70,6 +72,7 @@ class ModalProvider(CodeExecutionProvider):
|
|
70
72
|
self.default_packages: List[str] = default_packages
|
71
73
|
self.apt_packages: List[str] = apt_packages
|
72
74
|
self.python_version: str = python_version
|
75
|
+
self.authorized_imports = authorized_imports
|
73
76
|
|
74
77
|
# ----------------------------------------------------------------------
|
75
78
|
final_packages = list(set(self.default_packages + (pip_packages or [])))
|
@@ -89,6 +92,7 @@ class ModalProvider(CodeExecutionProvider):
|
|
89
92
|
self.modal_secrets = modal.Secret.from_dict(self.secrets)
|
90
93
|
self.app = None
|
91
94
|
self._app_run_python = None
|
95
|
+
self.is_trusted_code = kwargs.get("trust_code", False)
|
92
96
|
|
93
97
|
self._setup_modal_app()
|
94
98
|
|
@@ -164,18 +168,30 @@ class ModalProvider(CodeExecutionProvider):
|
|
164
168
|
if self.executed_default_codes:
|
165
169
|
print("✔️ default codes already executed")
|
166
170
|
full_code = "\n".join(self.code_tools_definitions) +"\n\n"+code
|
171
|
+
# Code tools and default code are trusted, user code is not
|
167
172
|
else:
|
168
173
|
full_code = "\n".join(self.code_tools_definitions) +"\n\n"+ "\n".join(self.default_python_codes) + "\n\n" + code
|
169
174
|
self.executed_default_codes = True
|
175
|
+
# First execution includes framework code which is trusted
|
170
176
|
|
171
177
|
# Use Modal's native execution methods
|
172
178
|
if self.local_execution:
|
173
|
-
|
174
|
-
|
179
|
+
return self._app_run_python.local(
|
180
|
+
full_code,
|
181
|
+
globals_dict or {},
|
182
|
+
locals_dict or {},
|
183
|
+
self.authorized_imports,
|
184
|
+
self.is_trusted_code,
|
185
|
+
)
|
175
186
|
else:
|
176
|
-
# Use Modal's .remote() method for remote execution
|
177
187
|
with self.app.run():
|
178
|
-
return self._app_run_python.remote(
|
188
|
+
return self._app_run_python.remote(
|
189
|
+
full_code,
|
190
|
+
globals_dict or {},
|
191
|
+
locals_dict or {},
|
192
|
+
self.authorized_imports,
|
193
|
+
self.is_trusted_code,
|
194
|
+
)
|
179
195
|
|
180
196
|
def _log_response(self, response: Dict[str, Any]):
|
181
197
|
"""Log the response from code execution."""
|
@@ -184,15 +200,31 @@ class ModalProvider(CodeExecutionProvider):
|
|
184
200
|
print("#########################<printed_output>#########################")
|
185
201
|
print(response["printed_output"])
|
186
202
|
print("#########################</printed_output>#########################")
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
203
|
+
if response.get("return_value",None) not in [None,""]:
|
204
|
+
print("#########################<return_value>#########################")
|
205
|
+
print(response["return_value"])
|
206
|
+
print("#########################</return_value>#########################")
|
207
|
+
if response.get("stderr",None) not in [None,""]:
|
208
|
+
print("#########################<stderr>#########################")
|
209
|
+
print(response["stderr"])
|
210
|
+
print("#########################</stderr>#########################")
|
211
|
+
if response.get("error_traceback",None) not in [None,""]:
|
212
|
+
print("#########################<traceback>#########################")
|
213
|
+
# Check if this is a security exception and highlight it in red if so
|
214
|
+
error_text = response["error_traceback"]
|
215
|
+
if "SECURITY" in error_text:
|
216
|
+
try:
|
217
|
+
from ..modal_sandbox import COLOR
|
218
|
+
except ImportError:
|
219
|
+
# Fallback colors if modal_sandbox is not available
|
220
|
+
COLOR = {
|
221
|
+
"RED": "\033[91m",
|
222
|
+
"ENDC": "\033[0m",
|
223
|
+
}
|
224
|
+
print(f"{COLOR['RED']}{error_text}{COLOR['ENDC']}")
|
225
|
+
else:
|
226
|
+
print(error_text)
|
227
|
+
print("#########################</traceback>#########################")
|
196
228
|
|
197
229
|
async def cleanup(self):
|
198
230
|
"""Clean up Modal resources."""
|