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:
qzl
2026-03-19 18:43:35 +08:00
parent 524b91f454
commit 7fd536e976
11 changed files with 195 additions and 324 deletions
+1 -7
View File
@@ -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,
)
+49
View File
@@ -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",
]
+25 -8
View File
@@ -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
+106 -7
View File
@@ -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
+14 -15
View File
@@ -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