Rebase onto upstream (a4d95fd)
#12
@@ -45,7 +45,7 @@ async def test_process_direct_passes_metadata():
|
|||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_suppress_mode_adds_hidden_prefix():
|
async def test_suppress_mode_adds_hidden_prefix():
|
||||||
"""Test that suppress_output metadata adds [HIDDEN] prefix."""
|
"""Test that suppress_output metadata adds [HIDDEN:signature] prefix."""
|
||||||
bus = MessageBus()
|
bus = MessageBus()
|
||||||
provider = MagicMock(spec=LLMProvider)
|
provider = MagicMock(spec=LLMProvider)
|
||||||
provider.chat = AsyncMock(return_value=LLMResponse(
|
provider.chat = AsyncMock(return_value=LLMResponse(
|
||||||
@@ -66,14 +66,20 @@ async def test_suppress_mode_adds_hidden_prefix():
|
|||||||
metadata={"suppress_output": True}
|
metadata={"suppress_output": True}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Response content should have [HIDDEN] prefix
|
# Response content should have [HIDDEN:signature] prefix with 8-char hex signature
|
||||||
assert response.startswith("[HIDDEN]")
|
assert response.startswith("[HIDDEN:")
|
||||||
|
assert "]" in response
|
||||||
|
# Extract signature part between [HIDDEN: and ]
|
||||||
|
prefix_end = response.index("]")
|
||||||
|
signature = response[8:prefix_end] # Skip "[HIDDEN:" to get signature
|
||||||
|
assert len(signature) == 8 # 8-character hex signature
|
||||||
|
assert all(c in "0123456789abcdef" for c in signature) # Valid hex
|
||||||
assert "This is the agent response" in response
|
assert "This is the agent response" in response
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_normal_mode_no_hidden_prefix():
|
async def test_normal_mode_no_hidden_prefix():
|
||||||
"""Test that normal messages don't get [HIDDEN] prefix."""
|
"""Test that normal messages don't get [HIDDEN:signature] prefix."""
|
||||||
bus = MessageBus()
|
bus = MessageBus()
|
||||||
provider = MagicMock(spec=LLMProvider)
|
provider = MagicMock(spec=LLMProvider)
|
||||||
provider.chat = AsyncMock(return_value=LLMResponse(
|
provider.chat = AsyncMock(return_value=LLMResponse(
|
||||||
@@ -91,6 +97,6 @@ async def test_normal_mode_no_hidden_prefix():
|
|||||||
# Call without suppress_output
|
# Call without suppress_output
|
||||||
response = await loop.process_direct(content="test message")
|
response = await loop.process_direct(content="test message")
|
||||||
|
|
||||||
# Response should NOT have [HIDDEN] prefix
|
# Response should NOT have [HIDDEN:signature] prefix
|
||||||
assert not response.startswith("[HIDDEN]")
|
assert not response.startswith("[HIDDEN:")
|
||||||
assert response == "Normal response"
|
assert response == "Normal response"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from unittest.mock import AsyncMock, MagicMock
|
|||||||
async def test_idle_heartbeat_end_to_end(tmp_path):
|
async def test_idle_heartbeat_end_to_end(tmp_path):
|
||||||
"""
|
"""
|
||||||
Integration test: heartbeat triggers when idle, runs in main session,
|
Integration test: heartbeat triggers when idle, runs in main session,
|
||||||
output is suppressed, session contains [HIDDEN] content.
|
output is suppressed, session contains [HIDDEN:signature] content.
|
||||||
"""
|
"""
|
||||||
workspace = tmp_path / "test-integration"
|
workspace = tmp_path / "test-integration"
|
||||||
workspace.mkdir()
|
workspace.mkdir()
|
||||||
@@ -91,14 +91,20 @@ async def test_idle_heartbeat_end_to_end(tmp_path):
|
|||||||
# 1. Session has new messages
|
# 1. Session has new messages
|
||||||
assert len(session.messages) > 1
|
assert len(session.messages) > 1
|
||||||
|
|
||||||
# 2. Find the heartbeat response (assistant message)
|
# 2. Find the heartbeat response (assistant message with signed visibility marker)
|
||||||
heartbeat_messages = [
|
heartbeat_messages = [
|
||||||
m for m in session.messages
|
m for m in session.messages
|
||||||
if m.get("role") == "assistant" and "[HIDDEN]" in m.get("content", "")
|
if m.get("role") == "assistant" and "[HIDDEN:" in m.get("content", "")
|
||||||
]
|
]
|
||||||
assert len(heartbeat_messages) == 1, "Expected exactly 1 [HIDDEN] heartbeat message"
|
assert len(heartbeat_messages) == 1, "Expected exactly 1 [HIDDEN:signature] heartbeat message"
|
||||||
|
|
||||||
# 3. Verify content is prefixed with [HIDDEN]
|
# 3. Verify content is prefixed with [HIDDEN:signature]
|
||||||
heartbeat_msg = heartbeat_messages[0]
|
heartbeat_msg = heartbeat_messages[0]
|
||||||
assert heartbeat_msg["content"].startswith("[HIDDEN]")
|
assert heartbeat_msg["content"].startswith("[HIDDEN:")
|
||||||
|
# Verify signature format (8-char hex)
|
||||||
|
content = heartbeat_msg["content"]
|
||||||
|
prefix_end = content.index("]")
|
||||||
|
signature = content[8:prefix_end] # Skip "[HIDDEN:" to get signature
|
||||||
|
assert len(signature) == 8, f"Expected 8-char signature, got {len(signature)}"
|
||||||
|
assert all(c in "0123456789abcdef" for c in signature), "Signature should be hex"
|
||||||
assert "Heartbeat executed successfully" in heartbeat_msg["content"]
|
assert "Heartbeat executed successfully" in heartbeat_msg["content"]
|
||||||
|
|||||||
Reference in New Issue
Block a user