Coverage for integrations / agent_engine / __init__.py: 9.0%

89 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-12 04:49 +0000

1""" 

2Unified Agent Goal Engine 

3 

4Generic framework for autonomous agent goals: marketing, coding, analytics, etc. 

5Adding a new agent type = register a prompt builder + tool tags. 

6 

7Enabled via HEVOLVE_AGENT_ENGINE_ENABLED=true (default: false). 

8""" 

9import os 

10import logging 

11 

12logger = logging.getLogger('hevolve_social') 

13 

14_engine_bp = None 

15 

16 

17def get_engine_blueprint(): 

18 global _engine_bp 

19 if _engine_bp is None: 

20 from .api import agent_engine_bp as bp 

21 _engine_bp = bp 

22 return _engine_bp 

23 

24 

25_agent_engine_initialized = False 

26_agent_engine_init_lock = None # threading.Lock() lazy-created in init 

27 

28 

29def init_agent_engine(app): 

30 """Initialize the unified agent goal engine. 

31 

32 Idempotent: safe to call multiple times — only the first call does work. 

33 The previous opt-in gate (`HEVOLVE_AGENT_ENGINE_ENABLED`) was added on 

34 2026-04-19 to escape a 244s cold-boot stall caused by the import chain 

35 `agent_baseline_service` → `helper` (the hart_intelligence top-level 

36 `helper.py` module) racing with the Nunba `hartos-init` thread on 

37 `from hart_intelligence import app`. Both threads enter 

38 `_find_and_load → _lock_unlock_module → acquire`; CPython serialises 

39 on the per-module import lock and one thread blocks indefinitely 

40 because the other is mid-import of a parent package. 

41 

42 Fix (2026-04-28): keep the function callable unconditionally but make 

43 the heavy `agent_baseline_service` + `agent_daemon` imports lazy, run 

44 inside the function body (not at module load), and protected by an 

45 idempotency guard so duplicate callers (Nunba's main.py 

46 `_deferred_social_init` AND HARTOS's own `social/__init__.py`) cannot 

47 double-bootstrap. The `helper` import inside `agent_baseline_service` 

48 already has a fallback path, so it is allowed to run after 

49 hart_intelligence is fully imported (hartos-init done) — we no longer 

50 race. 

51 """ 

52 global _agent_engine_initialized, _agent_engine_init_lock 

53 

54 if _agent_engine_init_lock is None: 

55 import threading as _t 

56 _agent_engine_init_lock = _t.Lock() 

57 

58 with _agent_engine_init_lock: 

59 if _agent_engine_initialized: 

60 logger.debug("Agent engine already initialised — skipping duplicate call") 

61 return 

62 # Mark BEFORE the heavy work so a second caller racing on the lock 

63 # exits cleanly even if our own work is still in progress in this 

64 # thread (we hold the lock for the duration; the second caller 

65 # can't observe a half-initialised state). 

66 _agent_engine_initialized = True 

67 

68 if os.environ.get('HEVOLVE_AGENT_ENGINE_ENABLED', 'false').lower() != 'true': 

69 logger.info("Agent engine disabled (HEVOLVE_AGENT_ENGINE_ENABLED != true)") 

70 return 

71 

72 # Register API blueprint 

73 try: 

74 bp = get_engine_blueprint() 

75 app.register_blueprint(bp) 

76 logger.info("Agent engine endpoints registered") 

77 except Exception as e: 

78 logger.warning(f"Agent engine blueprint registration failed: {e}") 

79 return 

80 

81 # Bootstrap "HART Platform" product for self-marketing (idempotent) 

82 product_id = None 

83 try: 

84 from integrations.social.models import get_db, Product, User 

85 db = get_db() 

86 existing = db.query(Product).filter_by(is_platform_product=True).first() 

87 if not existing: 

88 product = Product( 

89 name='HART Platform', 

90 description='Crowdsourced agentic intelligence platform — a gift from hevolve.ai', 

91 tagline='Crowdsourced intelligence, human control', 

92 product_url='https://hevolve.ai', 

93 category='platform', 

94 target_audience='Developers, businesses, and creators who want AI-powered automation', 

95 unique_value_prop='96 expert agents, autonomous recipe-based execution, ' 

96 'cross-session memory, multi-channel distribution', 

97 keywords_json=['AI', 'agents', 'automation', 'marketing', 'chatbot', 

98 'autonomous', 'multi-agent', 'LLM'], 

99 is_platform_product=True, 

100 ) 

101 db.add(product) 

102 db.flush() 

103 product_id = str(product.id) 

104 logger.info("Bootstrapped HART Platform product for self-marketing") 

105 else: 

106 product_id = str(existing.id) 

107 

108 # Bootstrap system agent for goal execution (idempotent) 

109 sys_agent = db.query(User).filter_by(username='hevolve_system_agent').first() 

110 if not sys_agent: 

111 sys_agent = User( 

112 username='hevolve_system_agent', 

113 display_name='HART System Agent', 

114 user_type='agent', 

115 idle_compute_opt_in=True, 

116 is_admin=False, 

117 ) 

