134 lines
4.3 KiB
Python
134 lines
4.3 KiB
Python
"""
|
|
Platform Bridge - Cloud-to-Local Agent Bridge
|
|
==============================================
|
|
WorkBuddy-compatible sync client for local Goose agent.
|
|
|
|
Provides:
|
|
- Periodic knowledge base sync
|
|
- Usage metrics collection and reporting
|
|
- License validation and refresh
|
|
- Platform health monitoring
|
|
"""
|
|
import os
|
|
import json
|
|
import time
|
|
import hashlib
|
|
from datetime import datetime, timedelta
|
|
|
|
# Import the MCP server client
|
|
from .mcp_server import PlatformBridgeClient
|
|
|
|
|
|
class SyncManager:
|
|
"""Manages periodic synchronization between local agent and cloud platform"""
|
|
|
|
def __init__(self, client: PlatformBridgeClient = None):
|
|
self.client = client or PlatformBridgeClient()
|
|
self.sync_interval = 3600 # Default: 1 hour
|
|
self.last_sync = {}
|
|
self.last_license_check = None
|
|
self.last_usage_report = None
|
|
self.usage_buffer = []
|
|
|
|
def configure(self, config: dict):
|
|
"""Configure sync parameters from privacy config"""
|
|
frequency_map = {
|
|
"realtime": 60,
|
|
"hourly": 3600,
|
|
"daily": 86400,
|
|
"manual": None, # No auto sync
|
|
}
|
|
freq = config.get("sync_frequency", "daily")
|
|
self.sync_interval = frequency_map.get(freq, 86400)
|
|
self.client.user_id = config.get("user_id", self.client.user_id)
|
|
|
|
def should_sync_kb(self, kb_id: int) -> bool:
|
|
"""Check if a KB needs syncing"""
|
|
last = self.last_sync.get(kb_id, 0)
|
|
return (time.time() - last) >= self.sync_interval
|
|
|
|
def sync_kb(self, kb_id: int) -> dict:
|
|
"""Sync a single knowledge base"""
|
|
result = self.client.sync_knowledge_base(kb_id)
|
|
self.last_sync[kb_id] = time.time()
|
|
return result
|
|
|
|
def sync_all(self, kb_ids: list) -> list:
|
|
"""Sync all configured knowledge bases"""
|
|
results = []
|
|
for kb_id in kb_ids:
|
|
if self.should_sync_kb(kb_id):
|
|
result = self.sync_kb(kb_id)
|
|
results.append({"kb_id": kb_id, "result": result})
|
|
return results
|
|
|
|
def check_license(self, license_key: str) -> dict:
|
|
"""Check if license is still valid"""
|
|
now = time.time()
|
|
if self.last_license_check and (now - self.last_license_check) < 3600:
|
|
return {"valid": True, "cached": True}
|
|
|
|
result = self.client.validate_license(license_key)
|
|
self.last_license_check = now
|
|
return result
|
|
|
|
def track_usage(self, event_type: str, metadata: dict = None):
|
|
"""Buffer a usage event for reporting"""
|
|
self.usage_buffer.append({
|
|
"type": event_type,
|
|
"timestamp": time.time(),
|
|
"metadata": metadata or {},
|
|
})
|
|
|
|
def report_usage(self) -> dict:
|
|
"""Submit buffered usage events"""
|
|
if not self.usage_buffer:
|
|
return {"reported": 0}
|
|
|
|
events = self.usage_buffer[:]
|
|
self.usage_buffer = []
|
|
|
|
metrics = {
|
|
"event_count": len(events),
|
|
"event_types": {},
|
|
"time_range": {
|
|
"start": min(e["timestamp"] for e in events),
|
|
"end": max(e["timestamp"] for e in events),
|
|
}
|
|
}
|
|
|
|
for e in events:
|
|
t = e["type"]
|
|
metrics["event_types"][t] = metrics["event_types"].get(t, 0) + 1
|
|
|
|
result = self.client.report_usage(metrics)
|
|
self.last_usage_report = time.time()
|
|
result["reported"] = len(events)
|
|
return result
|
|
|
|
def health_check(self) -> dict:
|
|
"""Run a full health check"""
|
|
platform = self.client.check_health()
|
|
config = self.client.get_privacy_config()
|
|
|
|
return {
|
|
"platform": platform,
|
|
"privacy_mode": config.get("data", {}).get("privacy_mode", "unknown"),
|
|
"pending_events": len(self.usage_buffer),
|
|
"last_license_check": self.last_license_check,
|
|
"last_usage_report": self.last_usage_report,
|
|
}
|
|
|
|
|
|
def create_sync_manager(api_url: str = None, user_id: str = None) -> SyncManager:
|
|
"""Factory function to create a configured SyncManager"""
|
|
client = PlatformBridgeClient(api_url=api_url, user_id=user_id)
|
|
manager = SyncManager(client)
|
|
|
|
# Load config
|
|
config_result = client.get_privacy_config()
|
|
if config_result.get("code") == 0:
|
|
manager.configure(config_result["data"])
|
|
|
|
return manager
|