mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-11 12:17:45 +02:00
[Haik]: ckpt, modes subapp is done and satisfactory for now, altho future touch ups may be done
This commit is contained in:
@@ -3,10 +3,16 @@
|
||||
Separated from models.py to keep schema classes small and data separate.
|
||||
"""
|
||||
|
||||
from backend.apps.modes.models import Mode
|
||||
from backend.config.paths import OUTPUTS_WORKSPACE_DIR as OUTPUTS_WORKSPACE, SKILLS_WORKSPACE_DIR as SKILLS_WORKSPACE
|
||||
from backend.apps.modes.Mode import Mode
|
||||
from typing import List
|
||||
from backend.config.paths import DB_ROOT
|
||||
import os
|
||||
|
||||
BUILTIN_MODES: list[Mode] = [
|
||||
# NOTE: When the skills and outputs subapps are implemented, we will need to update these paths to import from the subapps.
|
||||
SKILLS_WORKSPACE: str = os.path.join(DB_ROOT, "skills")
|
||||
OUTPUTS_WORKSPACE: str = os.path.join(DB_ROOT, "outputs")
|
||||
|
||||
BUILTIN_MODES: List[Mode] = [
|
||||
Mode(
|
||||
id="agent",
|
||||
name="Agent",
|
||||
@@ -0,0 +1,16 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
class Mode(BaseModel):
|
||||
id: str = Field(default_factory=lambda: uuid4().hex)
|
||||
name: str
|
||||
description: str = ""
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
is_builtin: bool = False
|
||||
icon: str = "smart_toy"
|
||||
color: str = "#818cf8"
|
||||
default_folder: Optional[str] = None
|
||||
@@ -1,38 +0,0 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
class Mode(BaseModel):
|
||||
id: str = Field(default_factory=lambda: uuid4().hex)
|
||||
name: str
|
||||
description: str = ""
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
is_builtin: bool = False
|
||||
icon: str = "smart_toy"
|
||||
color: str = "#818cf8"
|
||||
default_folder: Optional[str] = None
|
||||
|
||||
|
||||
class ModeCreate(BaseModel):
|
||||
name: str
|
||||
description: str = ""
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
icon: str = "smart_toy"
|
||||
color: str = "#818cf8"
|
||||
default_folder: Optional[str] = None
|
||||
|
||||
|
||||
class ModeUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
color: Optional[str] = None
|
||||
default_folder: Optional[str] = None
|
||||
+42
-28
@@ -1,50 +1,54 @@
|
||||
import json
|
||||
import os
|
||||
import logging
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from backend.config.Apps import SubApp
|
||||
from backend.apps.common.json_store import JsonStore
|
||||
from backend.apps.modes.models import Mode, ModeCreate, ModeUpdate
|
||||
from backend.apps.modes.builtin import BUILTIN_MODES
|
||||
from backend.core.db.PydanticStore import PydanticStore
|
||||
from backend.apps.modes.Mode import Mode
|
||||
from backend.apps.modes.BUILTIN_MODES import BUILTIN_MODES
|
||||
from backend.config.paths import DB_ROOT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from backend.config.paths import MODES_DIR as DATA_DIR
|
||||
|
||||
MODE_STORE: PydanticStore[Mode] = PydanticStore[Mode](
|
||||
model_cls=Mode,
|
||||
data_dir=os.path.join(DB_ROOT, "modes"),
|
||||
id_field="id",
|
||||
dump_mode="json",
|
||||
not_found_detail="Mode not found",
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def modes_lifespan():
|
||||
os.makedirs(DATA_DIR, exist_ok=True)
|
||||
for builtin in BUILTIN_MODES:
|
||||
path = os.path.join(DATA_DIR, f"{builtin.id}.json")
|
||||
if not os.path.exists(path):
|
||||
_save(builtin)
|
||||
MODE_STORE.save(builtin)
|
||||
yield
|
||||
|
||||
|
||||
modes = SubApp("modes", modes_lifespan)
|
||||
|
||||
|
||||
_store = JsonStore(Mode, DATA_DIR, not_found_detail="Mode not found")
|
||||
|
||||
_load_all = _store.load_all
|
||||
_save = _store.save
|
||||
_load = _store.load
|
||||
load_mode = _store.load_or_none
|
||||
|
||||
|
||||
@modes.router.get("/list")
|
||||
async def list_modes():
|
||||
builtin_defaults = {m.id: m.model_dump() for m in BUILTIN_MODES}
|
||||
return {"modes": [m.model_dump() for m in _load_all()], "builtin_defaults": builtin_defaults}
|
||||
return {"modes": [m.model_dump() for m in MODE_STORE.load_all()], "builtin_defaults": builtin_defaults}
|
||||
|
||||
|
||||
@modes.router.get("/{mode_id}")
|
||||
async def get_mode(mode_id: str):
|
||||
return _load(mode_id).model_dump()
|
||||
return MODE_STORE.load(mode_id).model_dump()
|
||||
|
||||
|
||||
class ModeCreate(BaseModel):
|
||||
name: str
|
||||
description: str = ""
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
icon: str = "smart_toy"
|
||||
color: str = "#818cf8"
|
||||
default_folder: Optional[str] = None
|
||||
|
||||
@modes.router.post("/create")
|
||||
async def create_mode(body: ModeCreate):
|
||||
mode = Mode(
|
||||
@@ -58,16 +62,26 @@ async def create_mode(body: ModeCreate):
|
||||
default_folder=body.default_folder,
|
||||
is_builtin=False,
|
||||
)
|
||||
_save(mode)
|
||||
MODE_STORE.save(mode)
|
||||
return {"ok": True, "mode": mode.model_dump()}
|
||||
|
||||
|
||||
class ModeUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
system_prompt: Optional[str] = None
|
||||
tools: Optional[list[str]] = None
|
||||
default_next_mode: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
color: Optional[str] = None
|
||||
default_folder: Optional[str] = None
|
||||
|
||||
@modes.router.put("/{mode_id}")
|
||||
async def update_mode(mode_id: str, body: ModeUpdate):
|
||||
mode = _load(mode_id)
|
||||
mode = MODE_STORE.load(mode_id)
|
||||
for k, v in body.model_dump(exclude_unset=True).items():
|
||||
setattr(mode, k, v)
|
||||
_save(mode)
|
||||
MODE_STORE.save(mode)
|
||||
return {"ok": True, "mode": mode.model_dump()}
|
||||
|
||||
|
||||
@@ -77,14 +91,14 @@ async def reset_mode(mode_id: str):
|
||||
builtin = next((m for m in BUILTIN_MODES if m.id == mode_id), None)
|
||||
if not builtin:
|
||||
raise HTTPException(status_code=400, detail="Only built-in modes can be reset")
|
||||
_save(builtin)
|
||||
MODE_STORE.save(builtin)
|
||||
return {"ok": True, "mode": builtin.model_dump()}
|
||||
|
||||
|
||||
@modes.router.delete("/{mode_id}")
|
||||
async def delete_mode(mode_id: str):
|
||||
mode = _load(mode_id)
|
||||
mode = MODE_STORE.load(mode_id)
|
||||
if mode.is_builtin:
|
||||
raise HTTPException(status_code=403, detail="Cannot delete built-in modes")
|
||||
_store.delete(mode_id)
|
||||
MODE_STORE.delete(mode_id)
|
||||
return {"ok": True}
|
||||
|
||||
Reference in New Issue
Block a user