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,48 @@
1
+ """YAML type detection for unified CLI dispatcher."""
2
+
3
+ from typing import Any, Literal
4
+
5
+ YamlType = Literal["scenario", "module"]
6
+
7
+ VALID_TYPES: set[str] = {"scenario", "module"}
8
+
9
+
10
+ def detect_yaml_type(data: dict[str, Any]) -> YamlType:
11
+ """Detect YAML type from structure.
12
+
13
+ Detection priority:
14
+ 1. Explicit `type:` field
15
+ 2. Scenario: has `goals` or `tools_from`
16
+ 3. Module (legacy): has `environment.sandbox_type`
17
+
18
+ Args:
19
+ data: Parsed YAML data
20
+
21
+ Returns:
22
+ Detected type string
23
+
24
+ Raises:
25
+ ValueError: If type cannot be detected
26
+
27
+ """
28
+ # Explicit type field takes priority
29
+ if "type" in data:
30
+ explicit_type = data["type"]
31
+ if explicit_type not in VALID_TYPES:
32
+ raise ValueError(
33
+ f"Invalid type '{explicit_type}'. Valid types: {', '.join(sorted(VALID_TYPES))}"
34
+ )
35
+ return explicit_type # type: ignore[return-value]
36
+
37
+ # Scenario: has goals or tools_from
38
+ if "goals" in data or "tools_from" in data:
39
+ return "scenario"
40
+
41
+ # Module (legacy): has environment with sandbox_type
42
+ if "environment" in data:
43
+ env = data.get("environment", {})
44
+ if isinstance(env, dict) and "sandbox_type" in env:
45
+ return "module"
46
+
47
+ # Default to scenario - the unified format handles everything
48
+ return "scenario"
sandboxy/config.py ADDED
@@ -0,0 +1,49 @@
1
+ """Centralized configuration for Sandboxy.
2
+
3
+ All configuration is loaded from environment variables with SANDBOXY_ prefix.
4
+ """
5
+
6
+ from functools import lru_cache
7
+ from pathlib import Path
8
+
9
+ from pydantic import Field
10
+ from pydantic_settings import BaseSettings, SettingsConfigDict
11
+
12
+
13
+ class Config(BaseSettings):
14
+ """Application configuration from environment variables."""
15
+
16
+ model_config = SettingsConfigDict(
17
+ env_prefix="SANDBOXY_",
18
+ env_file=".env",
19
+ env_file_encoding="utf-8",
20
+ extra="ignore",
21
+ )
22
+
23
+ # Paths
24
+ modules_dir: Path = Path("modules")
25
+ agents_dir: Path = Path("agents")
26
+ tools_dir: Path = Path("tools")
27
+
28
+ # Security
29
+ cors_origins: list[str] = Field(default_factory=list)
30
+ allow_dynamic_tools: bool = True
31
+
32
+ # HTTP Client
33
+ http_timeout: float = 120.0
34
+
35
+ # Runtime
36
+ env: str = "development"
37
+ debug: bool = False
38
+ host: str = "0.0.0.0"
39
+ port: int = 8000
40
+
41
+
42
+ @lru_cache(maxsize=1)
43
+ def get_config() -> Config:
44
+ """Get the application configuration singleton."""
45
+ return Config()
46
+
47
+
48
+ # Convenience alias
49
+ config = get_config()
@@ -0,0 +1 @@
1
+ """Core module - MDL parser, runner, and state management."""