Files
aiagent/backend/app/agent_runtime/context.py
renjianbo beff3fac8d fix: delete agent 500 error + dynamic personality + deployment guide
- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions,
  schedules, executions, team_members) and unbind goals/tasks before delete
- Remove hardcoded personality templates in Android, replace with dynamic
  system prompt generation from name + description
- Set promptSectionsEnabled=false to bypass PromptComposer for personality
- Add Tencent Cloud Linux deployment guide (Docker Compose)
- Accumulated backend service updates, frontend UI fixes, Android app changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-29 01:17:21 +08:00

125 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Agent 会话上下文管理:维护消息历史、状态追踪。
"""
from __future__ import annotations
import uuid
from typing import Any, Dict, List, Optional
class AgentContext:
"""
Agent 会话上下文:
- 消息历史messages 列表OpenAI 格式)
- 会话元信息session_id, user_id 等)
- 执行追踪iteration 计数, 工具调用统计)
"""
def __init__(
self,
system_prompt: str = "你是一个有用的AI助手。",
user_id: Optional[str] = None,
session_id: Optional[str] = None,
):
self.session_id = session_id or str(uuid.uuid4())
self.user_id = user_id
self._messages: List[Dict[str, Any]] = []
self._system_prompt = system_prompt
# 执行状态
self.iteration = 0
self.tool_calls_made = 0
@property
def messages(self) -> List[Dict[str, Any]]:
"""获取完整消息列表(含 system prompt"""
if self._system_prompt:
# 确保 system prompt 始终在第一条
has_system = (
len(self._messages) > 0
and self._messages[0].get("role") == "system"
)
if not has_system:
return [
{"role": "system", "content": self._system_prompt},
*self._messages,
]
return self._messages
def add_user_message(self, content: str) -> None:
"""添加用户消息。"""
self._messages.append({"role": "user", "content": content})
def add_assistant_message(
self,
content: str,
tool_calls: Optional[List[Dict[str, Any]]] = None,
reasoning_content: Optional[str] = None,
) -> None:
"""添加助手回复。"""
msg: Dict[str, Any] = {"role": "assistant", "content": content or ""}
if tool_calls:
msg["tool_calls"] = tool_calls
if reasoning_content:
msg["reasoning_content"] = reasoning_content
self._messages.append(msg)
def add_tool_result(
self, tool_call_id: str, tool_name: str, result: str
) -> None:
"""添加工具执行结果。"""
self._messages.append({
"role": "tool",
"tool_call_id": tool_call_id,
"content": result,
"name": tool_name,
})
def set_system_prompt(self, prompt: str) -> None:
"""更新 system prompt仅在未发送过消息时有效"""
if not self._messages:
self._system_prompt = prompt
# ──────────────────── 消息操作(为 Compaction 提供) ────────────────────
@property
def raw_messages(self) -> List[Dict[str, Any]]:
"""获取原始消息列表(不含自动 prepend 的 system prompt
用于 CompactionEngine 直接操作 _messages避免 system prompt 重复。
"""
return self._messages
def replace_internal_messages(self, new_messages: List[Dict[str, Any]]) -> None:
"""替换全部内部消息CompactionEngine 用)。"""
self._messages = new_messages
def remove_messages_before(self, index: int) -> None:
"""移除指定索引之前的所有消息(保留 system prompt 在首位时的位置)。
注意:不修改 _system_prompt调用方通过 messages 属性获取时会自动 prepend。
"""
if index > 0:
self._messages = self._messages[index:]
def replace_message_range(
self, start: int, end: int, new_messages: List[Dict[str, Any]]
) -> None:
"""替换消息列表中 [start, end) 区间的消息。"""
self._messages[start:end] = new_messages
def estimate_tokens(self, token_counter=None) -> int:
"""估算当前消息列表的总 token 数(含 system prompt"""
from app.core.token_counter import TokenCounter
if token_counter is None:
token_counter = TokenCounter()
return token_counter.count_messages(self.messages)
# ──────────────────── 生命周期 ────────────────────
def reset(self) -> None:
"""重置上下文(保留 system prompt 和 session_id"""
self._messages = []
self.iteration = 0
self.tool_calls_made = 0