From d8ab0ba567f5e149275474289d9abd1c5e2818e7 Mon Sep 17 00:00:00 2001 From: Hyu Date: Sat, 1 Aug 2026 02:10:59 +0800 Subject: [PATCH] feat(telemetry): report workspace execution generation (#2374) Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com> --- src/langbot/pkg/telemetry/heartbeat.py | 2 ++ tests/unit_tests/telemetry/test_heartbeat.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/langbot/pkg/telemetry/heartbeat.py b/src/langbot/pkg/telemetry/heartbeat.py index 1296d9145..2dd2b2afd 100644 --- a/src/langbot/pkg/telemetry/heartbeat.py +++ b/src/langbot/pkg/telemetry/heartbeat.py @@ -37,6 +37,7 @@ class WorkspaceResourceSnapshot(typing.TypedDict): extension_count: int skill_count: int adapters: list[str] + execution_generation: int async def _count( @@ -81,6 +82,7 @@ async def _cloud_workspace_resource_counts(ap: core_app.Application, bindings) - 'extension_count': 0, 'skill_count': 0, 'adapters': [], + 'execution_generation': binding.placement_generation, } for binding in bindings } diff --git a/tests/unit_tests/telemetry/test_heartbeat.py b/tests/unit_tests/telemetry/test_heartbeat.py index 7a1b76484..3d7e60620 100644 --- a/tests/unit_tests/telemetry/test_heartbeat.py +++ b/tests/unit_tests/telemetry/test_heartbeat.py @@ -139,8 +139,8 @@ class TestBuildHeartbeatPayload: } ap.workspace_service.list_active_execution_bindings = AsyncMock( return_value=[ - SimpleNamespace(workspace_uuid='workspace-a'), - SimpleNamespace(workspace_uuid='workspace-b'), + SimpleNamespace(workspace_uuid='workspace-a', placement_generation=7), + SimpleNamespace(workspace_uuid='workspace-b', placement_generation=9), ], ) ap.platform_mgr._bots_by_key[('instance-a', 'workspace-b', 'bot-b')] = SimpleNamespace( @@ -159,10 +159,12 @@ class TestBuildHeartbeatPayload: assert by_workspace['workspace-a']['plugin_count'] == 2 assert by_workspace['workspace-a']['extension_count'] == 5 assert by_workspace['workspace-a']['skill_count'] == 2 + assert by_workspace['workspace-a']['execution_generation'] == 7 assert by_workspace['workspace-a']['adapters'] == ['WorkspaceAAdapter'] assert by_workspace['workspace-b']['bot_count'] == 1 assert by_workspace['workspace-b']['pipeline_count'] == 0 assert by_workspace['workspace-b']['skill_count'] == 1 + assert by_workspace['workspace-b']['execution_generation'] == 9 assert by_workspace['workspace-b']['adapters'] == ['WorkspaceBAdapter'] assert 'workspace_resources' not in by_workspace['workspace-a'] ap.persistence_mgr.execute_async.assert_not_awaited()