118 db.add(sys_agent) 

119 db.flush() 

120 logger.info("Bootstrapped system agent for goal execution") 

121 

122 # Seed bootstrap goals (idempotent) 

123 from .goal_seeding import seed_bootstrap_goals 

124 count = seed_bootstrap_goals(db, platform_product_id=product_id) 

125 if count > 0: 

126 logger.info(f"Seeded {count} bootstrap goal(s)") 

127 

128 db.commit() 

129 db.close() 

130 except Exception as e: 

131 logger.debug(f"Platform product bootstrap skipped: {e}") 

132 

133 # Register commercial API blueprint 

134 try: 

135 from .commercial_api import commercial_api_bp 

136 app.register_blueprint(commercial_api_bp) 

137 logger.info("Commercial API endpoints registered") 

138 except Exception as e: 

139 logger.debug(f"Commercial API blueprint skipped: {e}") 

140 

141 # Register build distribution blueprint 

142 try: 

143 from .build_distribution import build_distribution_bp 

144 app.register_blueprint(build_distribution_bp) 

145 logger.info("Build distribution endpoints registered") 

146 except Exception as e: 

147 logger.debug(f"Build distribution blueprint skipped: {e}") 

148 

149 # Register regional host blueprint 

150 try: 

151 from integrations.social.api_regional_host import regional_host_bp 

152 app.register_blueprint(regional_host_bp) 

153 logger.info("Regional host endpoints registered") 

154 except Exception as e: 

155 logger.debug(f"Regional host blueprint skipped: {e}") 

156 

157 # Heavy imports (`agent_baseline_service` → `helper` from 

158 # hart_intelligence top-level; `agent_daemon` → many tools chain) run 

159 # in a deferred thread. Reason: when called from Nunba's 

160 # `_deferred_social_init`, the `hartos-init` thread is concurrently 

161 # running `from hart_intelligence import app`, which acquires the 

162 # top-level `hart_intelligence` package import lock. If this thread 

163 # tries to import `helper` (a module inside hart_intelligence) at the 

164 # same instant, CPython's per-module lock serialises and one of the 

165 # two threads blocks indefinitely (hartos-init holds the package 

166 # init in progress; we wait for the same lock to do `from helper 

167 # import PROMPTS_DIR`). Smoking gun: server.log stack at 

168 # `_find_and_load → _lock_unlock_module → acquire` from inside 

169 # `init_agent_engine` line 119. 

170 # 

171 # Solution: spawn a small worker thread that polls 

172 # `routes.hartos_backend_adapter._hartos_initialized` (set True by 

173 # the hartos-init thread when its `from hart_intelligence import app` 

174 # finishes, success OR failure), and only THEN do the heavy imports. 

175 # The Flask app + blueprints + bootstrap above have already been 

176 # registered synchronously, so the admin dashboard endpoint is live 

177 # immediately; the daemon and AgentBaselineAdapter come online a few 

178 # seconds later, exactly like the existing `_deferred_social_init` 

179 # pattern. 

180 def _finish_init_deferred(): 

181 import time as _t 

182 # Wait up to 10 minutes for hartos-init to settle. If it never 

183 # settles (Tier-1 retry budget exhausted, network down, etc.), 

184 # we still proceed because by then the import lock contention is 

185 # gone — the hartos-init thread has either succeeded or given up. 

186 _start = _t.time() 

187 _max_wait = 600 

188 while _t.time() - _start < _max_wait: 

189 try: 

190 from routes.hartos_backend_adapter import _hartos_initialized 

191 if _hartos_initialized: 

192 break 

193 except Exception: 

194 # Not running inside Nunba — no hartos-init thread to wait 

195 # for. Proceed immediately. 

196 break 

197 _t.sleep(1) 

198 

199 # Register AgentBaselineAdapter with benchmark registry 

200 try: 

201 from .benchmark_registry import get_benchmark_registry 

202 from .agent_baseline_service import AgentBaselineAdapter 

203 registry = get_benchmark_registry() 

204 registry.register_benchmark(AgentBaselineAdapter()) 

205 logger.info("AgentBaselineAdapter registered with benchmark registry") 

206 except Exception as e: 

207 logger.debug(f"AgentBaselineAdapter registration skipped: {e}") 

208 

209 # Start background daemon 

210 try: 

211 from .agent_daemon import agent_daemon 

212 agent_daemon.start() 

213 logger.info("Agent engine daemon started") 

214 except Exception as e: 

215 logger.debug(f"Agent engine daemon start skipped: {e}") 

216 

217 # Start distributed worker loop (claims tasks from shared Redis) 

218 try: 

219 from integrations.distributed_agent.worker_loop import worker_loop 

220 worker_loop.start() 

221 except Exception as e: 

222 logger.debug(f"Distributed worker loop start skipped: {e}") 

223 

224 import threading as _t_mod 

225 _t_mod.Thread(target=_finish_init_deferred, daemon=True, 

226 name='agent-engine-finish').start() 

227 logger.info("Agent engine deferred-finish thread spawned (waits for hartos-init)")