The owner sets, for every guest at once (users.json guestDefaults): - promptShortcuts: what a guest's composer starts with. A guest who never saved settings gets them as the seed of their ai-agent-settings ui-state. - sharedSkills: lab/project skills handed to every guest run. The scope carries them to the host sidecar, which symlinks them into a generated plugin and passes --plugin-dir: they show up as shared:<name>. GET/PUT /api/guest-defaults (owner), GET /api/guest-skills (the composer's mentions: shared + granted projects' skills), shareRef/sharedWithGuests on the skills catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
117 lines
3.0 KiB
Python
117 lines
3.0 KiB
Python
"""Guests: ``/api/me``, the owner's user admin, conversation sharing."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional
|
|
|
|
from .base import Schema
|
|
|
|
__all__ = [
|
|
"ProjectGrant", "NotifyPrefs", "Me", "GuestUser", "UsersResponse",
|
|
"LoginLink", "ShareCandidate", "ConversationShare", "GuestShortcut",
|
|
"GuestDefaults", "GuestSkill", "GuestSkillsResponse",
|
|
]
|
|
|
|
|
|
class ProjectGrant(Schema):
|
|
slug: str
|
|
level: str # "view" | "chat" | "ship"
|
|
|
|
|
|
class NotifyPrefs(Schema):
|
|
channels: list[str] # "in_app" | "email" | "webpush"
|
|
|
|
|
|
class Me(Schema):
|
|
"""Who the browser is: the owner, or a guest with their grants."""
|
|
id: str
|
|
role: str # "owner" | "guest"
|
|
name: str
|
|
email: Optional[str] = None
|
|
readonly: bool = False
|
|
projects: list[ProjectGrant]
|
|
models: list[str]
|
|
budgetUsd: Optional[float] = None
|
|
spentUsd: Optional[float] = None
|
|
notify: Optional[NotifyPrefs] = None
|
|
mail: bool = False # outbound mail configured (login links can be mailed)
|
|
surface: Optional[str] = None # "admin" | "guest"
|
|
# A guest's starting prompt shortcuts (what Reset goes back to); None for
|
|
# the owner, whose defaults are built into the frontend.
|
|
defaultShortcuts: Optional[list["GuestShortcut"]] = None
|
|
|
|
|
|
class GuestUser(Schema):
|
|
id: str
|
|
email: str
|
|
name: str
|
|
role: str
|
|
projects: dict[str, str]
|
|
models: list[str]
|
|
budgetUsd: float
|
|
notify: NotifyPrefs
|
|
disabled: bool
|
|
createdAt: str
|
|
lastLoginAt: Optional[str] = None
|
|
sessions: int = 0
|
|
|
|
|
|
class UsersResponse(Schema):
|
|
users: list[GuestUser]
|
|
levels: list[str]
|
|
channels: list[str]
|
|
defaultModels: list[str]
|
|
mail: bool
|
|
guestUrl: Optional[str] = None
|
|
|
|
|
|
class LoginLink(Schema):
|
|
url: str
|
|
sent: bool
|
|
expiresInS: int
|
|
|
|
|
|
class ShareCandidate(Schema):
|
|
id: str
|
|
name: str
|
|
level: Optional[str] = None
|
|
|
|
|
|
class ConversationShare(Schema):
|
|
sessionId: str
|
|
owner: Optional[str] = None
|
|
project: Optional[str] = None
|
|
participants: list[str]
|
|
candidates: list[ShareCandidate]
|
|
|
|
|
|
class GuestShortcut(Schema):
|
|
"""A prompt shortcut in the frontend's ``PromptShortcut`` shape."""
|
|
id: str
|
|
label: str
|
|
icon: str = "Sparkles"
|
|
guideline: str = ""
|
|
defaultOn: bool = False
|
|
labelOff: Optional[str] = None
|
|
guidelineOff: Optional[str] = None
|
|
children: Optional[list[str]] = None
|
|
triggers: Optional[list[str]] = None
|
|
shared: Optional[bool] = None
|
|
|
|
|
|
class GuestDefaults(Schema):
|
|
"""What the owner sets for every guest at once (Settings → Users)."""
|
|
promptShortcuts: list[GuestShortcut]
|
|
sharedSkills: list[str] # `name` (repo) | `<project>/<name>`
|
|
|
|
|
|
class GuestSkill(Schema):
|
|
"""A skill a guest's run can use — the composer's `/` mentions."""
|
|
name: str # the invocation name (`shared:<name>` when shared)
|
|
description: str = ""
|
|
triggerWords: list[str] = []
|
|
source: str # "shared" | <project slug>
|
|
|
|
|
|
class GuestSkillsResponse(Schema):
|
|
skills: list[GuestSkill]
|