mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-22 12:42:22 +02:00
79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
"""ModeExportable: a user-created mode (system prompt + allowed tools). Pulled in
|
|
as a dependency when a shared dashboard's agent runs in a custom mode. Built-in
|
|
modes (agent/ask/plan/...) ship with every install, so they're never bundled,
|
|
they surface as requirements instead. Modes are referenced by slug, so import
|
|
reuses an existing same-slug mode rather than clobbering it (keeps the session's
|
|
`mode` pointer valid without rewriting it)."""
|
|
from __future__ import annotations
|
|
|
|
from backend.apps.swarm.exportable import DepRef, ExportContext, RemapTable
|
|
from backend.apps.swarm.models import EntityType, Requirement
|
|
|
|
# Machine-relative or install-owned fields that must not ride along.
|
|
P_DROP = {"is_builtin", "default_folder"}
|
|
|
|
|
|
class ModeExportable:
|
|
type = EntityType.mode
|
|
|
|
def __init__(self, mode_id: str, name: str, data: dict):
|
|
self.local_id = mode_id
|
|
self.name = name
|
|
self.p_data = data
|
|
|
|
@classmethod
|
|
def load(cls, local_id: str) -> "ModeExportable | None":
|
|
store = p_store()
|
|
if store is None:
|
|
return None
|
|
m = store.load_mode(local_id)
|
|
if m is None:
|
|
return None
|
|
d = m.model_dump()
|
|
return cls(local_id, d.get("name") or local_id, d)
|
|
|
|
def serialize(self, ctx: ExportContext) -> dict:
|
|
return {k: v for k, v in self.p_data.items() if k not in P_DROP}
|
|
|
|
def files(self) -> dict[str, bytes]:
|
|
return {}
|
|
|
|
def dependencies(self) -> list[DepRef]:
|
|
return []
|
|
|
|
def requirements(self) -> list[Requirement]:
|
|
return []
|
|
|
|
@classmethod
|
|
def import_(cls, payload: dict, files: dict[str, bytes], remap: RemapTable) -> str:
|
|
store = p_store()
|
|
model = p_model()
|
|
if store is None or model is None:
|
|
from backend.apps.swarm.ziputil import BundleError
|
|
raise BundleError("can't import this mode on this build")
|
|
mid = payload.get("id") or (payload.get("name") or "mode").lower().replace(" ", "-")
|
|
# Reuse a same-slug mode (incl. built-ins) instead of overwriting it; sessions point at modes by this slug.
|
|
if store.load_mode(mid) is not None:
|
|
return mid
|
|
data = {k: v for k, v in payload.items() if k != "is_builtin"}
|
|
data["id"] = mid
|
|
data["is_builtin"] = False
|
|
store._save(model(**data))
|
|
return mid
|
|
|
|
|
|
def p_store():
|
|
try:
|
|
from backend.apps.modes import modes
|
|
return modes
|
|
except Exception:
|
|
return None
|
|
|
|
|
|
def p_model():
|
|
try:
|
|
from backend.apps.modes.models import Mode
|
|
return Mode
|
|
except Exception:
|
|
return None
|