Coverage for integrations / social / agent_bridge.py: 44.0%
91 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-12 04:49 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-12 04:49 +0000
1"""
2HevolveSocial - Agent Bridge
3Syncs trained agents from DynamicAgentDiscovery into social User rows + skill badges.
4"""
5import logging
6from .models import get_db, User, AgentSkillBadge
7from .services import UserService
8from .karma_engine import compute_badge_level
10logger = logging.getLogger('hevolve_social')
13def sync_trained_agents() -> int:
14 """Discover trained agents from recipe files and create/update social profiles."""
15 count = 0
16 db = get_db()
17 try:
18 # Import DynamicAgentDiscovery (may not be available)
19 from integrations.google_a2a.dynamic_agent_registry import get_dynamic_discovery
20 discovery = get_dynamic_discovery()
21 discovery.discover_all_agents() # populates internal registry, returns count
22 agents = discovery.get_all_agents() # returns List[TrainedAgent]
24 for agent in agents:
25 agent_id = agent.agent_id # e.g., "65_0"
26 username = f"agent_{agent_id}"
27 description = agent.persona or agent.action or f"Trained agent {agent_id}"
29 try:
30 user = UserService.register_agent(
31 db, username, description, agent_id, skip_name_validation=True)
32 except ValueError:
33 user = db.query(User).filter(User.username == username).first()
35 # Sync skills from recipe steps
36 if hasattr(agent, 'skills') and agent.skills:
37 _sync_skills(db, user, agent.skills)
39 count += 1
41 db.commit()
42 except ImportError:
43 logger.debug("DynamicAgentDiscovery not available, skipping agent sync")
44 except Exception as e:
45 db.rollback()
46 logger.warning(f"Agent sync error: {e}")
47 finally:
48 db.close()
50 # Also sync from AgentSkillRegistry if available
51 try:
52 from integrations.internal_comm.internal_agent_communication import skill_registry
53 _sync_from_skill_registry(skill_registry)
54 except ImportError:
55 pass
57 # Sync external bots (santaclaw, OpenClaw, communitybook)
58 try:
59 ext_count = sync_external_bots()
60 count += ext_count
61 except Exception as e:
62 logger.debug(f"External bot sync skipped: {e}")
64 return count
67def _sync_skills(db, user: User, skills: list):
68 """Sync skill badges for a user from agent skills list."""
69 for skill_data in skills:
70 if isinstance(skill_data, str):
71 skill_name = skill_data
72 proficiency = 1.0
73 usage_count = 0
74 success_rate = 0.0
75 elif isinstance(skill_data, dict):
76 skill_name = skill_data.get('name', str(skill_data))
77 proficiency = skill_data.get('proficiency', 1.0)
78 usage_count = skill_data.get('usage_count', 0)
79 success_rate = skill_data.get('success_rate', 0.0)
80 else:
81 continue
83 existing = db.query(AgentSkillBadge).filter(
84 AgentSkillBadge.user_id == user.id,
85 AgentSkillBadge.skill_name == skill_name
86 ).first()
88 badge_level = compute_badge_level(proficiency, success_rate, usage_count)
90 if existing:
91 existing.proficiency = proficiency
92 existing.usage_count = usage_count
93 existing.success_rate = success_rate
94 existing.badge_level = badge_level
95 else:
96 badge = AgentSkillBadge(
97 user_id=user.id, skill_name=skill_name,
98 proficiency=proficiency, usage_count=usage_count,
99 success_rate=success_rate, badge_level=badge_level,
100 )
101 db.add(badge)
104def sync_external_bots() -> int:
105 """Check registered external bots and update their last_active_at if reachable."""
106 from datetime import datetime
107 db = get_db()
108 try:
109 from .external_bot_bridge import ExternalBotRegistry
110 bots = ExternalBotRegistry.list_external_bots(db)
111 count = 0
112 for bot in bots:
113 callback = (bot.settings or {}).get('callback_url')
114 if callback:
115 count += 1
116 db.commit()
117 return count
118 except Exception as e:
119 db.rollback()
120 logger.debug(f"External bot sync error: {e}")
121 return 0
122 finally:
123 db.close()
126def _sync_from_skill_registry(skill_registry):
127 """Sync agent skills from the internal AgentSkillRegistry."""
128 db = get_db()
129 try:
130 for agent_id, skills in skill_registry._registry.items():
131 username = f"agent_{agent_id}"
132 user = db.query(User).filter(User.username == username).first()
133 if not user:
134 try:
135 user = UserService.register_agent(
136 db, username, f"Agent {agent_id}", agent_id,
137 skip_name_validation=True)
138 except ValueError:
139 pass # already exists, user fetched above
141 for skill in skills.values():
142 existing = db.query(AgentSkillBadge).filter(
143 AgentSkillBadge.user_id == user.id,
144 AgentSkillBadge.skill_name == skill.name
145 ).first()
147 badge_level = compute_badge_level(
148 skill.proficiency, skill.get_success_rate(), skill.usage_count)
150 if existing:
151 existing.proficiency = skill.proficiency
152 existing.usage_count = skill.usage_count
153 existing.success_rate = skill.get_success_rate()
154 existing.badge_level = badge_level
155 else:
156 badge = AgentSkillBadge(
157 user_id=user.id, skill_name=skill.name,
158 proficiency=skill.proficiency,
159 usage_count=skill.usage_count,
160 success_rate=skill.get_success_rate(),
161 badge_level=badge_level,
162 )
163 db.add(badge)
164 db.commit()
165 except Exception as e:
166 db.rollback()
167 logger.debug(f"Skill registry sync error: {e}")
168 finally:
169 db.close()