hyperagents 1.2.3rc5.post3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. agents/__init__.py +31 -0
  2. agents/background_monitor.py +453 -0
  3. agents/learning.py +460 -0
  4. agents/planner.py +421 -0
  5. agents/transcriber.py +341 -0
  6. civilization/__init__.py +51 -0
  7. civilization/api/__init__.py +7 -0
  8. civilization/api/civilization_api.py +361 -0
  9. civilization/graph/__init__.py +19 -0
  10. civilization/graph/knowledge_linker.py +348 -0
  11. civilization/graph/org_graph.py +348 -0
  12. civilization/graph/process_graph.py +386 -0
  13. civilization/ingestion/__init__.py +20 -0
  14. civilization/ingestion/chunker.py +273 -0
  15. civilization/ingestion/document_ingestor.py +358 -0
  16. civilization/ingestion/embedder.py +262 -0
  17. civilization/ingestion/extractor.py +224 -0
  18. civilization/interview/__init__.py +19 -0
  19. civilization/interview/gap_detector.py +380 -0
  20. civilization/interview/interviewer.py +323 -0
  21. civilization/interview/questioner.py +363 -0
  22. civilization/retrieval/__init__.py +17 -0
  23. civilization/retrieval/civilization_rag.py +316 -0
  24. civilization/retrieval/context_injector.py +342 -0
  25. civilization/retrieval/relevance_ranker.py +287 -0
  26. civilization/schema.py +299 -0
  27. civilization/store.py +177 -0
  28. civilization/sync/__init__.py +16 -0
  29. civilization/sync/confluence_sync.py +317 -0
  30. civilization/sync/gdrive_sync.py +262 -0
  31. civilization/sync/notion_sync.py +237 -0
  32. civilization/versioning/__init__.py +19 -0
  33. civilization/versioning/diff_engine.py +351 -0
  34. civilization/versioning/staleness_detector.py +303 -0
  35. civilization/versioning/version_manager.py +293 -0
  36. cli/__init__.py +1 -0
  37. cli/doctor.py +334 -0
  38. cli/hyperclaw.py +1357 -0
  39. cli/onboarding.py +469 -0
  40. core/__init__.py +1 -0
  41. core/connectors/__init__.py +119 -0
  42. core/connectors/infrastructure.py +772 -0
  43. core/connectors/messaging.py +586 -0
  44. core/connectors/productivity.py +764 -0
  45. core/connectors/smarthome.py +528 -0
  46. core/connectors/social.py +730 -0
  47. core/hyperrouter/__init__.py +23 -0
  48. core/hyperrouter/bandit.py +218 -0
  49. core/hyperrouter/fast_loop.py +68 -0
  50. core/hyperrouter/slow_loop.py +143 -0
  51. core/hyperstate/__init__.py +24 -0
  52. core/hyperstate/certifier.py +154 -0
  53. core/hyperstate/schema.py +160 -0
  54. core/hyperstate/state_manager.py +103 -0
  55. core/hyperstate/store.py +163 -0
  56. core/providers/__init__.py +121 -0
  57. core/providers/embeddings.py +389 -0
  58. core/providers/image.py +534 -0
  59. core/providers/llm.py +1935 -0
  60. core/providers/search.py +608 -0
  61. core/providers/voice.py +474 -0
  62. hyperagents-1.2.3rc5.post3.dist-info/METADATA +469 -0
  63. hyperagents-1.2.3rc5.post3.dist-info/RECORD +361 -0
  64. hyperagents-1.2.3rc5.post3.dist-info/WHEEL +5 -0
  65. hyperagents-1.2.3rc5.post3.dist-info/entry_points.txt +6 -0
  66. hyperagents-1.2.3rc5.post3.dist-info/licenses/LICENSE +21 -0
  67. hyperagents-1.2.3rc5.post3.dist-info/top_level.txt +13 -0
  68. hyperclaw/__init__.py +67 -0
  69. hyperclaw/__main__.py +220 -0
  70. hyperclaw/agent.py +775 -0
  71. hyperclaw/agent_coordinator.py +577 -0
  72. hyperclaw/anthropic_params.py +225 -0
  73. hyperclaw/api_utils.py +85 -0
  74. hyperclaw/approval_telegram.py +209 -0
  75. hyperclaw/approval_terminal.py +80 -0
  76. hyperclaw/attachments.py +177 -0
  77. hyperclaw/branding.py +55 -0
  78. hyperclaw/brief/__init__.py +11 -0
  79. hyperclaw/brief/cli.py +204 -0
  80. hyperclaw/brief/collect.py +146 -0
  81. hyperclaw/brief/compose.py +333 -0
  82. hyperclaw/brief/diff.py +110 -0
  83. hyperclaw/brief/errors.py +99 -0
  84. hyperclaw/brief/google.py +269 -0
  85. hyperclaw/brief/google_auth.py +294 -0
  86. hyperclaw/brief/links.py +124 -0
  87. hyperclaw/brief/service.py +424 -0
  88. hyperclaw/brief/store.py +205 -0
  89. hyperclaw/brief/tasks.py +200 -0
  90. hyperclaw/chat_scope.py +115 -0
  91. hyperclaw/cli_tui.py +497 -0
  92. hyperclaw/client_guard.py +717 -0
  93. hyperclaw/connection_check.py +113 -0
  94. hyperclaw/cost_guard.py +1728 -0
  95. hyperclaw/default_config/agents.yaml +534 -0
  96. hyperclaw/default_config/hyperclaw.yaml +27 -0
  97. hyperclaw/default_config/models.yaml +161 -0
  98. hyperclaw/deployment.py +39 -0
  99. hyperclaw/digest/__init__.py +9 -0
  100. hyperclaw/digest/cli.py +117 -0
  101. hyperclaw/digest/errors.py +100 -0
  102. hyperclaw/digest/gitlab.py +187 -0
  103. hyperclaw/digest/http.py +113 -0
  104. hyperclaw/digest/redact.py +32 -0
  105. hyperclaw/digest/service.py +271 -0
  106. hyperclaw/digest/slack.py +223 -0
  107. hyperclaw/digest/state.py +124 -0
  108. hyperclaw/digest/summarize.py +198 -0
  109. hyperclaw/digest/tokens.py +143 -0
  110. hyperclaw/distribution.py +46 -0
  111. hyperclaw/documents.py +351 -0
  112. hyperclaw/feeds.py +339 -0
  113. hyperclaw/google_workspace/__init__.py +5 -0
  114. hyperclaw/google_workspace/api.py +151 -0
  115. hyperclaw/google_workspace/auth.py +397 -0
  116. hyperclaw/google_workspace/calendar.py +157 -0
  117. hyperclaw/google_workspace/cli.py +72 -0
  118. hyperclaw/google_workspace/drive.py +236 -0
  119. hyperclaw/google_workspace/errors.py +58 -0
  120. hyperclaw/google_workspace/gmail.py +295 -0
  121. hyperclaw/google_workspace/meet.py +122 -0
  122. hyperclaw/google_workspace/tools.py +319 -0
  123. hyperclaw/hyperspeed.py +57 -0
  124. hyperclaw/integrations_layer.py +1427 -0
  125. hyperclaw/live_state.py +188 -0
  126. hyperclaw/managed_config.py +245 -0
  127. hyperclaw/media_hub.py +179 -0
  128. hyperclaw/memory_manager.py +584 -0
  129. hyperclaw/model_catalog.py +551 -0
  130. hyperclaw/model_policy.py +211 -0
  131. hyperclaw/model_router.py +595 -0
  132. hyperclaw/model_selector.py +72 -0
  133. hyperclaw/naming.py +284 -0
  134. hyperclaw/notices.py +65 -0
  135. hyperclaw/oai_stream.py +106 -0
  136. hyperclaw/orchestrator.py +591 -0
  137. hyperclaw/outbox.py +82 -0
  138. hyperclaw/persona.py +367 -0
  139. hyperclaw/prometheus.py +219 -0
  140. hyperclaw/prompt_assembly.py +157 -0
  141. hyperclaw/provider_setup.py +146 -0
  142. hyperclaw/providers.py +340 -0
  143. hyperclaw/qualification.py +341 -0
  144. hyperclaw/qualification_keys/hyper-d292fd127cef5a3e.pub +1 -0
  145. hyperclaw/qualification_records/anthropic--claude-sonnet-5-5.json +14 -0
  146. hyperclaw/reasoning_display.py +35 -0
  147. hyperclaw/scheduler.py +454 -0
  148. hyperclaw/server.py +847 -0
  149. hyperclaw/setup.py +627 -0
  150. hyperclaw/skills.py +717 -0
  151. hyperclaw/solomon.py +442 -0
  152. hyperclaw/swarm.py +533 -0
  153. hyperclaw/taint.py +832 -0
  154. hyperclaw/team/__init__.py +28 -0
  155. hyperclaw/team/dispatcher.py +431 -0
  156. hyperclaw/team/genesis.py +106 -0
  157. hyperclaw/team/lead.py +110 -0
  158. hyperclaw/team/model.py +135 -0
  159. hyperclaw/team/morning.py +238 -0
  160. hyperclaw/team/repos.py +66 -0
  161. hyperclaw/team/roster.py +264 -0
  162. hyperclaw/team/specialist.py +235 -0
  163. hyperclaw/team/status.py +163 -0
  164. hyperclaw/team/watchers.py +112 -0
  165. hyperclaw/teamsetup/__init__.py +17 -0
  166. hyperclaw/teamsetup/checks.py +208 -0
  167. hyperclaw/teamsetup/item.py +391 -0
  168. hyperclaw/teamsetup/oauth_loopback.py +84 -0
  169. hyperclaw/teamsetup/onboard.py +550 -0
  170. hyperclaw/teamsetup/profile.py +82 -0
  171. hyperclaw/teamsetup/secrets.py +313 -0
  172. hyperclaw/teamsetup/selfcheck.py +295 -0
  173. hyperclaw/teamsetup/service.py +495 -0
  174. hyperclaw/teamsetup/slack_oauth.py +442 -0
  175. hyperclaw/teamsetup/tty.py +62 -0
  176. hyperclaw/telegram_bot.py +1106 -0
  177. hyperclaw/telegram_intake.py +126 -0
  178. hyperclaw/telegram_pairing.py +360 -0
  179. hyperclaw/terminal_provider.py +323 -0
  180. hyperclaw/tools/__init__.py +1 -0
  181. hyperclaw/tools/approval.py +949 -0
  182. hyperclaw/tools/args.py +212 -0
  183. hyperclaw/tools/catalog.py +244 -0
  184. hyperclaw/tools/classify.py +266 -0
  185. hyperclaw/tools/effects.py +724 -0
  186. hyperclaw/tools/egress.py +210 -0
  187. hyperclaw/tools/envelope.py +188 -0
  188. hyperclaw/tools/guard.py +367 -0
  189. hyperclaw/tools/ledger.py +339 -0
  190. hyperclaw/tools/receipts.py +70 -0
  191. hyperclaw/tools/registry.py +318 -0
  192. hyperclaw/tools/service_guard.py +151 -0
  193. hyperclaw/tools/surfaces.py +54 -0
  194. hyperclaw/tools/workspace.py +87 -0
  195. hyperclaw/trading/__init__.py +77 -0
  196. hyperclaw/truth_guard.py +791 -0
  197. hyperclaw/tts.py +124 -0
  198. hyperclaw/tui.py +4255 -0
  199. hyperclaw/tui_bridge.py +938 -0
  200. hyperclaw/unattended.py +60 -0
  201. hyperclaw/updates/__init__.py +54 -0
  202. hyperclaw/updates/check.py +131 -0
  203. hyperclaw/updates/index.py +178 -0
  204. hyperclaw/updates/install.py +110 -0
  205. hyperclaw/updates/managed.py +161 -0
  206. hyperclaw/updates/manifest.py +138 -0
  207. hyperclaw/updates/notices.py +86 -0
  208. hyperclaw/updates/paths.py +53 -0
  209. hyperclaw/updates/release.py +146 -0
  210. hyperclaw/updates/upgrade.py +253 -0
  211. hyperclaw/updates/versioning.py +104 -0
  212. hyperclaw/userconfig.py +119 -0
  213. hyperclaw/xai.py +83 -0
  214. integrations/__init__.py +31 -0
  215. integrations/automation/__init__.py +1 -0
  216. integrations/automation/make.py +87 -0
  217. integrations/automation/zapier.py +87 -0
  218. integrations/base.py +476 -0
  219. integrations/communication/__init__.py +1 -0
  220. integrations/communication/twilio.py +279 -0
  221. integrations/communication/zoom.py +290 -0
  222. integrations/data/__init__.py +1 -0
  223. integrations/data/google_analytics.py +135 -0
  224. integrations/data/postgres.py +182 -0
  225. integrations/data/supabase_connector.py +202 -0
  226. integrations/data/weather_feeds.py +450 -0
  227. integrations/developer/__init__.py +9 -0
  228. integrations/developer/github.py +406 -0
  229. integrations/developer/gitlab.py +298 -0
  230. integrations/enterprise/__init__.py +13 -0
  231. integrations/enterprise/confluence.py +266 -0
  232. integrations/enterprise/hubspot.py +293 -0
  233. integrations/enterprise/jira.py +314 -0
  234. integrations/enterprise/salesforce.py +286 -0
  235. integrations/finance/__init__.py +1 -0
  236. integrations/finance/polymarket_client.py +247 -0
  237. integrations/finance/quickbooks.py +281 -0
  238. integrations/finance/stripe.py +261 -0
  239. integrations/gateway.py +238 -0
  240. integrations/messaging/__init__.py +32 -0
  241. integrations/messaging/discord.py +159 -0
  242. integrations/messaging/email.py +401 -0
  243. integrations/messaging/imessage.py +443 -0
  244. integrations/messaging/signal.py +175 -0
  245. integrations/messaging/slack.py +217 -0
  246. integrations/messaging/sms.py +175 -0
  247. integrations/messaging/teams.py +208 -0
  248. integrations/messaging/telegram.py +260 -0
  249. integrations/messaging/whatsapp.py +203 -0
  250. integrations/productivity/__init__.py +17 -0
  251. integrations/productivity/airtable.py +217 -0
  252. integrations/productivity/asana.py +248 -0
  253. integrations/productivity/google/__init__.py +19 -0
  254. integrations/productivity/google/base.py +89 -0
  255. integrations/productivity/google/calendar.py +272 -0
  256. integrations/productivity/google/docs.py +202 -0
  257. integrations/productivity/google/drive.py +268 -0
  258. integrations/productivity/google/gmail.py +279 -0
  259. integrations/productivity/google/meet.py +218 -0
  260. integrations/productivity/google/sheets.py +222 -0
  261. integrations/productivity/google/tasks.py +199 -0
  262. integrations/productivity/linear.py +279 -0
  263. integrations/productivity/microsoft/__init__.py +13 -0
  264. integrations/productivity/microsoft/base.py +93 -0
  265. integrations/productivity/microsoft/calendar.py +207 -0
  266. integrations/productivity/microsoft/onedrive.py +222 -0
  267. integrations/productivity/microsoft/outlook.py +241 -0
  268. integrations/productivity/microsoft/sharepoint.py +211 -0
  269. integrations/productivity/notion.py +243 -0
  270. integrations/productivity/todoist.py +250 -0
  271. integrations/productivity/trello.py +244 -0
  272. integrations/storage/__init__.py +1 -0
  273. integrations/storage/box.py +279 -0
  274. integrations/storage/dropbox.py +215 -0
  275. integrations/telegram_inbound.py +179 -0
  276. integrations/telegram_poller.py +151 -0
  277. memory/__init__.py +1 -0
  278. memory/causal_graph.py +125 -0
  279. memory/impact_tracker.py +88 -0
  280. memory/vector_memory.py +436 -0
  281. models/__init__.py +12 -0
  282. models/chatjimmy_client.py +210 -0
  283. models/claude_client.py +235 -0
  284. models/claude_code_subagent.py +192 -0
  285. models/openai_client.py +120 -0
  286. models/router.py +162 -0
  287. recursive/discovery_loop.py +118 -0
  288. recursive/optimization_loop.py +135 -0
  289. recursive/validation_loop.py +38 -0
  290. security/__init__.py +1 -0
  291. security/audit_logger.py +106 -0
  292. security/filesystem_guard.py +100 -0
  293. security/hypershield.py +99 -0
  294. security/network_guard.py +97 -0
  295. security/policy_engine.py +198 -0
  296. swarm/__init__.py +1 -0
  297. swarm/agents/__init__.py +0 -0
  298. swarm/agents/base.py +230 -0
  299. swarm/agents/business/__init__.py +0 -0
  300. swarm/agents/business/counsel.py +31 -0
  301. swarm/agents/business/herald.py +32 -0
  302. swarm/agents/business/ledger.py +26 -0
  303. swarm/agents/business/nexus.py +30 -0
  304. swarm/agents/business/ops.py +30 -0
  305. swarm/agents/business/pipeline.py +28 -0
  306. swarm/agents/business/revenue.py +30 -0
  307. swarm/agents/business/sovereign.py +31 -0
  308. swarm/agents/business/strategos.py +27 -0
  309. swarm/agents/business/talent.py +27 -0
  310. swarm/agents/business/venture.py +32 -0
  311. swarm/agents/comms/__init__.py +1 -0
  312. swarm/agents/comms/cipher.py +32 -0
  313. swarm/agents/comms/echo_comms.py +31 -0
  314. swarm/agents/comms/envoy.py +31 -0
  315. swarm/agents/comms/herald_scheduler.py +33 -0
  316. swarm/agents/comms/pulse.py +29 -0
  317. swarm/agents/creative/__init__.py +0 -0
  318. swarm/agents/creative/author.py +27 -0
  319. swarm/agents/creative/lens.py +25 -0
  320. swarm/agents/executive/__init__.py +1 -0
  321. swarm/agents/intelligence/__init__.py +1 -0
  322. swarm/agents/intelligence/arbiter.py +30 -0
  323. swarm/agents/intelligence/sentinel.py +30 -0
  324. swarm/agents/media/__init__.py +0 -0
  325. swarm/agents/personal/__init__.py +0 -0
  326. swarm/agents/personal/atlas.py +27 -0
  327. swarm/agents/personal/hearth.py +26 -0
  328. swarm/agents/personal/midas.py +27 -0
  329. swarm/agents/personal/navigator.py +27 -0
  330. swarm/agents/personal/nourish.py +31 -0
  331. swarm/agents/personal/vitals.py +33 -0
  332. swarm/agents/recursive/__init__.py +0 -0
  333. swarm/agents/recursive/alchemist.py +73 -0
  334. swarm/agents/recursive/calibrator.py +45 -0
  335. swarm/agents/recursive/scout.py +97 -0
  336. swarm/agents/scientific/__init__.py +0 -0
  337. swarm/agents/scientific/cosmos.py +36 -0
  338. swarm/agents/scientific/gaia.py +26 -0
  339. swarm/agents/scientific/medicus.py +33 -0
  340. swarm/agents/scientific/oracle_agent.py +39 -0
  341. swarm/agents/scientific/scribe.py +39 -0
  342. swarm/agents/talent/__init__.py +0 -0
  343. swarm/agents/talent/deal.py +28 -0
  344. swarm/agents/talent/roster.py +29 -0
  345. swarm/agents/talent/scout.py +29 -0
  346. swarm/agents/talent/stage.py +27 -0
  347. swarm/agents/tech/__init__.py +0 -0
  348. swarm/agents/tech/aegis.py +28 -0
  349. swarm/agents/tech/bridge.py +28 -0
  350. swarm/agents/tech/forge.py +28 -0
  351. swarm/agents/trading/__init__.py +1 -0
  352. swarm/agents/trading/global_prediction_engine.py +611 -0
  353. swarm/agents/trading/polymarket_trader.py +165 -0
  354. swarm/agents/trading/prediction_strategist.py +218 -0
  355. swarm/autogen_bridge.py +68 -0
  356. swarm/bid_protocol.py +196 -0
  357. swarm/dispatcher.py +527 -0
  358. swarm/nexus.py +181 -0
  359. swarm/registry.py +112 -0
  360. telegram_listener.py +403 -0
  361. ui/tui/app.py +214 -0
