From eeaec1f9516c823b4a56d1db631b26c147253429 Mon Sep 17 00:00:00 2001 From: Xubin Ren Date: Mon, 27 Apr 2026 06:23:43 +0000 Subject: [PATCH] fix(agent): prevent message time metadata from leaking into replies --- nanobot/templates/agent/identity.md | 4 ++++ tests/agent/test_context_prompt_cache.py | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/nanobot/templates/agent/identity.md b/nanobot/templates/agent/identity.md index a53be709..0000b51c 100644 --- a/nanobot/templates/agent/identity.md +++ b/nanobot/templates/agent/identity.md @@ -28,5 +28,9 @@ Output is rendered in a terminal. Avoid markdown headings and tables. Use plain - On broad searches, use `grep(output_mode="count")` to scope before requesting full content. {% include 'agent/_snippets/untrusted_content.md' %} +Historical messages may include `[Message Time: ...]` prefixes. Treat them as +metadata for chronology only; never quote, copy, or include those markers in +your response. + Reply directly with text for conversations. Only use the 'message' tool to send to a specific chat channel. IMPORTANT: To send files (images, video, audio, documents) to the user, you MUST call the 'message' tool with the 'media' parameter. Do NOT use read_file to "send" a file — reading a file only shows its content to you, it does NOT deliver the file to the user. Examples: message(content="Here is the image", media=["/path/to/file.png"]) or message(content="Here is the video", media=["/path/to/video.mp4"]) diff --git a/tests/agent/test_context_prompt_cache.py b/tests/agent/test_context_prompt_cache.py index ea1052ca..0a7cb551 100644 --- a/tests/agent/test_context_prompt_cache.py +++ b/tests/agent/test_context_prompt_cache.py @@ -188,6 +188,16 @@ def test_identity_has_no_behavioral_instructions(tmp_path) -> None: assert "Execution Rules" not in identity +def test_system_prompt_treats_message_time_as_metadata(tmp_path) -> None: + workspace = _make_workspace(tmp_path) + builder = ContextBuilder(workspace) + + prompt = builder.build_system_prompt() + + assert "Historical messages may include `[Message Time: ...]` prefixes" in prompt + assert "never quote, copy, or include those markers" in prompt + + def test_default_soul_template_contains_execution_rules() -> None: """Default SOUL.md template must contain execution rules with act/plan layering.""" soul = (pkg_files("nanobot") / "templates" / "SOUL.md").read_text(encoding="utf-8")