Agent patterns (ReAct / CodeAct / MemAct) built on AbstractRuntime (durable execution) and AbstractCore (tools + LLM integration).
AbstractAgent is part of the AbstractFramework ecosystem:
- AbstractFramework (ecosystem overview): https://github.com/lpalbou/AbstractFramework
- AbstractCore (providers + tool schemas): https://github.com/lpalbou/abstractcore
- AbstractRuntime (durable workflows + storage/ledger): https://github.com/lpalbou/abstractruntime
Start here: docs/getting-started.md (then docs/README.md for the full index)
flowchart LR
Host[Your app / service] --> Agent[AbstractAgent<br/>ReAct / CodeAct / MemAct]
Agent --> RT[AbstractRuntime<br/>WorkflowSpec + Effects]
RT --> Core[AbstractCore<br/>LLM + tool-call normalization]
RT --> Stores[RunStore + LedgerStore]
Agent --> Tools[Tool callables<br/>(abstractcore common_tools + agent tools)]
- Getting started:
docs/getting-started.md - API reference:
docs/api.md - Loop hooks (listen/steer/capture):
docs/hooks.md - FAQ:
docs/faq.md - Troubleshooting:
docs/troubleshooting.md - Architecture (diagrams):
docs/architecture.md - Changelog:
CHANGELOG.md - Contributing:
CONTRIBUTING.md - Security:
SECURITY.md - Acknowledgements:
ACKNOWLEDMENTS.md - Code of conduct:
CODE_OF_CONDUCT.md
- ReAct: tool-first Reason → Act → Observe loop
- CodeAct: executes Python (tool calls; on prompted-tools models also fenced
```python```blocks) - MemAct (experimental): memory-enhanced agent using runtime-owned Active Memory — distinct architecture, less production mileage; import from
abstractagent.agents.memact(deliberately not top-level) - Durable runs: pause/resume via
run_id+ runtime stores - Tool control: explicit tool bundles + per-run allowlists (unresolvable grant names are recorded loudly, never dropped silently)
- Loop hooks: listen/steer/capture on the running loop via
LoopHooks(seedocs/hooks.md); the flaton_stepcallback remains - Generation controls: temperature, seed, media policy, prompt-cache
identity, streaming, Core
thinkingandspeculation(MTP) are normalized before LLM calls and inherited by delegated children - Scheduled runs (ReAct): the
schedule_runtool schedules work or a reminder for later in the same conversation, with at most the agent's tools (seedocs/tools.md) - Public conversation (ReAct, opt-in): short public updates from the ordinary
continuation, an action-bound explanation for approval requests and timed
clarification questions (see
docs/public-conversation.md) - Observability: durable ledger of LLM calls, tool calls, and waits
Where this lives in code (source of truth):
- Agents:
src/abstractagent/agents/* - Workflows/adapters:
src/abstractagent/adapters/*_runtime.py - Prompting/parsing logic (runtime-agnostic):
src/abstractagent/logic/* - Default tool bundle:
src/abstractagent/tools/__init__.py
- Python
>=3.10(seepyproject.toml)
From source (development):
pip install -e .With dev dependencies:
pip install -e ".[dev]"From PyPI:
pip install abstractagentNative Python hardware profile cascades are available for deployment manifests:
abstractagent[apple] and abstractagent[gpu]. These delegate to the matching
AbstractCore and AbstractRuntime profiles; AbstractAgent itself remains
provider/runtime agnostic.
AbstractAgent 0.5.0 requires abstractcore[tools]>=2.30.0 and
AbstractRuntime>=0.16.0 (the runtime release that carries a public action
explanation into tool approval waits and enforces conversational ask_user
question policies, on top of the SCHEDULE_RUN effect behind the ReAct
schedule_run tool, the 50k-token history window that ReAct applies when a host
sets _runtime.history_window_tokens, live token streaming, turn grounding,
in-flight cancellation and speculation inheritance).
What's new in 0.5.0: opt-in public conversation updates for ReAct, an
action-bound public explanation for approval requests, and timed clarification
questions with a declared fallback. See docs/public-conversation.md
and the changelog.
Note: the repository may be ahead of the latest published PyPI release. To verify what you installed:
python -c "import importlib.metadata as md; print(md.version('abstractagent'))"from abstractagent import create_react_agent
# provider/model resolve from your AbstractCore config defaults
# (`abstractcore --config`) when omitted; pass them explicitly to pin.
agent = create_react_agent(provider="ollama", model="qwen3:4b")
agent.start("List the files in the current directory")
state = agent.run_to_completion()
print(state.output["answer"])Tip: these loops send the full transcript plus ~19 tool schemas every cycle —
prefer a tool-capable model. On Ollama, raise the context window to the model's
maximum available context or the server silently truncates from the oldest
content first: per-call llm_kwargs={"num_ctx": <model max>} or server-side OLLAMA_CONTEXT_LENGTH=<model max> ollama serve.
House rule: maximum available context unless you explicitly choose otherwise —
a fixed lower number is a hidden ceiling (see docs/faq.md).
By default, the factory helpers use an in-memory runtime store. For resume across process restarts,
pass a persistent RunStore/LedgerStore (example below uses JSON files).
from abstractagent import create_react_agent
from abstractruntime.storage.json_files import JsonFileRunStore, JsonlLedgerStore
run_store = JsonFileRunStore(".runs")
ledger_store = JsonlLedgerStore(".runs")
agent = create_react_agent(run_store=run_store, ledger_store=ledger_store)
agent.start("Long running task")
agent.save_state("agent_state.json")
# ... later / after restart ...
agent2 = create_react_agent(run_store=run_store, ledger_store=ledger_store)
agent2.load_state("agent_state.json")
state = agent2.run_to_completion()
print(state.output["answer"])More details: docs/persistence.md
This repository still installs a react-agent entrypoint, but it is deprecated and only prints a migration hint
(see src/abstractagent/repl.py and pyproject.toml).
Interactive UX lives in AbstractCode.
MIT (see LICENSE).