fix: keep proactive agent history in contexts (#9818)

Preserve structured conversation history for cron and background-task wakeups so normal context truncation can process it.

Refs #9763

Co-authored-by: liruihan <liruihan@example.com>
This commit is contained in:
Ruihan Li
2026-08-27 00:40:33 +08:00
committed by GitHub
parent 87a1917e80
commit c61fa088b7
4 changed files with 29 additions and 26 deletions
+1 -9
View File
@@ -565,15 +565,7 @@ class FunctionToolExecutor(BaseFunctionToolExecutor[AstrAgentContext]):
req = ProviderRequest()
conv = await _get_session_conv(event=cron_event, plugin_context=ctx)
req.conversation = conv
context = json.loads(conv.history)
if context:
req.contexts = context
context_dump = req._print_friendly_context()
req.contexts = []
req.system_prompt += (
"\n\nBellow is you and user previous conversation history:\n"
f"{context_dump}"
)
req.contexts = json.loads(conv.history)
bg = json.dumps(extras["background_task_result"], ensure_ascii=False)
req.system_prompt += BACKGROUND_TASK_RESULT_WOKE_SYSTEM_PROMPT.format(
+1 -12
View File
@@ -458,18 +458,7 @@ class CronJobManager:
req = ProviderRequest()
conv = await _get_session_conv(event=cron_event, plugin_context=self.ctx)
req.conversation = conv
# finetine the messages
context = json.loads(conv.history)
if context:
req.contexts = context
context_dump = req._print_friendly_context()
req.contexts = []
req.system_prompt += (
"\n\nBellow is you and user previous conversation history:\n"
f"---\n"
f"{context_dump}\n"
f"---\n"
)
req.contexts = json.loads(conv.history)
cron_job_str = json.dumps(extras.get("cron_job", {}), ensure_ascii=False)
req.system_prompt += PROACTIVE_AGENT_CRON_WOKE_SYSTEM_PROMPT.format(
cron_job=cron_job_str
+12 -2
View File
@@ -1,3 +1,4 @@
import json
from types import SimpleNamespace
from unittest.mock import AsyncMock
@@ -366,18 +367,23 @@ async def test_execute_handoff_passes_tool_call_timeout_to_tool_loop_agent(
@pytest.mark.asyncio
async def test_background_wakeup_passes_provider_settings_to_main_agent(
async def test_background_wakeup_passes_history_and_provider_settings_to_main_agent(
monkeypatch: pytest.MonkeyPatch,
):
"""Test background wakeup keeps structured history and provider settings."""
provider_settings = {
"fallback_chat_models": ["fallback-provider"],
"request_max_retries": 3,
"stream": True,
}
history = [
{"role": "user", "content": "old question"},
{"role": "assistant", "content": "old answer"},
]
captured: dict = {}
async def _fake_get_session_conv(**_kwargs):
return SimpleNamespace(history="[]")
return SimpleNamespace(history=json.dumps(history))
async def _fake_build_main_agent(**kwargs):
captured.update(kwargs)
@@ -428,6 +434,10 @@ async def test_background_wakeup_passes_provider_settings_to_main_agent(
assert config.streaming_response == provider_settings["stream"]
assert config.provider_settings == provider_settings
assert config.provider_settings["fallback_chat_models"] == ["fallback-provider"]
request = captured["req"]
assert "old question" not in request.system_prompt
assert "old answer" not in request.system_prompt
assert request.contexts == history
@pytest.mark.asyncio
+15 -3
View File
@@ -1,5 +1,6 @@
"""Tests for CronJobManager."""
import json
from datetime import datetime, timedelta, timezone
from unittest.mock import AsyncMock, MagicMock, patch
from zoneinfo import ZoneInfo
@@ -585,8 +586,10 @@ class TestRunActiveAgentJob:
"""Tests for active agent cron job execution."""
@pytest.mark.asyncio
async def test_woke_main_agent_passes_provider_settings(self, cron_manager):
"""Test active cron agent keeps fallback chat model settings."""
async def test_woke_main_agent_passes_history_and_provider_settings(
self, cron_manager
):
"""Test active cron agent keeps structured history and provider settings."""
provider_settings = {
"tool_call_timeout": 77,
"fallback_chat_models": ["fallback-provider"],
@@ -598,8 +601,12 @@ class TestRunActiveAgentJob:
}
cron_manager.ctx = ctx
history = [
{"role": "user", "content": "old question"},
{"role": "assistant", "content": "old answer"},
]
conv = MagicMock()
conv.history = "[]"
conv.history = json.dumps(history)
class FakeRunner:
def step_until_done(self, max_step):
@@ -616,6 +623,7 @@ class TestRunActiveAgentJob:
async def fake_build_main_agent(*, event, plugin_context, config, req):
captured["config"] = config
captured["req"] = req
return MagicMock(agent_runner=FakeRunner())
async def fake_persist_agent_history(*args, **kwargs):
@@ -645,6 +653,10 @@ class TestRunActiveAgentJob:
assert config.tool_call_timeout == 77
assert config.provider_settings is provider_settings
assert config.provider_settings["fallback_chat_models"] == ["fallback-provider"]
request = captured["req"]
assert "old question" not in request.system_prompt
assert "old answer" not in request.system_prompt
assert request.contexts == history
@pytest.mark.asyncio
@pytest.mark.parametrize(