- 智能体支持从广场收藏到「我的」(新增 agent_favorites 表与收藏/取消收藏接口) - 定时任务新增「必须生成Markdown文件」开关:注入提示词并校验生成的 .md 文件且正文超过100字,否则记为失败(存于 execution_context,无需迁移) - 聊天问答展示时间(年月日 时分):问题在右下角、回答在左下角 - 常用提示词改为与账号绑定(新增 user_custom_prompts 表与 /api/user-prompts 接口),仅在首页输入框上方以居中标签 + 轮播展示,齿轮置于最右侧管理 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
55 lines
2.9 KiB
Python
55 lines
2.9 KiB
Python
"""ORM model for custom agents."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import BigInteger, Boolean, String, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime
|
|
|
|
|
|
class AgentRow(Base):
|
|
__tablename__ = "agents"
|
|
|
|
# Stored as a plain string so the same id can be used as the filesystem
|
|
# directory name under {base_dir}/agents/{id}/.
|
|
id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
name: Mapped[str] = mapped_column(String(191), nullable=False, index=True)
|
|
description: Mapped[str] = mapped_column(String(1024), nullable=False, default="")
|
|
user_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
|
|
published: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
|
|
# When True, the agent is moved into the password-gated "private square"
|
|
# (私密广场) and is hidden from the regular public square / built-in list.
|
|
# The flag is independent of ``published``: a private agent is still
|
|
# visible to its owner in the "我的" tab, and visible to anyone in the
|
|
# private-square listing once the password has been verified.
|
|
is_private: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
|
|
# NULL = not featured on the homepage selector. Non-NULL = admin-curated
|
|
# featured rank (lower sorts first). Only ``published=True`` agents are
|
|
# eligible; the router enforces that invariant on writes. BIGINT so the
|
|
# frontend can seed initial ranks from ``Date.now()`` (ms-resolution
|
|
# timestamps overflow a 4-byte INT on MySQL).
|
|
featured_order: Mapped[int | None] = mapped_column(BigInteger, nullable=True, index=True)
|
|
created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC))
|
|
updated_at: Mapped[datetime] = mapped_column(BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC))
|
|
|
|
|
|
class AgentFavoriteRow(Base):
|
|
"""A user's bookmark of a (typically public-square) agent.
|
|
|
|
Lets a user collect agents from the 广场 (square) into their "我的" tab
|
|
without owning them. One row per (user, agent); the unique constraint makes
|
|
favoriting idempotent.
|
|
"""
|
|
|
|
__tablename__ = "agent_favorites"
|
|
__table_args__ = (UniqueConstraint("user_id", "agent_id", name="uq_agent_favorites_user_agent"),)
|
|
|
|
id: Mapped[str] = mapped_column(String(64), primary_key=True)
|
|
user_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
|
agent_id: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
|
created_at: Mapped[datetime] = mapped_column(BeijingDateTime(), nullable=False, default=lambda: datetime.now(UTC))
|