mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-21 04:02:22 +02:00
198 lines
6.0 KiB
Python
198 lines
6.0 KiB
Python
from pydantic import BaseModel, Field, model_validator
|
|
from typing import Optional, Any
|
|
from uuid import uuid4
|
|
from datetime import datetime
|
|
|
|
|
|
class AutoRunConfig(BaseModel):
|
|
enabled: bool = False
|
|
prompt: str = ""
|
|
context_paths: list[dict[str, str]] = Field(default_factory=list)
|
|
forced_tools: list[dict[str, Any]] = Field(default_factory=list)
|
|
mode: str = "agent"
|
|
model: str = "sonnet"
|
|
|
|
|
|
class Output(BaseModel):
|
|
id: str = Field(default_factory=lambda: uuid4().hex)
|
|
name: str
|
|
description: str = ""
|
|
icon: str = "view_quilt"
|
|
input_schema: dict[str, Any] = Field(default_factory=lambda: {
|
|
"type": "object",
|
|
"properties": {},
|
|
"required": [],
|
|
})
|
|
files: dict[str, str] = Field(default_factory=dict)
|
|
permission: str = "ask"
|
|
auto_run_config: Optional[AutoRunConfig] = None
|
|
thumbnail: Optional[str] = None
|
|
created_at: str = Field(default_factory=lambda: datetime.now().isoformat())
|
|
updated_at: str = Field(default_factory=lambda: datetime.now().isoformat())
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def _migrate_flat_fields(cls, data: Any) -> Any:
|
|
"""Migrate legacy frontend_code/backend_code fields into the files dict."""
|
|
if not isinstance(data, dict):
|
|
return data
|
|
if "files" not in data or not data["files"]:
|
|
files: dict[str, str] = {}
|
|
fc = data.pop("frontend_code", None)
|
|
bc = data.pop("backend_code", None)
|
|
if fc:
|
|
files["index.html"] = fc
|
|
if bc:
|
|
files["backend.py"] = bc
|
|
data["files"] = files
|
|
else:
|
|
data.pop("frontend_code", None)
|
|
data.pop("backend_code", None)
|
|
return data
|
|
|
|
@property
|
|
def frontend_code(self) -> str:
|
|
return self.files.get("index.html", "")
|
|
|
|
@property
|
|
def backend_code(self) -> str | None:
|
|
return self.files.get("backend.py")
|
|
|
|
|
|
class OutputCreate(BaseModel):
|
|
name: str
|
|
description: str = ""
|
|
icon: str = "view_quilt"
|
|
input_schema: dict[str, Any] = Field(default_factory=lambda: {
|
|
"type": "object",
|
|
"properties": {},
|
|
"required": [],
|
|
})
|
|
files: dict[str, str] = Field(default_factory=dict)
|
|
auto_run_config: Optional[dict[str, Any]] = None
|
|
thumbnail: Optional[str] = None
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def _migrate_flat_fields(cls, data: Any) -> Any:
|
|
if not isinstance(data, dict):
|
|
return data
|
|
if "files" not in data or not data["files"]:
|
|
files: dict[str, str] = {}
|
|
fc = data.pop("frontend_code", None)
|
|
bc = data.pop("backend_code", None)
|
|
if fc:
|
|
files["index.html"] = fc
|
|
if bc:
|
|
files["backend.py"] = bc
|
|
data["files"] = files
|
|
else:
|
|
data.pop("frontend_code", None)
|
|
data.pop("backend_code", None)
|
|
return data
|
|
|
|
|
|
class OutputUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
icon: Optional[str] = None
|
|
input_schema: Optional[dict[str, Any]] = None
|
|
files: Optional[dict[str, str]] = None
|
|
permission: Optional[str] = None
|
|
auto_run_config: Optional[dict[str, Any]] = None
|
|
thumbnail: Optional[str] = None
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def _migrate_flat_fields(cls, data: Any) -> Any:
|
|
if not isinstance(data, dict):
|
|
return data
|
|
if "files" not in data:
|
|
files: dict[str, str] = {}
|
|
fc = data.pop("frontend_code", None)
|
|
bc = data.pop("backend_code", None)
|
|
if fc:
|
|
files["index.html"] = fc
|
|
if bc:
|
|
files["backend.py"] = bc
|
|
if files:
|
|
data["files"] = files
|
|
else:
|
|
data.pop("frontend_code", None)
|
|
data.pop("backend_code", None)
|
|
return data
|
|
|
|
|
|
class OutputExecute(BaseModel):
|
|
output_id: str
|
|
input_data: dict[str, Any] = Field(default_factory=dict)
|
|
|
|
|
|
class OutputExecuteResult(BaseModel):
|
|
output_id: str
|
|
output_name: str
|
|
frontend_code: str
|
|
input_data: dict[str, Any]
|
|
backend_result: Optional[dict[str, Any]] = None
|
|
stdout: Optional[str] = None
|
|
stderr: Optional[str] = None
|
|
error: Optional[str] = None
|
|
|
|
|
|
class AutoRunRequest(BaseModel):
|
|
prompt: str
|
|
input_schema: dict[str, Any] = Field(default_factory=dict)
|
|
backend_code: Optional[str] = None
|
|
context_paths: list[dict[str, str]] = Field(default_factory=list)
|
|
forced_tools: list[str] = Field(default_factory=list)
|
|
model: str = "sonnet"
|
|
|
|
|
|
class AutoRunAgentRequest(BaseModel):
|
|
prompt: str
|
|
input_schema: dict[str, Any] = Field(default_factory=dict)
|
|
output_id: str
|
|
model: str = "sonnet"
|
|
forced_tools: list[str] = Field(default_factory=list)
|
|
context_paths: list[dict[str, str]] = Field(default_factory=list)
|
|
|
|
|
|
class WorkspaceSeedRequest(BaseModel):
|
|
workspace_id: str
|
|
files: Optional[dict[str, str]] = None
|
|
meta: Optional[dict[str, Any]] = None
|
|
|
|
@model_validator(mode="before")
|
|
@classmethod
|
|
def _migrate_flat_fields(cls, data: Any) -> Any:
|
|
"""Accept legacy frontend_code/backend_code/schema_json fields."""
|
|
if not isinstance(data, dict):
|
|
return data
|
|
if "files" not in data:
|
|
files: dict[str, str] = {}
|
|
fc = data.pop("frontend_code", None)
|
|
bc = data.pop("backend_code", None)
|
|
sj = data.pop("schema_json", None)
|
|
if fc:
|
|
files["index.html"] = fc
|
|
if bc:
|
|
files["backend.py"] = bc
|
|
if sj:
|
|
files["schema.json"] = sj
|
|
if files:
|
|
data["files"] = files
|
|
else:
|
|
data.pop("frontend_code", None)
|
|
data.pop("backend_code", None)
|
|
data.pop("schema_json", None)
|
|
return data
|
|
|
|
|
|
class VibeCodeRequest(BaseModel):
|
|
prompt: str
|
|
current_frontend_code: str = ""
|
|
current_backend_code: str = ""
|
|
current_schema: str = ""
|
|
name: str = ""
|
|
description: str = ""
|