diff --git a/app-instance/backend/beaver/engine/loop.py b/app-instance/backend/beaver/engine/loop.py index 35ce61d..235e0fc 100644 --- a/app-instance/backend/beaver/engine/loop.py +++ b/app-instance/backend/beaver/engine/loop.py @@ -644,29 +644,32 @@ class AgentLoop: } if thinking_enabled is not None: chat_kwargs["thinking_enabled"] = thinking_enabled + message_char_length = len(json.dumps(messages, ensure_ascii=False, default=str)) + tool_schema_char_length = len(json.dumps(tool_schemas, ensure_ascii=False, default=str)) + tool_names = [ + str(tool.get("function", {}).get("name") or tool.get("name") or "tool") + for tool in (tool_schemas or []) + if isinstance(tool, dict) + ] + snapshot_payload = { + "iteration": iterations, + "provider_name": final_provider_name, + "model": final_model, + "message_count": len(messages), + "tool_names": tool_names, + "message_char_length": message_char_length, + "tool_schema_char_length": tool_schema_char_length, + "max_tokens": resolved_max_tokens, + "temperature": resolved_temperature, + "thinking_enabled": thinking_enabled, + } session_manager.append_message( resolved_session_id, run_id=resolved_run_id, role="system", event_type="llm_request_snapshotted", - event_payload={ - "iteration": iterations, - "provider_name": final_provider_name, - "model": final_model, - "messages": messages, - "tools": tool_schemas, - "max_tokens": resolved_max_tokens, - "temperature": resolved_temperature, - "thinking_enabled": thinking_enabled, - }, - content=json.dumps( - { - "messages": messages, - "tools": tool_schemas, - }, - ensure_ascii=False, - default=str, - ), + event_payload=snapshot_payload, + content=json.dumps(snapshot_payload, ensure_ascii=False, default=str), context_visible=False, source=source, title=title, diff --git a/app-instance/backend/tests/unit/test_phase5_skills_runtime.py b/app-instance/backend/tests/unit/test_phase5_skills_runtime.py index 29e810a..08a6242 100644 --- a/app-instance/backend/tests/unit/test_phase5_skills_runtime.py +++ b/app-instance/backend/tests/unit/test_phase5_skills_runtime.py @@ -633,3 +633,23 @@ def test_agent_loop_records_max_tool_iterations_as_failed_skill_effect(tmp_path: effect_records = loaded.run_memory_store.list_skill_effects("docker-debug", version="v0007") assert effect_records[-1].run_id == result.run_id assert effect_records[-1].success is False + + +def test_llm_request_snapshot_defaults_to_compact_payload(tmp_path: Path) -> None: + loop = AgentLoop(loader=EngineLoader(workspace=tmp_path, skill_assembler=StubSkillAssembler([]))) + bundle = ProviderBundle( + main_runtime=SimpleNamespace(model="stub-model", provider_name="stub"), + main_provider=StubProvider( + [LLMResponse(content="done", finish_reason="stop", provider_name="stub", model="stub-model")] + ), + ) + + result = asyncio.run(loop.process_direct("hello", provider_bundle=bundle)) + loaded = loop.boot() + events = loaded.session_manager.get_run_event_records(result.session_id, result.run_id) + snapshot = next(event for event in events if event.event_type == "llm_request_snapshotted") + + assert "message_count" in snapshot.event_payload + assert "tool_names" in snapshot.event_payload + assert "messages" not in snapshot.event_payload + assert "tools" not in snapshot.event_payload