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.
- agents/__init__.py +31 -0
- agents/background_monitor.py +453 -0
- agents/learning.py +460 -0
- agents/planner.py +421 -0
- agents/transcriber.py +341 -0
- civilization/__init__.py +51 -0
- civilization/api/__init__.py +7 -0
- civilization/api/civilization_api.py +361 -0
- civilization/graph/__init__.py +19 -0
- civilization/graph/knowledge_linker.py +348 -0
- civilization/graph/org_graph.py +348 -0
- civilization/graph/process_graph.py +386 -0
- civilization/ingestion/__init__.py +20 -0
- civilization/ingestion/chunker.py +273 -0
- civilization/ingestion/document_ingestor.py +358 -0
- civilization/ingestion/embedder.py +262 -0
- civilization/ingestion/extractor.py +224 -0
- civilization/interview/__init__.py +19 -0
- civilization/interview/gap_detector.py +380 -0
- civilization/interview/interviewer.py +323 -0
- civilization/interview/questioner.py +363 -0
- civilization/retrieval/__init__.py +17 -0
- civilization/retrieval/civilization_rag.py +316 -0
- civilization/retrieval/context_injector.py +342 -0
- civilization/retrieval/relevance_ranker.py +287 -0
- civilization/schema.py +299 -0
- civilization/store.py +177 -0
- civilization/sync/__init__.py +16 -0
- civilization/sync/confluence_sync.py +317 -0
- civilization/sync/gdrive_sync.py +262 -0
- civilization/sync/notion_sync.py +237 -0
- civilization/versioning/__init__.py +19 -0
- civilization/versioning/diff_engine.py +351 -0
- civilization/versioning/staleness_detector.py +303 -0
- civilization/versioning/version_manager.py +293 -0
- cli/__init__.py +1 -0
- cli/doctor.py +334 -0
- cli/hyperclaw.py +1357 -0
- cli/onboarding.py +469 -0
- core/__init__.py +1 -0
- core/connectors/__init__.py +119 -0
- core/connectors/infrastructure.py +772 -0
- core/connectors/messaging.py +586 -0
- core/connectors/productivity.py +764 -0
- core/connectors/smarthome.py +528 -0
- core/connectors/social.py +730 -0
- core/hyperrouter/__init__.py +23 -0
- core/hyperrouter/bandit.py +218 -0
- core/hyperrouter/fast_loop.py +68 -0
- core/hyperrouter/slow_loop.py +143 -0
- core/hyperstate/__init__.py +24 -0
- core/hyperstate/certifier.py +154 -0
- core/hyperstate/schema.py +160 -0
- core/hyperstate/state_manager.py +103 -0
- core/hyperstate/store.py +163 -0
- core/providers/__init__.py +121 -0
- core/providers/embeddings.py +389 -0
- core/providers/image.py +534 -0
- core/providers/llm.py +1935 -0
- core/providers/search.py +608 -0
- core/providers/voice.py +474 -0
- hyperagents-1.2.3rc5.post3.dist-info/METADATA +469 -0
- hyperagents-1.2.3rc5.post3.dist-info/RECORD +361 -0
- hyperagents-1.2.3rc5.post3.dist-info/WHEEL +5 -0
- hyperagents-1.2.3rc5.post3.dist-info/entry_points.txt +6 -0
- hyperagents-1.2.3rc5.post3.dist-info/licenses/LICENSE +21 -0
- hyperagents-1.2.3rc5.post3.dist-info/top_level.txt +13 -0
- hyperclaw/__init__.py +67 -0
- hyperclaw/__main__.py +220 -0
- hyperclaw/agent.py +775 -0
- hyperclaw/agent_coordinator.py +577 -0
- hyperclaw/anthropic_params.py +225 -0
- hyperclaw/api_utils.py +85 -0
- hyperclaw/approval_telegram.py +209 -0
- hyperclaw/approval_terminal.py +80 -0
- hyperclaw/attachments.py +177 -0
- hyperclaw/branding.py +55 -0
- hyperclaw/brief/__init__.py +11 -0
- hyperclaw/brief/cli.py +204 -0
- hyperclaw/brief/collect.py +146 -0
- hyperclaw/brief/compose.py +333 -0
- hyperclaw/brief/diff.py +110 -0
- hyperclaw/brief/errors.py +99 -0
- hyperclaw/brief/google.py +269 -0
- hyperclaw/brief/google_auth.py +294 -0
- hyperclaw/brief/links.py +124 -0
- hyperclaw/brief/service.py +424 -0
- hyperclaw/brief/store.py +205 -0
- hyperclaw/brief/tasks.py +200 -0
- hyperclaw/chat_scope.py +115 -0
- hyperclaw/cli_tui.py +497 -0
- hyperclaw/client_guard.py +717 -0
- hyperclaw/connection_check.py +113 -0
- hyperclaw/cost_guard.py +1728 -0
- hyperclaw/default_config/agents.yaml +534 -0
- hyperclaw/default_config/hyperclaw.yaml +27 -0
- hyperclaw/default_config/models.yaml +161 -0
- hyperclaw/deployment.py +39 -0
- hyperclaw/digest/__init__.py +9 -0
- hyperclaw/digest/cli.py +117 -0
- hyperclaw/digest/errors.py +100 -0
- hyperclaw/digest/gitlab.py +187 -0
- hyperclaw/digest/http.py +113 -0
- hyperclaw/digest/redact.py +32 -0
- hyperclaw/digest/service.py +271 -0
- hyperclaw/digest/slack.py +223 -0
- hyperclaw/digest/state.py +124 -0
- hyperclaw/digest/summarize.py +198 -0
- hyperclaw/digest/tokens.py +143 -0
- hyperclaw/distribution.py +46 -0
- hyperclaw/documents.py +351 -0
- hyperclaw/feeds.py +339 -0
- hyperclaw/google_workspace/__init__.py +5 -0
- hyperclaw/google_workspace/api.py +151 -0
- hyperclaw/google_workspace/auth.py +397 -0
- hyperclaw/google_workspace/calendar.py +157 -0
- hyperclaw/google_workspace/cli.py +72 -0
- hyperclaw/google_workspace/drive.py +236 -0
- hyperclaw/google_workspace/errors.py +58 -0
- hyperclaw/google_workspace/gmail.py +295 -0
- hyperclaw/google_workspace/meet.py +122 -0
- hyperclaw/google_workspace/tools.py +319 -0
- hyperclaw/hyperspeed.py +57 -0
- hyperclaw/integrations_layer.py +1427 -0
- hyperclaw/live_state.py +188 -0
- hyperclaw/managed_config.py +245 -0
- hyperclaw/media_hub.py +179 -0
- hyperclaw/memory_manager.py +584 -0
- hyperclaw/model_catalog.py +551 -0
- hyperclaw/model_policy.py +211 -0
- hyperclaw/model_router.py +595 -0
- hyperclaw/model_selector.py +72 -0
- hyperclaw/naming.py +284 -0
- hyperclaw/notices.py +65 -0
- hyperclaw/oai_stream.py +106 -0
- hyperclaw/orchestrator.py +591 -0
- hyperclaw/outbox.py +82 -0
- hyperclaw/persona.py +367 -0
- hyperclaw/prometheus.py +219 -0
- hyperclaw/prompt_assembly.py +157 -0
- hyperclaw/provider_setup.py +146 -0
- hyperclaw/providers.py +340 -0
- hyperclaw/qualification.py +341 -0
- hyperclaw/qualification_keys/hyper-d292fd127cef5a3e.pub +1 -0
- hyperclaw/qualification_records/anthropic--claude-sonnet-5-5.json +14 -0
- hyperclaw/reasoning_display.py +35 -0
- hyperclaw/scheduler.py +454 -0
- hyperclaw/server.py +847 -0
- hyperclaw/setup.py +627 -0
- hyperclaw/skills.py +717 -0
- hyperclaw/solomon.py +442 -0
- hyperclaw/swarm.py +533 -0
- hyperclaw/taint.py +832 -0
- hyperclaw/team/__init__.py +28 -0
- hyperclaw/team/dispatcher.py +431 -0
- hyperclaw/team/genesis.py +106 -0
- hyperclaw/team/lead.py +110 -0
- hyperclaw/team/model.py +135 -0
- hyperclaw/team/morning.py +238 -0
- hyperclaw/team/repos.py +66 -0
- hyperclaw/team/roster.py +264 -0
- hyperclaw/team/specialist.py +235 -0
- hyperclaw/team/status.py +163 -0
- hyperclaw/team/watchers.py +112 -0
- hyperclaw/teamsetup/__init__.py +17 -0
- hyperclaw/teamsetup/checks.py +208 -0
- hyperclaw/teamsetup/item.py +391 -0
- hyperclaw/teamsetup/oauth_loopback.py +84 -0
- hyperclaw/teamsetup/onboard.py +550 -0
- hyperclaw/teamsetup/profile.py +82 -0
- hyperclaw/teamsetup/secrets.py +313 -0
- hyperclaw/teamsetup/selfcheck.py +295 -0
- hyperclaw/teamsetup/service.py +495 -0
- hyperclaw/teamsetup/slack_oauth.py +442 -0
- hyperclaw/teamsetup/tty.py +62 -0
- hyperclaw/telegram_bot.py +1106 -0
- hyperclaw/telegram_intake.py +126 -0
- hyperclaw/telegram_pairing.py +360 -0
- hyperclaw/terminal_provider.py +323 -0
- hyperclaw/tools/__init__.py +1 -0
- hyperclaw/tools/approval.py +949 -0
- hyperclaw/tools/args.py +212 -0
- hyperclaw/tools/catalog.py +244 -0
- hyperclaw/tools/classify.py +266 -0
- hyperclaw/tools/effects.py +724 -0
- hyperclaw/tools/egress.py +210 -0
- hyperclaw/tools/envelope.py +188 -0
- hyperclaw/tools/guard.py +367 -0
- hyperclaw/tools/ledger.py +339 -0
- hyperclaw/tools/receipts.py +70 -0
- hyperclaw/tools/registry.py +318 -0
- hyperclaw/tools/service_guard.py +151 -0
- hyperclaw/tools/surfaces.py +54 -0
- hyperclaw/tools/workspace.py +87 -0
- hyperclaw/trading/__init__.py +77 -0
- hyperclaw/truth_guard.py +791 -0
- hyperclaw/tts.py +124 -0
- hyperclaw/tui.py +4255 -0
- hyperclaw/tui_bridge.py +938 -0
- hyperclaw/unattended.py +60 -0
- hyperclaw/updates/__init__.py +54 -0
- hyperclaw/updates/check.py +131 -0
- hyperclaw/updates/index.py +178 -0
- hyperclaw/updates/install.py +110 -0
- hyperclaw/updates/managed.py +161 -0
- hyperclaw/updates/manifest.py +138 -0
- hyperclaw/updates/notices.py +86 -0
- hyperclaw/updates/paths.py +53 -0
- hyperclaw/updates/release.py +146 -0
- hyperclaw/updates/upgrade.py +253 -0
- hyperclaw/updates/versioning.py +104 -0
- hyperclaw/userconfig.py +119 -0
- hyperclaw/xai.py +83 -0
- integrations/__init__.py +31 -0
- integrations/automation/__init__.py +1 -0
- integrations/automation/make.py +87 -0
- integrations/automation/zapier.py +87 -0
- integrations/base.py +476 -0
- integrations/communication/__init__.py +1 -0
- integrations/communication/twilio.py +279 -0
- integrations/communication/zoom.py +290 -0
- integrations/data/__init__.py +1 -0
- integrations/data/google_analytics.py +135 -0
- integrations/data/postgres.py +182 -0
- integrations/data/supabase_connector.py +202 -0
- integrations/data/weather_feeds.py +450 -0
- integrations/developer/__init__.py +9 -0
- integrations/developer/github.py +406 -0
- integrations/developer/gitlab.py +298 -0
- integrations/enterprise/__init__.py +13 -0
- integrations/enterprise/confluence.py +266 -0
- integrations/enterprise/hubspot.py +293 -0
- integrations/enterprise/jira.py +314 -0
- integrations/enterprise/salesforce.py +286 -0
- integrations/finance/__init__.py +1 -0
- integrations/finance/polymarket_client.py +247 -0
- integrations/finance/quickbooks.py +281 -0
- integrations/finance/stripe.py +261 -0
- integrations/gateway.py +238 -0
- integrations/messaging/__init__.py +32 -0
- integrations/messaging/discord.py +159 -0
- integrations/messaging/email.py +401 -0
- integrations/messaging/imessage.py +443 -0
- integrations/messaging/signal.py +175 -0
- integrations/messaging/slack.py +217 -0
- integrations/messaging/sms.py +175 -0
- integrations/messaging/teams.py +208 -0
- integrations/messaging/telegram.py +260 -0
- integrations/messaging/whatsapp.py +203 -0
- integrations/productivity/__init__.py +17 -0
- integrations/productivity/airtable.py +217 -0
- integrations/productivity/asana.py +248 -0
- integrations/productivity/google/__init__.py +19 -0
- integrations/productivity/google/base.py +89 -0
- integrations/productivity/google/calendar.py +272 -0
- integrations/productivity/google/docs.py +202 -0
- integrations/productivity/google/drive.py +268 -0
- integrations/productivity/google/gmail.py +279 -0
- integrations/productivity/google/meet.py +218 -0
- integrations/productivity/google/sheets.py +222 -0
- integrations/productivity/google/tasks.py +199 -0
- integrations/productivity/linear.py +279 -0
- integrations/productivity/microsoft/__init__.py +13 -0
- integrations/productivity/microsoft/base.py +93 -0
- integrations/productivity/microsoft/calendar.py +207 -0
- integrations/productivity/microsoft/onedrive.py +222 -0
- integrations/productivity/microsoft/outlook.py +241 -0
- integrations/productivity/microsoft/sharepoint.py +211 -0
- integrations/productivity/notion.py +243 -0
- integrations/productivity/todoist.py +250 -0
- integrations/productivity/trello.py +244 -0
- integrations/storage/__init__.py +1 -0
- integrations/storage/box.py +279 -0
- integrations/storage/dropbox.py +215 -0
- integrations/telegram_inbound.py +179 -0
- integrations/telegram_poller.py +151 -0
- memory/__init__.py +1 -0
- memory/causal_graph.py +125 -0
- memory/impact_tracker.py +88 -0
- memory/vector_memory.py +436 -0
- models/__init__.py +12 -0
- models/chatjimmy_client.py +210 -0
- models/claude_client.py +235 -0
- models/claude_code_subagent.py +192 -0
- models/openai_client.py +120 -0
- models/router.py +162 -0
- recursive/discovery_loop.py +118 -0
- recursive/optimization_loop.py +135 -0
- recursive/validation_loop.py +38 -0
- security/__init__.py +1 -0
- security/audit_logger.py +106 -0
- security/filesystem_guard.py +100 -0
- security/hypershield.py +99 -0
- security/network_guard.py +97 -0
- security/policy_engine.py +198 -0
- swarm/__init__.py +1 -0
- swarm/agents/__init__.py +0 -0
- swarm/agents/base.py +230 -0
- swarm/agents/business/__init__.py +0 -0
- swarm/agents/business/counsel.py +31 -0
- swarm/agents/business/herald.py +32 -0
- swarm/agents/business/ledger.py +26 -0
- swarm/agents/business/nexus.py +30 -0
- swarm/agents/business/ops.py +30 -0
- swarm/agents/business/pipeline.py +28 -0
- swarm/agents/business/revenue.py +30 -0
- swarm/agents/business/sovereign.py +31 -0
- swarm/agents/business/strategos.py +27 -0
- swarm/agents/business/talent.py +27 -0
- swarm/agents/business/venture.py +32 -0
- swarm/agents/comms/__init__.py +1 -0
- swarm/agents/comms/cipher.py +32 -0
- swarm/agents/comms/echo_comms.py +31 -0
- swarm/agents/comms/envoy.py +31 -0
- swarm/agents/comms/herald_scheduler.py +33 -0
- swarm/agents/comms/pulse.py +29 -0
- swarm/agents/creative/__init__.py +0 -0
- swarm/agents/creative/author.py +27 -0
- swarm/agents/creative/lens.py +25 -0
- swarm/agents/executive/__init__.py +1 -0
- swarm/agents/intelligence/__init__.py +1 -0
- swarm/agents/intelligence/arbiter.py +30 -0
- swarm/agents/intelligence/sentinel.py +30 -0
- swarm/agents/media/__init__.py +0 -0
- swarm/agents/personal/__init__.py +0 -0
- swarm/agents/personal/atlas.py +27 -0
- swarm/agents/personal/hearth.py +26 -0
- swarm/agents/personal/midas.py +27 -0
- swarm/agents/personal/navigator.py +27 -0
- swarm/agents/personal/nourish.py +31 -0
- swarm/agents/personal/vitals.py +33 -0
- swarm/agents/recursive/__init__.py +0 -0
- swarm/agents/recursive/alchemist.py +73 -0
- swarm/agents/recursive/calibrator.py +45 -0
- swarm/agents/recursive/scout.py +97 -0
- swarm/agents/scientific/__init__.py +0 -0
- swarm/agents/scientific/cosmos.py +36 -0
- swarm/agents/scientific/gaia.py +26 -0
- swarm/agents/scientific/medicus.py +33 -0
- swarm/agents/scientific/oracle_agent.py +39 -0
- swarm/agents/scientific/scribe.py +39 -0
- swarm/agents/talent/__init__.py +0 -0
- swarm/agents/talent/deal.py +28 -0
- swarm/agents/talent/roster.py +29 -0
- swarm/agents/talent/scout.py +29 -0
- swarm/agents/talent/stage.py +27 -0
- swarm/agents/tech/__init__.py +0 -0
- swarm/agents/tech/aegis.py +28 -0
- swarm/agents/tech/bridge.py +28 -0
- swarm/agents/tech/forge.py +28 -0
- swarm/agents/trading/__init__.py +1 -0
- swarm/agents/trading/global_prediction_engine.py +611 -0
- swarm/agents/trading/polymarket_trader.py +165 -0
- swarm/agents/trading/prediction_strategist.py +218 -0
- swarm/autogen_bridge.py +68 -0
- swarm/bid_protocol.py +196 -0
- swarm/dispatcher.py +527 -0
- swarm/nexus.py +181 -0
- swarm/registry.py +112 -0
- telegram_listener.py +403 -0
- ui/tui/app.py +214 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""POLYMARKET TRADER — Prediction Market Trading Agent. Executes trades on Polymarket based on intelligence analysis."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from swarm.agents.base import BaseAgent
|
|
4
|
+
from core.hyperstate.schema import HyperState
|
|
5
|
+
import asyncio
|
|
6
|
+
import httpx
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger("polymarket_trader")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PolymarketTraderAgent(BaseAgent):
|
|
13
|
+
agent_id = "POLYMARKET_TRADER"
|
|
14
|
+
domain = "trading"
|
|
15
|
+
description = "Prediction market trading on Polymarket — executes trades based on PROPHET intelligence"
|
|
16
|
+
supported_task_types = ["trade", "analyze", "position", "research"]
|
|
17
|
+
preferred_model = "claude-sonnet-4-6"
|
|
18
|
+
|
|
19
|
+
def __init__(self, model_router=None, state_manager=None, causal_graph=None, hyper_shield=None):
|
|
20
|
+
super().__init__(model_router, state_manager, causal_graph, hyper_shield)
|
|
21
|
+
# Trading limits and risk management
|
|
22
|
+
self.max_position_size = 100 # USD
|
|
23
|
+
self.max_daily_risk = 500 # USD
|
|
24
|
+
self.min_probability_edge = 0.05 # 5% edge minimum
|
|
25
|
+
self.active_positions = {}
|
|
26
|
+
|
|
27
|
+
async def run(self, task: str, state: HyperState, context: dict) -> str:
|
|
28
|
+
system = self._build_system(
|
|
29
|
+
"You are POLYMARKET TRADER, prediction market specialist for HyperClaw. "
|
|
30
|
+
"You analyze Polymarket prediction markets and execute trades when you identify "
|
|
31
|
+
"statistical edges based on intelligence analysis. "
|
|
32
|
+
"TRADING PHILOSOPHY: "
|
|
33
|
+
"- Only trade when you have >5% probability edge vs market price. "
|
|
34
|
+
"- Maximum $100 per position, $500 daily risk limit. "
|
|
35
|
+
"- Focus on markets with high volume and clear catalysts. "
|
|
36
|
+
"- Prioritize markets where you have information advantages. "
|
|
37
|
+
"KEY DOMAINS: "
|
|
38
|
+
"- AI/Tech developments. "
|
|
39
|
+
"- Industry-specific events. "
|
|
40
|
+
"- Economic/Fed policy. "
|
|
41
|
+
"- Geopolitical events affecting business. "
|
|
42
|
+
"RISK MANAGEMENT: "
|
|
43
|
+
"- Never risk more than 2% of bankroll on single trade. "
|
|
44
|
+
"- Maintain detailed position tracking. "
|
|
45
|
+
"- Set stop losses at -20% of position value. "
|
|
46
|
+
"- Report all trades to the user immediately. "
|
|
47
|
+
"Your output should include: market analysis, edge calculation, position sizing, "
|
|
48
|
+
"entry/exit strategy, and risk assessment. Always explain your reasoning."
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
result = await self.model_router.call(
|
|
52
|
+
task_type="analysis",
|
|
53
|
+
messages=[{"role": "user", "content": task}],
|
|
54
|
+
system=system,
|
|
55
|
+
state=state,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
await self.log_completion(state, result, self.preferred_model, bool(result))
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
async def analyze_market_opportunity(self, market_data: dict) -> dict:
|
|
62
|
+
"""Analyze a specific Polymarket opportunity for trading edge."""
|
|
63
|
+
try:
|
|
64
|
+
market_id = market_data.get("id")
|
|
65
|
+
title = market_data.get("title", "")
|
|
66
|
+
current_prob = float(market_data.get("probability", 0))
|
|
67
|
+
volume = float(market_data.get("volume", 0))
|
|
68
|
+
|
|
69
|
+
# Basic filters
|
|
70
|
+
if volume < 1000: # Require minimum $1K volume
|
|
71
|
+
return {"action": "skip", "reason": "Insufficient volume"}
|
|
72
|
+
|
|
73
|
+
if current_prob < 0.1 or current_prob > 0.9: # Avoid extreme probabilities
|
|
74
|
+
return {"action": "skip", "reason": "Extreme probability, low edge potential"}
|
|
75
|
+
|
|
76
|
+
# Analyze based on our intelligence domains
|
|
77
|
+
edge_analysis = await self._calculate_edge(title, current_prob)
|
|
78
|
+
|
|
79
|
+
if abs(edge_analysis["estimated_edge"]) < self.min_probability_edge:
|
|
80
|
+
return {"action": "skip", "reason": "Insufficient edge"}
|
|
81
|
+
|
|
82
|
+
# Position sizing based on Kelly criterion
|
|
83
|
+
edge = edge_analysis["estimated_edge"]
|
|
84
|
+
confidence = edge_analysis["confidence"]
|
|
85
|
+
kelly_fraction = (edge * confidence) / abs(edge) # Simplified Kelly
|
|
86
|
+
position_size = min(self.max_position_size, kelly_fraction * 500) # Cap at $100
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
"action": "trade",
|
|
90
|
+
"market_id": market_id,
|
|
91
|
+
"title": title,
|
|
92
|
+
"current_prob": current_prob,
|
|
93
|
+
"estimated_fair_prob": edge_analysis["fair_probability"],
|
|
94
|
+
"edge": edge,
|
|
95
|
+
"confidence": confidence,
|
|
96
|
+
"position_size": position_size,
|
|
97
|
+
"reasoning": edge_analysis["reasoning"]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.error(f"Market analysis error: {e}")
|
|
102
|
+
return {"action": "error", "error": str(e)}
|
|
103
|
+
|
|
104
|
+
async def _calculate_edge(self, title: str, current_prob: float) -> dict:
|
|
105
|
+
"""Calculate estimated edge based on intelligence analysis."""
|
|
106
|
+
# This would integrate with PROPHET agent for deep analysis
|
|
107
|
+
# For now, implementing basic heuristics
|
|
108
|
+
|
|
109
|
+
title_lower = title.lower()
|
|
110
|
+
|
|
111
|
+
# AI/Tech markets - we have expertise advantage
|
|
112
|
+
if any(keyword in title_lower for keyword in ["ai", "artificial intelligence", "openai", "chatgpt", "machine learning"]):
|
|
113
|
+
# Slight bullish bias on AI adoption
|
|
114
|
+
fair_prob = min(current_prob + 0.05, 0.85)
|
|
115
|
+
confidence = 0.7
|
|
116
|
+
reasoning = "AI/Tech market - domain intelligence advantage"
|
|
117
|
+
|
|
118
|
+
# Hospitality/Travel markets - direct industry knowledge
|
|
119
|
+
elif any(keyword in title_lower for keyword in ["hotel", "travel", "tourism", "marriott", "hilton", "airbnb"]):
|
|
120
|
+
fair_prob = current_prob # Start neutral, need PROPHET analysis
|
|
121
|
+
confidence = 0.8
|
|
122
|
+
reasoning = "Hospitality market - the user's domain expertise"
|
|
123
|
+
|
|
124
|
+
# Fed/Economic policy - affects all ventures
|
|
125
|
+
elif any(keyword in title_lower for keyword in ["fed", "interest rate", "inflation", "recession", "gdp"]):
|
|
126
|
+
fair_prob = current_prob # Neutral without specific intel
|
|
127
|
+
confidence = 0.6
|
|
128
|
+
reasoning = "Economic policy - broad impact analysis needed"
|
|
129
|
+
|
|
130
|
+
else:
|
|
131
|
+
fair_prob = current_prob
|
|
132
|
+
confidence = 0.4
|
|
133
|
+
reasoning = "Outside core expertise domains"
|
|
134
|
+
|
|
135
|
+
edge = fair_prob - current_prob
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
"fair_probability": fair_prob,
|
|
139
|
+
"estimated_edge": edge,
|
|
140
|
+
"confidence": confidence,
|
|
141
|
+
"reasoning": reasoning
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async def execute_trade(self, trade_analysis: dict) -> dict:
|
|
145
|
+
"""Execute the actual Polymarket trade (PLACEHOLDER - needs API integration)."""
|
|
146
|
+
# TODO: Integrate with Polymarket API for actual trading
|
|
147
|
+
# For now, return simulation result
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
"status": "simulated",
|
|
151
|
+
"message": f"SIMULATED TRADE: {trade_analysis['title']} - ${trade_analysis['position_size']} position",
|
|
152
|
+
"market_id": trade_analysis["market_id"],
|
|
153
|
+
"position_size": trade_analysis["position_size"],
|
|
154
|
+
"entry_price": trade_analysis["current_prob"],
|
|
155
|
+
"reasoning": trade_analysis["reasoning"]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async def get_portfolio_status(self) -> dict:
|
|
159
|
+
"""Return current Polymarket portfolio status."""
|
|
160
|
+
return {
|
|
161
|
+
"active_positions": len(self.active_positions),
|
|
162
|
+
"total_exposure": sum(pos.get("size", 0) for pos in self.active_positions.values()),
|
|
163
|
+
"daily_pnl": 0.0, # TODO: Calculate from actual positions
|
|
164
|
+
"available_capital": self.max_daily_risk - sum(pos.get("size", 0) for pos in self.active_positions.values())
|
|
165
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"""PREDICTION STRATEGIST — Strategic analysis for prediction markets. Coordinates PROPHET intelligence with Polymarket opportunities."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from swarm.agents.base import BaseAgent
|
|
4
|
+
from core.hyperstate.schema import HyperState
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger("prediction_strategist")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PredictionStrategistAgent(BaseAgent):
|
|
12
|
+
agent_id = "PREDICTION_STRATEGIST"
|
|
13
|
+
domain = "trading"
|
|
14
|
+
description = "Strategic coordinator for prediction market trading — synthesizes PROPHET intel with market opportunities"
|
|
15
|
+
supported_task_types = ["strategy", "analyze", "coordinate", "research"]
|
|
16
|
+
preferred_model = "claude-sonnet-4-6"
|
|
17
|
+
|
|
18
|
+
def __init__(self, model_router=None, state_manager=None, causal_graph=None, hyper_shield=None):
|
|
19
|
+
super().__init__(model_router, state_manager, causal_graph, hyper_shield)
|
|
20
|
+
self.active_strategies = {}
|
|
21
|
+
self.market_themes = {
|
|
22
|
+
"ai_development": {"weight": 0.9, "expertise": "high"},
|
|
23
|
+
"hospitality_trends": {"weight": 0.95, "expertise": "very_high"},
|
|
24
|
+
"economic_policy": {"weight": 0.7, "expertise": "medium"},
|
|
25
|
+
"geopolitics": {"weight": 0.6, "expertise": "medium"},
|
|
26
|
+
"tech_adoption": {"weight": 0.8, "expertise": "high"},
|
|
27
|
+
"crypto_regulation": {"weight": 0.7, "expertise": "high"}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async def run(self, task: str, state: HyperState, context: dict) -> str:
|
|
31
|
+
system = self._build_system(
|
|
32
|
+
"You are PREDICTION STRATEGIST, the strategic coordinator for HyperClaw's prediction market operations. "
|
|
33
|
+
"You work closely with PROPHET (intelligence) and POLYMARKET_TRADER (execution) to identify "
|
|
34
|
+
"and capitalize on prediction market opportunities where the user's ventures have information advantages. "
|
|
35
|
+
|
|
36
|
+
"STRATEGIC MISSION:\n"
|
|
37
|
+
"Your primary role is identifying prediction markets where the organization ecosystem intelligence "
|
|
38
|
+
"provides asymmetric advantages. You don't just find mispriced markets — you find markets "
|
|
39
|
+
"where our unique position gives us edge. "
|
|
40
|
+
|
|
41
|
+
"CORE ADVANTAGE DOMAINS:\n"
|
|
42
|
+
"1. HOSPITALITY INTELLIGENCE (95% confidence)\n"
|
|
43
|
+
" - the user's 15+ years luxury hospitality experience\n"
|
|
44
|
+
" - the organization platform data from hotel operations\n"
|
|
45
|
+
" - Industry relationships and insider perspective\n"
|
|
46
|
+
" - Travel/tourism trend analysis\n"
|
|
47
|
+
|
|
48
|
+
"2. AI/TECH DEVELOPMENT (90% confidence)\n"
|
|
49
|
+
" - the organization AI platform development insights\n"
|
|
50
|
+
" - Direct experience with AI adoption in enterprise\n"
|
|
51
|
+
" - Technical team assessments of feasibility\n"
|
|
52
|
+
" - Early visibility into AI implementation challenges\n"
|
|
53
|
+
|
|
54
|
+
"3. ENTERPRISE SOFTWARE ADOPTION (85% confidence)\n"
|
|
55
|
+
" - B2B SaaS market insights from the organization operations\n"
|
|
56
|
+
" - Customer adoption pattern recognition\n"
|
|
57
|
+
" - Pricing and market penetration intelligence\n"
|
|
58
|
+
|
|
59
|
+
"4. STARTUP/VC ECOSYSTEM (80% confidence)\n"
|
|
60
|
+
" - Network within the user's local tech ecosystem\n"
|
|
61
|
+
" - Fundraising and valuation trend awareness\n"
|
|
62
|
+
" - Industry partnership and M&A intelligence\n"
|
|
63
|
+
|
|
64
|
+
"STRATEGIC APPROACH:\n"
|
|
65
|
+
"- Coordinate with PROPHET for macro intelligence synthesis\n"
|
|
66
|
+
"- Identify markets where our unique data provides 5%+ edge\n"
|
|
67
|
+
"- Focus on medium-term markets (1-6 months) where intelligence compounds\n"
|
|
68
|
+
"- Avoid pure speculation — only trade where we have genuine information advantage\n"
|
|
69
|
+
"- Maintain portfolio of 3-8 strategic positions with clear thesis\n"
|
|
70
|
+
|
|
71
|
+
"OUTPUT FORMAT:\n"
|
|
72
|
+
"Always provide: Market assessment, Intelligence edge analysis, Strategic recommendation, "
|
|
73
|
+
"Risk/reward profile, Timeline considerations, and Coordination needs with other agents."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
result = await self.model_router.call(
|
|
77
|
+
task_type="strategy",
|
|
78
|
+
messages=[{"role": "user", "content": task}],
|
|
79
|
+
system=system,
|
|
80
|
+
state=state,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
await self.log_completion(state, result, self.preferred_model, bool(result))
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
async def analyze_strategic_opportunities(self, markets: list) -> dict:
|
|
87
|
+
"""Analyze Polymarket opportunities for strategic intelligence advantages."""
|
|
88
|
+
opportunities = []
|
|
89
|
+
|
|
90
|
+
for market in markets:
|
|
91
|
+
title = market.get("title", "").lower()
|
|
92
|
+
category = self._categorize_market(title)
|
|
93
|
+
|
|
94
|
+
if category and category in self.market_themes:
|
|
95
|
+
theme_data = self.market_themes[category]
|
|
96
|
+
edge_potential = await self._assess_intelligence_edge(market, category)
|
|
97
|
+
|
|
98
|
+
if edge_potential["confidence"] > 0.6:
|
|
99
|
+
opportunities.append({
|
|
100
|
+
"market": market,
|
|
101
|
+
"category": category,
|
|
102
|
+
"theme_weight": theme_data["weight"],
|
|
103
|
+
"expertise_level": theme_data["expertise"],
|
|
104
|
+
"edge_assessment": edge_potential,
|
|
105
|
+
"strategic_priority": self._calculate_priority(theme_data, edge_potential)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
# Sort by strategic priority
|
|
109
|
+
opportunities.sort(key=lambda x: x["strategic_priority"], reverse=True)
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
"total_opportunities": len(opportunities),
|
|
113
|
+
"high_priority": [op for op in opportunities if op["strategic_priority"] > 0.7],
|
|
114
|
+
"medium_priority": [op for op in opportunities if 0.4 < op["strategic_priority"] <= 0.7],
|
|
115
|
+
"recommendations": self._generate_strategic_recommendations(opportunities[:5])
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
def _categorize_market(self, title: str) -> str:
|
|
119
|
+
"""Categorize market based on title keywords."""
|
|
120
|
+
categories = {
|
|
121
|
+
"ai_development": ["ai", "artificial intelligence", "openai", "chatgpt", "machine learning", "llm", "gpt"],
|
|
122
|
+
"hospitality_trends": ["hotel", "travel", "tourism", "marriott", "hilton", "hyatt", "airbnb", "booking"],
|
|
123
|
+
"economic_policy": ["fed", "interest rate", "inflation", "recession", "gdp", "unemployment", "housing"],
|
|
124
|
+
"geopolitics": ["election", "war", "sanctions", "trade", "china", "russia", "nato", "biden", "trump"],
|
|
125
|
+
"tech_adoption": ["apple", "microsoft", "google", "meta", "tesla", "netflix", "saas", "cloud"],
|
|
126
|
+
"crypto_regulation": ["bitcoin", "ethereum", "crypto", "sec", "regulation", "cbdc", "stablecoin"]
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for category, keywords in categories.items():
|
|
130
|
+
if any(keyword in title for keyword in keywords):
|
|
131
|
+
return category
|
|
132
|
+
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
async def _assess_intelligence_edge(self, market: dict, category: str) -> dict:
|
|
136
|
+
"""Assess our intelligence edge for a specific market."""
|
|
137
|
+
title = market.get("title", "")
|
|
138
|
+
current_prob = market.get("probability", 0.5)
|
|
139
|
+
|
|
140
|
+
# Category-specific intelligence assessment
|
|
141
|
+
if category == "hospitality_trends":
|
|
142
|
+
confidence = 0.85
|
|
143
|
+
reasoning = "Direct industry experience and the organization hospitality data"
|
|
144
|
+
|
|
145
|
+
elif category == "ai_development":
|
|
146
|
+
confidence = 0.80
|
|
147
|
+
reasoning = "Active AI development team and enterprise deployment experience"
|
|
148
|
+
|
|
149
|
+
elif category == "economic_policy":
|
|
150
|
+
confidence = 0.60
|
|
151
|
+
reasoning = "Macro impact analysis on hospitality and tech sectors"
|
|
152
|
+
|
|
153
|
+
elif category == "tech_adoption":
|
|
154
|
+
confidence = 0.75
|
|
155
|
+
reasoning = "B2B SaaS platform experience and adoption pattern recognition"
|
|
156
|
+
|
|
157
|
+
elif category == "crypto_regulation":
|
|
158
|
+
confidence = 0.65
|
|
159
|
+
reasoning = "Trading operations and regulatory impact assessment"
|
|
160
|
+
|
|
161
|
+
else:
|
|
162
|
+
confidence = 0.40
|
|
163
|
+
reasoning = "Limited specific intelligence advantage"
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
"confidence": confidence,
|
|
167
|
+
"reasoning": reasoning,
|
|
168
|
+
"intelligence_sources": self._get_intelligence_sources(category),
|
|
169
|
+
"edge_magnitude": "medium" if confidence > 0.7 else "low"
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
def _get_intelligence_sources(self, category: str) -> list:
|
|
173
|
+
"""List relevant intelligence sources for category."""
|
|
174
|
+
sources = {
|
|
175
|
+
"hospitality_trends": ["the organization client data", "Industry relationships", "the user's network"],
|
|
176
|
+
"ai_development": ["the organization AI team", "Tech development insights", "Enterprise AI adoption data"],
|
|
177
|
+
"economic_policy": ["PROPHET macro analysis", "Industry impact modeling"],
|
|
178
|
+
"tech_adoption": ["B2B SaaS metrics", "Customer adoption patterns"],
|
|
179
|
+
"crypto_regulation": ["ATLAS_TRADING trading data", "Market structure analysis"]
|
|
180
|
+
}
|
|
181
|
+
return sources.get(category, ["General market research"])
|
|
182
|
+
|
|
183
|
+
def _calculate_priority(self, theme_data: dict, edge_assessment: dict) -> float:
|
|
184
|
+
"""Calculate strategic priority score."""
|
|
185
|
+
weight = theme_data["weight"]
|
|
186
|
+
confidence = edge_assessment["confidence"]
|
|
187
|
+
expertise_bonus = {"very_high": 1.2, "high": 1.1, "medium": 1.0, "low": 0.9}.get(theme_data["expertise"], 1.0)
|
|
188
|
+
|
|
189
|
+
return (weight * confidence * expertise_bonus) / 1.2 # Normalize to 0-1
|
|
190
|
+
|
|
191
|
+
def _generate_strategic_recommendations(self, top_opportunities: list) -> list:
|
|
192
|
+
"""Generate specific strategic recommendations."""
|
|
193
|
+
recommendations = []
|
|
194
|
+
|
|
195
|
+
for i, opp in enumerate(top_opportunities[:3]):
|
|
196
|
+
market = opp["market"]
|
|
197
|
+
rec = {
|
|
198
|
+
"rank": i + 1,
|
|
199
|
+
"title": market.get("title"),
|
|
200
|
+
"category": opp["category"],
|
|
201
|
+
"strategic_rationale": f"{opp['expertise_level']} expertise in {opp['category']}",
|
|
202
|
+
"intelligence_edge": opp["edge_assessment"]["reasoning"],
|
|
203
|
+
"recommended_action": "Deep analysis" if opp["strategic_priority"] > 0.8 else "Monitor",
|
|
204
|
+
"position_sizing": "Small" if opp["strategic_priority"] < 0.6 else "Medium",
|
|
205
|
+
"timeline": "1-3 months" if "policy" in opp["category"] else "2-8 weeks"
|
|
206
|
+
}
|
|
207
|
+
recommendations.append(rec)
|
|
208
|
+
|
|
209
|
+
return recommendations
|
|
210
|
+
|
|
211
|
+
async def coordinate_with_prophet(self, market_theme: str) -> dict:
|
|
212
|
+
"""Request specific intelligence from PROPHET agent."""
|
|
213
|
+
# This would integrate with PROPHET agent for targeted analysis
|
|
214
|
+
return {
|
|
215
|
+
"status": "coordination_needed",
|
|
216
|
+
"theme": market_theme,
|
|
217
|
+
"intelligence_request": f"Deep analysis needed for {market_theme} prediction markets"
|
|
218
|
+
}
|
swarm/autogen_bridge.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AutoGen Bridge — compatibility layer for AutoGen multi-agent group chat patterns.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from core.hyperstate.schema import HyperState
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from swarm.agents.base import BaseAgent
|
|
13
|
+
from swarm.nexus import NexusAgent
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger("hyperclaw.autogen_bridge")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class HyperClawGroupChat:
|
|
19
|
+
"""
|
|
20
|
+
Wraps AutoGen GroupChat + GroupChatManager patterns.
|
|
21
|
+
NEXUS acts as GroupChatManager. Specialist agents are ConversableAgents.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
agents: list["BaseAgent"],
|
|
27
|
+
nexus: "NexusAgent",
|
|
28
|
+
) -> None:
|
|
29
|
+
self._agents = {a.agent_id: a for a in agents}
|
|
30
|
+
self._nexus = nexus
|
|
31
|
+
self._conversation_history: list[dict] = []
|
|
32
|
+
|
|
33
|
+
async def run(self, task: str, domain: str, state: HyperState) -> str:
|
|
34
|
+
"""
|
|
35
|
+
Run a full multi-agent conversation to completion.
|
|
36
|
+
NEXUS decomposes, routes to agents, HERALD assembles final output.
|
|
37
|
+
"""
|
|
38
|
+
log.info(f"HyperClawGroupChat: starting task='{task[:60]}' domain={domain}")
|
|
39
|
+
self._conversation_history = [
|
|
40
|
+
{"role": "user", "content": task, "agent": "user"}
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
# NEXUS orchestrates
|
|
44
|
+
final_state = await self._nexus.orchestrate(task, domain)
|
|
45
|
+
|
|
46
|
+
# Compile conversation history from experiment_log
|
|
47
|
+
output_parts = []
|
|
48
|
+
for entry in final_state.experiment_log[-10:]:
|
|
49
|
+
if entry.result:
|
|
50
|
+
output_parts.append(f"[{entry.model_used}] {entry.result[:200]}")
|
|
51
|
+
|
|
52
|
+
final_output = "\n".join(output_parts) or f"Task completed. State: {final_state.state_id}"
|
|
53
|
+
self._conversation_history.append(
|
|
54
|
+
{"role": "assistant", "content": final_output, "agent": "HERALD"}
|
|
55
|
+
)
|
|
56
|
+
return final_output
|
|
57
|
+
|
|
58
|
+
async def add_agent(self, agent: "BaseAgent") -> None:
|
|
59
|
+
self._agents[agent.agent_id] = agent
|
|
60
|
+
log.info(f"HyperClawGroupChat: added agent {agent.agent_id}")
|
|
61
|
+
|
|
62
|
+
async def remove_agent(self, agent_id: str) -> None:
|
|
63
|
+
self._agents.pop(agent_id, None)
|
|
64
|
+
log.info(f"HyperClawGroupChat: removed agent {agent_id}")
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def agent_count(self) -> int:
|
|
68
|
+
return len(self._agents)
|
swarm/bid_protocol.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HyperSwarm Bid Protocol — agents bid for tasks using UCB1-derived confidence scores.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import math
|
|
7
|
+
import uuid
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from uuid import UUID
|
|
12
|
+
|
|
13
|
+
from core.hyperrouter.bandit import HyperRouter, MODEL_LATENCY_MS, MODEL_COSTS, ucb1_score
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class BidRequest:
|
|
18
|
+
request_id: UUID = field(default_factory=uuid.uuid4)
|
|
19
|
+
subtask_id: UUID = field(default_factory=uuid.uuid4)
|
|
20
|
+
task_type: str = "research"
|
|
21
|
+
domain: str = "business"
|
|
22
|
+
context_summary: str = ""
|
|
23
|
+
deadline_ms: int = 5000
|
|
24
|
+
cost_budget_usd: float = 0.10
|
|
25
|
+
issued_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class Bid:
|
|
30
|
+
bid_id: UUID = field(default_factory=uuid.uuid4)
|
|
31
|
+
request_id: UUID = field(default_factory=uuid.uuid4)
|
|
32
|
+
agent_id: str = ""
|
|
33
|
+
model_id: str = ""
|
|
34
|
+
confidence: float = 0.5
|
|
35
|
+
eta_seconds: float = 2.0
|
|
36
|
+
estimated_cost_usd: float = 0.001
|
|
37
|
+
rationale: str = ""
|
|
38
|
+
issued_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class Award:
|
|
43
|
+
award_id: UUID = field(default_factory=uuid.uuid4)
|
|
44
|
+
request_id: UUID = field(default_factory=uuid.uuid4)
|
|
45
|
+
winning_agent_id: str = ""
|
|
46
|
+
winning_model_id: str = ""
|
|
47
|
+
awarded_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
|
48
|
+
competing_bids: int = 0
|
|
49
|
+
score: float = 0.0
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _bid_score(bid: Bid, request: BidRequest) -> float:
|
|
53
|
+
"""Score = confidence*0.6 + (1 - cost/budget)*0.2 + (1 - eta/30)*0.2"""
|
|
54
|
+
cost_ratio = min(bid.estimated_cost_usd / max(request.cost_budget_usd, 1e-9), 1.0)
|
|
55
|
+
eta_ratio = min(bid.eta_seconds / 30.0, 1.0)
|
|
56
|
+
return bid.confidence * 0.6 + (1.0 - cost_ratio) * 0.2 + (1.0 - eta_ratio) * 0.2
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class BidCoordinator:
|
|
60
|
+
"""
|
|
61
|
+
Manages the full bid lifecycle: broadcast → collect → award → (repeat).
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
hyper_router: HyperRouter,
|
|
67
|
+
registered_agents: list[str],
|
|
68
|
+
) -> None:
|
|
69
|
+
self._router = hyper_router
|
|
70
|
+
self._agents = registered_agents
|
|
71
|
+
self._pending: dict[UUID, BidRequest] = {}
|
|
72
|
+
self._bids: dict[UUID, list[Bid]] = {}
|
|
73
|
+
self._agent_load: dict[str, int] = {a: 0 for a in registered_agents}
|
|
74
|
+
|
|
75
|
+
async def broadcast(
|
|
76
|
+
self,
|
|
77
|
+
subtask_id: UUID,
|
|
78
|
+
task_type: str,
|
|
79
|
+
domain: str,
|
|
80
|
+
context_summary: str,
|
|
81
|
+
deadline_ms: int = 5000,
|
|
82
|
+
cost_budget_usd: float = 0.10,
|
|
83
|
+
) -> BidRequest:
|
|
84
|
+
req = BidRequest(
|
|
85
|
+
subtask_id=subtask_id,
|
|
86
|
+
task_type=task_type,
|
|
87
|
+
domain=domain,
|
|
88
|
+
context_summary=context_summary,
|
|
89
|
+
deadline_ms=deadline_ms,
|
|
90
|
+
cost_budget_usd=cost_budget_usd,
|
|
91
|
+
)
|
|
92
|
+
self._pending[req.request_id] = req
|
|
93
|
+
self._bids[req.request_id] = []
|
|
94
|
+
return req
|
|
95
|
+
|
|
96
|
+
async def collect(self, request_id: UUID, timeout_ms: int = 3000) -> list[Bid]:
|
|
97
|
+
return self._bids.get(request_id, [])
|
|
98
|
+
|
|
99
|
+
def submit_bid(self, bid: Bid) -> None:
|
|
100
|
+
"""Called by agents to submit their bids."""
|
|
101
|
+
if bid.request_id in self._bids:
|
|
102
|
+
self._bids[bid.request_id].append(bid)
|
|
103
|
+
|
|
104
|
+
async def award(self, request: BidRequest, bids: list[Bid]) -> Award:
|
|
105
|
+
"""
|
|
106
|
+
Select the winning bid.
|
|
107
|
+
Score = confidence*0.6 + (1 - cost/budget)*0.2 + (1 - eta/30)*0.2
|
|
108
|
+
Ties broken by lowest estimated_cost_usd.
|
|
109
|
+
Falls back to HyperRouter UCB1 if no bids.
|
|
110
|
+
"""
|
|
111
|
+
if not bids:
|
|
112
|
+
# Fallback: UCB1 direct selection
|
|
113
|
+
agent_id, model_id = self._router.route(request.task_type)
|
|
114
|
+
return Award(
|
|
115
|
+
request_id=request.request_id,
|
|
116
|
+
winning_agent_id=agent_id,
|
|
117
|
+
winning_model_id=model_id,
|
|
118
|
+
competing_bids=0,
|
|
119
|
+
score=0.0,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
scored = [(b, _bid_score(b, request)) for b in bids]
|
|
123
|
+
# Sort: score DESC, then cost ASC for tie-breaking
|
|
124
|
+
scored.sort(key=lambda x: (-x[1], x[0].estimated_cost_usd))
|
|
125
|
+
winner, score = scored[0]
|
|
126
|
+
|
|
127
|
+
self._agent_load[winner.agent_id] = self._agent_load.get(winner.agent_id, 0) + 1
|
|
128
|
+
|
|
129
|
+
return Award(
|
|
130
|
+
request_id=request.request_id,
|
|
131
|
+
winning_agent_id=winner.agent_id,
|
|
132
|
+
winning_model_id=winner.model_id,
|
|
133
|
+
competing_bids=len(bids),
|
|
134
|
+
score=score,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
async def negotiate(
|
|
138
|
+
self,
|
|
139
|
+
subtask_id: UUID,
|
|
140
|
+
task_type: str,
|
|
141
|
+
domain: str,
|
|
142
|
+
context_summary: str,
|
|
143
|
+
) -> Award:
|
|
144
|
+
"""Full pipeline: broadcast → collect → award."""
|
|
145
|
+
request = await self.broadcast(subtask_id, task_type, domain, context_summary)
|
|
146
|
+
bids = await self.collect(request.request_id)
|
|
147
|
+
return await self.award(request, bids)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class AgentBidder:
|
|
151
|
+
"""Mixin for all specialist agents — computes UCB1-derived bids."""
|
|
152
|
+
|
|
153
|
+
agent_id: str = "base"
|
|
154
|
+
active_tasks: int = 0
|
|
155
|
+
|
|
156
|
+
async def compute_bid(
|
|
157
|
+
self,
|
|
158
|
+
request: BidRequest,
|
|
159
|
+
agent_scores: dict,
|
|
160
|
+
) -> Bid:
|
|
161
|
+
"""
|
|
162
|
+
Base confidence = UCB1 score for task_type (clamped to 0–1).
|
|
163
|
+
If active_tasks > 3: confidence *= 0.7
|
|
164
|
+
"""
|
|
165
|
+
score_map = agent_scores.get(self.agent_id)
|
|
166
|
+
if score_map:
|
|
167
|
+
total = max(sum(s.attempts for s in agent_scores.values()), 1)
|
|
168
|
+
raw_ucb1 = ucb1_score(
|
|
169
|
+
score_map.successes,
|
|
170
|
+
score_map.attempts,
|
|
171
|
+
total,
|
|
172
|
+
)
|
|
173
|
+
# Clamp inf → 1.0, then clamp to [0, 1]
|
|
174
|
+
confidence = min(raw_ucb1, 1.0) if raw_ucb1 != float("inf") else 1.0
|
|
175
|
+
else:
|
|
176
|
+
confidence = 0.7 # prior for unknown agents
|
|
177
|
+
|
|
178
|
+
if self.active_tasks > 3:
|
|
179
|
+
confidence *= 0.7
|
|
180
|
+
|
|
181
|
+
confidence = max(0.0, min(1.0, confidence))
|
|
182
|
+
|
|
183
|
+
# Select model
|
|
184
|
+
model_id = getattr(self, "preferred_model", "claude-sonnet-4-6")
|
|
185
|
+
latency = MODEL_LATENCY_MS.get(model_id, 2000.0) / 1000.0
|
|
186
|
+
cost = MODEL_COSTS.get(model_id, 0.003) * 500 / 1000 # assume ~500 tokens
|
|
187
|
+
|
|
188
|
+
return Bid(
|
|
189
|
+
request_id=request.request_id,
|
|
190
|
+
agent_id=self.agent_id,
|
|
191
|
+
model_id=model_id,
|
|
192
|
+
confidence=confidence,
|
|
193
|
+
eta_seconds=latency,
|
|
194
|
+
estimated_cost_usd=cost,
|
|
195
|
+
rationale=f"{self.agent_id} handles {request.task_type} in {request.domain}",
|
|
196
|
+
)
|