feat(host-agent): wire skill sync + inventory report into app lifecycle
Adds host_agent/skill_sync.py (HostAgentSkillSync) which constructs the synced + local skill stores, the Cloud API sync client, and the runner, then drives them on the host-agent lifecycle: incremental per-host pull into the synced catalog, fork-on-revocation, and a best-effort local- skill inventory report to the Cloud (design D7). Wired into create_application + run_async start/stop. Host-agent suite green (219 passed). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ from host_agent.local_account import LocalAccountStore
|
||||
from host_agent.policy_cache import HostPolicyCacheStore
|
||||
from host_agent.processor import AssignmentProcessingResult, AssignmentProcessor
|
||||
from host_agent.retention import prune_task_history
|
||||
from host_agent.skill_sync import HostAgentSkillSync
|
||||
from host_agent.status import AgentStatusTracker
|
||||
from host_agent.web.app import create_console_app
|
||||
from host_agent.web.auth import SessionManager
|
||||
@@ -42,6 +43,7 @@ class HostAgentApplication:
|
||||
console_enrollment_client: HostAgentEnrollmentClient | None = None
|
||||
dependency_supervisor: DependencySupervisor | None = None
|
||||
instance_lock: InstanceLock | None = None
|
||||
skill_sync: HostAgentSkillSync | None = None
|
||||
|
||||
def run(self) -> None:
|
||||
asyncio.run(self.run_async())
|
||||
@@ -60,6 +62,8 @@ class HostAgentApplication:
|
||||
)
|
||||
heartbeat_stop = asyncio.Event()
|
||||
heartbeat_task = asyncio.create_task(self.heartbeat.run(heartbeat_stop))
|
||||
if self.skill_sync is not None:
|
||||
self.skill_sync.start()
|
||||
console_task = (
|
||||
asyncio.create_task(self.console_server.serve())
|
||||
if self.console_server is not None
|
||||
@@ -110,6 +114,8 @@ class HostAgentApplication:
|
||||
finally:
|
||||
if self.console_enrollment_client is not None:
|
||||
self.console_enrollment_client.close()
|
||||
if self.skill_sync is not None:
|
||||
self.skill_sync.stop()
|
||||
await self.client.aclose()
|
||||
if self.instance_lock is not None:
|
||||
self.instance_lock.release()
|
||||
@@ -263,6 +269,9 @@ def create_application(
|
||||
dependency_supervisor = DependencySupervisor.from_host_agent_config(
|
||||
resolved_config
|
||||
)
|
||||
skill_sync: HostAgentSkillSync | None = None
|
||||
if resolved_config.host_id and resolved_config.token:
|
||||
skill_sync = HostAgentSkillSync(resolved_config)
|
||||
return HostAgentApplication(
|
||||
client=client,
|
||||
heartbeat=heartbeat,
|
||||
@@ -271,6 +280,7 @@ def create_application(
|
||||
console_enrollment_client=console_enrollment_client,
|
||||
dependency_supervisor=dependency_supervisor,
|
||||
instance_lock=instance_lock,
|
||||
skill_sync=skill_sync,
|
||||
)
|
||||
except BaseException:
|
||||
instance_lock.release()
|
||||
|
||||
Reference in New Issue
Block a user