Files
microdao-daarion/services/usage-engine/models.py
Apple fca48b3eb0 feat(node2): Complete NODE2 setup - guardian, agents, swapper models
- Node-guardian running on MacBook and updating metrics
- NODE2 agents (Atlas, Greeter, Oracle, Builder Bot) assigned to node-2-macbook-m4max
- Swapper models displaying correctly (8 models)
- DAGI Router agents showing with correct status (3 active, 1 stale)
- Router health check using node_cache for remote nodes
2025-12-02 07:07:58 -08:00

165 lines
4.2 KiB
Python

"""
Usage Engine Data Models
Tracks LLM calls, tool executions, agent invocations
"""
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional, Dict, Any
from enum import Enum
class UsageEventType(str, Enum):
LLM_CALL = "llm_call"
TOOL_CALL = "tool_call"
AGENT_INVOCATION = "agent_invocation"
MESSAGE_SENT = "message_sent"
class ActorType(str, Enum):
HUMAN = "human"
AGENT = "agent"
SERVICE = "service"
# ============================================================================
# Usage Events (inbound from NATS)
# ============================================================================
class LlmUsageEvent(BaseModel):
"""LLM call usage event from llm-proxy"""
event_id: str
timestamp: datetime
actor_id: str
actor_type: ActorType
agent_id: Optional[str] = None
microdao_id: Optional[str] = None
model: str
provider: str # "openai", "deepseek", "local"
prompt_tokens: int
completion_tokens: int
total_tokens: int
latency_ms: int
success: bool = True
error: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
class ToolUsageEvent(BaseModel):
"""Tool execution usage event from toolcore"""
event_id: str
timestamp: datetime
actor_id: str
actor_type: ActorType
agent_id: Optional[str] = None
microdao_id: Optional[str] = None
tool_id: str
tool_name: str
success: bool
latency_ms: int
error: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
class AgentInvocationEvent(BaseModel):
"""Agent invocation usage event from agent-runtime"""
event_id: str
timestamp: datetime
agent_id: str
microdao_id: Optional[str] = None
channel_id: Optional[str] = None
trigger: str # "message", "scheduled", "manual"
duration_ms: int
llm_calls: int = 0
tool_calls: int = 0
success: bool = True
error: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
class MessageUsageEvent(BaseModel):
"""Message sent usage event from messaging-service"""
event_id: str
timestamp: datetime
actor_id: str
actor_type: ActorType
microdao_id: str
channel_id: str
message_length: int
metadata: Optional[Dict[str, Any]] = None
# ============================================================================
# Aggregated Usage Reports (outbound API)
# ============================================================================
class UsageSummary(BaseModel):
"""Aggregated usage summary"""
period_start: datetime
period_end: datetime
microdao_id: Optional[str] = None
agent_id: Optional[str] = None
# LLM stats
llm_calls_total: int = 0
llm_tokens_total: int = 0
llm_tokens_prompt: int = 0
llm_tokens_completion: int = 0
llm_latency_avg_ms: float = 0.0
# Tool stats
tool_calls_total: int = 0
tool_calls_success: int = 0
tool_calls_failed: int = 0
tool_latency_avg_ms: float = 0.0
# Agent stats
agent_invocations_total: int = 0
agent_invocations_success: int = 0
agent_invocations_failed: int = 0
# Message stats
messages_sent: int = 0
messages_total_length: int = 0
class ModelUsage(BaseModel):
"""Usage by model"""
model: str
provider: str
calls: int
tokens: int
avg_latency_ms: float
class AgentUsage(BaseModel):
"""Usage by agent"""
agent_id: str
invocations: int
llm_calls: int
tool_calls: int
messages_sent: int
total_tokens: int
class ToolUsage(BaseModel):
"""Usage by tool"""
tool_id: str
tool_name: str
calls: int
success_rate: float
avg_latency_ms: float
# ============================================================================
# API Request/Response Models
# ============================================================================
class UsageQueryRequest(BaseModel):
"""Request for usage summary"""
microdao_id: Optional[str] = None
agent_id: Optional[str] = None
period_hours: int = Field(24, ge=1, le=720) # 1h - 30 days
class UsageQueryResponse(BaseModel):
"""Response for usage summary"""
summary: UsageSummary
models: list[ModelUsage] = []
agents: list[AgentUsage] = []
tools: list[ToolUsage] = []