Spaces:
Runtime error
Runtime error
GitHub Copilot
commited on
Commit
·
ad60bb2
1
Parent(s):
d77237a
Sync: Deployed Dynamic Agent Onboarding logic to Space
Browse files- logos/agent_dispatcher.py +88 -8
- logos/agents/base_agent.py +38 -0
- logos/agents/video_atomizer.py +53 -5
logos/agent_dispatcher.py
CHANGED
|
@@ -347,6 +347,7 @@ class LogosSwarm:
|
|
| 347 |
"""
|
| 348 |
Protocol 21: The Async Interference Bus.
|
| 349 |
Agents pulse in parallel; the solution is the geometric intersection.
|
|
|
|
| 350 |
"""
|
| 351 |
def __init__(self, base_url="http://localhost:1234/v1", model="google/gemma-3-4b"):
|
| 352 |
self.connector = get_connector('local', base_url=base_url, model=model)
|
|
@@ -359,6 +360,39 @@ class LogosSwarm:
|
|
| 359 |
self.oversight = DolphinOversight(self.state)
|
| 360 |
self.metadata = GemmaMetadata()
|
| 361 |
self.routing = RNJ1Routing(self.state, self.connector)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 362 |
|
| 363 |
async def process(self, raw_input: str):
|
| 364 |
print("\n🌊 [HOLOGRAPHIC BUS] PULSING WAVE FUNCTIONS...")
|
|
@@ -368,27 +402,41 @@ class LogosSwarm:
|
|
| 368 |
user_packet = {"content": raw_input, "type": "text_command"}
|
| 369 |
action, packet = self.oversight.ingest(user_packet)
|
| 370 |
|
| 371 |
-
# 2. PARALLEL INTERFERENCE: Gemma
|
| 372 |
# They "interfere" to find the true deterministic coordinate
|
| 373 |
gemma_task = asyncio.create_task(self.metadata.process(packet))
|
| 374 |
rnj1_task = asyncio.create_task(self.routing.calculate_position(packet))
|
| 375 |
|
| 376 |
-
# reasoning_task: Pulse to LLM
|
| 377 |
reasoning_task = asyncio.create_task(self.routing.connector.chat_async(
|
| 378 |
f"Analyze this packet for topological resonance: {raw_input}",
|
| 379 |
system_prompt="You are the SWARM_REASONER. Identify the high-level intent and potential manifold collisions."
|
| 380 |
))
|
| 381 |
-
|
| 382 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
await asyncio.gather(gemma_task, rnj1_task, reasoning_task)
|
| 384 |
|
| 385 |
gemma_status, mass = gemma_task.result()
|
| 386 |
res = rnj1_task.result()
|
| 387 |
reasoning, logprobs = reasoning_task.result()
|
| 388 |
|
| 389 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
if logprobs:
|
| 391 |
-
# logprobs from OpenAI usually contain 'content' if it's chat/completion
|
| 392 |
log_content = logprobs.get('content', [])
|
| 393 |
self.oversight.kill_switch.monitor_bulk(log_content)
|
| 394 |
|
|
@@ -472,15 +520,47 @@ class LogosSwarm:
|
|
| 472 |
})
|
| 473 |
except: pass
|
| 474 |
|
| 475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
Analyze the following user input and classify it into one of these categories:
|
| 477 |
- 'fractal_architect': For code, debugging, storage, sharding, or technical implementation.
|
| 478 |
- 'prime_navigator': For math, primes, geometry, calculations, or physics.
|
| 479 |
- 'creative': For descriptions, stories, or documentation style.
|
| 480 |
- 'general': For greetings or anything else.
|
|
|
|
| 481 |
|
| 482 |
Reply with ONLY a JSON object in this format:
|
| 483 |
-
{"intent": "category_name", "confidence": 0.9}
|
| 484 |
Do not write any introductory text.
|
| 485 |
"""
|
| 486 |
|
|
|
|
| 347 |
"""
|
| 348 |
Protocol 21: The Async Interference Bus.
|
| 349 |
Agents pulse in parallel; the solution is the geometric intersection.
|
| 350 |
+
Protocol 26: Dynamic Agent Onboarding (Matroska Router Connection).
|
| 351 |
"""
|
| 352 |
def __init__(self, base_url="http://localhost:1234/v1", model="google/gemma-3-4b"):
|
| 353 |
self.connector = get_connector('local', base_url=base_url, model=model)
|
|
|
|
| 360 |
self.oversight = DolphinOversight(self.state)
|
| 361 |
self.metadata = GemmaMetadata()
|
| 362 |
self.routing = RNJ1Routing(self.state, self.connector)
|
| 363 |
+
|
| 364 |
+
# Dynamic Agent Registry
|
| 365 |
+
self.agents: Dict[str, Any] = {}
|
| 366 |
+
self.discover_agents()
|
| 367 |
+
|
| 368 |
+
def discover_agents(self):
|
| 369 |
+
"""
|
| 370 |
+
Onboards agents from logos/agents/ that implement BaseAgent.
|
| 371 |
+
"""
|
| 372 |
+
import pkgutil
|
| 373 |
+
import importlib
|
| 374 |
+
import inspect
|
| 375 |
+
import logos.agents
|
| 376 |
+
from logos.agents.base_agent import BaseAgent
|
| 377 |
+
|
| 378 |
+
package = logos.agents
|
| 379 |
+
prefix = package.__name__ + "."
|
| 380 |
+
|
| 381 |
+
print("🔍 [SWARM] Scanning for Matroska Agents...")
|
| 382 |
+
for _, name, _ in pkgutil.iter_modules(package.__path__, prefix):
|
| 383 |
+
try:
|
| 384 |
+
module = importlib.import_module(name)
|
| 385 |
+
for name_cls, cls in inspect.getmembers(module, inspect.isclass):
|
| 386 |
+
if issubclass(cls, BaseAgent) and cls is not BaseAgent:
|
| 387 |
+
try:
|
| 388 |
+
instance = cls()
|
| 389 |
+
self.agents[instance.name.lower()] = instance
|
| 390 |
+
print(f" ✅ Onboarded: {instance.name} (Trigger: {instance.triggers})")
|
| 391 |
+
except Exception as e:
|
| 392 |
+
print(f" ⚠️ Failed to init {name_cls}: {e}")
|
| 393 |
+
except Exception as e:
|
| 394 |
+
print(f" ⚠️ Error loading module {name}: {e}")
|
| 395 |
+
|
| 396 |
|
| 397 |
async def process(self, raw_input: str):
|
| 398 |
print("\n🌊 [HOLOGRAPHIC BUS] PULSING WAVE FUNCTIONS...")
|
|
|
|
| 402 |
user_packet = {"content": raw_input, "type": "text_command"}
|
| 403 |
action, packet = self.oversight.ingest(user_packet)
|
| 404 |
|
| 405 |
+
# 2. PARALLEL INTERFERENCE: Gemma, RNJ-1, Reasoning, AND Dynamic Agents
|
| 406 |
# They "interfere" to find the true deterministic coordinate
|
| 407 |
gemma_task = asyncio.create_task(self.metadata.process(packet))
|
| 408 |
rnj1_task = asyncio.create_task(self.routing.calculate_position(packet))
|
| 409 |
|
| 410 |
+
# reasoning_task: Pulse to LLM
|
| 411 |
reasoning_task = asyncio.create_task(self.routing.connector.chat_async(
|
| 412 |
f"Analyze this packet for topological resonance: {raw_input}",
|
| 413 |
system_prompt="You are the SWARM_REASONER. Identify the high-level intent and potential manifold collisions."
|
| 414 |
))
|
| 415 |
+
|
| 416 |
+
# Dynamic Agent Task (if applicable)
|
| 417 |
+
agent_tasks = []
|
| 418 |
+
for agent_name, agent in self.agents.items():
|
| 419 |
+
# Check triggers or intent
|
| 420 |
+
if any(t in raw_input.lower() for t in agent.triggers):
|
| 421 |
+
print(f"🚀 [SWARM] Triggering Agent: {agent.name}")
|
| 422 |
+
agent_tasks.append(asyncio.create_task(agent.process(packet)))
|
| 423 |
+
|
| 424 |
+
# Wait for Core Triple Wave
|
| 425 |
await asyncio.gather(gemma_task, rnj1_task, reasoning_task)
|
| 426 |
|
| 427 |
gemma_status, mass = gemma_task.result()
|
| 428 |
res = rnj1_task.result()
|
| 429 |
reasoning, logprobs = reasoning_task.result()
|
| 430 |
|
| 431 |
+
# Process Agent Results
|
| 432 |
+
agent_results = []
|
| 433 |
+
if agent_tasks:
|
| 434 |
+
await asyncio.gather(*agent_tasks)
|
| 435 |
+
for t in agent_tasks:
|
| 436 |
+
agent_results.append(t.result())
|
| 437 |
+
|
| 438 |
+
# Update Entropy Kill Switch
|
| 439 |
if logprobs:
|
|
|
|
| 440 |
log_content = logprobs.get('content', [])
|
| 441 |
self.oversight.kill_switch.monitor_bulk(log_content)
|
| 442 |
|
|
|
|
| 520 |
})
|
| 521 |
except: pass
|
| 522 |
|
| 523 |
+
|
| 524 |
+
def get_onboarded_agents() -> Dict[str, Any]:
|
| 525 |
+
"""Helper to discover agents dynamically."""
|
| 526 |
+
import pkgutil
|
| 527 |
+
import importlib
|
| 528 |
+
import inspect
|
| 529 |
+
import logos.agents
|
| 530 |
+
from logos.agents.base_agent import BaseAgent
|
| 531 |
+
|
| 532 |
+
agents = {}
|
| 533 |
+
package = logos.agents
|
| 534 |
+
prefix = package.__name__ + "."
|
| 535 |
+
|
| 536 |
+
for _, name, _ in pkgutil.iter_modules(package.__path__, prefix):
|
| 537 |
+
try:
|
| 538 |
+
module = importlib.import_module(name)
|
| 539 |
+
for _, cls in inspect.getmembers(module, inspect.isclass):
|
| 540 |
+
if issubclass(cls, BaseAgent) and cls is not BaseAgent:
|
| 541 |
+
try:
|
| 542 |
+
instance = cls()
|
| 543 |
+
agents[instance.name.lower()] = instance
|
| 544 |
+
except: pass
|
| 545 |
+
except: pass
|
| 546 |
+
return agents
|
| 547 |
+
|
| 548 |
+
# Dynamic Prompt Construction
|
| 549 |
+
_onboarded = get_onboarded_agents()
|
| 550 |
+
_agent_lines = []
|
| 551 |
+
for name, agent in _onboarded.items():
|
| 552 |
+
_agent_lines.append(f"- '{name}': {agent.description}")
|
| 553 |
+
|
| 554 |
+
ROUTER_PROMPT = f"""
|
| 555 |
Analyze the following user input and classify it into one of these categories:
|
| 556 |
- 'fractal_architect': For code, debugging, storage, sharding, or technical implementation.
|
| 557 |
- 'prime_navigator': For math, primes, geometry, calculations, or physics.
|
| 558 |
- 'creative': For descriptions, stories, or documentation style.
|
| 559 |
- 'general': For greetings or anything else.
|
| 560 |
+
{chr(10).join(_agent_lines)}
|
| 561 |
|
| 562 |
Reply with ONLY a JSON object in this format:
|
| 563 |
+
{{"intent": "category_name", "confidence": 0.9}}
|
| 564 |
Do not write any introductory text.
|
| 565 |
"""
|
| 566 |
|
logos/agents/base_agent.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from abc import ABC, abstractmethod
|
| 3 |
+
from typing import Dict, Any, List, Optional
|
| 4 |
+
|
| 5 |
+
class BaseAgent(ABC):
|
| 6 |
+
"""
|
| 7 |
+
Protocol 26: Standard Agent Interface for Matroska Swarm.
|
| 8 |
+
All agents must implement this to be auto-discovered by the Router.
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
@property
|
| 12 |
+
@abstractmethod
|
| 13 |
+
def name(self) -> str:
|
| 14 |
+
"""Unique name of the agent (e.g., 'VideoAtomizer')"""
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
@property
|
| 18 |
+
@abstractmethod
|
| 19 |
+
def description(self) -> str:
|
| 20 |
+
"""Short description for the Router's system prompt"""
|
| 21 |
+
pass
|
| 22 |
+
|
| 23 |
+
@property
|
| 24 |
+
@abstractmethod
|
| 25 |
+
def triggers(self) -> List[str]:
|
| 26 |
+
"""List of keywords or regex patterns that trigger this agent"""
|
| 27 |
+
pass
|
| 28 |
+
|
| 29 |
+
@abstractmethod
|
| 30 |
+
async def process(self, task: Dict[str, Any]) -> Dict[str, Any]:
|
| 31 |
+
"""
|
| 32 |
+
Execute the agent's logic.
|
| 33 |
+
Args:
|
| 34 |
+
task: The input packet (e.g., {'content': '...', 'context': {}})
|
| 35 |
+
Returns:
|
| 36 |
+
Dict containing 'status', 'result', and 'tensor_updates'
|
| 37 |
+
"""
|
| 38 |
+
pass
|
logos/agents/video_atomizer.py
CHANGED
|
@@ -1,15 +1,43 @@
|
|
| 1 |
import re
|
| 2 |
import asyncio
|
| 3 |
from youtube_transcript_api import YouTubeTranscriptApi
|
|
|
|
| 4 |
|
| 5 |
-
class VideoAtomizer:
|
| 6 |
"""
|
| 7 |
Role: V-NODE (Video Ingest)
|
| 8 |
Function: Rips semantic atoms from video streams and collides them
|
| 9 |
with the existing Project Manifold.
|
| 10 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
def __init__(self):
|
| 12 |
-
self.
|
|
|
|
| 13 |
|
| 14 |
def extract_video_id(self, url):
|
| 15 |
# Extracts 'R9czY1uVq_k' from the URL
|
|
@@ -31,10 +59,30 @@ class VideoAtomizer:
|
|
| 31 |
|
| 32 |
# 1. FETCH TRANSCRIPT (The Raw Atoms)
|
| 33 |
try:
|
| 34 |
-
#
|
|
|
|
|
|
|
|
|
|
| 35 |
loop = asyncio.get_event_loop()
|
| 36 |
-
transcript_list = await loop.run_in_executor(None,
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
except Exception as e:
|
| 39 |
return {"error": f"Signal Lost: {e}"}
|
| 40 |
|
|
|
|
| 1 |
import re
|
| 2 |
import asyncio
|
| 3 |
from youtube_transcript_api import YouTubeTranscriptApi
|
| 4 |
+
from logos.agents.base_agent import BaseAgent
|
| 5 |
|
| 6 |
+
class VideoAtomizer(BaseAgent):
|
| 7 |
"""
|
| 8 |
Role: V-NODE (Video Ingest)
|
| 9 |
Function: Rips semantic atoms from video streams and collides them
|
| 10 |
with the existing Project Manifold.
|
| 11 |
"""
|
| 12 |
+
@property
|
| 13 |
+
def name(self) -> str:
|
| 14 |
+
return "VideoAtomizer"
|
| 15 |
+
|
| 16 |
+
@property
|
| 17 |
+
def description(self) -> str:
|
| 18 |
+
return "Ingests YouTube videos/playlists, extracts transcripts, and atomizes content into semantic tensors."
|
| 19 |
+
|
| 20 |
+
@property
|
| 21 |
+
def triggers(self) -> list:
|
| 22 |
+
return ["youtube", "playlist", "video", "transcript", "watch?v="]
|
| 23 |
+
|
| 24 |
+
async def process(self, task: dict) -> dict:
|
| 25 |
+
content = task.get('content', '')
|
| 26 |
+
project_dna = task.get('context', {}).get('dna', {})
|
| 27 |
+
|
| 28 |
+
# Extract URLs from content
|
| 29 |
+
urls = re.findall(r'(https?://(?:www\.|m\.)?youtube\.com/watch\?v=[\w-]+|https?://youtu\.be/[\w-]+)', content)
|
| 30 |
+
|
| 31 |
+
results = []
|
| 32 |
+
for url in urls:
|
| 33 |
+
res = await self.ingest_and_align(url, project_dna)
|
| 34 |
+
results.append(res)
|
| 35 |
+
|
| 36 |
+
return {"status": "COMPLETE", "result": results}
|
| 37 |
+
|
| 38 |
def __init__(self):
|
| 39 |
+
self._name = "VideoAtomizer" # Internal generic
|
| 40 |
+
|
| 41 |
|
| 42 |
def extract_video_id(self, url):
|
| 43 |
# Extracts 'R9czY1uVq_k' from the URL
|
|
|
|
| 59 |
|
| 60 |
# 1. FETCH TRANSCRIPT (The Raw Atoms)
|
| 61 |
try:
|
| 62 |
+
# Instantiate the API wrapper (Local Environment Quirk)
|
| 63 |
+
yt_api = YouTubeTranscriptApi()
|
| 64 |
+
|
| 65 |
+
# Use 'fetch' method in thread executor
|
| 66 |
loop = asyncio.get_event_loop()
|
| 67 |
+
transcript_list = await loop.run_in_executor(None, yt_api.fetch, video_id)
|
| 68 |
+
|
| 69 |
+
# Handle return types
|
| 70 |
+
if isinstance(transcript_list, dict):
|
| 71 |
+
full_text = str(transcript_list)
|
| 72 |
+
elif isinstance(transcript_list, list):
|
| 73 |
+
if len(transcript_list) > 0:
|
| 74 |
+
first = transcript_list[0]
|
| 75 |
+
if isinstance(first, str):
|
| 76 |
+
full_text = " ".join(transcript_list)
|
| 77 |
+
elif isinstance(first, dict):
|
| 78 |
+
full_text = " ".join([t.get('text', '') for t in transcript_list])
|
| 79 |
+
else:
|
| 80 |
+
full_text = str(transcript_list)
|
| 81 |
+
else:
|
| 82 |
+
full_text = ""
|
| 83 |
+
else:
|
| 84 |
+
full_text = str(transcript_list)
|
| 85 |
+
|
| 86 |
except Exception as e:
|
| 87 |
return {"error": f"Signal Lost: {e}"}
|
| 88 |
|