Defining a Module
What is an AgentModule?
Section titled “What is an AgentModule?”AgentModule is a thin async base class for building agent-like modules around an optional LM. You implement async forward(...), optionally attach an LM, and can expose additional callable actions via the @agent_action decorator.
Key behaviors:
- Implement
async forward(...)in subclasses - Call an instance like a function to schedule
forwardand get an awaitable Future - Register actions using
@agent_action; discovered on init underinstance.actions - Optional
LMhelpers:lm_call(...)andawait lm_invoke(func, ...)
Minimal example
Section titled “Minimal example”import asynciofrom vagents.core.module import AgentModule, agent_action
class ToyAgent(AgentModule): @agent_action async def greet(self, name: str) -> str: await asyncio.sleep(0) return f"hello {name}"
async def forward(self, x: int) -> int: await asyncio.sleep(0) return x + 1
# Usageagent = ToyAgent()assert "greet" in agent.actionsresult = await agent(1) # schedules forward via internal executorDefining actions
Section titled “Defining actions”Annotate instance methods with @agent_action to auto-register them as actions on initialization.
class MyAgent(AgentModule): @agent_action async def summarize(self, text: str) -> str: ...
agent = MyAgent()await agent.actions["summarize"]("Some text")Integrating an LM
Section titled “Integrating an LM”If you construct your module with an LM instance, you can call it via helpers.
from vagents.core import LM
class ChatAgent(AgentModule): def __init__(self, lm: LM): super().__init__(lm)
async def forward(self, prompt: str) -> str: # Calls self.lm(prompt, ...) through the executor and awaits the result text = await self.lm_call(prompt) return text
@agent_action async def tool_use(self, data: dict) -> dict: # Or invoke a specific LM function with arguments return await self.lm_invoke(lambda lm, d: lm.process(d), data)Using AgentInput/AgentOutput (for packaging and orchestration)
Section titled “Using AgentInput/AgentOutput (for packaging and orchestration)”For packages and orchestrators, prefer the standardized protocols:
from vagents.core import AgentInput, AgentOutput
class EchoAgent(AgentModule): async def forward(self, input: AgentInput) -> AgentOutput: return AgentOutput(input_id=input.id, result={"echo": input.payload})AgentInputcarriespayloadand optionalcontextfor processingAgentOutputcarries aresultpayload or anerrormessage
When executed via the package manager, arguments and piped stdin are assembled into an AgentInput automatically when your entry point is an AgentModule or a function that accepts AgentInput.
Testing tips
Section titled “Testing tips”- Await
agent(...)directly; it returns an awaitable Future - Assert action discovery with
"action_name" in agent.actions - Use small awaits (e.g.,
await asyncio.sleep(0)) in tests to yield control