diff --git a/backend/app/api/dingtalk.py b/backend/app/api/dingtalk.py index 98edb23f..940e8d3b 100644 --- a/backend/app/api/dingtalk.py +++ b/backend/app/api/dingtalk.py @@ -14,6 +14,7 @@ from app.core.security import get_current_user from app.database import get_db from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE from app.models.user import User from app.schemas.schemas import ChannelConfigOut @@ -167,7 +168,7 @@ async def process_dingtalk_message( logger.warning(f"[DingTalk] Agent {agent_id} not found") return creator_id = agent_obj.creator_id - ctx_size = agent_obj.context_window_size if agent_obj else 20 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE # Determine conv_id for session isolation if conversation_type == "2": diff --git a/backend/app/api/discord_bot.py b/backend/app/api/discord_bot.py index 9481b47b..d05fc1f5 100644 --- a/backend/app/api/discord_bot.py +++ b/backend/app/api/discord_bot.py @@ -12,6 +12,7 @@ from app.core.security import get_current_user from app.database import get_db from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE from app.models.user import User from app.schemas.schemas import ChannelConfigOut @@ -300,7 +301,7 @@ async def handle_in_background(): agent_r = await bg_db.execute(select(AgentModel).where(AgentModel.id == agent_id)) agent_obj = agent_r.scalar_one_or_none() creator_id = agent_obj.creator_id if agent_obj else agent_id - ctx_size = agent_obj.context_window_size if agent_obj else 20 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE # Find-or-create platform user for this Discord sender from app.models.user import User as _User diff --git a/backend/app/api/feishu.py b/backend/app/api/feishu.py index a0058c51..7521eaa1 100644 --- a/backend/app/api/feishu.py +++ b/backend/app/api/feishu.py @@ -11,6 +11,7 @@ from app.core.security import get_current_user from app.database import get_db from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE from app.models.user import User from app.models.identity import IdentityProvider from app.schemas.schemas import ChannelConfigCreate, ChannelConfigOut, TokenResponse, UserOut @@ -405,7 +406,7 @@ async def process_feishu_event(agent_id: uuid.UUID, body: dict, db: AsyncSession agent_r = await db.execute(select(AgentModel).where(AgentModel.id == agent_id)) agent_obj = agent_r.scalar_one_or_none() creator_id = agent_obj.creator_id if agent_obj else agent_id - ctx_size = agent_obj.context_window_size if agent_obj else 100 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE # Pre-resolve session so history lookup uses the UUID (session created later if new) _pre_sess_r = await db.execute( @@ -1045,7 +1046,7 @@ async def _handle_feishu_file(db, agent_id, config, message, sender_open_id, cha _sess.last_message_at = _dt.now(_tz.utc) # Load conversation history for LLM context - ctx_size = agent_obj.context_window_size if agent_obj else 100 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE _hist_r = await db.execute( _select(ChatMessage) .where(ChatMessage.agent_id == agent_id, ChatMessage.conversation_id == session_conv_id) @@ -1232,7 +1233,7 @@ async def _call_agent_llm(db: AsyncSession, agent_id: uuid.UUID, user_text: str, # Build conversation messages (without system prompt — call_llm adds it) messages: list[dict] = [] - ctx_size = agent.context_window_size or 100 + ctx_size = agent.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE if history: messages.extend(history[-ctx_size:]) messages.append({"role": "user", "content": user_text}) diff --git a/backend/app/api/slack.py b/backend/app/api/slack.py index 57eb0a8f..00d2a2eb 100644 --- a/backend/app/api/slack.py +++ b/backend/app/api/slack.py @@ -14,6 +14,7 @@ from app.core.security import get_current_user from app.database import get_db from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE from app.models.user import User from app.schemas.schemas import ChannelConfigOut @@ -238,7 +239,7 @@ async def slack_event_webhook( agent_r = await db.execute(select(AgentModel).where(AgentModel.id == agent_id)) agent_obj = agent_r.scalar_one_or_none() creator_id = agent_obj.creator_id if agent_obj else agent_id - ctx_size = agent_obj.context_window_size if agent_obj else 20 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE # Find-or-create platform user for this Slack sender from app.models.user import User as _User diff --git a/backend/app/api/teams.py b/backend/app/api/teams.py index b07e7503..3377ee8b 100644 --- a/backend/app/api/teams.py +++ b/backend/app/api/teams.py @@ -18,7 +18,7 @@ from app.core.permissions import check_agent_access, is_agent_creator from app.core.security import get_current_user from app.database import get_db -from app.models.agent import Agent as AgentModel +from app.models.agent import Agent as AgentModel, DEFAULT_CONTEXT_WINDOW_SIZE from app.models.audit import ChatMessage from app.models.channel_config import ChannelConfig from app.models.user import User @@ -499,7 +499,7 @@ async def teams_event_webhook( # Load history agent_r = await db.execute(select(AgentModel).where(AgentModel.id == agent_id)) agent_obj = agent_r.scalar_one_or_none() - ctx_size = agent_obj.context_window_size if agent_obj else 20 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE history_r = await db.execute( select(ChatMessage) diff --git a/backend/app/api/websocket.py b/backend/app/api/websocket.py index 7533ce59..2dd653bf 100644 --- a/backend/app/api/websocket.py +++ b/backend/app/api/websocket.py @@ -12,7 +12,7 @@ from app.core.security import decode_access_token from app.core.permissions import check_agent_access, is_agent_expired from app.database import async_session -from app.models.agent import Agent +from app.models.agent import Agent, DEFAULT_CONTEXT_WINDOW_SIZE from app.models.audit import ChatMessage from app.models.llm import LLMModel from app.models.user import User @@ -459,7 +459,7 @@ async def websocket_chat( agent_type = agent.agent_type or "" role_description = agent.role_description or "" welcome_message = agent.welcome_message or "" - ctx_size = agent.context_window_size or 100 + ctx_size = agent.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE logger.info(f"[WS] Agent: {agent_name}, type: {agent_type}, model_id: {agent.primary_model_id}, ctx: {ctx_size}") # Load the agent's primary model diff --git a/backend/app/api/wecom.py b/backend/app/api/wecom.py index 27e88b9e..6890345b 100644 --- a/backend/app/api/wecom.py +++ b/backend/app/api/wecom.py @@ -21,6 +21,7 @@ from app.core.security import get_current_user from app.database import get_db from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE from app.models.user import User from app.schemas.schemas import ChannelConfigOut @@ -480,7 +481,7 @@ async def _process_wecom_text( logger.warning(f"[WeCom] Agent {agent_id} not found") return creator_id = agent_obj.creator_id - ctx_size = agent_obj.context_window_size if agent_obj else 20 + ctx_size = (agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE) if agent_obj else DEFAULT_CONTEXT_WINDOW_SIZE # Distinguish group chat from P2P by chat_id presence _is_group = bool(chat_id) diff --git a/backend/app/models/agent.py b/backend/app/models/agent.py index c76ded55..7e8dcfb4 100644 --- a/backend/app/models/agent.py +++ b/backend/app/models/agent.py @@ -9,6 +9,8 @@ from app.database import Base +DEFAULT_CONTEXT_WINDOW_SIZE = 100 + class Agent(Base): """Digital employee (Agent) instance. @@ -74,7 +76,7 @@ class Agent(Base): last_daily_reset: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) last_monthly_reset: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) tokens_used_total: Mapped[int] = mapped_column(Integer, default=0) - context_window_size: Mapped[int] = mapped_column(Integer, default=100) + context_window_size: Mapped[int] = mapped_column(Integer, default=DEFAULT_CONTEXT_WINDOW_SIZE) max_tool_rounds: Mapped[int] = mapped_column(Integer, default=50) # Trigger limits (per-agent, configurable from Settings UI) diff --git a/backend/app/services/discord_gateway.py b/backend/app/services/discord_gateway.py index 101f9871..3c612890 100644 --- a/backend/app/services/discord_gateway.py +++ b/backend/app/services/discord_gateway.py @@ -18,6 +18,7 @@ from app.database import async_session from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE try: import discord @@ -170,7 +171,7 @@ async def _handle_message( if not agent_obj: return "Agent not found." creator_id = agent_obj.creator_id - ctx_size = agent_obj.context_window_size or 20 + ctx_size = agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE # Find or create platform user for this Discord sender _username = f"discord_{sender_id}" diff --git a/backend/app/services/wecom_stream.py b/backend/app/services/wecom_stream.py index 2a84bcad..dd533108 100644 --- a/backend/app/services/wecom_stream.py +++ b/backend/app/services/wecom_stream.py @@ -13,6 +13,7 @@ from app.database import async_session from app.models.channel_config import ChannelConfig +from app.models.agent import DEFAULT_CONTEXT_WINDOW_SIZE class WeComStreamManager: @@ -289,7 +290,7 @@ async def _process_wecom_stream_message( if not agent_obj: logger.warning(f"[WeCom Stream] Agent {agent_id} not found") return "Agent not found" - ctx_size = agent_obj.context_window_size or 20 + ctx_size = agent_obj.context_window_size or DEFAULT_CONTEXT_WINDOW_SIZE # Conversation ID: differentiate single chat vs group chat # Group detection is based on chatid presence, not chattype (SDK bug)