AutoAgent and CustomAgent represent two fundamentally different execution models, but this boundary is not documented anywhere, and JarvisLifespan creates a misleading picture by treating them identically at startup.
The Split
CustomAgent is a mesh citizen. It implements a full run() listener loop (customagent.py:L143) that calls self.peers.receive(), dispatches via _dispatch_message(), and routes to on_peer_request() / on_peer_notify() handlers. It is designed to receive P2P messages from peer agents.
AutoAgent is a task worker. It has zero references to peer, listen, or on_peer across all 825 lines of its implementation. It inherits Agent.run() which is a no-op pass (agent.py:L156). It is designed to be called directly via execute_task() — by the WorkflowEngine or by application code — not by peer messages.
The Problem
JarvisLifespan boots both types into the same mesh, injects PeerClient into every agent, and starts background run() loops for all of them. From the outside, all agents appear to be equal mesh participants. There is no warning, no log message, and no documentation indicating that AutoAgent.run() is a no-op and that it will silently ignore all incoming P2P requests.
A developer building a hybrid mesh — a CustomAgent front-door that delegates to AutoAgent specialists via ask_peer — will discover this gap only at runtime when peer requests hang indefinitely with no error.
Proposed Fix
Option A — Documentation only: Add a clear docstring to AutoAgent stating it is a task worker, not a mesh listener. JarvisLifespan should log a WARNING when it boots an AutoAgent alongside CustomAgents in P2P mode.
Option B — Opt-in P2P support: Add a p2p_responder = True class attribute to AutoAgent that wires up a listener loop automatically, delegating incoming peer requests to execute_task():
class DataAgent(AutoAgent):
p2p_responder = True # Wires run() → peer listener → execute_task()
AutoAgentandCustomAgentrepresent two fundamentally different execution models, but this boundary is not documented anywhere, andJarvisLifespancreates a misleading picture by treating them identically at startup.The Split
CustomAgentis a mesh citizen. It implements a fullrun()listener loop (customagent.py:L143) that callsself.peers.receive(), dispatches via_dispatch_message(), and routes toon_peer_request()/on_peer_notify()handlers. It is designed to receive P2P messages from peer agents.AutoAgentis a task worker. It has zero references topeer,listen, oron_peeracross all 825 lines of its implementation. It inheritsAgent.run()which is a no-oppass(agent.py:L156). It is designed to be called directly viaexecute_task()— by theWorkflowEngineor by application code — not by peer messages.The Problem
JarvisLifespanboots both types into the same mesh, injectsPeerClientinto every agent, and starts backgroundrun()loops for all of them. From the outside, all agents appear to be equal mesh participants. There is no warning, no log message, and no documentation indicating thatAutoAgent.run()is a no-op and that it will silently ignore all incoming P2P requests.A developer building a hybrid mesh — a
CustomAgentfront-door that delegates toAutoAgentspecialists viaask_peer— will discover this gap only at runtime when peer requests hang indefinitely with no error.Proposed Fix
Option A — Documentation only: Add a clear docstring to
AutoAgentstating it is a task worker, not a mesh listener.JarvisLifespanshould log aWARNINGwhen it boots anAutoAgentalongsideCustomAgents in P2P mode.Option B — Opt-in P2P support: Add a
p2p_responder = Trueclass attribute toAutoAgentthat wires up a listener loop automatically, delegating incoming peer requests toexecute_task():