Agent Module

This module provides the core classes and data model of the agent.

Core Classes

AgentBase

class agentsociety2.agent.base.AgentBase[source]

Bases: ABC

Abstract 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 by from_workspace()).

classmethod create(workspace_path, profile, config)[source]

Create the initial agent workspace (static, write-once config).

Writes config.json (static, never rewritten) + initial AGENT.json + the standard empty directories. Does NOT return an agent instance; use from_workspace() to reconstruct.

Parameters:
  • workspace_path (Path) – Agent workspace root (created if missing).

  • profile (dict) – Agent profile dict (must include id).

  • config (dict) – Static config dict written verbatim to config.json.

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:

AgentBase

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.

abstractmethod async step(tick, t)[source]

Run one simulation step.

property id: int

type identifier。

property name: str

Agent display name.

property logger: Logger

Agent-scoped logger.

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.

Returns:

Dictionary containing id, agent_id, person_id.

Return type:

dict[str, Any]

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 variables key 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.

Parameters:
  • messages (list[dict[str, Any]]) – Chat messages.

  • stream (bool) – Streaming flag (False by default; the local LLM dispatcher does not support streaming).

  • **kwargs (Any) – Extra litellm kwargs (timeout, tools, …).

Returns:

The LLM response (litellm ModelResponse).

Return type:

Any

async close()[source]

Close the agent and release resources. Subclasses may override.

get_profile()[source]

Return the agent profile as a dict.

Returns:

Profile dict (raw dict, model_dump, or {"raw": str}).

Return type:

Dict[str, Any]

classmethod description()[source]

Return a short agent description for module lists.

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).

Parameters:
  • tick (int | None) – Current simulation tick, if available.

  • t (Any | None) – Current simulation time, if available.

Returns:

Article data dictionary

Return type:

dict[str, Any]

persist_agent_json(*, tick=None, t=None)[source]

Persist consolidated agent self-description to AGENT.json.

Parameters:
  • tick (int | None) – Current simulation tick, if available.

  • t (Any | None) – Current simulation time, if available.

Returns:

Data written to AGENT.json.

Return type:

dict[str, Any]

discover_skill_sources(env, *, extra_skill_paths=None)[source]

Scan skills from an environment module’s skill directory.

Scans the default <root>/custom/skills locations (env.run_dir and this agent’s workspace root), then any extra skill directories merged from two sources:

  • declarative: extra_skill_paths in config.json (resolved in restore());

  • programmatic: the extra_skill_paths argument 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:

dict[str, list[str]]

async run_lifecycle_hooks(hook_type, *, tick, t)[source]

Run lifecycle hooks for currently activated skills.

Parameters:
  • hook_type (str) – Lifecycle hook name, such as pre_step or post_step.

  • tick (int) – Current simulation tick.

  • t (Any) – Current simulation time.

Returns:

Tool execution result.

Return type:

list[dict[str, Any]]

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).

Parameters:
  • action (str) – Tool metadata.

  • args (dict[str, Any]) – Tool argument dictionary.

  • readonly (bool) – Whether mutation tools should be blocked.

Returns:

Tool execution result.

Return type:

ReactToolResult

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:

str

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:

list[dict[str, str]]

dispatch_todo_tool(action, args)[source]

Registry for built-in analysis tools.

Parameters:
  • action (str) – TODO tool action name.

  • args (dict[str, Any]) – Tool argument dictionary.

Returns:

Tool execution result.

Return type:

ReactToolResult

PersonAgent

class agentsociety2.agent.person.PersonAgent[source]

Bases: AgentBase

Workspace-backed simulated person agent.

Person-specific responsibilities:

  • Memory runtime (PersonMemoryRuntime): MEMORY.md + episodes, plus the memory_* tool dispatch.

  • todo_* tool dispatch (the generic TODO state store + helpers live on AgentBase; PersonAgent routes the todo_* prefix to them).

  • Person prompt building (build_react_messages) — the prompt hook the generic ReAct loop calls.

  • step / ask orchestration (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.

classmethod description()[source]

Hypothesis description

classmethod init_description()[source]

Return initialization guidance for generated configs.

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.json is NOT rewritten. Memory (MEMORY.md + episodes) is persisted via the memory runtime’s after_step path during step().

Parameters:

workspace_path (Path) – Path to the workspace directory

build_agent_json(*, tick, t)[source]

Build AGENT.json with person-specific memory / skill fields.

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 from AgentBase; 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).

build_react_messages(*, tick, t, observations, question=None, readonly=False, skill_hooks=None)[source]

Build ReAct prompt messages (person-specific).

async step(tick, t)[source]

Run one simulation step.

async ask(message, readonly=True, *, t=None)[source]

Answer an external question through the ReAct loop.

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.