sandboxy 0.0.1__py3-none-any.whl

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.
Files changed (60) hide show
  1. sandboxy/__init__.py +3 -0
  2. sandboxy/agents/__init__.py +21 -0
  3. sandboxy/agents/base.py +66 -0
  4. sandboxy/agents/llm_prompt.py +308 -0
  5. sandboxy/agents/loader.py +222 -0
  6. sandboxy/api/__init__.py +5 -0
  7. sandboxy/api/app.py +76 -0
  8. sandboxy/api/routes/__init__.py +1 -0
  9. sandboxy/api/routes/agents.py +92 -0
  10. sandboxy/api/routes/local.py +1388 -0
  11. sandboxy/api/routes/tools.py +106 -0
  12. sandboxy/cli/__init__.py +1 -0
  13. sandboxy/cli/main.py +1196 -0
  14. sandboxy/cli/type_detector.py +48 -0
  15. sandboxy/config.py +49 -0
  16. sandboxy/core/__init__.py +1 -0
  17. sandboxy/core/async_runner.py +824 -0
  18. sandboxy/core/mdl_parser.py +441 -0
  19. sandboxy/core/runner.py +599 -0
  20. sandboxy/core/safe_eval.py +165 -0
  21. sandboxy/core/state.py +234 -0
  22. sandboxy/datasets/__init__.py +20 -0
  23. sandboxy/datasets/loader.py +193 -0
  24. sandboxy/datasets/runner.py +442 -0
  25. sandboxy/errors.py +166 -0
  26. sandboxy/local/context.py +235 -0
  27. sandboxy/local/results.py +173 -0
  28. sandboxy/logging.py +31 -0
  29. sandboxy/mcp/__init__.py +25 -0
  30. sandboxy/mcp/client.py +360 -0
  31. sandboxy/mcp/wrapper.py +99 -0
  32. sandboxy/providers/__init__.py +34 -0
  33. sandboxy/providers/anthropic_provider.py +271 -0
  34. sandboxy/providers/base.py +123 -0
  35. sandboxy/providers/http_client.py +101 -0
  36. sandboxy/providers/openai_provider.py +282 -0
  37. sandboxy/providers/openrouter.py +958 -0
  38. sandboxy/providers/registry.py +199 -0
  39. sandboxy/scenarios/__init__.py +11 -0
  40. sandboxy/scenarios/comparison.py +491 -0
  41. sandboxy/scenarios/loader.py +262 -0
  42. sandboxy/scenarios/runner.py +468 -0
  43. sandboxy/scenarios/unified.py +1434 -0
  44. sandboxy/session/__init__.py +21 -0
  45. sandboxy/session/manager.py +278 -0
  46. sandboxy/tools/__init__.py +34 -0
  47. sandboxy/tools/base.py +127 -0
  48. sandboxy/tools/loader.py +270 -0
  49. sandboxy/tools/yaml_tools.py +708 -0
  50. sandboxy/ui/__init__.py +27 -0
  51. sandboxy/ui/dist/assets/index-CgAkYWrJ.css +1 -0
  52. sandboxy/ui/dist/assets/index-D4zoGFcr.js +347 -0
  53. sandboxy/ui/dist/index.html +14 -0
  54. sandboxy/utils/__init__.py +3 -0
  55. sandboxy/utils/time.py +20 -0
  56. sandboxy-0.0.1.dist-info/METADATA +241 -0
  57. sandboxy-0.0.1.dist-info/RECORD +60 -0
  58. sandboxy-0.0.1.dist-info/WHEEL +4 -0
  59. sandboxy-0.0.1.dist-info/entry_points.txt +3 -0
  60. sandboxy-0.0.1.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,106 @@
1
+ """Tool listing routes with config schemas."""
2
+
3
+ import logging
4
+ from typing import Any
5
+
6
+ from fastapi import APIRouter, HTTPException
7
+ from pydantic import BaseModel
8
+
9
+ from sandboxy.tools.base import ToolConfig
10
+ from sandboxy.tools.loader import BUILTIN_TOOLS, load_tool_class
11
+
12
+ logger = logging.getLogger(__name__)
13
+ router = APIRouter()
14
+
15
+
16
+ class ToolAction(BaseModel):
17
+ """Schema for a tool action."""
18
+
19
+ name: str
20
+ description: str
21
+ parameters: dict[str, Any]
22
+
23
+
24
+ class ToolResponse(BaseModel):
25
+ """Response model for a tool."""
26
+
27
+ id: str
28
+ name: str
29
+ description: str | None = None
30
+ config_schema: dict[str, Any]
31
+ actions: list[ToolAction]
32
+
33
+
34
+ class ToolListResponse(BaseModel):
35
+ """Response model for tool listing."""
36
+
37
+ tools: list[ToolResponse]
38
+ count: int
39
+
40
+
41
+ def _load_tools() -> list[ToolResponse]:
42
+ """Load tools and their schemas from the built-in tools registry."""
43
+ tools = []
44
+
45
+ for tool_id, tool_path in BUILTIN_TOOLS.items():
46
+ try:
47
+ tool_class = load_tool_class(tool_path)
48
+
49
+ # Get config schema if available
50
+ config_schema = {}
51
+ if hasattr(tool_class, "config_schema"):
52
+ config_schema = tool_class.config_schema()
53
+
54
+ # Get actions by instantiating with minimal config
55
+ actions = []
56
+ try:
57
+ # Create a minimal ToolConfig for instantiation
58
+ minimal_config = ToolConfig(name=tool_id, type=tool_id)
59
+ tool_instance = tool_class(minimal_config)
60
+ if hasattr(tool_instance, "get_actions"):
61
+ raw_actions = tool_instance.get_actions()
62
+ for action in raw_actions:
63
+ actions.append(
64
+ ToolAction(
65
+ name=action.get("name", ""),
66
+ description=action.get("description", ""),
67
+ parameters=action.get("parameters", {}),
68
+ )
69
+ )
70
+ except Exception as e:
71
+ # If instantiation fails, skip actions but log the issue
72
+ logger.debug("Could not instantiate tool %s for action discovery: %s", tool_id, e)
73
+
74
+ tools.append(
75
+ ToolResponse(
76
+ id=tool_id,
77
+ name=tool_class.__name__,
78
+ description=tool_class.__doc__,
79
+ config_schema=config_schema,
80
+ actions=actions,
81
+ )
82
+ )
83
+ except Exception as e:
84
+ # Skip tools that fail to load but log the error
85
+ logger.warning("Failed to load tool %s: %s", tool_id, e)
86
+ continue
87
+
88
+ return tools
89
+
90
+
91
+ @router.get("/tools", response_model=ToolListResponse)
92
+ async def list_tools():
93
+ """List all available tools with their config schemas and actions."""
94
+ tools = _load_tools()
95
+ return ToolListResponse(tools=tools, count=len(tools))
96
+
97
+
98
+ @router.get("/tools/{tool_id}", response_model=ToolResponse)
99
+ async def get_tool(tool_id: str):
100
+ """Get a specific tool by ID."""
101
+ tools = _load_tools()
102
+ for tool in tools:
103
+ if tool.id == tool_id:
104
+ return tool
105
+
106
+ raise HTTPException(status_code=404, detail=f"Tool not found: {tool_id}")
@@ -0,0 +1 @@
1
+ """CLI module - Command-line interface for Sandboxy."""