refactor: 重构 schemas 结构,统一枚举定义

This commit is contained in:
qzl
2026-03-25 12:36:31 +08:00
parent 389f5248fc
commit d22ded21f8
122 changed files with 774 additions and 1456 deletions
@@ -7,8 +7,9 @@ from uuid import UUID
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from models.agent_chat_message import AgentChatMessage, AgentChatMessageRole
from models.agent_chat_session import AgentChatSession, AgentChatSessionStatus
from models.agent_chat_message import AgentChatMessage
from models.agent_chat_session import AgentChatSession
from schemas.enums import AgentChatMessageRole, AgentChatSessionStatus
class MessageRepository:
+2 -3
View File
@@ -6,12 +6,11 @@ from uuid import UUID
from core.agentscope.events.persistence import MessageRepository, SessionRepository
from core.logging import get_logger
from models.agent_chat_message import AgentChatMessageRole
from models.agent_chat_session import AgentChatSessionStatus
from schemas.enums import AgentChatMessageRole, AgentChatSessionStatus
from schemas.agent.system_agent import AgentType
from schemas.agent.runtime_models import AgentOutput, RouterAgentOutput, ToolAgentOutput
from schemas.agent.visibility import SystemVisibilityBit, bit_mask
from schemas.messages.chat_message import AgentChatMessageMetadata
from schemas.domain.chat_message import AgentChatMessageMetadata
class EventStore(Protocol):
@@ -9,7 +9,7 @@ from uuid import UUID
import redis.asyncio as redis
from core.config.settings import config
from core.logging import get_logger
from schemas.user import (
from schemas.shared.user import (
UserContext,
parse_profile_settings,
)
@@ -2,7 +2,7 @@ from __future__ import annotations
import json
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
def _wrap_section(section: str, content: str) -> str:
@@ -17,8 +17,8 @@ from core.agentscope.prompts.route_prompt import build_frontend_route_prompt
from core.agentscope.prompts.tool_prompt import build_tools_prompt
from schemas.agent.system_agent import AgentType, SystemAgentLLMConfig
from schemas.agent.forwarded_props import ClientTimeContext
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.user.context import UserContext
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from schemas.shared.user import UserContext
def _wrap_section(section: str, content: str) -> str:
@@ -6,9 +6,9 @@ from ag_ui.core.types import RunAgentInput
from agentscope.message import Msg
from core.agentscope.runtime.runner import AgentScopeRunner
from core.logging import get_logger
from schemas.automation import RuntimeConfig
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.user import UserContext
from schemas.domain.automation import RuntimeConfig
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from schemas.shared.user import UserContext
logger = get_logger("core.agentscope.runtime.orchestrator")
@@ -40,9 +40,9 @@ from schemas.agent.system_agent import (
AgentType,
SystemAgentLLMConfig,
)
from schemas.automation import RuntimeConfig
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.user import UserContext
from schemas.domain.automation import RuntimeConfig
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from schemas.shared.user import UserContext
from services.litellm.service import LiteLLMService
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
+4 -4
View File
@@ -20,13 +20,13 @@ from core.config.settings import config
from core.db.session import AsyncSessionLocal
from core.logging import get_logger
from core.taskiq.app import worker_agent_broker, worker_automation_broker
from schemas.automation import MessageContextConfig, RuntimeConfig
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.messages.chat_message import (
from schemas.domain.automation import MessageContextConfig, RuntimeConfig
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from schemas.domain.chat_message import (
AgentChatMessageMetadata,
extract_user_message_attachments,
)
from schemas.user import UserContext
from schemas.shared.user import UserContext
from services.base.redis import get_or_init_redis_client
from services.base.supabase import supabase_service
from v1.agent.repository import AgentRepository
@@ -6,7 +6,7 @@ from typing import Any, Protocol
from schemas.agent.visibility import SystemVisibilityBit, bit_mask
from schemas.automation import ContextWindowMode, MessageContextConfig
from schemas.domain.automation import ContextWindowMode, MessageContextConfig
_DEFAULT_CONTEXT_WINDOW_USER_MESSAGES = 20
@@ -84,7 +84,7 @@ class CalendarWriteOperation(BaseModel):
le=10080,
description="Reminder minutes before event start.",
)
status: Literal["active", "completed", "canceled", "archived"] | None = Field(
status: Literal["active", "archived"] | None = Field(
default=None,
description="Optional status for update action.",
)
@@ -163,6 +163,10 @@ async def calendar_read(
) -> ToolResponse:
"""Read calendar events with optional keyword filtering and pagination.
Status semantics for returned events:
- active: Event is actionable.
- archived: Event is historical/expired and should not trigger reminders.
Args:
query: Optional keyword used to filter events by text fields.
page: Page number starting from 1.
@@ -15,9 +15,9 @@ from core.agentscope.tools.utils.tool_response_builder import (
build_error_output,
build_tool_response,
)
from models.memories import MemoryType
from schemas.enums import MemoryType
from schemas.agent.runtime_models import ErrorInfo, ToolAgentOutput, ToolStatus
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
class MemoryWriteArgs(BaseModel):
@@ -46,6 +46,9 @@ def create_schedule_service(
def schedule_event_to_dict(event: object) -> dict[str, Any]:
event_id = str(getattr(event, "id"))
metadata = getattr(event, "metadata", None)
status_value = getattr(event, "status", None)
if hasattr(status_value, "value"):
status_value = getattr(status_value, "value")
location_value = getattr(metadata, "location", None)
color_value = getattr(metadata, "color", None) or "#4F46E5"
reminder_minutes_value = getattr(metadata, "reminder_minutes", None)
@@ -58,6 +61,7 @@ def schedule_event_to_dict(event: object) -> dict[str, Any]:
if getattr(event, "end_at") is not None
else None,
"timezone": getattr(event, "timezone"),
"status": status_value,
"location": location_value,
"color": color_value,
"reminderMinutes": reminder_minutes_value,
+1 -1
View File
@@ -5,7 +5,7 @@ from uuid import UUID
from core.config.settings import config
from core.logging import get_logger
from schemas.automation import RuntimeConfig
from schemas.domain.automation import RuntimeConfig
logger = get_logger("core.automation.scheduler")
+2 -1
View File
@@ -6,7 +6,7 @@ from models.automation_jobs import AutomationJob
from models.group_members import GroupMember
from models.groups import Group
from models.inbox_messages import InboxMessage
from models.invite_code import InviteCode, InviteCodeStatus
from models.invite_code import InviteCode
from models.llm import Llm
from models.llm_factory import LlmFactory
from models.memories import Memory
@@ -16,6 +16,7 @@ from models.schedule_subscriptions import ScheduleSubscription
from models.system_agents import SystemAgents
from models.todos import Todo
from models.todo_sources import TodoSource
from schemas.enums import InviteCodeStatus
__all__ = [
"AgentChatMessage",
+2 -7
View File
@@ -2,7 +2,6 @@ from __future__ import annotations
from decimal import Decimal
import uuid
from enum import Enum
from sqlalchemy import (
BigInteger,
@@ -19,13 +18,9 @@ from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import AgentChatMessageRole
class AgentChatMessageRole(str, Enum):
USER = "user"
ASSISTANT = "assistant"
SYSTEM = "system"
TOOL = "tool"
__all__ = ["AgentChatMessage", "AgentChatMessageRole"]
class AgentChatMessage(TimestampMixin, SoftDeleteMixin, Base):
+2 -12
View File
@@ -3,7 +3,6 @@ from __future__ import annotations
from datetime import datetime
from decimal import Decimal
import uuid
from enum import Enum
from sqlalchemy import (
DateTime,
@@ -19,18 +18,9 @@ from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import AgentChatSessionStatus, SessionType
class AgentChatSessionStatus(str, Enum):
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class SessionType(str, Enum):
CHAT = "chat"
AUTOMATION = "automation"
__all__ = ["AgentChatSession", "AgentChatSessionStatus", "SessionType"]
class AgentChatSession(TimestampMixin, SoftDeleteMixin, Base):
+2 -10
View File
@@ -2,23 +2,15 @@ from __future__ import annotations
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy import DateTime, JSON, String
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import AutomationJobStatus, ScheduleType
class AutomationJobStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
class ScheduleType(str, Enum):
DAILY = "daily"
WEEKLY = "weekly"
__all__ = ["AutomationJob", "AutomationJobStatus", "ScheduleType"]
class AutomationJob(TimestampMixin, SoftDeleteMixin, Base):
+2 -8
View File
@@ -2,21 +2,15 @@ from __future__ import annotations
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy import DateTime, String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import FriendshipStatus
class FriendshipStatus(str, Enum):
PENDING = "pending"
ACCEPTED = "accepted"
BLOCKED = "blocked"
DECLINED = "declined"
CANCELED = "canceled"
__all__ = ["Friendship", "FriendshipStatus"]
class Friendship(TimestampMixin, SoftDeleteMixin, Base):
+7 -17
View File
@@ -1,30 +1,20 @@
from __future__ import annotations
import uuid
from enum import Enum
from sqlalchemy import String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import GroupMemberRole, GroupMemberSource, GroupMemberStatus
class GroupMemberRole(str, Enum):
OWNER = "owner"
ADMIN = "admin"
MEMBER = "member"
class GroupMemberSource(str, Enum):
INVITED = "invited"
JOINED = "joined"
class GroupMemberStatus(str, Enum):
ACTIVE = "active"
MUTED = "muted"
REMOVED = "removed"
__all__ = [
"GroupMember",
"GroupMemberRole",
"GroupMemberSource",
"GroupMemberStatus",
]
class GroupMember(TimestampMixin, SoftDeleteMixin, Base):
+2 -5
View File
@@ -1,18 +1,15 @@
from __future__ import annotations
import uuid
from enum import Enum
from sqlalchemy import String, Text
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import GroupStatus
class GroupStatus(str, Enum):
ACTIVE = "active"
ARCHIVED = "archived"
__all__ = ["Group", "GroupStatus"]
class Group(TimestampMixin, SoftDeleteMixin, Base):
+2 -14
View File
@@ -1,27 +1,15 @@
from __future__ import annotations
import uuid
from enum import Enum
from sqlalchemy import Boolean, String
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, TimestampMixin
from schemas.enums import InboxMessageStatus, InboxMessageType
class InboxMessageType(str, Enum):
FRIEND_REQUEST = "friend_request"
CALENDAR = "calendar"
SYSTEM = "system"
GROUP = "group"
class InboxMessageStatus(str, Enum):
PENDING = "pending"
ACCEPTED = "accepted"
REJECTED = "rejected"
DISMISSED = "dismissed"
__all__ = ["InboxMessage", "InboxMessageType", "InboxMessageStatus"]
class InboxMessage(TimestampMixin, Base):
+2 -6
View File
@@ -2,7 +2,6 @@ from __future__ import annotations
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy import CheckConstraint, DateTime, ForeignKey, Integer, String
from sqlalchemy.dialects.postgresql import UUID
@@ -10,12 +9,9 @@ from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, TimestampMixin
from core.db.types import json_jsonb
from schemas.enums import InviteCodeStatus
class InviteCodeStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
EXPIRED = "expired"
__all__ = ["InviteCode", "InviteCodeStatus"]
class InviteCode(TimestampMixin, Base):
+2 -10
View File
@@ -1,7 +1,6 @@
from __future__ import annotations
import uuid
from enum import Enum
from sqlalchemy import String
from sqlalchemy.dialects.postgresql import UUID
@@ -9,16 +8,9 @@ from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, TimestampMixin
from core.db.types import json_jsonb
from schemas.enums import MemoryStatus, MemoryType
class MemoryType(str, Enum):
USER = "user"
WORK = "work"
class MemoryStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
__all__ = ["Memory", "MemoryType", "MemoryStatus"]
class Memory(TimestampMixin, Base):
+2 -13
View File
@@ -2,7 +2,6 @@ from __future__ import annotations
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy import DateTime, String, Text
from sqlalchemy.dialects.postgresql import UUID
@@ -10,19 +9,9 @@ from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from core.db.types import json_jsonb
from schemas.enums import ScheduleItemSourceType, ScheduleItemStatus
class ScheduleItemStatus(str, Enum):
ACTIVE = "active"
COMPLETED = "completed"
CANCELED = "canceled"
ARCHIVED = "archived"
class ScheduleItemSourceType(str, Enum):
MANUAL = "manual"
IMPORTED = "imported"
AGENT_GENERATED = "agent_generated"
__all__ = ["ScheduleItem", "ScheduleItemStatus", "ScheduleItemSourceType"]
class ScheduleItem(TimestampMixin, SoftDeleteMixin, Base):
+7 -20
View File
@@ -1,33 +1,20 @@
from __future__ import annotations
import uuid
from enum import Enum
from sqlalchemy import Integer, String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, TimestampMixin
from schemas.enums import NotifyLevel, SubscriptionPermission, SubscriptionStatus
class SubscriptionStatus(str, Enum):
ACTIVE = "active"
PENDING = "pending"
PAUSED = "paused"
UNSUBSCRIBED = "unsubscribed"
class NotifyLevel(str, Enum):
ALL = "all"
MENTIONS = "mentions"
NONE = "none"
class SubscriptionPermission(int, Enum):
VIEW = 1 # 001 - 可查看
INVITE = 2 # 010 - 可邀请
EDIT = 4 # 100 - 可编辑
OWNER = 7 # 111 - 所有者(VIEW + INVITE + EDIT
__all__ = [
"ScheduleSubscription",
"SubscriptionStatus",
"NotifyLevel",
"SubscriptionPermission",
]
class ScheduleSubscription(TimestampMixin, Base):
+2 -13
View File
@@ -2,26 +2,15 @@ from __future__ import annotations
import uuid
from datetime import datetime
from enum import Enum
from sqlalchemy import DateTime, Integer, String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from core.db.base import Base, SoftDeleteMixin, TimestampMixin
from schemas.enums import TodoPriority, TodoStatus
class TodoStatus(str, Enum):
PENDING = "pending"
DONE = "done"
CANCELED = "canceled"
class TodoPriority(int, Enum):
IMPORTANT_URGENT = 1
IMPORTANT_NOT_URGENT = 2
NOT_IMPORTANT_URGENT = 3
NOT_IMPORTANT_NOT_URGENT = 4
__all__ = ["Todo", "TodoStatus", "TodoPriority"]
class Todo(TimestampMixin, SoftDeleteMixin, Base):
+1 -45
View File
@@ -1,45 +1 @@
"""Centralized shared schemas for cross-module contracts."""
from schemas.inbox.messages import (
CalendarContent,
CalendarDeleteContent,
CalendarInviteContent,
CalendarUpdateContent,
FriendshipContent,
InboxMessageContent,
InboxMessageStatus,
InboxMessageType,
parse_calendar_content,
)
from schemas.invite_codes import InviteCodeRewardConfig
from schemas.messages import AgentChatMessageMetadata
from schemas.schedule.items import (
AttachmentType,
ScheduleItemMetadata,
ScheduleItemMetadataAttachment,
ScheduleItemSourceType,
ScheduleItemStatus,
)
from schemas.sessions import SessionStateSnapshot
from schemas.user.context import UserContext
__all__ = [
"AgentChatMessageMetadata",
"AttachmentType",
"CalendarContent",
"CalendarDeleteContent",
"CalendarInviteContent",
"CalendarUpdateContent",
"FriendshipContent",
"InboxMessageContent",
"InboxMessageStatus",
"InboxMessageType",
"InviteCodeRewardConfig",
"ScheduleItemMetadata",
"ScheduleItemMetadataAttachment",
"ScheduleItemSourceType",
"ScheduleItemStatus",
"SessionStateSnapshot",
"UserContext",
"parse_calendar_content",
]
"""Backend reusable schemas package."""
+1 -1
View File
@@ -12,7 +12,7 @@ Version: 2.0
from __future__ import annotations
from enum import Enum
from typing import Any, Literal, NotRequired, TypedDict, Union
from typing import Any, Literal, TypedDict, Union
# ============================================================
# Enums
+1
View File
@@ -0,0 +1 @@
"""Reusable domain schemas shared across backend modules."""
@@ -2,13 +2,27 @@ from __future__ import annotations
from datetime import datetime
from enum import Enum
from typing import Protocol
from uuid import UUID
from core.agentscope.tools.tool_config import AgentTool
from pydantic import BaseModel, ConfigDict, Field, model_validator
from schemas.enums import AutomationJobStatus, ScheduleType
from models.automation_jobs import AutomationJob as OrmAutomationJob
from models.automation_jobs import AutomationJobStatus, ScheduleType
class AutomationJobLike(Protocol):
id: UUID
owner_id: UUID
bootstrap_key: str | None
title: str
config: dict[str, object]
next_run_at: datetime
timezone: str
last_run_at: datetime | None
status: AutomationJobStatus
created_by: UUID | None
created_at: datetime
updated_at: datetime
class ContextSource(str, Enum):
@@ -50,8 +64,7 @@ class ScheduleConfig(BaseModel):
invalid = [day for day in self.weekdays if day < 1 or day > 7]
if invalid:
raise ValueError("weekdays must be within 1-7")
deduped = sorted(set(self.weekdays))
self.weekdays = deduped
self.weekdays = sorted(set(self.weekdays))
else:
self.weekdays = None
return self
@@ -90,20 +103,20 @@ class AutomationJob(BaseModel):
updated_at: datetime
@classmethod
def from_orm(cls, obj: OrmAutomationJob) -> "AutomationJob":
def from_orm(cls, obj: object) -> "AutomationJob":
return cls(
id=obj.id,
owner_id=obj.owner_id,
bootstrap_key=obj.bootstrap_key,
title=obj.title,
config=AutomationJobConfig.model_validate(obj.config or {}),
next_run_at=obj.next_run_at,
timezone=obj.timezone,
last_run_at=obj.last_run_at,
status=obj.status,
created_by=obj.created_by,
created_at=obj.created_at,
updated_at=obj.updated_at,
id=getattr(obj, "id"),
owner_id=getattr(obj, "owner_id"),
bootstrap_key=getattr(obj, "bootstrap_key"),
title=getattr(obj, "title"),
config=AutomationJobConfig.model_validate(getattr(obj, "config", {}) or {}),
next_run_at=getattr(obj, "next_run_at"),
timezone=getattr(obj, "timezone"),
last_run_at=getattr(obj, "last_run_at"),
status=getattr(obj, "status"),
created_by=getattr(obj, "created_by"),
created_at=getattr(obj, "created_at"),
updated_at=getattr(obj, "updated_at"),
)
@property
@@ -1,24 +1,22 @@
from __future__ import annotations
import json
from enum import Enum
from typing import ClassVar, Literal, Union
from pydantic import BaseModel, ConfigDict, Field
from schemas.enums import InboxMessageStatus, InboxMessageType
class InboxMessageType(str, Enum):
FRIEND_REQUEST = "friend_request"
CALENDAR = "calendar"
SYSTEM = "system"
GROUP = "group"
class InboxMessageStatus(str, Enum):
PENDING = "pending"
ACCEPTED = "accepted"
REJECTED = "rejected"
DISMISSED = "dismissed"
__all__ = [
"InboxMessageType",
"InboxMessageStatus",
"CalendarInviteContent",
"CalendarUpdateContent",
"CalendarDeleteContent",
"FriendshipContent",
"CalendarContent",
"InboxMessageContent",
"parse_calendar_content",
]
class CalendarInviteContent(BaseModel):
@@ -1,13 +1,11 @@
from __future__ import annotations
from datetime import datetime
from enum import Enum
from typing import ClassVar, Literal
from uuid import UUID
from pydantic import BaseModel, ConfigDict
from schemas.memories.memory_content import (
from schemas.domain.memory_content import (
TeamMember,
UserMemoryContent,
UserPreferences,
@@ -15,16 +13,7 @@ from schemas.memories.memory_content import (
WorkProfileContent,
WorkProject,
)
class MemoryType(str, Enum):
USER = "user"
WORK = "work"
class MemoryStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
from schemas.enums import MemoryStatus, MemoryType
class MemoryModel(BaseModel):
@@ -5,6 +5,15 @@ from typing import ClassVar, Literal
from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
from schemas.enums import ScheduleItemSourceType, ScheduleItemStatus
__all__ = [
"AttachmentType",
"ScheduleItemMetadataAttachment",
"ScheduleItemMetadata",
"ScheduleItemSourceType",
"ScheduleItemStatus",
]
class AttachmentType(str, Enum):
@@ -32,16 +41,3 @@ class ScheduleItemMetadata(BaseModel):
attachments: list[ScheduleItemMetadataAttachment] = Field(default_factory=list)
reminder_minutes: int | None = Field(default=None, ge=0, le=10080)
version: Literal[1] = 1
class ScheduleItemStatus(str, Enum):
ACTIVE = "active"
COMPLETED = "completed"
CANCELED = "canceled"
ARCHIVED = "archived"
class ScheduleItemSourceType(str, Enum):
MANUAL = "manual"
IMPORTED = "imported"
AGENT_GENERATED = "agent_generated"
+136
View File
@@ -0,0 +1,136 @@
from __future__ import annotations
from enum import Enum
class ScheduleItemStatus(str, Enum):
ACTIVE = "active"
ARCHIVED = "archived"
class ScheduleItemSourceType(str, Enum):
MANUAL = "manual"
IMPORTED = "imported"
AGENT_GENERATED = "agent_generated"
class AutomationJobStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
class ScheduleType(str, Enum):
DAILY = "daily"
WEEKLY = "weekly"
class MemoryType(str, Enum):
USER = "user"
WORK = "work"
class MemoryStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
class TodoStatus(str, Enum):
PENDING = "pending"
DONE = "done"
CANCELED = "canceled"
class TodoPriority(int, Enum):
IMPORTANT_URGENT = 1
IMPORTANT_NOT_URGENT = 2
NOT_IMPORTANT_URGENT = 3
NOT_IMPORTANT_NOT_URGENT = 4
class AgentChatMessageRole(str, Enum):
USER = "user"
ASSISTANT = "assistant"
SYSTEM = "system"
TOOL = "tool"
class AgentChatSessionStatus(str, Enum):
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class SessionType(str, Enum):
CHAT = "chat"
AUTOMATION = "automation"
class InboxMessageType(str, Enum):
FRIEND_REQUEST = "friend_request"
CALENDAR = "calendar"
SYSTEM = "system"
GROUP = "group"
class InboxMessageStatus(str, Enum):
PENDING = "pending"
ACCEPTED = "accepted"
REJECTED = "rejected"
DISMISSED = "dismissed"
class SubscriptionStatus(str, Enum):
ACTIVE = "active"
PENDING = "pending"
PAUSED = "paused"
UNSUBSCRIBED = "unsubscribed"
class NotifyLevel(str, Enum):
ALL = "all"
MENTIONS = "mentions"
NONE = "none"
class SubscriptionPermission(int, Enum):
VIEW = 1
INVITE = 2
EDIT = 4
OWNER = 7
class FriendshipStatus(str, Enum):
PENDING = "pending"
ACCEPTED = "accepted"
BLOCKED = "blocked"
DECLINED = "declined"
CANCELED = "canceled"
class InviteCodeStatus(str, Enum):
ACTIVE = "active"
DISABLED = "disabled"
EXPIRED = "expired"
class GroupStatus(str, Enum):
ACTIVE = "active"
ARCHIVED = "archived"
class GroupMemberRole(str, Enum):
OWNER = "owner"
ADMIN = "admin"
MEMBER = "member"
class GroupMemberSource(str, Enum):
INVITED = "invited"
JOINED = "joined"
class GroupMemberStatus(str, Enum):
ACTIVE = "active"
MUTED = "muted"
REMOVED = "removed"
-3
View File
@@ -1,3 +0,0 @@
from schemas.inbox.messages import InboxMessageStatus, InboxMessageType
__all__ = ["InboxMessageStatus", "InboxMessageType"]
-3
View File
@@ -1,3 +0,0 @@
from schemas.messages.chat_message import AgentChatMessage, AgentChatMessageMetadata
__all__ = ["AgentChatMessage", "AgentChatMessageMetadata"]
-27
View File
@@ -1,27 +0,0 @@
from schemas.inbox.messages import (
CalendarContent,
CalendarDeleteContent,
CalendarInviteContent,
CalendarUpdateContent,
parse_calendar_content,
)
from schemas.schedule.items import (
AttachmentType,
ScheduleItemMetadata,
ScheduleItemMetadataAttachment,
ScheduleItemSourceType,
ScheduleItemStatus,
)
__all__ = [
"AttachmentType",
"CalendarContent",
"CalendarDeleteContent",
"CalendarInviteContent",
"CalendarUpdateContent",
"ScheduleItemMetadata",
"ScheduleItemMetadataAttachment",
"ScheduleItemSourceType",
"ScheduleItemStatus",
"parse_calendar_content",
]
-3
View File
@@ -1,3 +0,0 @@
from schemas.sessions.chat_session import SessionStateSnapshot
__all__ = ["SessionStateSnapshot"]
+1
View File
@@ -0,0 +1 @@
"""Shared schemas used across multiple domain modules."""
-3
View File
@@ -1,3 +0,0 @@
from .contracts import TodoOrder
__all__ = ["TodoOrder"]
-17
View File
@@ -1,17 +0,0 @@
from schemas.user.context import (
PreferenceSettings,
ProfileSettingsUnion,
ProfileSettingsV1,
UserContext,
parse_profile_settings,
upgrade_to_latest,
)
__all__ = [
"PreferenceSettings",
"ProfileSettingsUnion",
"ProfileSettingsV1",
"UserContext",
"parse_profile_settings",
"upgrade_to_latest",
]
+3 -2
View File
@@ -9,10 +9,11 @@ from fastapi import HTTPException
from sqlalchemy import Select, select
from sqlalchemy.ext.asyncio import AsyncSession
from models.agent_chat_message import AgentChatMessage, AgentChatMessageRole
from models.agent_chat_message import AgentChatMessage
from models.agent_chat_session import AgentChatSession
from models.system_agents import SystemAgents
from schemas.messages.chat_message import (
from schemas.enums import AgentChatMessageRole
from schemas.domain.chat_message import (
AgentChatMessage as AgentChatMessageSchema,
AgentChatMessageMetadata,
)
+3 -3
View File
@@ -18,8 +18,8 @@ from schemas.agent.forwarded_props import (
RuntimeMode,
)
from schemas.agent.visibility import SystemVisibilityBit, bit_mask
from schemas.automation import RuntimeConfig
from schemas.messages.chat_message import (
from schemas.domain.automation import RuntimeConfig
from schemas.domain.chat_message import (
AgentChatMessageMetadata,
UserMessageAttachment,
extract_user_message_attachments,
@@ -362,7 +362,7 @@ class AgentService:
before: date | None,
current_user: CurrentUser,
) -> HistorySnapshotResponse:
from schemas.messages.chat_message import AgentChatMessage
from schemas.domain.chat_message import AgentChatMessage
from v1.agent.utils import convert_message_to_history
from v1.agent.schemas import HistoryMessage
+1 -1
View File
@@ -11,7 +11,7 @@ from pydantic import ValidationError
from core.agentscope.tools.tool_config import AgentTool
from schemas.agent.system_agent import SystemAgentLLMConfig
from schemas.automation import (
from schemas.domain.automation import (
ContextSource,
ContextWindowMode,
MessageContextConfig,
+1 -1
View File
@@ -8,7 +8,7 @@ from collections.abc import Callable
from typing import Any
from core.agentscope.runtime.ui_compiler import compile as compile_ui_hints
from schemas.messages.chat_message import (
from schemas.domain.chat_message import (
AgentChatMessage,
AgentChatMessageMetadata,
extract_user_message_attachments,
@@ -7,7 +7,7 @@ from typing import Any
import yaml
from schemas.automation import AutomationJobConfig
from schemas.domain.automation import AutomationJobConfig
_CONFIG_NAME_PATTERN = re.compile(r"^[a-z0-9][a-z0-9_-]{0,63}$")
@@ -10,12 +10,12 @@ from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.ext.asyncio import AsyncSession
from core.logging import get_logger
from models.automation_jobs import AutomationJob, AutomationJobStatus, ScheduleType
from models.memories import MemoryType
from models.automation_jobs import AutomationJob
from schemas.enums import AutomationJobStatus, MemoryType, ScheduleType
from models.profile import Profile
from schemas.automation import AutomationJobConfig, ScheduleConfig
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.user.context import parse_profile_settings
from schemas.domain.automation import AutomationJobConfig, ScheduleConfig
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from schemas.shared.user import parse_profile_settings
from v1.auth.automation_static_config import load_static_automation_job_config
from v1.auth.schemas import RegistrationBootstrapRequest
from v1.memories.repository import SQLAlchemyMemoriesRepository
+4 -3
View File
@@ -9,9 +9,10 @@ from sqlalchemy.ext.asyncio import AsyncSession
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from core.db.base_repository import BaseRepository
from models.agent_chat_session import AgentChatSession, SessionType
from models.automation_jobs import AutomationJob, AutomationJobStatus, ScheduleType
from schemas.automation import AutomationJobConfig, ScheduleConfig
from models.agent_chat_session import AgentChatSession
from models.automation_jobs import AutomationJob
from schemas.enums import AutomationJobStatus, ScheduleType, SessionType
from schemas.domain.automation import AutomationJobConfig, ScheduleConfig
if TYPE_CHECKING:
from v1.automation_jobs.schemas import (
+15 -16
View File
@@ -7,9 +7,8 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from models.automation_jobs import AutomationJob as OrmAutomationJob
from models.automation_jobs import AutomationJobStatus
from schemas.automation import AutomationJobConfig
from schemas.domain.automation import AutomationJobConfig
from schemas.enums import AutomationJobStatus
class AutomationJobResponse(BaseModel):
@@ -29,20 +28,20 @@ class AutomationJobResponse(BaseModel):
updated_at: datetime
@classmethod
def from_orm(cls, obj: OrmAutomationJob) -> Self:
def from_orm(cls, obj: object) -> Self:
return cls(
id=obj.id,
owner_id=obj.owner_id,
bootstrap_key=obj.bootstrap_key,
title=obj.title,
timezone=obj.timezone,
status=obj.status,
is_system=obj.bootstrap_key is not None,
config=AutomationJobConfig.model_validate(obj.config or {}),
next_run_at=obj.next_run_at,
last_run_at=obj.last_run_at,
created_at=obj.created_at,
updated_at=obj.updated_at,
id=getattr(obj, "id"),
owner_id=getattr(obj, "owner_id"),
bootstrap_key=getattr(obj, "bootstrap_key"),
title=getattr(obj, "title"),
timezone=getattr(obj, "timezone"),
status=getattr(obj, "status"),
is_system=getattr(obj, "bootstrap_key") is not None,
config=AutomationJobConfig.model_validate(getattr(obj, "config", {}) or {}),
next_run_at=getattr(obj, "next_run_at"),
last_run_at=getattr(obj, "last_run_at"),
created_at=getattr(obj, "created_at"),
updated_at=getattr(obj, "updated_at"),
)
+2 -2
View File
@@ -7,8 +7,8 @@ from uuid import UUID
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from fastapi import HTTPException, status
from models.automation_jobs import ScheduleType
from schemas.automation import (
from schemas.enums import ScheduleType
from schemas.domain.automation import (
AutomationJob as AutomationJobSchema,
MessageContextConfig,
RuntimeConfig,
+4 -3
View File
@@ -9,9 +9,10 @@ from sqlalchemy.exc import SQLAlchemyError
from core.db.base_repository import BaseRepository
from core.logging import get_logger
from models.friendships import Friendship, FriendshipStatus
from models.inbox_messages import InboxMessage, InboxMessageStatus, InboxMessageType
from schemas.inbox.messages import FriendshipContent
from models.friendships import Friendship
from models.inbox_messages import InboxMessage
from schemas.enums import FriendshipStatus, InboxMessageStatus, InboxMessageType
from schemas.domain.inbox import FriendshipContent
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
+1 -1
View File
@@ -6,7 +6,7 @@ from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
class FriendRequestCreate(BaseModel):
+5 -4
View File
@@ -10,8 +10,9 @@ from sqlalchemy.exc import SQLAlchemyError
from core.auth.models import CurrentUser
from core.db.base_service import BaseService
from core.logging import get_logger
from models.friendships import Friendship, FriendshipStatus
from models.inbox_messages import InboxMessage, InboxMessageStatus, InboxMessageType
from models.friendships import Friendship
from models.inbox_messages import InboxMessage
from schemas.enums import FriendshipStatus, InboxMessageStatus, InboxMessageType
from v1.friendships.repository import FriendshipRepository
from v1.friendships.schemas import (
FriendRequestCreate,
@@ -22,7 +23,7 @@ from v1.users.repository import UserRepository
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
logger = get_logger("v1.friendships.service")
@@ -593,7 +594,7 @@ class FriendshipService(BaseService):
)
def _build_user_basic_info(self, profile: Any) -> "UserContext":
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
if profile is None:
return UserContext(id="", username="")
+2 -1
View File
@@ -7,7 +7,8 @@ from sqlalchemy import select, update
from sqlalchemy.exc import SQLAlchemyError
from core.logging import get_logger
from models.inbox_messages import InboxMessage, InboxMessageType, InboxMessageStatus
from models.inbox_messages import InboxMessage
from schemas.enums import InboxMessageStatus, InboxMessageType
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
+1 -1
View File
@@ -6,7 +6,7 @@ from uuid import UUID
from pydantic import BaseModel, ConfigDict
from schemas.inbox.messages import InboxMessageStatus, InboxMessageType
from schemas.domain.inbox import InboxMessageStatus, InboxMessageType
class InboxMessageResponse(BaseModel):
+2 -1
View File
@@ -9,7 +9,8 @@ from sqlalchemy.exc import SQLAlchemyError
from core.db.base_repository import BaseRepository
from core.logging import get_logger
from models.memories import Memory, MemoryStatus, MemoryType
from models.memories import Memory
from schemas.enums import MemoryStatus, MemoryType
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
+1 -1
View File
@@ -4,7 +4,7 @@ from typing import Annotated
from fastapi import APIRouter, Depends, status
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from v1.memories.dependencies import get_memories_service
from v1.memories.schemas import (
MemoryListResponse,
+1 -1
View File
@@ -4,7 +4,7 @@ from typing import ClassVar
from pydantic import BaseModel, ConfigDict
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
class UserMemoryUpdate(BaseModel):
+3 -2
View File
@@ -8,8 +8,9 @@ from sqlalchemy.exc import SQLAlchemyError
from core.auth.models import CurrentUser
from core.db.base_service import BaseService
from core.logging import get_logger
from models.memories import Memory, MemoryType
from schemas.memories.memory_content import UserMemoryContent, WorkProfileContent
from models.memories import Memory
from schemas.enums import MemoryType
from schemas.domain.memory_content import UserMemoryContent, WorkProfileContent
from v1.memories.repository import MemoriesRepositoryLike
if TYPE_CHECKING:
+3 -2
View File
@@ -9,8 +9,9 @@ from sqlalchemy.exc import SQLAlchemyError
from core.db.base_repository import BaseRepository
from core.logging import get_logger
from models.schedule_items import ScheduleItem, ScheduleItemStatus
from models.schedule_subscriptions import ScheduleSubscription, SubscriptionStatus
from models.schedule_items import ScheduleItem
from models.schedule_subscriptions import ScheduleSubscription
from schemas.enums import ScheduleItemStatus, SubscriptionStatus
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
+2 -2
View File
@@ -7,14 +7,14 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from pydantic import BaseModel, ConfigDict, Field, field_validator
from schemas.inbox.messages import (
from schemas.domain.inbox import (
CalendarContent,
CalendarDeleteContent,
CalendarInviteContent,
CalendarUpdateContent,
parse_calendar_content,
)
from schemas.schedule.items import (
from schemas.domain.schedule import (
AttachmentType,
ScheduleItemMetadata,
ScheduleItemMetadataAttachment,
+12 -3
View File
@@ -10,9 +10,14 @@ from sqlalchemy.exc import SQLAlchemyError
from core.auth.models import CurrentUser
from core.db.base_service import BaseService
from core.logging import get_logger
from models.inbox_messages import InboxMessage, InboxMessageType, InboxMessageStatus
from models.inbox_messages import InboxMessage
from models.schedule_items import ScheduleItem
from models.schedule_subscriptions import SubscriptionPermission, SubscriptionStatus
from schemas.enums import (
InboxMessageStatus,
InboxMessageType,
SubscriptionPermission,
SubscriptionStatus,
)
from v1.auth.gateway import SupabaseAuthGateway
from v1.inbox_messages.repository import InboxMessageRepository
from v1.schedule_items.repository import ScheduleItemRepository
@@ -35,6 +40,8 @@ if TYPE_CHECKING:
logger = get_logger("v1.schedule_items.service")
_LEGACY_ARCHIVED_STATUSES = {"completed", "canceled"}
class AuthByPhoneGateway(Protocol):
async def get_user_by_phone(self, phone: str) -> "UserByPhoneResponse": ...
@@ -417,8 +424,10 @@ class ScheduleItemService(BaseService):
permission: int = 1,
) -> ScheduleItemResponse:
status_value = (
item.status.value if hasattr(item.status, "value") else item.status
item.status.value if hasattr(item.status, "value") else str(item.status)
)
if status_value in _LEGACY_ARCHIVED_STATUSES:
status_value = ScheduleItemStatus.ARCHIVED.value
source_type_value = (
item.source_type.value
if hasattr(item.source_type, "value")
+2 -1
View File
@@ -10,7 +10,8 @@ from sqlalchemy.exc import SQLAlchemyError
from core.db.base_repository import BaseRepository
from core.logging import get_logger
from models.todo_sources import TodoSource
from models.todos import Todo, TodoPriority, TodoStatus
from models.todos import Todo
from schemas.enums import TodoPriority, TodoStatus
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
+1 -1
View File
@@ -5,7 +5,7 @@ from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field
from schemas.todo import TodoOrder
from schemas.domain.todo import TodoOrder
class TodoCreate(BaseModel):
+2 -1
View File
@@ -10,7 +10,8 @@ from sqlalchemy.exc import SQLAlchemyError
from core.auth.models import CurrentUser
from core.db.base_service import BaseService
from core.logging import get_logger
from models.todos import Todo, TodoStatus
from models.todos import Todo
from schemas.enums import TodoStatus
from v1.schedule_items.repository import SQLAlchemyScheduleItemRepository
from v1.todo.repository import TodoRepository
from v1.todo.schemas import (
+1 -1
View File
@@ -5,7 +5,7 @@ from uuid import UUID
from fastapi import APIRouter, Depends
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
from v1.users.dependencies import get_user_service
from v1.users.schemas import UserSearchRequest, UserUpdateRequest
from v1.users.service import UserService
+3 -3
View File
@@ -13,14 +13,14 @@ from core.agentscope.persistence.user_context_cache import (
)
from core.db.base_service import BaseService
from core.logging import get_logger
from schemas.user.context import UserContext, parse_profile_settings
from schemas.shared.user import UserContext, parse_profile_settings
from v1.users.repository import UserRepository
from v1.users.schemas import UserSearchRequest, UserUpdateRequest
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
logger = get_logger("v1.users.service")
@@ -105,7 +105,7 @@ class UserService(BaseService):
)
async def get_user_by_id(self, user_id: UUID) -> "UserContext":
from schemas.user.context import UserContext
from schemas.shared.user import UserContext
try:
profile = await self._repository.get_by_user_id(user_id)