Agent Module¶
This module provides the core classes and data model of the agent.
Core Classes¶
AgentBase¶
- class agentsociety2.agent.base.AgentBase[source]¶
Bases:
ABCAbstract base class for all agents.
Directly owns the generic agent runtime (workspace binding, skill runtime, ReAct tool dispatch) plus identity, service slots, and the abstract contract. Construction is via
create/from_workspace;__init__is arg-less.Subclasses must implement (forced abstracts):
- __init__()[source]¶
Initialize an unbound agent (arg-less).
Only empty slots are set; no profile parsing, no id required. The real initialization happens in
restore()(called byfrom_workspace()).
- classmethod create(workspace_path, profile, config)[source]¶
Create the initial agent workspace (static, write-once config).
Writes
config.json(static, never rewritten) + initialAGENT.json+ the standard empty directories. Does NOT return an agent instance; usefrom_workspace()to reconstruct.
- async classmethod from_workspace(workspace_path, service_proxy)[source]¶
Reconstruct a ready agent from its workspace.
agent = cls()(arg-less);await agent.restore(ws, proxy); return the agent.- Parameters:
workspace_path (Path) – Path to the workspace directory
service_proxy (ServiceProxy) – Shared service container (env / llm / trace / replay).
- Returns:
Ready agent instance.
- Return type:
- async restore(workspace_path, service_proxy)[source]¶
The real initialization (called by
from_workspace).Reads
config.json+AGENT.json; sets_id/_profile/_name/_config; calls_bind_services+_bind_workspace; restores visible/activated skills + counters.Subclasses override this to ALSO restore person-specific state after
await super().restore(...).- Parameters:
workspace_path (Path) – Path to the workspace directory
service_proxy (ServiceProxy) – Shared service container.
- abstractmethod async to_workspace(workspace_path)[source]¶
Write current dynamic state back to the workspace.
- abstractmethod async ask(message, readonly=True, *, t=None)[source]¶
Answer an external question through the agent’s reasoning flow.
- env_ask_env_ctx_overlay()[source]¶
Generate the ask_env / CodeGenRouter.ask context overlay.
Returns the stable identity keys (id, agent_id, person_id) provided by the framework, independent of any skill.
- async ask_env(ctx, message, readonly, template_mode=False, trace_id=None, parent_span_id=None)[source]¶
Name of the environment module
Wraps interaction with the simulation environment, supporting template mode and context-variable substitution.
- Parameters:
ctx (dict) – Context dict (may include a
variableskey for template mode).message (str) – Request message.
readonly (bool) – Whether this is a read-only request.
template_mode (bool) – Whether to enable template mode.
trace_id (str | None) – OTel trace ID for cross-agent/env correlation.
parent_span_id (str | None) – OTel parent span ID.
- Returns:
(ctx, answer) tuple
- async acompletion(messages, stream=False, **kwargs)[source]¶
Single LLM completion via the bound default-role dispatcher.
Convenience for subclasses that need a one-shot LLM call (the full multi-turn tool loop is
run_react_loop()). Uses the agent’s bound dispatcher + model.
- classmethod init_description()[source]¶
Return AI-readable initialization guidance for this agent class.
- workspace_root_path()[source]¶
Return the agent-owned workspace root.
- Raises:
RuntimeError – When the workspace is not initialized.
- trace_span(name, *, trace_id=None, parent_span_id=None, attributes=None, end_attributes=None)[source]¶
Create an agent-owned trace span context.
- build_agent_json(*, tick, t)[source]¶
Build the consolidated self-description file for the agent.
Subclasses may override to add extra fields (e.g. memory summary).
- persist_agent_json(*, tick=None, t=None)[source]¶
Persist consolidated agent self-description to AGENT.json.
- discover_skill_sources(env, *, extra_skill_paths=None)[source]¶
Scan skills from an environment module’s skill directory.
Scans the default
<root>/custom/skillslocations (env.run_dirand this agent’s workspace root), then any extra skill directories merged from two sources:declarative:
extra_skill_pathsinconfig.json(resolved inrestore());programmatic: the
extra_skill_pathsargument here.
Each extra entry is a directory containing skill subdirectories (same layout as
custom/skills). Relative entries resolve against the workspace root. The default scan is unchanged when neither is given, so agents can load custom skills stored anywhere via either entry point.- Parameters:
env (RouterBase) – Environment router used to locate run directories and modules.
extra_skill_paths (Iterable[Path | str] | None) – Additional skill directories to scan now (each a root of skill subdirectories).
- Returns:
Mapping from discovery source labels to added skill IDs.
- Return type:
- async run_lifecycle_hooks(hook_type, *, tick, t)[source]¶
Run lifecycle hooks for currently activated skills.
- async dispatch_react_tool(action, args, *, readonly=False)[source]¶
Dispatch one ReAct tool call.
Handles workspace file tools, skill tools, and ask_env. Person-specific tools (memory_*, todo_*) are handled by the subclass before this method is reached (or via a subclass override).
- async run_react_loop(*, tick, t, observations=None, question=None, readonly=False, skill_hooks=None)[source]¶
Run the ReAct loop until finish or turn limit.
- Parameters:
tick (int) – Current simulation tick.
t (datetime) – Current simulation time.
observations (list[dict[str, Any]] | None) – Initial observation list (appended in-place).
question (str | None) – Optional external question (ask mode).
readonly (bool) – Whether mutation tools are blocked.
skill_hooks (list[dict[str, Any]] | None) – Optional pre_step hook outputs for the prompt.
- Returns:
Final result string from the loop.
- Return type:
- build_react_messages(*, tick, t, observations, question=None, readonly=False, skill_hooks=None)[source]¶
Build ReAct prompt messages (subclass prompt hook).
The base implementation raises
NotImplementedError. Subclasses (e.g. PersonAgent) override this to assemble their agent-specific prompt and return OpenAI-style chat messages.- Parameters:
tick (int) – Current simulation tick.
t (datetime) – Current simulation time.
observations (list[dict[str, Any]]) – Recent observation list.
question (str | None) – Optional external question (ask mode).
readonly (bool) – Whether mutation tools are blocked.
skill_hooks (list[dict[str, Any]] | None) – Optional pre_step hook outputs for the prompt.
- Returns:
OpenAI-style chat messages.
- Raises:
NotImplementedError – Always, in the base class.
- Return type:
PersonAgent¶
- class agentsociety2.agent.person.PersonAgent[source]¶
Bases:
AgentBaseWorkspace-backed simulated person agent.
Person-specific responsibilities:
Memory runtime (
PersonMemoryRuntime):MEMORY.md+ episodes, plus thememory_*tool dispatch.todo_*tool dispatch (the generic TODO state store + helpers live onAgentBase; PersonAgent routes thetodo_*prefix to them).Person prompt building (
build_react_messages) — the prompt hook the generic ReAct loop calls.step/askorchestration (observe + react loop + lifecycle hooks).
Generic agent machinery (workspace binding, skill discovery, file/skill/ask_env tool dispatch, the ReAct loop, LLM dispatch, response parsing, TODO state, trace spans, AGENT.json persistence, construction model) is inherited from
AgentBase.- async restore(workspace_path, service_proxy)[source]¶
Restore base state, then build person-specific runtime (memory).
- Parameters:
workspace_path (Path) – Path to the workspace directory
service_proxy (ServiceProxy) – Shared service container.
- async to_workspace(workspace_path)[source]¶
Write current dynamic state back to the workspace.
Writes
AGENT.json(profile / step_count / current_time / skills / initialized_at).config.jsonis NOT rewritten. Memory (MEMORY.md+ episodes) is persisted via the memory runtime’safter_steppath duringstep().- Parameters:
workspace_path (Path) – Path to the workspace directory
- async dispatch_react_tool(action, args, *, readonly=False)[source]¶
Dispatch person-specific prefixes, then delegate the rest to base.
Person-specific prefixes handled here:
memory_*→_dispatch_memory_tool()(person memory runtime).todo_*→dispatch_todo_tool()(inherited fromAgentBase; the generic TODO store + arg normalization).
All other actions (workspace / skill / ask_env) are delegated to
await super().dispatch_react_tool(action, args, readonly=readonly).
AgentBase directly owns generic capabilities such as workspace binding, the skill runtime, ReAct tool loop, TODO state, trace, and AGENT.json persistence. PersonAgent is a thin orchestrator on top that only implements person-oriented behavior. Agents are no longer constructed by passing parameters to __init__; instead, AgentBase.create() writes the workspace once and await AgentBase.from_workspace(path, service_proxy) rebuilds the agent (see Using Agents).
If you only want to extend agent behavior, prefer adding or modifying an Agent Skill; only inherit from AgentBase / PersonAgent to create a new class when you need to change the agent lifecycle, state machine, or external system interaction patterns. See Agent Skills for the skill system design guide, and see Skills Module for the API reference.