@@ -0,0 +1,450 @@
1
+ """Weather & Agricultural Data Feeds — Global data integration for prediction markets."""
2
+ from __future__ import annotations
3
+ import asyncio
4
+ import httpx
5
+ import logging
6
+ from typing import Dict, List, Optional, Any
7
+ from datetime import datetime, timedelta
8
+ import json
9
+
10
+ logger = logging.getLogger("weather_feeds")
11
+
12
+
13
+ class WeatherIntelligence:
14
+ """Global weather and agricultural data aggregation for prediction advantage."""
15
+
16
+ def __init__(self):
17
+ self.session = None
18
+
19
+ # Multiple weather API endpoints for redundancy
20
+ self.apis = {
21
+ "openweather": {
22
+ "url": "https://api.openweathermap.org/data/2.5",
23
+ "key": None # Will need API key
24
+ },
25
+ "weatherapi": {
26
+ "url": "https://api.weatherapi.com/v1",
27
+ "key": None # Alternative source
28
+ },
29
+ "noaa": {
30
+ "url": "https://api.weather.gov", # US government, free
31
+ "key": None
32
+ }
33
+ }
34
+
35
+ # Critical agricultural regions for crop predictions
36
+ self.crop_regions = {
37
+ "corn_belt": {
38
+ "name": "US Corn Belt",
39
+ "coords": [(41.8781, -87.6298), (40.7589, -89.6465), (42.0308, -93.6319)],
40
+ "primary_crops": ["corn", "soybeans"],
41
+ "markets": ["corn prices", "soybean futures", "food inflation"]
42
+ },
43
+ "wheat_belt": {
44
+ "name": "Great Plains Wheat",
45
+ "coords": [(39.7392, -104.9903), (37.6872, -97.3301), (46.8083, -100.7837)],
46
+ "primary_crops": ["wheat", "barley"],
47
+ "markets": ["wheat prices", "grain exports", "food security"]
48
+ },
49
+ "ukraine_farming": {
50
+ "name": "Ukrainian Agricultural Region",
51
+ "coords": [(50.4501, 30.5234), (48.3794, 31.1656), (49.9935, 36.2304)],
52
+ "primary_crops": ["wheat", "corn", "sunflower"],
53
+ "markets": ["global grain supply", "food crisis", "ukraine conflict impact"]
54
+ },
55
+ "brazil_soy": {
56
+ "name": "Brazilian Soy Belt",
57
+ "coords": [(-15.7975, -47.8919), (-16.6869, -49.2648), (-14.2350, -51.9253)],
58
+ "primary_crops": ["soybeans", "corn", "cotton"],
59
+ "markets": ["soy exports", "deforestation", "brazil politics"]
60
+ }
61
+ }
62
+
63
+ async def __aenter__(self):
64
+ self.session = httpx.AsyncClient(timeout=30.0)
65
+ return self
66
+
67
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
68
+ if self.session:
69
+ await self.session.aclose()
70
+
71
+ async def get_regional_weather_analysis(self, region: str) -> Dict:
72
+ """Analyze weather conditions for agricultural regions."""
73
+ if region not in self.crop_regions:
74
+ return {"error": f"Unknown region: {region}"}
75
+
76
+ region_data = self.crop_regions[region]
77
+ weather_summary = []
78
+
79
+ try:
80
+ # Sample multiple coordinates within region
81
+ for coord in region_data["coords"][:3]: # Limit to avoid rate limits
82
+ lat, lon = coord
83
+ weather = await self._get_location_weather(lat, lon)
84
+ if weather:
85
+ weather_summary.append(weather)
86
+
87
+ if not weather_summary:
88
+ return {"error": "No weather data available"}
89
+
90
+ # Aggregate regional conditions
91
+ analysis = self._analyze_agricultural_impact(weather_summary, region_data)
92
+
93
+ return {
94
+ "region": region_data["name"],
95
+ "primary_crops": region_data["primary_crops"],
96
+ "affected_markets": region_data["markets"],
97
+ "weather_analysis": analysis,
98
+ "prediction_signals": self._generate_prediction_signals(analysis, region_data),
99
+ "timestamp": datetime.utcnow().isoformat()
100
+ }
101
+
102
+ except Exception as e:
103
+ logger.error(f"Error analyzing region {region}: {e}")
104
+ return {"error": str(e)}
105
+
106
+ async def _get_location_weather(self, lat: float, lon: float) -> Optional[Dict]:
107
+ """Fetch weather data for specific coordinates."""
108
+ try:
109
+ # Using NOAA (free, US government data)
110
+ if -90 <= lat <= 90 and -180 <= lon <= 180:
111
+ # For US locations, use NOAA
112
+ if 25 <= lat <= 49 and -125 <= lon <= -66:
113
+ return await self._fetch_noaa_weather(lat, lon)
114
+
115
+ # Fallback: simulate weather data for demo
116
+ return self._generate_sample_weather(lat, lon)
117
+
118
+ except Exception as e:
119
+ logger.error(f"Error fetching weather for {lat}, {lon}: {e}")
120
+ return None
121
+
122
+ async def _fetch_noaa_weather(self, lat: float, lon: float) -> Optional[Dict]:
123
+ """Fetch from NOAA API (US locations)."""
124
+ try:
125
+ # Get grid point
126
+ response = await self.session.get(
127
+ f"{self.apis['noaa']['url']}/points/{lat},{lon}"
128
+ )
129
+ response.raise_for_status()
130
+
131
+ data = response.json()
132
+ forecast_url = data["properties"]["forecast"]
133
+
134
+ # Get forecast
135
+ forecast_response = await self.session.get(forecast_url)
136
+ forecast_response.raise_for_status()
137
+
138
+ forecast_data = forecast_response.json()
139
+ periods = forecast_data["properties"]["periods"][:7] # 7 days
140
+
141
+ return {
142
+ "source": "NOAA",
143
+ "lat": lat,
144
+ "lon": lon,
145
+ "forecast": periods,
146
+ "alerts": data.get("properties", {}).get("alerts", [])
147
+ }
148
+
149
+ except Exception as e:
150
+ logger.error(f"NOAA fetch error: {e}")
151
+ return self._generate_sample_weather(lat, lon)
152
+
153
+ def _generate_sample_weather(self, lat: float, lon: float) -> Dict:
154
+ """Generate representative weather data for analysis."""
155
+ import random
156
+
157
+ # Seasonal adjustment based on month
158
+ month = datetime.now().month
159
+
160
+ if 3 <= month <= 5: # Spring
161
+ temp_base = 15
162
+ precip_chance = 0.4
163
+ elif 6 <= month <= 8: # Summer
164
+ temp_base = 25
165
+ precip_chance = 0.3
166
+ elif 9 <= month <= 11: # Fall
167
+ temp_base = 12
168
+ precip_chance = 0.5
169
+ else: # Winter
170
+ temp_base = 5
171
+ precip_chance = 0.4
172
+
173
+ return {
174
+ "source": "simulated",
175
+ "lat": lat,
176
+ "lon": lon,
177
+ "current": {
178
+ "temperature": temp_base + random.uniform(-5, 10),
179
+ "humidity": random.uniform(40, 80),
180
+ "precipitation_mm": random.uniform(0, 20) if random.random() < precip_chance else 0,
181
+ "wind_speed": random.uniform(5, 25),
182
+ "pressure": random.uniform(1000, 1020)
183
+ },
184
+ "forecast_7day": {
185
+ "avg_temp": temp_base + random.uniform(-3, 8),
186
+ "total_precipitation": random.uniform(0, 50),
187
+ "extreme_weather_risk": random.choice(["low", "medium", "high"]),
188
+ "growing_conditions": random.choice(["poor", "fair", "good", "excellent"])
189
+ }
190
+ }
191
+
192
+ def _analyze_agricultural_impact(self, weather_data: List[Dict], region_info: Dict) -> Dict:
193
+ """Analyze weather impact on agricultural production."""
194
+ if not weather_data:
195
+ return {}
196
+
197
+ # Aggregate weather metrics
198
+ temperatures = []
199
+ precipitation = []
200
+ extreme_risks = []
201
+
202
+ for location in weather_data:
203
+ if "current" in location:
204
+ temperatures.append(location["current"]["temperature"])
205
+ precipitation.append(location["current"]["precipitation_mm"])
206
+
207
+ if "forecast_7day" in location:
208
+ extreme_risks.append(location["forecast_7day"]["extreme_weather_risk"])
209
+
210
+ avg_temp = sum(temperatures) / len(temperatures) if temperatures else 15
211
+ total_precip = sum(precipitation) if precipitation else 0
212
+
213
+ # Assess agricultural conditions
214
+ analysis = {
215
+ "temperature_analysis": {
216
+ "average": avg_temp,
217
+ "status": self._assess_temperature_impact(avg_temp, region_info["primary_crops"])
218
+ },
219
+ "precipitation_analysis": {
220
+ "total_mm": total_precip,
221
+ "status": self._assess_precipitation_impact(total_precip, region_info["primary_crops"])
222
+ },
223
+ "overall_conditions": self._calculate_overall_conditions(avg_temp, total_precip),
224
+ "crop_stress_indicators": self._identify_stress_factors(avg_temp, total_precip, extreme_risks),
225
+ "market_impact_probability": self._estimate_market_impact(avg_temp, total_precip, extreme_risks)
226
+ }
227
+
228
+ return analysis
229
+
230
+ def _assess_temperature_impact(self, temp: float, crops: List[str]) -> str:
231
+ """Assess temperature impact on specific crops."""
232
+ # Corn optimal: 20-30°C, Soybeans: 20-25°C, Wheat: 15-25°C
233
+ optimal_ranges = {
234
+ "corn": (20, 30),
235
+ "soybeans": (20, 25),
236
+ "wheat": (15, 25),
237
+ "cotton": (21, 27),
238
+ "barley": (15, 20)
239
+ }
240
+
241
+ impacts = []
242
+ for crop in crops:
243
+ if crop in optimal_ranges:
244
+ min_temp, max_temp = optimal_ranges[crop]
245
+ if min_temp <= temp <= max_temp:
246
+ impacts.append("optimal")
247
+ elif temp < min_temp - 5 or temp > max_temp + 5:
248
+ impacts.append("stress")
249
+ else:
250
+ impacts.append("suboptimal")
251
+ else:
252
+ impacts.append("unknown")
253
+
254
+ if "stress" in impacts:
255
+ return "stress_conditions"
256
+ elif "optimal" in impacts:
257
+ return "favorable_conditions"
258
+ else:
259
+ return "neutral_conditions"
260
+
261
+ def _assess_precipitation_impact(self, precip: float, crops: List[str]) -> str:
262
+ """Assess precipitation impact on crops."""
263
+ if precip < 5:
264
+ return "drought_risk"
265
+ elif precip > 40:
266
+ return "flood_risk"
267
+ elif 15 <= precip <= 25:
268
+ return "optimal_moisture"
269
+ else:
270
+ return "adequate_moisture"
271
+
272
+ def _calculate_overall_conditions(self, temp: float, precip: float) -> str:
273
+ """Calculate overall agricultural conditions score."""
274
+ temp_score = 5 # Neutral baseline
275
+ precip_score = 5
276
+
277
+ # Temperature scoring (5 = optimal)
278
+ if 18 <= temp <= 27:
279
+ temp_score = 5
280
+ elif 15 <= temp < 18 or 27 < temp <= 32:
281
+ temp_score = 4
282
+ elif temp < 10 or temp > 35:
283
+ temp_score = 1
284
+ else:
285
+ temp_score = 3
286
+
287
+ # Precipitation scoring
288
+ if 15 <= precip <= 25:
289
+ precip_score = 5
290
+ elif 10 <= precip < 15 or 25 < precip <= 35:
291
+ precip_score = 4
292
+ elif precip < 5 or precip > 50:
293
+ precip_score = 1
294
+ else:
295
+ precip_score = 3
296
+
297
+ overall = (temp_score + precip_score) / 2
298
+
299
+ if overall >= 4.5:
300
+ return "excellent"
301
+ elif overall >= 3.5:
302
+ return "good"
303
+ elif overall >= 2.5:
304
+ return "fair"
305
+ else:
306
+ return "poor"
307
+
308
+ def _identify_stress_factors(self, temp: float, precip: float, extreme_risks: List[str]) -> List[str]:
309
+ """Identify stress factors affecting crop production."""
310
+ stress_factors = []
311
+
312
+ if temp > 32:
313
+ stress_factors.append("heat_stress")
314
+ if temp < 10:
315
+ stress_factors.append("cold_stress")
316
+ if precip < 5:
317
+ stress_factors.append("drought_stress")
318
+ if precip > 40:
319
+ stress_factors.append("waterlog_stress")
320
+ if "high" in extreme_risks:
321
+ stress_factors.append("extreme_weather_risk")
322
+
323
+ return stress_factors
324
+
325
+ def _estimate_market_impact(self, temp: float, precip: float, extreme_risks: List[str]) -> float:
326
+ """Estimate probability of significant market impact (0-1)."""
327
+ impact_score = 0.0
328
+
329
+ # Temperature extremes
330
+ if temp > 35 or temp < 5:
331
+ impact_score += 0.3
332
+ elif temp > 30 or temp < 10:
333
+ impact_score += 0.1
334
+
335
+ # Precipitation extremes
336
+ if precip > 50 or precip < 2:
337
+ impact_score += 0.3
338
+ elif precip > 35 or precip < 8:
339
+ impact_score += 0.1
340
+
341
+ # Extreme weather
342
+ high_risk_count = extreme_risks.count("high")
343
+ impact_score += high_risk_count * 0.2
344
+
345
+ return min(impact_score, 1.0) # Cap at 100%
346
+
347
+ def _generate_prediction_signals(self, analysis: Dict, region_info: Dict) -> List[Dict]:
348
+ """Generate specific prediction market signals from weather analysis."""
349
+ signals = []
350
+
351
+ overall_conditions = analysis.get("overall_conditions", "fair")
352
+ market_impact_prob = analysis.get("market_impact_probability", 0.0)
353
+ stress_factors = analysis.get("crop_stress_indicators", [])
354
+
355
+ # Generate signals for each affected market
356
+ for market in region_info.get("affected_markets", []):
357
+ signal_strength = self._calculate_signal_strength(
358
+ overall_conditions, market_impact_prob, stress_factors, market
359
+ )
360
+
361
+ direction = self._determine_market_direction(
362
+ overall_conditions, stress_factors, market
363
+ )
364
+
365
+ if signal_strength > 0.3: # Only significant signals
366
+ signals.append({
367
+ "market_category": market,
368
+ "signal_strength": signal_strength,
369
+ "direction": direction,
370
+ "confidence": min(signal_strength * 0.8, 0.95),
371
+ "reasoning": self._explain_signal_reasoning(
372
+ overall_conditions, stress_factors, market, direction
373
+ )
374
+ })
375
+
376
+ return signals
377
+
378
+ def _calculate_signal_strength(self, conditions: str, impact_prob: float,
379
+ stress_factors: List[str], market: str) -> float:
380
+ """Calculate signal strength for specific market."""
381
+ base_strength = {
382
+ "excellent": 0.2,
383
+ "good": 0.1,
384
+ "fair": 0.05,
385
+ "poor": 0.4
386
+ }.get(conditions, 0.05)
387
+
388
+ # Boost for high impact probability
389
+ impact_boost = impact_prob * 0.3
390
+
391
+ # Boost for stress factors
392
+ stress_boost = len(stress_factors) * 0.1
393
+
394
+ return min(base_strength + impact_boost + stress_boost, 1.0)
395
+
396
+ def _determine_market_direction(self, conditions: str, stress_factors: List[str],
397
+ market: str) -> str:
398
+ """Determine expected market direction."""
399
+ if any(stress in stress_factors for stress in ["drought_stress", "heat_stress", "extreme_weather_risk"]):
400
+ if "price" in market.lower() or "inflation" in market.lower():
401
+ return "bullish" # Stress → higher prices
402
+ elif "supply" in market.lower():
403
+ return "bearish" # Stress → lower supply
404
+
405
+ if conditions in ["excellent", "good"]:
406
+ if "price" in market.lower():
407
+ return "bearish" # Good conditions → lower prices
408
+ elif "supply" in market.lower():
409
+ return "bullish" # Good conditions → higher supply
410
+
411
+ return "neutral"
412
+
413
+ def _explain_signal_reasoning(self, conditions: str, stress_factors: List[str],
414
+ market: str, direction: str) -> str:
415
+ """Generate human-readable reasoning for signal."""
416
+ if direction == "bullish" and "price" in market.lower():
417
+ return f"Weather stress factors {stress_factors} likely to reduce crop yields, driving prices higher"
418
+ elif direction == "bearish" and "price" in market.lower():
419
+ return f"Favorable conditions ({conditions}) suggest good yields, likely suppressing prices"
420
+ elif direction == "bullish" and "supply" in market.lower():
421
+ return f"Good weather conditions ({conditions}) support strong crop production"
422
+ elif direction == "bearish" and "supply" in market.lower():
423
+ return f"Weather stress {stress_factors} threatens crop production levels"
424
+ else:
425
+ return f"Weather analysis ({conditions}) provides moderate signal for {market}"
426
+
427
+
428
+ async def test_weather_intelligence():
429
+ """Test weather data integration."""
430
+ async with WeatherIntelligence() as weather:
431
+ # Test corn belt analysis
432
+ analysis = await weather.get_regional_weather_analysis("corn_belt")
433
+
434
+ print("=== CORN BELT WEATHER ANALYSIS ===")
435
+ print(f"Region: {analysis.get('region')}")
436
+ print(f"Crops: {analysis.get('primary_crops')}")
437
+ print(f"Overall Conditions: {analysis.get('weather_analysis', {}).get('overall_conditions')}")
438
+
439
+ signals = analysis.get('prediction_signals', [])
440
+ print(f"\n=== PREDICTION SIGNALS ({len(signals)} found) ===")
441
+
442
+ for signal in signals:
443
+ print(f"\nMarket: {signal['market_category']}")
444
+ print(f"Direction: {signal['direction']}")
445
+ print(f"Strength: {signal['signal_strength']:.2f}")
446
+ print(f"Reasoning: {signal['reasoning']}")
447
+
448
+
449
+ if __name__ == "__main__":
450
+ asyncio.run(test_weather_intelligence())
@@ -0,0 +1,9 @@
1
+ """HyperClaw Developer Connectors."""
2
+
3
+ from integrations.developer.github import GitHubConnector
4
+ from integrations.developer.gitlab import GitLabConnector
5
+
6
+ __all__ = [
7
+ "GitHubConnector",
8
+ "GitLabConnector",
9
+ ]