mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-27 16:04:21 +00:00
fix(agent-runner): harden run lifecycle and protocol stores
This commit is contained in:
@@ -275,6 +275,37 @@ def test_context_builder_includes_consumable_base64_attachments():
|
||||
assert input_data.attachments[1].name == "hello.txt"
|
||||
|
||||
|
||||
def test_context_builder_deduplicates_message_chain_attachments():
|
||||
query = make_query()
|
||||
query.user_message = None
|
||||
query.message_chain = platform_message.MessageChain(
|
||||
[platform_message.Image(base64="data:image/jpeg;base64,aGVsbG8=")]
|
||||
)
|
||||
|
||||
input_data = QueryEntryAdapter._build_input(query)
|
||||
|
||||
assert [content.type for content in input_data.contents] == ["image_base64"]
|
||||
assert len(input_data.attachments) == 1
|
||||
assert input_data.attachments[0].artifact_type == "image"
|
||||
assert input_data.attachments[0].content == "data:image/jpeg;base64,aGVsbG8="
|
||||
|
||||
|
||||
def test_context_builder_preserves_same_source_duplicate_attachments():
|
||||
query = make_query()
|
||||
query.user_message = provider_message.Message(
|
||||
role="user",
|
||||
content=[
|
||||
provider_message.ContentElement.from_image_base64("data:image/png;base64,aGVsbG8="),
|
||||
provider_message.ContentElement.from_image_base64("data:image/png;base64,aGVsbG8="),
|
||||
],
|
||||
)
|
||||
query.message_chain = platform_message.MessageChain([])
|
||||
|
||||
input_data = QueryEntryAdapter._build_input(query)
|
||||
|
||||
assert [attachment.artifact_type for attachment in input_data.attachments] == ["image", "image"]
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
async def clean_agent_state():
|
||||
"""Reset all singleton stores and create a test database engine."""
|
||||
@@ -546,6 +577,29 @@ async def test_orchestrator_unregisters_session_after_runner_failure(clean_agent
|
||||
assert await get_session_registry().get(context["run_id"]) is None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_orchestrator_unregisters_session_after_event_log_failure(clean_agent_state):
|
||||
"""Journal failures before runner invocation must not leave steerable sessions."""
|
||||
db_engine = clean_agent_state
|
||||
descriptor = make_descriptor()
|
||||
plugin_connector = FakePluginConnector(
|
||||
results=[
|
||||
{
|
||||
"type": "message.completed",
|
||||
"data": {"message": {"role": "assistant", "content": "unused"}},
|
||||
}
|
||||
]
|
||||
)
|
||||
orchestrator = AgentRunOrchestrator(FakeApplication(plugin_connector, db_engine), FakeRegistry(descriptor))
|
||||
orchestrator.journal.write_event_log = AsyncMock(side_effect=RuntimeError("journal unavailable"))
|
||||
|
||||
with pytest.raises(RuntimeError, match="journal unavailable"):
|
||||
[message async for message in orchestrator.run_from_query(make_query())]
|
||||
|
||||
assert plugin_connector.contexts == []
|
||||
assert await get_session_registry().list_active_runs() == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_orchestrator_enforces_total_runner_deadline(clean_agent_state):
|
||||
"""Test that orchestrator enforces total runner timeout."""
|
||||
|
||||
Reference in New Issue
Block a user