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
swarm/nexus.py
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HyperSwarm NEXUS — Central swarm facilitator. Decomposes goals, orchestrates agents, assembles results.
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import uuid
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from core.hyperstate.schema import HyperState
|
|
11
|
+
from swarm.agents.base import BaseAgent
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from core.hyperstate.state_manager import StateManager
|
|
15
|
+
from memory.causal_graph import CausalGraph
|
|
16
|
+
from models.router import ModelRouter
|
|
17
|
+
from security.hypershield import HyperShield
|
|
18
|
+
from swarm.bid_protocol import BidCoordinator
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger("hyperclaw.nexus")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class NexusAgent(BaseAgent):
|
|
24
|
+
"""
|
|
25
|
+
HyperSwarm facilitator — manages HyperState, coordinates bids, decomposes tasks.
|
|
26
|
+
NEXUS is the always-on orchestrator: every goal passes through it.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
agent_id = "NEXUS"
|
|
30
|
+
domain = "recursive"
|
|
31
|
+
description = "HyperSwarm facilitator — manages HyperState, coordinates bids, decomposes tasks"
|
|
32
|
+
supported_task_types = ["planning", "routing", "coordination"]
|
|
33
|
+
preferred_model = "claude-sonnet-4-6"
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
bid_coordinator: "BidCoordinator",
|
|
38
|
+
model_router: "ModelRouter",
|
|
39
|
+
state_manager: "StateManager",
|
|
40
|
+
causal_graph: "CausalGraph",
|
|
41
|
+
hyper_shield: "HyperShield",
|
|
42
|
+
) -> None:
|
|
43
|
+
super().__init__(model_router, state_manager, causal_graph, hyper_shield)
|
|
44
|
+
self.bid_coordinator = bid_coordinator
|
|
45
|
+
self._registry: dict = {} # agent_id → BaseAgent, injected post-init
|
|
46
|
+
|
|
47
|
+
def set_registry(self, registry: dict) -> None:
|
|
48
|
+
self._registry = registry
|
|
49
|
+
|
|
50
|
+
async def decompose(self, goal: str, domain: str) -> list[dict]:
|
|
51
|
+
"""
|
|
52
|
+
Use Claude to break a goal into subtasks.
|
|
53
|
+
Returns [{subtask_id, task_type, description, domain, depends_on}]
|
|
54
|
+
"""
|
|
55
|
+
system = (
|
|
56
|
+
"You are NEXUS, a task decomposition engine. "
|
|
57
|
+
"Break the given goal into 2-5 concrete subtasks. "
|
|
58
|
+
"For each subtask, specify: task_type (one of: research, analysis, synthesis, planning, code, health, finance), "
|
|
59
|
+
"description (one sentence), and depends_on (list of subtask indices that must complete first, or []). "
|
|
60
|
+
"Respond as a JSON array only. Example: "
|
|
61
|
+
'[{"task_type":"research","description":"Research X","depends_on":[]},{"task_type":"synthesis","description":"Synthesize findings","depends_on":[0]}]'
|
|
62
|
+
)
|
|
63
|
+
# Create a temporary state for decomposition
|
|
64
|
+
temp_state = HyperState(domain=domain, task=__import__("core.hyperstate.schema", fromlist=["Task"]).Task(goal=goal, task_type="planning"))
|
|
65
|
+
|
|
66
|
+
raw = await self.model_router.call(
|
|
67
|
+
task_type="planning",
|
|
68
|
+
messages=[{"role": "user", "content": f"Goal: {goal}\nDomain: {domain}"}],
|
|
69
|
+
system=system,
|
|
70
|
+
state=temp_state,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Parse JSON
|
|
74
|
+
import json, re
|
|
75
|
+
try:
|
|
76
|
+
# Extract JSON array
|
|
77
|
+
match = re.search(r'\[.*\]', raw, re.DOTALL)
|
|
78
|
+
subtasks_raw = json.loads(match.group(0)) if match else []
|
|
79
|
+
except Exception:
|
|
80
|
+
# Fallback: single subtask
|
|
81
|
+
subtasks_raw = [{"task_type": "synthesis", "description": goal, "depends_on": []}]
|
|
82
|
+
|
|
83
|
+
subtasks = []
|
|
84
|
+
for i, s in enumerate(subtasks_raw[:5]):
|
|
85
|
+
subtasks.append({
|
|
86
|
+
"subtask_id": str(uuid.uuid4()),
|
|
87
|
+
"task_type": s.get("task_type", "research"),
|
|
88
|
+
"description": s.get("description", ""),
|
|
89
|
+
"domain": domain,
|
|
90
|
+
"depends_on": s.get("depends_on", []),
|
|
91
|
+
})
|
|
92
|
+
return subtasks
|
|
93
|
+
|
|
94
|
+
async def orchestrate(self, goal: str, domain: str) -> HyperState:
|
|
95
|
+
"""
|
|
96
|
+
Full orchestration pipeline:
|
|
97
|
+
1. create_state → 2. decompose → 3. dispatch → 4. HERALD assembly → 5. impact record
|
|
98
|
+
"""
|
|
99
|
+
from core.hyperstate.schema import Task
|
|
100
|
+
state = await self.state_manager.create_state(
|
|
101
|
+
goal=goal,
|
|
102
|
+
domain=domain,
|
|
103
|
+
task_type="planning",
|
|
104
|
+
)
|
|
105
|
+
log.info(f"NEXUS: orchestrating goal='{goal[:60]}' state={state.state_id}")
|
|
106
|
+
|
|
107
|
+
subtasks = await self.decompose(goal, domain)
|
|
108
|
+
results: list[str] = []
|
|
109
|
+
|
|
110
|
+
import time
|
|
111
|
+
from core.hyperstate.schema import ExperimentEntry
|
|
112
|
+
|
|
113
|
+
for subtask in subtasks:
|
|
114
|
+
task_type = subtask["task_type"]
|
|
115
|
+
description = subtask["description"]
|
|
116
|
+
t0 = time.time()
|
|
117
|
+
|
|
118
|
+
# Find best agent from registry
|
|
119
|
+
agent = self._find_agent(task_type, domain)
|
|
120
|
+
if agent:
|
|
121
|
+
try:
|
|
122
|
+
result = await agent.run(description, state, {"domain": domain})
|
|
123
|
+
agent_label = agent.agent_id
|
|
124
|
+
except Exception as e:
|
|
125
|
+
log.warning(f"NEXUS: agent {agent.agent_id} failed: {e}")
|
|
126
|
+
result = f"(agent error: {e})"
|
|
127
|
+
agent_label = agent.agent_id
|
|
128
|
+
else:
|
|
129
|
+
# Direct model call as fallback
|
|
130
|
+
result = await self.model_router.call(
|
|
131
|
+
task_type=task_type,
|
|
132
|
+
messages=[{"role": "user", "content": description}],
|
|
133
|
+
system="Complete this task concisely and helpfully.",
|
|
134
|
+
state=state,
|
|
135
|
+
)
|
|
136
|
+
agent_label = f"NEXUS-{task_type}"
|
|
137
|
+
|
|
138
|
+
results.append(f"[{agent_label}] {result[:800]}")
|
|
139
|
+
|
|
140
|
+
# Record in experiment log
|
|
141
|
+
entry = ExperimentEntry(
|
|
142
|
+
method=agent_label,
|
|
143
|
+
model_used="claude-sonnet-4-6",
|
|
144
|
+
result=result[:1000],
|
|
145
|
+
certified=len(result) > 50,
|
|
146
|
+
latency_ms=(time.time() - t0) * 1000,
|
|
147
|
+
)
|
|
148
|
+
state.experiment_log.append(entry)
|
|
149
|
+
|
|
150
|
+
# HERALD assembly
|
|
151
|
+
herald = self._registry.get("HERALD")
|
|
152
|
+
combined = "\n\n".join(results)
|
|
153
|
+
if herald:
|
|
154
|
+
final = await herald.run(
|
|
155
|
+
f"Assemble this into a final deliverable for the goal: '{goal}'\n\nAgent outputs:\n{combined}",
|
|
156
|
+
state,
|
|
157
|
+
{},
|
|
158
|
+
)
|
|
159
|
+
else:
|
|
160
|
+
final = combined
|
|
161
|
+
|
|
162
|
+
# Update state
|
|
163
|
+
state.task.goal = goal
|
|
164
|
+
await self.state_manager.update_state(state.state_id, {"routing_weights": state.routing_weights})
|
|
165
|
+
return state
|
|
166
|
+
|
|
167
|
+
def _find_agent(self, task_type: str, domain: str) -> "BaseAgent | None":
|
|
168
|
+
"""Find the best registered agent for this task_type and domain."""
|
|
169
|
+
candidates = [
|
|
170
|
+
a for a in self._registry.values()
|
|
171
|
+
if task_type in a.supported_task_types and a.agent_id != "NEXUS"
|
|
172
|
+
]
|
|
173
|
+
# Prefer domain match
|
|
174
|
+
domain_match = [a for a in candidates if a.domain == domain]
|
|
175
|
+
pool = domain_match or candidates
|
|
176
|
+
return pool[0] if pool else None
|
|
177
|
+
|
|
178
|
+
async def run(self, task: str, state: HyperState, context: dict) -> str:
|
|
179
|
+
domain = context.get("domain", state.domain)
|
|
180
|
+
final_state = await self.orchestrate(task, domain)
|
|
181
|
+
return f"NEXUS orchestration complete. State: {final_state.state_id}"
|
swarm/registry.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentRegistry — HyperSwarm Registry
|
|
3
|
+
Specialist AI agents with shared dependencies.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from swarm.agents.base import BaseAgent
|
|
12
|
+
from models.router import ModelRouter
|
|
13
|
+
from core.hyperstate.state_manager import StateManager
|
|
14
|
+
from memory.causal_graph import CausalGraph
|
|
15
|
+
from security.hypershield import HyperShield
|
|
16
|
+
|
|
17
|
+
log = logging.getLogger("hyperclaw.registry")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AgentRegistry:
|
|
21
|
+
"""Central registry of all HyperSwarm agents."""
|
|
22
|
+
|
|
23
|
+
def __init__(self) -> None:
|
|
24
|
+
self._agents: dict[str, "BaseAgent"] = {}
|
|
25
|
+
|
|
26
|
+
def register(self, agent: "BaseAgent") -> None:
|
|
27
|
+
self._agents[agent.agent_id] = agent
|
|
28
|
+
log.debug(f"Registered agent: {agent.agent_id} ({agent.domain})")
|
|
29
|
+
|
|
30
|
+
def get(self, agent_id: str) -> "BaseAgent":
|
|
31
|
+
if agent_id not in self._agents:
|
|
32
|
+
raise KeyError(f"Agent '{agent_id}' not registered")
|
|
33
|
+
return self._agents[agent_id]
|
|
34
|
+
|
|
35
|
+
def list_all(self) -> list["BaseAgent"]:
|
|
36
|
+
return list(self._agents.values())
|
|
37
|
+
|
|
38
|
+
def list_by_domain(self, domain: str) -> list["BaseAgent"]:
|
|
39
|
+
return [a for a in self._agents.values() if a.domain == domain]
|
|
40
|
+
|
|
41
|
+
def list_by_task_type(self, task_type: str) -> list["BaseAgent"]:
|
|
42
|
+
return [a for a in self._agents.values() if task_type in a.supported_task_types]
|
|
43
|
+
|
|
44
|
+
def as_dict(self) -> dict[str, "BaseAgent"]:
|
|
45
|
+
return dict(self._agents)
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def build_default(
|
|
49
|
+
cls,
|
|
50
|
+
model_router: "ModelRouter",
|
|
51
|
+
state_manager: "StateManager",
|
|
52
|
+
causal_graph: "CausalGraph",
|
|
53
|
+
hyper_shield: "HyperShield",
|
|
54
|
+
) -> "AgentRegistry":
|
|
55
|
+
"""
|
|
56
|
+
Instantiate and register all specialist agents with shared dependencies.
|
|
57
|
+
"""
|
|
58
|
+
registry = cls()
|
|
59
|
+
deps = (model_router, state_manager, causal_graph, hyper_shield)
|
|
60
|
+
|
|
61
|
+
# Discover every agent dynamically — a hand-maintained import list
|
|
62
|
+
# silently drops agents added later (VENTURE, trading, intelligence
|
|
63
|
+
# were all missing from the old list).
|
|
64
|
+
import importlib
|
|
65
|
+
import inspect
|
|
66
|
+
import pkgutil
|
|
67
|
+
|
|
68
|
+
import swarm.agents as _pkg
|
|
69
|
+
from swarm.agents.base import BaseAgent
|
|
70
|
+
|
|
71
|
+
for mod_info in pkgutil.walk_packages(_pkg.__path__, _pkg.__name__ + "."):
|
|
72
|
+
try:
|
|
73
|
+
mod = importlib.import_module(mod_info.name)
|
|
74
|
+
except Exception as e:
|
|
75
|
+
log.warning(f"Agent module {mod_info.name} failed to import: {e}")
|
|
76
|
+
continue
|
|
77
|
+
for _, obj in inspect.getmembers(mod, inspect.isclass):
|
|
78
|
+
if not (issubclass(obj, BaseAgent) and obj is not BaseAgent
|
|
79
|
+
and obj.__module__ == mod.__name__):
|
|
80
|
+
continue
|
|
81
|
+
try:
|
|
82
|
+
agent = obj(*deps)
|
|
83
|
+
except TypeError:
|
|
84
|
+
# Older agents take no shared deps — construct bare and
|
|
85
|
+
# attach the deps they understand.
|
|
86
|
+
try:
|
|
87
|
+
agent = obj()
|
|
88
|
+
for attr, val in zip(
|
|
89
|
+
("model_router", "state_manager", "causal_graph", "hyper_shield"),
|
|
90
|
+
deps,
|
|
91
|
+
):
|
|
92
|
+
if not hasattr(agent, attr) or getattr(agent, attr) is None:
|
|
93
|
+
setattr(agent, attr, val)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
log.warning(f"{obj.__name__} failed to initialize: {e}")
|
|
96
|
+
continue
|
|
97
|
+
except Exception as e:
|
|
98
|
+
log.warning(f"{obj.__name__} failed to initialize: {e}")
|
|
99
|
+
continue
|
|
100
|
+
if agent.agent_id in registry._agents:
|
|
101
|
+
# Never silently overwrite — qualify with the domain.
|
|
102
|
+
alt = f"{agent.agent_id}-{agent.domain.upper()}"
|
|
103
|
+
log.warning(
|
|
104
|
+
f"agent_id collision: '{agent.agent_id}' already registered "
|
|
105
|
+
f"({registry._agents[agent.agent_id].__class__.__name__}); "
|
|
106
|
+
f"registering {obj.__name__} as '{alt}'"
|
|
107
|
+
)
|
|
108
|
+
agent.agent_id = alt
|
|
109
|
+
registry.register(agent)
|
|
110
|
+
|
|
111
|
+
log.info(f"AgentRegistry: {len(registry._agents)} agents registered — HyperSwarm ONLINE")
|
|
112
|
+
return registry
|