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/cli/main.py
CHANGED
|
@@ -1594,5 +1594,376 @@ def mcp_list_servers() -> None:
|
|
|
1594
1594
|
click.echo("More servers: https://github.com/modelcontextprotocol/servers")
|
|
1595
1595
|
|
|
1596
1596
|
|
|
1597
|
+
# =============================================================================
|
|
1598
|
+
# PROVIDERS COMMAND GROUP
|
|
1599
|
+
# =============================================================================
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
@main.group()
|
|
1603
|
+
def providers() -> None:
|
|
1604
|
+
"""Manage local model providers (Ollama, LM Studio, vLLM, etc.)."""
|
|
1605
|
+
pass
|
|
1606
|
+
|
|
1607
|
+
|
|
1608
|
+
@providers.command("list")
|
|
1609
|
+
@click.option("--json", "as_json", is_flag=True, help="Output as JSON")
|
|
1610
|
+
def providers_list(as_json: bool) -> None:
|
|
1611
|
+
"""List all configured local providers.
|
|
1612
|
+
|
|
1613
|
+
Shows provider name, type, URL, connection status, and model count.
|
|
1614
|
+
|
|
1615
|
+
Examples:
|
|
1616
|
+
sandboxy providers list
|
|
1617
|
+
sandboxy providers list --json
|
|
1618
|
+
"""
|
|
1619
|
+
import asyncio
|
|
1620
|
+
|
|
1621
|
+
from sandboxy.providers.config import load_providers_config
|
|
1622
|
+
from sandboxy.providers.local import LocalProvider
|
|
1623
|
+
|
|
1624
|
+
config = load_providers_config()
|
|
1625
|
+
|
|
1626
|
+
if not config.providers:
|
|
1627
|
+
if as_json:
|
|
1628
|
+
click.echo(json.dumps({"providers": []}))
|
|
1629
|
+
else:
|
|
1630
|
+
click.echo("No local providers configured.")
|
|
1631
|
+
click.echo("")
|
|
1632
|
+
click.echo("Add a provider with:")
|
|
1633
|
+
click.echo(" sandboxy providers add ollama --url http://localhost:11434/v1")
|
|
1634
|
+
return
|
|
1635
|
+
|
|
1636
|
+
async def get_statuses():
|
|
1637
|
+
results = []
|
|
1638
|
+
for pconfig in config.providers:
|
|
1639
|
+
provider = LocalProvider(pconfig)
|
|
1640
|
+
try:
|
|
1641
|
+
status = await provider.test_connection()
|
|
1642
|
+
results.append(
|
|
1643
|
+
{
|
|
1644
|
+
"name": pconfig.name,
|
|
1645
|
+
"type": pconfig.type,
|
|
1646
|
+
"base_url": pconfig.base_url,
|
|
1647
|
+
"enabled": pconfig.enabled,
|
|
1648
|
+
"status": status.status.value,
|
|
1649
|
+
"model_count": len(status.available_models),
|
|
1650
|
+
}
|
|
1651
|
+
)
|
|
1652
|
+
except Exception as e:
|
|
1653
|
+
results.append(
|
|
1654
|
+
{
|
|
1655
|
+
"name": pconfig.name,
|
|
1656
|
+
"type": pconfig.type,
|
|
1657
|
+
"base_url": pconfig.base_url,
|
|
1658
|
+
"enabled": pconfig.enabled,
|
|
1659
|
+
"status": "error",
|
|
1660
|
+
"model_count": 0,
|
|
1661
|
+
"error": str(e),
|
|
1662
|
+
}
|
|
1663
|
+
)
|
|
1664
|
+
finally:
|
|
1665
|
+
await provider.close()
|
|
1666
|
+
return results
|
|
1667
|
+
|
|
1668
|
+
statuses = asyncio.run(get_statuses())
|
|
1669
|
+
|
|
1670
|
+
if as_json:
|
|
1671
|
+
click.echo(json.dumps({"providers": statuses}, indent=2))
|
|
1672
|
+
return
|
|
1673
|
+
|
|
1674
|
+
# Table output
|
|
1675
|
+
click.echo(f"{'NAME':<15} {'TYPE':<18} {'URL':<35} {'STATUS':<12} {'MODELS':<6}")
|
|
1676
|
+
for s in statuses:
|
|
1677
|
+
status_display = s["status"]
|
|
1678
|
+
if s["status"] == "connected":
|
|
1679
|
+
status_display = click.style("connected", fg="green")
|
|
1680
|
+
elif s["status"] in ("disconnected", "error"):
|
|
1681
|
+
status_display = click.style(s["status"], fg="red")
|
|
1682
|
+
|
|
1683
|
+
click.echo(
|
|
1684
|
+
f"{s['name']:<15} {s['type']:<18} {s['base_url']:<35} {status_display:<12} {s['model_count']:<6}"
|
|
1685
|
+
)
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
@providers.command("add")
|
|
1689
|
+
@click.argument("name")
|
|
1690
|
+
@click.option(
|
|
1691
|
+
"--type",
|
|
1692
|
+
"provider_type",
|
|
1693
|
+
type=click.Choice(["ollama", "lmstudio", "vllm", "openai-compatible"]),
|
|
1694
|
+
default="openai-compatible",
|
|
1695
|
+
help="Provider type",
|
|
1696
|
+
)
|
|
1697
|
+
@click.option("--url", required=True, help="Base URL for the provider API")
|
|
1698
|
+
@click.option("--api-key", help="Optional API key for authentication")
|
|
1699
|
+
@click.option("--model", "models", multiple=True, help="Manually specify model (can be repeated)")
|
|
1700
|
+
@click.option("--no-test", is_flag=True, help="Skip connection test")
|
|
1701
|
+
def providers_add(
|
|
1702
|
+
name: str,
|
|
1703
|
+
provider_type: str,
|
|
1704
|
+
url: str,
|
|
1705
|
+
api_key: str | None,
|
|
1706
|
+
models: tuple[str, ...],
|
|
1707
|
+
no_test: bool,
|
|
1708
|
+
) -> None:
|
|
1709
|
+
"""Add a new local model provider.
|
|
1710
|
+
|
|
1711
|
+
Examples:
|
|
1712
|
+
sandboxy providers add ollama --url http://localhost:11434/v1
|
|
1713
|
+
sandboxy providers add my-vllm --type vllm --url http://gpu:8000/v1 --api-key $KEY
|
|
1714
|
+
sandboxy providers add custom --url http://localhost:8080/v1 --model llama3 --model mistral
|
|
1715
|
+
"""
|
|
1716
|
+
import asyncio
|
|
1717
|
+
|
|
1718
|
+
from sandboxy.providers.config import (
|
|
1719
|
+
LocalProviderConfig,
|
|
1720
|
+
load_providers_config,
|
|
1721
|
+
save_providers_config,
|
|
1722
|
+
)
|
|
1723
|
+
from sandboxy.providers.local import LocalProvider
|
|
1724
|
+
from sandboxy.providers.registry import reload_local_providers
|
|
1725
|
+
|
|
1726
|
+
# Load existing config
|
|
1727
|
+
config = load_providers_config()
|
|
1728
|
+
|
|
1729
|
+
# Check for duplicate name
|
|
1730
|
+
if config.get_provider(name):
|
|
1731
|
+
click.echo(f"Error: Provider '{name}' already exists", err=True)
|
|
1732
|
+
sys.exit(1)
|
|
1733
|
+
|
|
1734
|
+
# Create provider config
|
|
1735
|
+
try:
|
|
1736
|
+
provider_config = LocalProviderConfig(
|
|
1737
|
+
name=name,
|
|
1738
|
+
type=provider_type,
|
|
1739
|
+
base_url=url,
|
|
1740
|
+
api_key=api_key,
|
|
1741
|
+
models=list(models),
|
|
1742
|
+
)
|
|
1743
|
+
except ValueError as e:
|
|
1744
|
+
click.echo(f"Error: {e}", err=True)
|
|
1745
|
+
sys.exit(1)
|
|
1746
|
+
|
|
1747
|
+
# Test connection unless skipped
|
|
1748
|
+
discovered_models: list[str] = []
|
|
1749
|
+
if not no_test:
|
|
1750
|
+
click.echo(f"Testing connection to {url}...")
|
|
1751
|
+
|
|
1752
|
+
async def test():
|
|
1753
|
+
provider = LocalProvider(provider_config)
|
|
1754
|
+
try:
|
|
1755
|
+
status = await provider.test_connection()
|
|
1756
|
+
return status
|
|
1757
|
+
finally:
|
|
1758
|
+
await provider.close()
|
|
1759
|
+
|
|
1760
|
+
try:
|
|
1761
|
+
status = asyncio.run(test())
|
|
1762
|
+
if status.status.value == "connected":
|
|
1763
|
+
click.echo(click.style("✓ Connected", fg="green"))
|
|
1764
|
+
discovered_models = status.available_models
|
|
1765
|
+
if discovered_models:
|
|
1766
|
+
click.echo(f"✓ Found {len(discovered_models)} models")
|
|
1767
|
+
else:
|
|
1768
|
+
click.echo(click.style(f"✗ Connection failed: {status.error_message}", fg="red"))
|
|
1769
|
+
click.echo("")
|
|
1770
|
+
click.echo("Provider will be added but may not work until server is running.")
|
|
1771
|
+
click.echo("Use --no-test to skip this check.")
|
|
1772
|
+
sys.exit(2)
|
|
1773
|
+
except Exception as e:
|
|
1774
|
+
click.echo(click.style(f"✗ Connection failed: {e}", fg="red"))
|
|
1775
|
+
sys.exit(2)
|
|
1776
|
+
|
|
1777
|
+
# Add and save
|
|
1778
|
+
config.add_provider(provider_config)
|
|
1779
|
+
save_providers_config(config)
|
|
1780
|
+
|
|
1781
|
+
# Reload providers in registry
|
|
1782
|
+
reload_local_providers()
|
|
1783
|
+
|
|
1784
|
+
click.echo(f"Added provider '{name}'")
|
|
1785
|
+
if discovered_models:
|
|
1786
|
+
model_list = ", ".join(discovered_models[:5])
|
|
1787
|
+
if len(discovered_models) > 5:
|
|
1788
|
+
model_list += f", ... ({len(discovered_models) - 5} more)"
|
|
1789
|
+
click.echo(f"Found {len(discovered_models)} models: {model_list}")
|
|
1790
|
+
elif models:
|
|
1791
|
+
click.echo(f"Configured {len(models)} model(s): {', '.join(models)}")
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
@providers.command("remove")
|
|
1795
|
+
@click.argument("name")
|
|
1796
|
+
def providers_remove(name: str) -> None:
|
|
1797
|
+
"""Remove a configured provider.
|
|
1798
|
+
|
|
1799
|
+
Examples:
|
|
1800
|
+
sandboxy providers remove ollama
|
|
1801
|
+
"""
|
|
1802
|
+
from sandboxy.providers.config import load_providers_config, save_providers_config
|
|
1803
|
+
from sandboxy.providers.registry import reload_local_providers
|
|
1804
|
+
|
|
1805
|
+
config = load_providers_config()
|
|
1806
|
+
|
|
1807
|
+
if not config.remove_provider(name):
|
|
1808
|
+
click.echo(f"Error: Provider '{name}' not found", err=True)
|
|
1809
|
+
sys.exit(1)
|
|
1810
|
+
|
|
1811
|
+
save_providers_config(config)
|
|
1812
|
+
reload_local_providers()
|
|
1813
|
+
|
|
1814
|
+
click.echo(f"Removed provider '{name}'")
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
@providers.command("test")
|
|
1818
|
+
@click.argument("name")
|
|
1819
|
+
def providers_test(name: str) -> None:
|
|
1820
|
+
"""Test connection to a provider.
|
|
1821
|
+
|
|
1822
|
+
Examples:
|
|
1823
|
+
sandboxy providers test ollama
|
|
1824
|
+
"""
|
|
1825
|
+
import asyncio
|
|
1826
|
+
|
|
1827
|
+
from sandboxy.providers.config import load_providers_config
|
|
1828
|
+
from sandboxy.providers.local import LocalProvider
|
|
1829
|
+
|
|
1830
|
+
config = load_providers_config()
|
|
1831
|
+
provider_config = config.get_provider(name)
|
|
1832
|
+
|
|
1833
|
+
if not provider_config:
|
|
1834
|
+
click.echo(f"Error: Provider '{name}' not found", err=True)
|
|
1835
|
+
sys.exit(1)
|
|
1836
|
+
|
|
1837
|
+
click.echo(f"Testing connection to {name} ({provider_config.base_url})...")
|
|
1838
|
+
|
|
1839
|
+
async def test():
|
|
1840
|
+
provider = LocalProvider(provider_config)
|
|
1841
|
+
try:
|
|
1842
|
+
return await provider.test_connection()
|
|
1843
|
+
finally:
|
|
1844
|
+
await provider.close()
|
|
1845
|
+
|
|
1846
|
+
try:
|
|
1847
|
+
status = asyncio.run(test())
|
|
1848
|
+
|
|
1849
|
+
if status.status.value == "connected":
|
|
1850
|
+
click.echo(click.style(f"✓ Connected in {status.latency_ms}ms", fg="green"))
|
|
1851
|
+
if status.available_models:
|
|
1852
|
+
click.echo(
|
|
1853
|
+
f"✓ Found {len(status.available_models)} models: {', '.join(status.available_models)}"
|
|
1854
|
+
)
|
|
1855
|
+
else:
|
|
1856
|
+
click.echo(click.style(f"✗ Connection failed: {status.error_message}", fg="red"))
|
|
1857
|
+
|
|
1858
|
+
# Provide helpful suggestions based on provider type
|
|
1859
|
+
if provider_config.type == "ollama":
|
|
1860
|
+
click.echo("")
|
|
1861
|
+
click.echo(" Suggestion: Ensure Ollama is running with: ollama serve")
|
|
1862
|
+
elif provider_config.type == "vllm":
|
|
1863
|
+
click.echo("")
|
|
1864
|
+
click.echo(
|
|
1865
|
+
" Suggestion: Start vLLM with: python -m vllm.entrypoints.openai.api_server"
|
|
1866
|
+
)
|
|
1867
|
+
elif provider_config.type == "lmstudio":
|
|
1868
|
+
click.echo("")
|
|
1869
|
+
click.echo(" Suggestion: Start the server in LM Studio and load a model")
|
|
1870
|
+
|
|
1871
|
+
sys.exit(1)
|
|
1872
|
+
|
|
1873
|
+
except Exception as e:
|
|
1874
|
+
click.echo(click.style(f"✗ Error: {e}", fg="red"))
|
|
1875
|
+
sys.exit(1)
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
@providers.command("models")
|
|
1879
|
+
@click.argument("name", required=False)
|
|
1880
|
+
@click.option("--json", "as_json", is_flag=True, help="Output as JSON")
|
|
1881
|
+
def providers_models(name: str | None, as_json: bool) -> None:
|
|
1882
|
+
"""List models from configured providers.
|
|
1883
|
+
|
|
1884
|
+
If NAME is provided, shows models only from that provider.
|
|
1885
|
+
Otherwise, shows models from all providers.
|
|
1886
|
+
|
|
1887
|
+
Examples:
|
|
1888
|
+
sandboxy providers models
|
|
1889
|
+
sandboxy providers models ollama
|
|
1890
|
+
sandboxy providers models --json
|
|
1891
|
+
"""
|
|
1892
|
+
import asyncio
|
|
1893
|
+
|
|
1894
|
+
from sandboxy.providers.config import load_providers_config
|
|
1895
|
+
from sandboxy.providers.local import LocalProvider
|
|
1896
|
+
|
|
1897
|
+
config = load_providers_config()
|
|
1898
|
+
|
|
1899
|
+
if name:
|
|
1900
|
+
provider_config = config.get_provider(name)
|
|
1901
|
+
if not provider_config:
|
|
1902
|
+
click.echo(f"Error: Provider '{name}' not found", err=True)
|
|
1903
|
+
sys.exit(1)
|
|
1904
|
+
providers_to_check = [provider_config]
|
|
1905
|
+
else:
|
|
1906
|
+
providers_to_check = [p for p in config.providers if p.enabled]
|
|
1907
|
+
|
|
1908
|
+
if not providers_to_check:
|
|
1909
|
+
if as_json:
|
|
1910
|
+
click.echo(json.dumps({"models": []}))
|
|
1911
|
+
else:
|
|
1912
|
+
click.echo("No providers configured.")
|
|
1913
|
+
return
|
|
1914
|
+
|
|
1915
|
+
async def get_models():
|
|
1916
|
+
all_models = []
|
|
1917
|
+
for pconfig in providers_to_check:
|
|
1918
|
+
provider = LocalProvider(pconfig)
|
|
1919
|
+
try:
|
|
1920
|
+
models = await provider.refresh_models()
|
|
1921
|
+
for m in models:
|
|
1922
|
+
all_models.append(
|
|
1923
|
+
{
|
|
1924
|
+
"provider": pconfig.name,
|
|
1925
|
+
"id": m.id,
|
|
1926
|
+
"name": m.name,
|
|
1927
|
+
"context_length": m.context_length,
|
|
1928
|
+
"supports_tools": m.supports_tools,
|
|
1929
|
+
}
|
|
1930
|
+
)
|
|
1931
|
+
except Exception:
|
|
1932
|
+
# Provider unreachable, use configured models if any
|
|
1933
|
+
for model_id in pconfig.models:
|
|
1934
|
+
all_models.append(
|
|
1935
|
+
{
|
|
1936
|
+
"provider": pconfig.name,
|
|
1937
|
+
"id": model_id,
|
|
1938
|
+
"name": model_id,
|
|
1939
|
+
"context_length": 0,
|
|
1940
|
+
"supports_tools": False,
|
|
1941
|
+
}
|
|
1942
|
+
)
|
|
1943
|
+
finally:
|
|
1944
|
+
await provider.close()
|
|
1945
|
+
return all_models
|
|
1946
|
+
|
|
1947
|
+
models = asyncio.run(get_models())
|
|
1948
|
+
|
|
1949
|
+
if as_json:
|
|
1950
|
+
output = {"models": models}
|
|
1951
|
+
if name:
|
|
1952
|
+
output["provider"] = name
|
|
1953
|
+
click.echo(json.dumps(output, indent=2))
|
|
1954
|
+
return
|
|
1955
|
+
|
|
1956
|
+
if not models:
|
|
1957
|
+
click.echo("No models found. Is the provider running?")
|
|
1958
|
+
return
|
|
1959
|
+
|
|
1960
|
+
# Table output
|
|
1961
|
+
click.echo(f"{'PROVIDER':<15} {'MODEL':<40} {'TOOLS':<6} {'CONTEXT':<10}")
|
|
1962
|
+
for m in models:
|
|
1963
|
+
tools = "✓" if m["supports_tools"] else "✗"
|
|
1964
|
+
ctx = str(m["context_length"]) if m["context_length"] > 0 else "?"
|
|
1965
|
+
click.echo(f"{m['provider']:<15} {m['id']:<40} {tools:<6} {ctx:<10}")
|
|
1966
|
+
|
|
1967
|
+
|
|
1597
1968
|
if __name__ == "__main__":
|
|
1598
1969
|
main()
|
sandboxy/mlflow/exporter.py
CHANGED
|
@@ -163,6 +163,7 @@ class MLflowExporter:
|
|
|
163
163
|
scenario_id: str,
|
|
164
164
|
agent_name: str = "default",
|
|
165
165
|
dataset_case: str | None = None,
|
|
166
|
+
run_name: str | None = None,
|
|
166
167
|
) -> str | None:
|
|
167
168
|
"""Export run result to MLflow (creates a new run).
|
|
168
169
|
|
|
@@ -176,6 +177,7 @@ class MLflowExporter:
|
|
|
176
177
|
scenario_id: Unique scenario identifier
|
|
177
178
|
agent_name: Agent configuration name
|
|
178
179
|
dataset_case: Optional dataset case identifier
|
|
180
|
+
run_name: Optional run name (defaults to "scenario_name - agent_name")
|
|
179
181
|
|
|
180
182
|
Returns:
|
|
181
183
|
MLflow run ID on success, None on failure
|
|
@@ -196,8 +198,12 @@ class MLflowExporter:
|
|
|
196
198
|
if not self._setup_tracking():
|
|
197
199
|
return None
|
|
198
200
|
|
|
201
|
+
# Generate run name if not provided
|
|
202
|
+
if run_name is None:
|
|
203
|
+
run_name = f"{scenario_name} - {agent_name}"
|
|
204
|
+
|
|
199
205
|
# Start run and log everything
|
|
200
|
-
with mlflow.start_run() as run:
|
|
206
|
+
with mlflow.start_run(run_name=run_name) as run:
|
|
201
207
|
run_id = run.info.run_id
|
|
202
208
|
|
|
203
209
|
self._log_parameters(result, scenario_name, scenario_id)
|
sandboxy/providers/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ Supports multiple LLM providers through a unified interface:
|
|
|
4
4
|
- OpenRouter (400+ models via single API)
|
|
5
5
|
- OpenAI (direct)
|
|
6
6
|
- Anthropic (direct)
|
|
7
|
+
- Local providers (Ollama, LM Studio, vLLM, OpenAI-compatible)
|
|
7
8
|
|
|
8
9
|
Usage:
|
|
9
10
|
from sandboxy.providers import get_provider, ProviderRegistry
|
|
@@ -12,23 +13,56 @@ Usage:
|
|
|
12
13
|
provider = get_provider("openai/gpt-4o")
|
|
13
14
|
response = await provider.complete("openai/gpt-4o", messages)
|
|
14
15
|
|
|
15
|
-
# Or use the registry
|
|
16
|
+
# Or use the registry for local models
|
|
16
17
|
registry = ProviderRegistry()
|
|
17
|
-
provider = registry.get_provider_for_model("
|
|
18
|
+
provider = registry.get_provider_for_model("ollama/llama3")
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
21
|
from sandboxy.providers.base import (
|
|
21
22
|
BaseProvider,
|
|
23
|
+
ModelInfo,
|
|
22
24
|
ModelResponse,
|
|
23
25
|
ProviderError,
|
|
24
26
|
)
|
|
25
|
-
from sandboxy.providers.
|
|
27
|
+
from sandboxy.providers.config import (
|
|
28
|
+
LocalModelInfo,
|
|
29
|
+
LocalProviderConfig,
|
|
30
|
+
ProvidersConfigFile,
|
|
31
|
+
ProviderStatus,
|
|
32
|
+
ProviderStatusEnum,
|
|
33
|
+
get_enabled_providers,
|
|
34
|
+
load_providers_config,
|
|
35
|
+
save_providers_config,
|
|
36
|
+
)
|
|
37
|
+
from sandboxy.providers.local import LocalProvider, LocalProviderConnectionError
|
|
38
|
+
from sandboxy.providers.registry import (
|
|
39
|
+
ProviderRegistry,
|
|
40
|
+
get_provider,
|
|
41
|
+
get_registry,
|
|
42
|
+
reload_local_providers,
|
|
43
|
+
)
|
|
26
44
|
|
|
27
45
|
__all__ = [
|
|
46
|
+
# Base types
|
|
28
47
|
"BaseProvider",
|
|
48
|
+
"ModelInfo",
|
|
29
49
|
"ModelResponse",
|
|
30
50
|
"ProviderError",
|
|
51
|
+
# Registry
|
|
31
52
|
"ProviderRegistry",
|
|
32
53
|
"get_provider",
|
|
33
54
|
"get_registry",
|
|
55
|
+
"reload_local_providers",
|
|
56
|
+
# Local provider
|
|
57
|
+
"LocalProvider",
|
|
58
|
+
"LocalProviderConnectionError",
|
|
59
|
+
"LocalProviderConfig",
|
|
60
|
+
"LocalModelInfo",
|
|
61
|
+
"ProvidersConfigFile",
|
|
62
|
+
"ProviderStatus",
|
|
63
|
+
"ProviderStatusEnum",
|
|
64
|
+
# Config functions
|
|
65
|
+
"load_providers_config",
|
|
66
|
+
"save_providers_config",
|
|
67
|
+
"get_enabled_providers",
|
|
34
68
|
]
|