This commit is contained in:
@@ -14,6 +14,7 @@ from cloud.internal_api.models import (
|
||||
DeviceSnapshotModel,
|
||||
HeartbeatResponse,
|
||||
HostEnrollmentResponse,
|
||||
HostTaskSubmissionResponse,
|
||||
LeaseRenewalResponse,
|
||||
TerminalResultResponse,
|
||||
)
|
||||
@@ -146,6 +147,7 @@ class HostAgentClient:
|
||||
devices: list[DeviceSnapshotModel],
|
||||
*,
|
||||
address: str | None = None,
|
||||
policy_revision: int = 0,
|
||||
) -> HeartbeatResponse:
|
||||
response = await self._request(
|
||||
"PUT",
|
||||
@@ -154,10 +156,28 @@ class HostAgentClient:
|
||||
"host_id": self.config.host_id,
|
||||
"address": address,
|
||||
"devices": [device.model_dump(mode="json") for device in devices],
|
||||
"policy_revision": policy_revision,
|
||||
},
|
||||
)
|
||||
return HeartbeatResponse.model_validate(response.json())
|
||||
|
||||
async def submit_self_task(
|
||||
self,
|
||||
*,
|
||||
goal: str,
|
||||
device_id: str | None = None,
|
||||
) -> HostTaskSubmissionResponse:
|
||||
response = await self._request(
|
||||
"POST",
|
||||
f"/internal/v1/hosts/{self.config.host_id}/tasks",
|
||||
json={
|
||||
"host_id": self.config.host_id,
|
||||
"goal": goal,
|
||||
"device_id": device_id,
|
||||
},
|
||||
)
|
||||
return HostTaskSubmissionResponse.model_validate(response.json())
|
||||
|
||||
async def claim(self) -> AssignmentModel | None:
|
||||
response = await self._request(
|
||||
"POST",
|
||||
|
||||
@@ -27,7 +27,7 @@ import httpx
|
||||
|
||||
from cloud.internal_api.models import PlannerDecisionError, PlannerDecisionResponse
|
||||
from host_agent.config import HostAgentConfig
|
||||
from runtime.tool_calling_client import ToolCallDecision, ToolCallUnavailable
|
||||
from runtime.tool_calling_client import ToolCallDecision, ToolCallUnavailable, ToolCallUsage
|
||||
from runtime.tool_specs import ToolSpec
|
||||
|
||||
|
||||
@@ -85,6 +85,22 @@ class CloudProxyToolCallingClient:
|
||||
return ToolCallDecision(
|
||||
tool_name=decoded.tool_name,
|
||||
arguments=dict(decoded.arguments),
|
||||
usage=(
|
||||
ToolCallUsage(
|
||||
input_tokens=decoded.input_tokens,
|
||||
output_tokens=decoded.output_tokens,
|
||||
total_tokens=decoded.total_tokens,
|
||||
)
|
||||
if any(
|
||||
value is not None
|
||||
for value in (
|
||||
decoded.input_tokens,
|
||||
decoded.output_tokens,
|
||||
decoded.total_tokens,
|
||||
)
|
||||
)
|
||||
else None
|
||||
),
|
||||
)
|
||||
raise ToolCallUnavailable(_error_detail(response))
|
||||
|
||||
|
||||
@@ -45,13 +45,19 @@ class HeartbeatSynchronizer:
|
||||
self._sleep = sleep
|
||||
self.status_tracker = status_tracker
|
||||
self.on_sync = on_sync
|
||||
self.policy_revision = 0
|
||||
self.policy = None
|
||||
|
||||
async def sync_once(self) -> HeartbeatResponse:
|
||||
snapshot = build_device_snapshot(self.manager)
|
||||
response = await self.client.heartbeat(
|
||||
snapshot,
|
||||
address=self.address,
|
||||
policy_revision=self.policy_revision,
|
||||
)
|
||||
self.policy_revision = response.policy_revision
|
||||
if response.policy is not None:
|
||||
self.policy = response.policy
|
||||
if self.status_tracker is not None:
|
||||
self.status_tracker.mark_heartbeat(ok=True, device_count=len(snapshot))
|
||||
if self.on_sync is not None:
|
||||
|
||||
@@ -58,7 +58,7 @@ def test_heartbeat_synchronizer_runs_at_configured_interval_until_stopped() -> N
|
||||
calls: list[list[str]] = []
|
||||
|
||||
class FakeClient:
|
||||
async def heartbeat(self, devices, *, address=None):
|
||||
async def heartbeat(self, devices, *, address=None, policy_revision=0):
|
||||
calls.append([device.device_id for device in devices])
|
||||
return HeartbeatResponse(
|
||||
host_id="host-a",
|
||||
@@ -96,7 +96,7 @@ def test_sync_once_notifies_status_tracker_and_on_sync_with_device_count() -> No
|
||||
)
|
||||
|
||||
class FakeClient:
|
||||
async def heartbeat(self, devices, *, address=None):
|
||||
async def heartbeat(self, devices, *, address=None, policy_revision=0):
|
||||
return HeartbeatResponse(
|
||||
host_id="host-a",
|
||||
accepted_devices=len(devices),
|
||||
|
||||
Reference in New Issue
Block a user