refactor: finalize agent schemas and profile model
- Remove deprecated calendar UI tests - Update profile model with phone field support - Update agent schemas with runtime_models and forwarded_props - Update system_agent with new agent configuration
This commit is contained in:
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import ForeignKey, String, Text
|
||||
from sqlalchemy import String, Text
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
@@ -43,9 +43,3 @@ class Profile(TimestampMixin, SoftDeleteMixin, Base):
|
||||
nullable=False,
|
||||
server_default="{}",
|
||||
)
|
||||
referred_by: Mapped[uuid.UUID | None] = mapped_column(
|
||||
UUID(as_uuid=True),
|
||||
ForeignKey("profiles.id", ondelete="SET NULL"),
|
||||
nullable=True,
|
||||
index=True,
|
||||
)
|
||||
|
||||
@@ -1,15 +1,39 @@
|
||||
from schemas.agent.consumer_registry import AgentConsumerBinding, ConsumerRegistry
|
||||
from schemas.agent.forwarded_props import (
|
||||
ClientTimeContext,
|
||||
ForwardedPropsPayload,
|
||||
parse_forwarded_props_agent_type,
|
||||
parse_forwarded_props_client_time,
|
||||
)
|
||||
from schemas.agent.pipeline_spec import (
|
||||
ContextPolicy,
|
||||
ContextWindowMode,
|
||||
ExecutorKind,
|
||||
PipelineSpec,
|
||||
StageSpec,
|
||||
)
|
||||
from schemas.agent.runtime_models import (
|
||||
AgentOutput,
|
||||
ConstraintItem,
|
||||
ExecutionMode,
|
||||
KeyEntity,
|
||||
NormalizedTaskInput,
|
||||
ResultTyping,
|
||||
ResultType,
|
||||
RouterAgentOutput,
|
||||
RouterUiDecision,
|
||||
RunStatus,
|
||||
TaskType,
|
||||
TaskTyping,
|
||||
ToolAgentOutput,
|
||||
ToolStatus,
|
||||
UiMode,
|
||||
WorkerAgentOutputLite,
|
||||
WorkerAgentOutputRich,
|
||||
resolve_worker_output_model,
|
||||
)
|
||||
from schemas.agent.system_agent import AgentType, SystemAgentLLMConfig
|
||||
from schemas.agent.visibility import SystemVisibilityBit, VisibilityMask, bit_mask
|
||||
from schemas.agent.ui_hints import (
|
||||
UiHintAction,
|
||||
UiHintIntent,
|
||||
@@ -21,16 +45,41 @@ from schemas.agent.ui_hints import (
|
||||
__all__ = [
|
||||
"AgentType",
|
||||
"AgentOutput",
|
||||
"AgentConsumerBinding",
|
||||
"ConstraintItem",
|
||||
"ConsumerRegistry",
|
||||
"ContextPolicy",
|
||||
"ContextWindowMode",
|
||||
"ExecutionMode",
|
||||
"ExecutorKind",
|
||||
"ForwardedPropsPayload",
|
||||
"KeyEntity",
|
||||
"NormalizedTaskInput",
|
||||
"PipelineSpec",
|
||||
"ResultTyping",
|
||||
"ClientTimeContext",
|
||||
"ResultType",
|
||||
"RouterAgentOutput",
|
||||
"RouterUiDecision",
|
||||
"RunStatus",
|
||||
"TaskType",
|
||||
"TaskTyping",
|
||||
"SystemAgentLLMConfig",
|
||||
"SystemVisibilityBit",
|
||||
"StageSpec",
|
||||
"ToolAgentOutput",
|
||||
"ToolStatus",
|
||||
"UiMode",
|
||||
"UiHintAction",
|
||||
"UiHintIntent",
|
||||
"UiHintSection",
|
||||
"UiHintStatus",
|
||||
"UiHintsPayload",
|
||||
"VisibilityMask",
|
||||
"WorkerAgentOutputLite",
|
||||
"WorkerAgentOutputRich",
|
||||
"bit_mask",
|
||||
"parse_forwarded_props_agent_type",
|
||||
"parse_forwarded_props_client_time",
|
||||
"resolve_worker_output_model",
|
||||
]
|
||||
|
||||
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
import re
|
||||
from typing import Any
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
from pydantic import (
|
||||
@@ -63,16 +62,34 @@ class ClientTimeContext(BaseModel):
|
||||
class ForwardedPropsPayload(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
agent_type: str = Field(..., min_length=1, max_length=64)
|
||||
client_time: ClientTimeContext | None = None
|
||||
|
||||
@field_validator("agent_type")
|
||||
@classmethod
|
||||
def validate_agent_type(cls, value: str) -> str:
|
||||
normalized = value.strip().lower()
|
||||
if not normalized:
|
||||
raise ValueError("invalid forwarded_props.agent_type")
|
||||
return normalized
|
||||
|
||||
|
||||
def parse_forwarded_props(forwarded_props: object) -> ForwardedPropsPayload:
|
||||
if not isinstance(forwarded_props, dict):
|
||||
raise ValueError("invalid RunAgentInput.forwardedProps")
|
||||
try:
|
||||
return ForwardedPropsPayload.model_validate(forwarded_props)
|
||||
except ValidationError as exc:
|
||||
raise ValueError("invalid RunAgentInput.forwardedProps") from exc
|
||||
|
||||
|
||||
def parse_forwarded_props_client_time(
|
||||
forwarded_props: Any,
|
||||
forwarded_props: object,
|
||||
) -> ClientTimeContext | None:
|
||||
if not isinstance(forwarded_props, dict):
|
||||
return None
|
||||
try:
|
||||
payload = ForwardedPropsPayload.model_validate(forwarded_props)
|
||||
except ValidationError as exc:
|
||||
raise ValueError("invalid RunAgentInput.forwardedProps") from exc
|
||||
payload = parse_forwarded_props(forwarded_props)
|
||||
return payload.client_time
|
||||
|
||||
|
||||
def parse_forwarded_props_agent_type(forwarded_props: object) -> str:
|
||||
payload = parse_forwarded_props(forwarded_props)
|
||||
return payload.agent_type
|
||||
|
||||
@@ -8,6 +8,22 @@ from pydantic import BaseModel, ConfigDict, Field
|
||||
from schemas.agent.ui_hints import UiHintsPayload
|
||||
|
||||
|
||||
class TaskType(str, Enum):
|
||||
KNOWLEDGE = "knowledge"
|
||||
RECOMMENDATION = "recommendation"
|
||||
PLANNING = "planning"
|
||||
SCHEDULING = "scheduling"
|
||||
REMINDER_MANAGEMENT = "reminder_management"
|
||||
TODO_MANAGEMENT = "todo_management"
|
||||
COMMUNICATION_DRAFTING = "communication_drafting"
|
||||
INFORMATION_ORGANIZATION = "information_organization"
|
||||
STATUS_TRACKING = "status_tracking"
|
||||
TRANSACTION_ASSIST = "transaction_assist"
|
||||
ACTION_EXECUTION = "action_execution"
|
||||
TROUBLESHOOTING = "troubleshooting"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
class ResultType(str, Enum):
|
||||
DIRECT_ANSWER = "direct_answer"
|
||||
OPTIONS_WITH_RECOMMENDATION = "options_with_recommendation"
|
||||
@@ -26,6 +42,31 @@ class ResultType(str, Enum):
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
class TaskTyping(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
primary: TaskType
|
||||
secondary: list[TaskType] = Field(default_factory=list, max_length=3)
|
||||
|
||||
|
||||
class ResultTyping(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
primary: ResultType
|
||||
secondary: list[ResultType] = Field(default_factory=list, max_length=3)
|
||||
|
||||
|
||||
class ExecutionMode(str, Enum):
|
||||
ONESTEP = "onestep"
|
||||
TOOL_ASSISTED = "tool_assisted"
|
||||
MULTISTEP = "multistep"
|
||||
|
||||
|
||||
class UiMode(str, Enum):
|
||||
NONE = "none"
|
||||
RICH = "rich"
|
||||
|
||||
|
||||
class RunStatus(str, Enum):
|
||||
SUCCESS = "success"
|
||||
PARTIAL_SUCCESS = "partial_success"
|
||||
@@ -38,13 +79,55 @@ class ToolStatus(str, Enum):
|
||||
PARTIAL = "partial"
|
||||
|
||||
|
||||
class KeyEntity(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
name: str
|
||||
type: str
|
||||
value: str | None = None
|
||||
|
||||
|
||||
class ConstraintItem(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
key: str
|
||||
value: str
|
||||
required: bool = True
|
||||
|
||||
|
||||
class NormalizedTaskInput(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
user_text: str
|
||||
multimodal_summary: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class RouterUiDecision(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
ui_mode: UiMode
|
||||
ui_decision_reason: str
|
||||
|
||||
|
||||
class RouterAgentOutput(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
normalized_task_input: NormalizedTaskInput
|
||||
key_entities: list[KeyEntity] = Field(default_factory=list)
|
||||
constraints: list[ConstraintItem] = Field(default_factory=list)
|
||||
task_typing: TaskTyping
|
||||
execution_mode: ExecutionMode
|
||||
result_typing: ResultTyping
|
||||
ui: RouterUiDecision
|
||||
|
||||
|
||||
class ErrorInfo(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
code: str = Field(..., description="Stable error code for programmatic handling.")
|
||||
message: str = Field(..., description="Human-readable error message.")
|
||||
retryable: bool = Field(default=False)
|
||||
details: dict[str, Any] | None = Field(default=None)
|
||||
code: str
|
||||
message: str
|
||||
retryable: bool = False
|
||||
details: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class ToolAgentOutput(BaseModel):
|
||||
@@ -58,13 +141,29 @@ class ToolAgentOutput(BaseModel):
|
||||
error: ErrorInfo | None = None
|
||||
|
||||
|
||||
class AgentOutput(BaseModel):
|
||||
class WorkerAgentOutputLite(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
status: RunStatus = Field(default=RunStatus.SUCCESS)
|
||||
status: RunStatus = RunStatus.SUCCESS
|
||||
answer: str
|
||||
key_points: list[str] = Field(default_factory=list)
|
||||
result_type: ResultType = Field(default=ResultType.UNKNOWN)
|
||||
result_type: ResultType = ResultType.UNKNOWN
|
||||
suggested_actions: list[str] = Field(default_factory=list)
|
||||
error: ErrorInfo | None = None
|
||||
|
||||
|
||||
class WorkerAgentOutputRich(WorkerAgentOutputLite):
|
||||
ui_hints: UiHintsPayload | None = None
|
||||
|
||||
|
||||
class AgentOutput(WorkerAgentOutputRich):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
|
||||
WorkerAgentOutput = WorkerAgentOutputLite | WorkerAgentOutputRich
|
||||
|
||||
|
||||
def resolve_worker_output_model(ui_mode: UiMode) -> type[WorkerAgentOutputLite]:
|
||||
if ui_mode == UiMode.RICH:
|
||||
return WorkerAgentOutputRich
|
||||
return WorkerAgentOutputLite
|
||||
|
||||
@@ -4,10 +4,11 @@ from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
from core.agentscope.tools.tool_config import ToolGroup
|
||||
from core.agentscope.tools.tool_config import AgentTool, parse_agent_tool
|
||||
|
||||
|
||||
class AgentType(str, Enum):
|
||||
ROUTER = "router"
|
||||
WORKER = "worker"
|
||||
MEMORY = "memory"
|
||||
|
||||
@@ -29,24 +30,22 @@ class SystemAgentLLMConfig(BaseModel):
|
||||
context_messages: ContextMessagesConfig = Field(
|
||||
default_factory=ContextMessagesConfig
|
||||
)
|
||||
enabled_tool_groups: list[ToolGroup] = Field(default_factory=list, max_length=8)
|
||||
visibility_consumer_bit: int = Field(default=16, ge=16, le=63)
|
||||
enabled_tools: list[AgentTool] = Field(default_factory=list, max_length=32)
|
||||
|
||||
@field_validator("enabled_tool_groups", mode="before")
|
||||
@field_validator("enabled_tools", mode="before")
|
||||
@classmethod
|
||||
def _normalize_enabled_tool_groups(cls, value: object) -> list[ToolGroup]:
|
||||
def _normalize_enabled_tools(cls, value: object) -> list[AgentTool]:
|
||||
if value is None:
|
||||
return []
|
||||
if not isinstance(value, list):
|
||||
raise ValueError("enabled_tool_groups must be a list")
|
||||
normalized: list[ToolGroup] = []
|
||||
raise ValueError("enabled_tools must be a list")
|
||||
normalized: list[AgentTool] = []
|
||||
for item in value:
|
||||
if isinstance(item, ToolGroup):
|
||||
group = item
|
||||
else:
|
||||
raw_group = str(item or "").strip().lower()
|
||||
if not raw_group:
|
||||
continue
|
||||
group = ToolGroup(raw_group)
|
||||
if group not in normalized:
|
||||
normalized.append(group)
|
||||
raw_item = str(item or "").strip()
|
||||
if not raw_item:
|
||||
continue
|
||||
tool = parse_agent_tool(raw_item)
|
||||
if tool not in normalized:
|
||||
normalized.append(tool)
|
||||
return normalized
|
||||
|
||||
Reference in New Issue
Block a user