feat: sync self-evolution switch and fix scheduler context

This commit is contained in:
zhayujie
2026-06-15 16:30:34 +08:00
parent e2cb9e11b0
commit ce09b14836
4 changed files with 46 additions and 1 deletions

View File

@@ -49,6 +49,12 @@ class ChatService:
agent.model.channel_type = channel_type or "" agent.model.channel_type = channel_type or ""
agent.model.session_id = session_id or "" agent.model.session_id = session_id or ""
# Build a context so context-aware tools (e.g. scheduler) can resolve the
# receiver/session. This streaming path bypasses agent_bridge.agent_reply,
# so the attach step that normally happens there must be done here too.
context = self._build_context(query, session_id, channel_type)
self._attach_context_aware_tools(agent, context)
# State shared between the event callback and this method # State shared between the event callback and this method
state = _StreamState() state = _StreamState()
@@ -272,6 +278,37 @@ class ChatService:
@staticmethod
def _build_context(query: str, session_id: str, channel_type: str):
"""Build a Context for tool resolution on the streaming chat path.
receiver falls back to session_id; the scheduler's delivery keys on
session_id as the receiver.
"""
from bridge.context import Context, ContextType
# Pass an explicit kwargs dict: Context's default kwargs is a shared
# mutable default, so omitting it would leak fields across sessions.
ctx = Context(ContextType.TEXT, query, kwargs={})
ctx["session_id"] = session_id
ctx["receiver"] = session_id
ctx["isgroup"] = False
ctx["channel_type"] = channel_type or ""
return ctx
@staticmethod
def _attach_context_aware_tools(agent, context):
"""Attach the current context to tools that need it (scheduler)."""
try:
if not (context and getattr(agent, "tools", None)):
return
for tool in agent.tools:
if tool.name == "scheduler":
from agent.tools.scheduler.integration import attach_scheduler_to_tool
attach_scheduler_to_tool(tool, context)
break
except Exception as e:
logger.warning(f"[ChatService] Failed to attach context to scheduler: {e}")
@staticmethod @staticmethod
def _persist_messages(session_id: str, new_messages: list, channel_type: str = ""): def _persist_messages(session_id: str, new_messages: list, channel_type: str = ""):
try: try:

View File

@@ -874,7 +874,7 @@ def _build_config():
"agent_max_context_turns": local_conf.get("agent_max_context_turns"), "agent_max_context_turns": local_conf.get("agent_max_context_turns"),
"agent_max_context_tokens": local_conf.get("agent_max_context_tokens"), "agent_max_context_tokens": local_conf.get("agent_max_context_tokens"),
"agent_max_steps": local_conf.get("agent_max_steps"), "agent_max_steps": local_conf.get("agent_max_steps"),
# Self-evolution switch reported so the cloud console can reflect state # Self-evolution switch reported so the console can reflect state
"self_evolution_enabled": "Y" if local_conf.get("self_evolution_enabled") else "N", "self_evolution_enabled": "Y" if local_conf.get("self_evolution_enabled") else "N",
"self_evolution_idle_minutes": local_conf.get("self_evolution_idle_minutes"), "self_evolution_idle_minutes": local_conf.get("self_evolution_idle_minutes"),
"self_evolution_min_turns": local_conf.get("self_evolution_min_turns"), "self_evolution_min_turns": local_conf.get("self_evolution_min_turns"),

View File

@@ -9,6 +9,10 @@ description: Self-Evolution — review a conversation after it goes idle to cons
Self-Evolution lets the Agent do more than finish one task at a time; it keeps improving as it works with you. After a conversation winds down, it quietly reviews what just happened: it saves anything worth remembering into long-term memory, fixes problems that surfaced in a skill, and picks up tasks that were left unfinished. Over time the Agent learns your preferences, repeats fewer mistakes, and gets better at wrapping things up on its own. All of this runs in the background, and it only tells you when it actually did something. Self-Evolution lets the Agent do more than finish one task at a time; it keeps improving as it works with you. After a conversation winds down, it quietly reviews what just happened: it saves anything worth remembering into long-term memory, fixes problems that surfaced in a skill, and picks up tasks that were left unfinished. Over time the Agent learns your preferences, repeats fewer mistakes, and gets better at wrapping things up on its own. All of this runs in the background, and it only tells you when it actually did something.
<Note>
For the full architecture and engineering behind the self-evolution mechanism, see the blog post: [A Five-Layer Self-Evolution Mechanism for AI Agents](https://cowagent.ai/blog/self-evolution/).
</Note>
> Self-Evolution complements [Deep Dream](/memory/deep-dream). Deep Dream organizes memory itself, while Self-Evolution goes a step further to improve skills and push unfinished tasks forward, sharpening the Agent's abilities through everyday use. > Self-Evolution complements [Deep Dream](/memory/deep-dream). Deep Dream organizes memory itself, while Self-Evolution goes a step further to improve skills and push unfinished tasks forward, sharpening the Agent's abilities through everyday use.
<Frame> <Frame>

View File

@@ -9,6 +9,10 @@ description: Self-Evolution自动复盘沉淀记忆、优化技能、处
自主进化Self-Evolution让 Agent 不止于"完成单次任务",而是能在与你的相处中持续成长。在每段对话告一段落后,它会自动"回头复盘"一次把使用中暴露的问题修进技能、把没做完的事情接着推进并把值得记住的沉淀进记忆与知识库。久而久之Agent 会越来越懂你的偏好、越来越少重复犯错、越来越主动地把事情收尾,而这一切都在后台静默完成,当真正做了事情时才会主动地告诉你。 自主进化Self-Evolution让 Agent 不止于"完成单次任务",而是能在与你的相处中持续成长。在每段对话告一段落后,它会自动"回头复盘"一次把使用中暴露的问题修进技能、把没做完的事情接着推进并把值得记住的沉淀进记忆与知识库。久而久之Agent 会越来越懂你的偏好、越来越少重复犯错、越来越主动地把事情收尾,而这一切都在后台静默完成,当真正做了事情时才会主动地告诉你。
<Note>
想了解自进化机制完整的架构设计与工程实现,可阅读博客文章:[让 Agent 在对话中成长:自进化机制的五层实现](https://cowagent.ai/zh/blog/self-evolution/)。
</Note>
> 它与[梦境蒸馏](/zh/memory/deep-dream)互补:梦境蒸馏负责整理记忆本身,自主进化则在记忆之外,进一步优化技能、推进未完成的任务,让 Agent 的能力随使用不断打磨。 > 它与[梦境蒸馏](/zh/memory/deep-dream)互补:梦境蒸馏负责整理记忆本身,自主进化则在记忆之外,进一步优化技能、推进未完成的任务,让 Agent 的能力随使用不断打磨。
<Frame> <Frame>