Agents
The core container that hosts reasoners, skills, and sessions, and connects to the AgentField control plane
The top-level container that turns your code into a discoverable, governed, production microservice. An Agent instance hosts reasoners, skills, and sessions, and registers them with the control plane.
Without Agent, you would wire an HTTP server, registration, routing, identity, tracing, memory access, and cross-agent calls separately. With Agent, that infrastructure boundary is the object you instantiate.
from agentfield import Agent, AIConfig
from pydantic import BaseModel
app = Agent(
node_id="support-triage", # unique ID in the network
ai_config=AIConfig(model="anthropic/claude-sonnet-4-20250514"),
)
class TicketClassification(BaseModel):
priority: str # "critical" | "high" | "normal" | "low"
department: str # route to the right team
summary: str # one-line summary for the queue
@app.reasoner() # AI-powered — gets an LLM client automatically
async def classify_ticket(subject: str, body: str, customer_id: str) -> TicketClassification:
result = await app.ai(
system="You triage customer support tickets.",
user=f"Subject: {subject}\n\n{body}",
schema=TicketClassification, # validated, typed output
)
await app.memory.set(f"ticket:{customer_id}:last_priority", result.priority)
return result
@app.skill() # deterministic — no AI, just business logic
def escalation_policy(priority: str) -> dict:
sla = {"critical": 15, "high": 60, "normal": 240, "low": 1440}
return {"sla_minutes": sla.get(priority, 240)}
app.run() # starts HTTP server + registers with control plane
# POST /reasoners/classify_ticket → AI classification
# POST /skills/escalation_policy → SLA lookupWhat just happened
- One
Agentinstance exposed both AI and deterministic operations - The reasoner got model access, validation, and workflow context automatically
- The deterministic function became a separate callable endpoint without extra server code
- In all three SDKs, deterministic endpoints can be registered separately from AI-powered reasoners
- The memory write used the same execution context as the reasoner
Example generated surface:
Python/TypeScript:
POST /reasoners/classify_ticket
POST /skills/escalation_policy
target: support-triage.classify_ticket
Go equivalent:
POST /reasoners/classify_ticket
POST /skills/escalation_policy
What You Get
- HTTP server with auto-generated REST endpoints for every reasoner and skill
- Control plane registration with heartbeat, lease renewal, and graceful shutdown
- Cryptographic identity via automatic DID registration and verifiable credentials
- Cross-agent communication through the AgentField execution gateway
- Built-in AI client for structured LLM output with any provider
- Memory system for distributed state across workflows and sessions
- CLI mode for local testing and interactive debugging
Constructor Parameters
Python
Agent extends FastAPI. All FastAPI constructor parameters are also accepted.
| Parameter | Type | Default | Description |
|---|---|---|---|
node_id | str | required | Unique identifier for this agent node |
agentfield_server | str | None | "http://localhost:8080" | Control plane URL. Also reads AGENTFIELD_SERVER env var |
version | str | "1.0.0" | Agent version string |
description | str | None | None | Human-readable description |
tags | list[str] | None | None | Metadata labels for policy and discovery |
ai_config | AIConfig | None | None | LLM provider configuration |
harness_config | HarnessConfig | None | None | Configuration for the coding-agent harness. None or an unset provider means AForge, the default. |
memory_config | MemoryConfig | None | None | Memory auto-injection, retention, and caching settings |
dev_mode | bool | False | Enable verbose logging |
callback_url | str | None | auto-detected | URL the control plane uses to reach this agent |
auto_register | bool | True | Register with control plane on startup |
vc_enabled | bool | None | True | Enable verifiable credential generation |
api_key | str | None | None | API key for control plane auth |
enable_mcp | bool | False | Enable MCP server integration |
enable_did | bool | True | Enable DID-based identity |
local_verification | bool | False | Enable decentralized request verification |
TypeScript
| Parameter | Type | Default | Description |
|---|---|---|---|
nodeId | string | required | Unique identifier for this agent node |
agentFieldUrl | string | "http://localhost:8080" | Control plane URL |
port | number | 8001 | HTTP server port |
host | string | "0.0.0.0" | HTTP server bind address |
version | string | undefined | Agent version string |
teamId | string | undefined | Team grouping identifier |
aiConfig | AIConfig | undefined | LLM provider configuration |
harnessConfig | HarnessConfig | undefined | Coding-agent harness configuration. Omitted or an unset provider means AForge, the default. |
memoryConfig | MemoryConfig | undefined | Memory scope and TTL defaults |
didEnabled | boolean | true | Enable DID-based identity |
devMode | boolean | undefined | Enable verbose logging |
deploymentType | "long_running" | "serverless" | "long_running" | Execution mode |
mcp | MCPConfig | undefined | MCP server configuration |
localVerification | boolean | undefined | Enable decentralized request verification |
tags | string[] | undefined | Metadata labels for policy and discovery |
Go
| Parameter | Type | Default | Description |
|---|---|---|---|
NodeID | string | required | Unique identifier for this agent node |
Version | string | required | Agent version string |
TeamID | string | "default" | Team grouping identifier |
AgentFieldURL | string | "" | Control plane URL |
ListenAddress | string | ":8001" | HTTP server bind address |
PublicURL | string | auto-generated | URL the control plane uses to reach this agent |
Token | string | "" | Bearer token for control plane auth |
DeploymentType | string | "long_running" | Execution mode |
LeaseRefreshInterval | time.Duration | 2m | Heartbeat frequency |
AIConfig | *ai.Config | nil | LLM provider configuration |
HarnessConfig | *HarnessConfig | nil | Coding-agent harness configuration. nil or an unset Provider means AForge, the default. |
MemoryBackend | MemoryBackend | in-memory | Custom memory storage backend |
EnableDID | bool | false | Enable automatic DID registration |
VCEnabled | bool | false | Enable verifiable credential generation |
Tags | []string | nil | Metadata labels for policy and discovery |
LocalVerification | bool | false | Enable decentralized request verification |
RequireOriginAuth | bool | false | Validate incoming requests against token |
SDK Reference
| Operation | Python | TypeScript | Go |
|---|---|---|---|
| Create agent | Agent(node_id=...) | new Agent({ nodeId }) | agent.New(agent.Config{NodeID: ..., AgentFieldURL: ...}) |
| Register reasoner | @app.reasoner() | agent.reasoner(name, handler) | a.RegisterReasoner(name, handler) |
| Register skill | @app.skill() | agent.skill(name, handler) | N/A (use RegisterReasoner) |
| Include router | app.include_router(r) | agent.includeRouter(r) | N/A |
| Start server | app.serve(port=8001) | agent.serve() | a.Serve(ctx) |
| Auto-detect mode | app.run() | N/A | a.Run(ctx) |
| Call another agent | await app.call("agent.fn", **input) | await agent.call("agent.fn", input) | a.Call(ctx, "agent.fn", input) |
| AI structured output | await app.ai(user=..., schema=Model) | await ctx.ai(prompt, { schema }) | a.AI(ctx, prompt, opts) |
| Run harness | await app.harness(prompt) | await agent.harness(prompt) | a.Harness(ctx, prompt, schema, dest, opts) |
| Access memory | app.memory.set(key, val) | ctx.memory | a.Memory() |
| Discover agents | app.discover() | await agent.discover() | a.Discover(ctx) |
| Shutdown | automatic on SIGTERM | await agent.shutdown() | automatic on SIGTERM |
Patterns
Environment-based configuration
import os
from agentfield import Agent, AIConfig
app = Agent(
node_id=os.getenv("AGENT_ID", "my-agent"),
agentfield_server=os.getenv("AGENTFIELD_SERVER"),
ai_config=AIConfig(
model=os.getenv("LLM_MODEL", "openai/gpt-4o"),
),
dev_mode=os.getenv("DEV_MODE", "false").lower() == "true",
)Serverless deployment
from agentfield import Agent
app = Agent(
node_id="serverless-agent",
callback_url="https://my-function.vercel.app",
)
@app.reasoner()
async def process(data: dict) -> dict:
return {"processed": True, **data}
# Export the FastAPI app for serverless platforms
# Vercel, Railway, etc. use this directlyCross-agent communication
@app.reasoner()
async def orchestrate(task: str) -> dict:
# Call another agent's reasoner through the control plane
analysis = await app.call("analyzer-agent.analyze", text=task)
summary = await app.call("summarizer-agent.summarize", data=analysis)
return {"task": task, "result": summary}