- Live remote-stack logs over a WebSocket proxied through the central app to
the agent (/ws/agent-logs/{agent}/{stack}); agent gains a WS log endpoint.
- Deploy to a remote host from the UI: host selector in the New Stack editor
and template dialog; templates instantiate onto an agent via the proxy.
- Network attach/detach: expandable inspect view per network with
connect/disconnect + container picker; GET /{id}/containers, POST connect/disconnect.
- Remove dead pages/Placeholder.tsx.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
1.3 KiB
Python
59 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
from typing import Optional
|
|
|
|
from sqlmodel import Field, SQLModel
|
|
|
|
|
|
def _now() -> datetime:
|
|
return datetime.now(timezone.utc)
|
|
|
|
|
|
class Template(SQLModel, table=True):
|
|
"""User-saved custom template (bundled ones live on disk)."""
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
slug: str = Field(index=True, unique=True)
|
|
name: str
|
|
description: Optional[str] = None
|
|
tags: str = "" # comma separated
|
|
yaml: str = ""
|
|
created_at: datetime = Field(default_factory=_now)
|
|
|
|
|
|
# --- API schemas ---
|
|
|
|
|
|
class TemplateVariable(SQLModel):
|
|
name: str
|
|
description: str = ""
|
|
default: str = ""
|
|
|
|
|
|
class TemplateSummary(SQLModel):
|
|
id: str
|
|
name: str
|
|
description: Optional[str] = None
|
|
tags: list[str] = []
|
|
gpu: Optional[str] = None
|
|
source: str = "bundled" # "bundled" | "custom"
|
|
|
|
|
|
class TemplateDetail(TemplateSummary):
|
|
yaml: str
|
|
variables: list[TemplateVariable] = []
|
|
|
|
|
|
class TemplateSaveRequest(SQLModel):
|
|
name: str
|
|
description: Optional[str] = None
|
|
tags: list[str] = []
|
|
yaml: str
|
|
|
|
|
|
class TemplateInstantiateRequest(SQLModel):
|
|
name: str # new stack name
|
|
values: dict[str, str] = {}
|
|
agent_id: int | None = None # None = local host; otherwise deploy to a remote agent
|