sandboxy 0.0.4__py3-none-any.whl → 0.0.6__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.
- sandboxy/agents/llm_prompt.py +85 -14
- sandboxy/api/app.py +2 -1
- sandboxy/api/routes/local.py +34 -1
- sandboxy/api/routes/providers.py +369 -0
- sandboxy/cli/main.py +371 -0
- sandboxy/mlflow/exporter.py +7 -1
- sandboxy/providers/__init__.py +37 -3
- sandboxy/providers/config.py +243 -0
- sandboxy/providers/local.py +498 -0
- sandboxy/providers/registry.py +107 -13
- sandboxy/scenarios/unified.py +27 -3
- sandboxy/ui/dist/assets/index-BZFjoK-_.js +377 -0
- sandboxy/ui/dist/assets/index-Qf7gGJk_.css +1 -0
- sandboxy/ui/dist/index.html +2 -2
- {sandboxy-0.0.4.dist-info → sandboxy-0.0.6.dist-info}/METADATA +67 -27
- {sandboxy-0.0.4.dist-info → sandboxy-0.0.6.dist-info}/RECORD +19 -16
- sandboxy/ui/dist/assets/index-CU06wBqc.js +0 -362
- sandboxy/ui/dist/assets/index-Cgg2wY2m.css +0 -1
- {sandboxy-0.0.4.dist-info → sandboxy-0.0.6.dist-info}/WHEEL +0 -0
- {sandboxy-0.0.4.dist-info → sandboxy-0.0.6.dist-info}/entry_points.txt +0 -0
- {sandboxy-0.0.4.dist-info → sandboxy-0.0.6.dist-info}/licenses/LICENSE +0 -0
sandboxy/scenarios/unified.py
CHANGED
|
@@ -292,6 +292,9 @@ class RunResult:
|
|
|
292
292
|
cost_usd: float | None = None
|
|
293
293
|
error: str | None = None
|
|
294
294
|
created_at: datetime = field(default_factory=datetime.now)
|
|
295
|
+
# Provider info for distinguishing local vs cloud
|
|
296
|
+
is_local: bool = False
|
|
297
|
+
provider_name: str | None = None
|
|
295
298
|
|
|
296
299
|
def to_dict(self) -> dict[str, Any]:
|
|
297
300
|
"""Convert to dictionary."""
|
|
@@ -324,6 +327,8 @@ class RunResult:
|
|
|
324
327
|
"cost_usd": self.cost_usd,
|
|
325
328
|
"error": self.error,
|
|
326
329
|
"created_at": self.created_at.isoformat(),
|
|
330
|
+
"is_local": self.is_local,
|
|
331
|
+
"provider_name": self.provider_name,
|
|
327
332
|
}
|
|
328
333
|
|
|
329
334
|
def to_json(self, indent: int | None = 2) -> str:
|
|
@@ -332,9 +337,15 @@ class RunResult:
|
|
|
332
337
|
|
|
333
338
|
def pretty(self) -> str:
|
|
334
339
|
"""Format for human-readable display."""
|
|
340
|
+
model_display = self.model
|
|
341
|
+
if self.is_local:
|
|
342
|
+
model_display += " (local)"
|
|
343
|
+
elif self.provider_name:
|
|
344
|
+
model_display += f" ({self.provider_name})"
|
|
345
|
+
|
|
335
346
|
lines = [
|
|
336
347
|
f"Scenario: {self.scenario_id}",
|
|
337
|
-
f"Model: {
|
|
348
|
+
f"Model: {model_display}",
|
|
338
349
|
f"Latency: {self.latency_ms}ms",
|
|
339
350
|
]
|
|
340
351
|
|
|
@@ -516,6 +527,10 @@ class UnifiedRunner:
|
|
|
516
527
|
temperature=temperature,
|
|
517
528
|
)
|
|
518
529
|
|
|
530
|
+
# Detect if this is a local provider
|
|
531
|
+
is_local = hasattr(provider, "config") # LocalProvider has config attribute
|
|
532
|
+
provider_name = provider.provider_name if hasattr(provider, "provider_name") else None
|
|
533
|
+
|
|
519
534
|
return RunResult(
|
|
520
535
|
id="", # Set by caller
|
|
521
536
|
scenario_id=scenario.id,
|
|
@@ -528,7 +543,9 @@ class UnifiedRunner:
|
|
|
528
543
|
],
|
|
529
544
|
input_tokens=response.input_tokens,
|
|
530
545
|
output_tokens=response.output_tokens,
|
|
531
|
-
cost_usd=response.cost_usd,
|
|
546
|
+
cost_usd=response.cost_usd if not is_local else 0.0, # Local models have no cost
|
|
547
|
+
is_local=is_local,
|
|
548
|
+
provider_name=provider_name,
|
|
532
549
|
)
|
|
533
550
|
|
|
534
551
|
async def _run_multi_turn(
|
|
@@ -773,6 +790,11 @@ class UnifiedRunner:
|
|
|
773
790
|
# Calculate cost from token counts
|
|
774
791
|
cost_usd = self._calculate_cost(model, input_tokens, output_tokens)
|
|
775
792
|
|
|
793
|
+
# Detect if this is a local provider
|
|
794
|
+
provider = self.registry.get_provider_for_model(model)
|
|
795
|
+
is_local = hasattr(provider, "config")
|
|
796
|
+
provider_name = provider.provider_name if hasattr(provider, "provider_name") else None
|
|
797
|
+
|
|
776
798
|
return RunResult(
|
|
777
799
|
id="",
|
|
778
800
|
scenario_id=scenario.id,
|
|
@@ -783,7 +805,9 @@ class UnifiedRunner:
|
|
|
783
805
|
final_state=env_state,
|
|
784
806
|
input_tokens=input_tokens,
|
|
785
807
|
output_tokens=output_tokens,
|
|
786
|
-
cost_usd=cost_usd,
|
|
808
|
+
cost_usd=cost_usd if not is_local else 0.0,
|
|
809
|
+
is_local=is_local,
|
|
810
|
+
provider_name=provider_name,
|
|
787
811
|
)
|
|
788
812
|
|
|
789
813
|
finally:
|