Files
ai-agent/backend/schemas/agents.py
Gabriel Vidal 2119af66d5 refactor(schemas): split backend/schemas.py into a schemas/ package
One module per API area (base, files, activity, skills, conversations,
notifications, forms, search, plans, projects, services, misc, diff, cron,
agents) on a shared base.Schema; __init__.py re-exports every model so
handlers keep writing schemas.<Name>. OpenAPI output is byte-identical.
PlanSummary lives in conversations.py to keep the module graph a DAG.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:55:47 +02:00

124 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""The agents catalog (``backend/agents.py``) and the native Claude Code hooks."""
from __future__ import annotations
from typing import Optional
from .base import Schema
from .cron import CronJob
__all__ = [
"AgentSummary",
"AgentsTotals",
"AgentsResponse",
"AgentRun",
"AgentDay",
"AgentDetail",
"ClaudeHookEntry",
"ClaudeHooksResponse",
]
# ── agents catalog ───────────────────────────────────────────────────────────
# Sits after the cron models because an agent's detail carries the cron job
# scheduled on its definition file.
class AgentSummary(Schema):
"""One agent card: the definition on disk + what its runs actually cost.
The skills catalog can only *estimate* spend (context size × invocations);
an agent run is a whole conversation, so `cost`/`tokens` here are measured.
"""
name: str # the invocation name (frontmatter `name:`)
title: str
description: str
# None for a built-in agent type (`Explore`, `general-purpose`, …): nothing
# of it lives in this repo, so there is no file to link into the editor.
path: Optional[str] = None
dir: Optional[str] = None
source: str # "repo" | <project dir-name> | "builtin"
sourceKind: str # "repo" | "project" | "builtin"
tools: list[str] # frontmatter `tools:`; empty ⇒ inherits all
bytes: int
updatedAt: Optional[str] = None
# Run config declared in the frontmatter, verbatim (see agents.RUN_KEYS).
harness: Optional[str] = None
model: Optional[str] = None
effort: Optional[str] = None
thinking: Optional[str] = None
runs: int # total recorded runs, both origins
taskRuns: int # …spawned as a subagent (Task tool)
sessionRuns: int # …spawned as a session (cron / Run now)
lastRun: Optional[str] = None
conversations: int # distinct conversations it ran in
cost: float # real spend across every run
tokens: int
avgCost: float
contextTokens: Optional[int] = None # cost of loading the definition once
contextCost: Optional[float] = None
class AgentsTotals(Schema):
agents: int
used: int
runs: int
cost: float
tokens: int
class AgentsResponse(Schema):
agents: list[AgentSummary]
totals: AgentsTotals
class AgentRun(Schema):
"""One recorded run of an agent."""
agent: str
origin: str # "task" | "cron" | "manual"
account: Optional[str] = None # the Claude account the run billed
at: Optional[str] = None
cost: float
tokens: int
model: Optional[str] = None
title: Optional[str] = None
# The conversation to open: for a subagent run this is its *parent* (where
# the Task card is); `subConversationId` is the child transcript itself.
conversationId: Optional[str] = None
subConversationId: Optional[str] = None
class AgentDay(Schema):
"""One day of the detail page's run sparkline."""
date: str
runs: int
cost: float
class AgentDetail(Schema):
agent: AgentSummary
content: str # the definition file verbatim ("" if none)
runs: list[AgentRun] # most recent first
daily: list[AgentDay]
cron: Optional[CronJob] = None # the job scheduled on this definition
# False when cron would reject this definition as a prompt file (nested or
# project-local) — the UI explains instead of offering a button that 400s.
canSchedule: bool
# ── native Claude Code hooks ─────────────────────────────────────────────────
class ClaudeHookEntry(Schema):
"""One native Claude Code hook from the workspace's .claude/settings.json,
flattened to a single command."""
# PreToolUse / UserPromptSubmit / Stop / …
event: str
# The tool/name matcher, when the event supports one.
matcher: Optional[str] = None
type: str = "command"
command: str
class ClaudeHooksResponse(Schema):
"""The repo's native hooks — read-only: editing .claude/settings.json from
the container would be host-level code execution."""
path: str
exists: bool
entries: list[ClaudeHookEntry]