Agent execution history middleware for Autourgos — logs every thought, tool call, and observation to Markdown and JSON files with automatic sensitive-data redaction
Project description
autourgos-history
Agent execution history middleware for the Autourgos framework.
Attach it to any Autourgos agent and every run is automatically recorded: every Thought, every Tool Call, every Observation, and the Final Answer — written to a Markdown file and a structured JSON file.
Sensitive values (API keys, tokens, passwords) are automatically redacted before writing.
Zero required dependencies. Pure Python 3.10+.
Why use this?
When you build agents, you need to know what they did. This middleware gives you a complete, readable audit trail of every agent run without adding any code to your agent logic.
- Debug — see exactly where the agent went wrong
- Audit — keep records of every tool call and its inputs
- Monitor — review agent reasoning in plain English
- Privacy — choose exactly what gets logged with per-field flags
Table of Contents
- Install
- Quick Start
- Output Files
- Privacy Controls
- Custom File Location
- Using with ReactAgent
- Using with Any Agent
- Flushing Logs
- Constructor Reference
- Markdown Output Format
- JSON Output Format
- Redaction Rules
- Thread Safety
Install
pip install autourgos-history
Requires Python 3.10+. No other dependencies.
Quick Start
from autourgos_history import AgentHistoryMiddleware
from autourgos_react_agent import ReactAgent
from autourgos_openaichat import OpenAIChatModel
history = AgentHistoryMiddleware(
include_query=True,
include_tools=True,
include_observations=True,
include_final=True,
)
agent = ReactAgent(
llm=OpenAIChatModel(model="gpt-4o"),
middleware=[history],
)
agent.add_tools(my_tool)
result = agent.invoke("What is the weather in Tokyo?")
print(result)
# The weather in Tokyo is 22°C and sunny.
After the run, two files appear in ./Agent History/:
Agent History/
├── Task_20260616_120000_abc12345.md ← human-readable Markdown
└── Task_20260616_120000_abc12345.json ← structured JSON
Output Files
Markdown file (.md)
Human-readable. Open in any editor or Markdown viewer.
# Task Session: ReactAgent
**Started At:** 2026-06-16 12:00:00
## Initial Query
What is the weather in Tokyo?
---
## Iteration 1
### Thought
I need to call the get_weather tool to find the weather in Tokyo.
### Action (Tools)
**Tool:** `get_weather`
**Parameters:**
```json
{
"city": "Tokyo",
"unit": "celsius"
}
Observations
get_weather: "The weather in Tokyo is 22°C and sunny."
Final Answer
The weather in Tokyo is 22°C and sunny.
### JSON file (`.json`)
Structured. Use for programmatic processing, dashboards, or storage.
```json
{
"query": "What is the weather in Tokyo?",
"agent_name": "ReactAgent",
"start_time": "2026-06-16T12:00:00.123456",
"end_time": "2026-06-16T12:00:02.456789",
"iterations": [
{
"iteration": 1,
"thought": "I need to call the get_weather tool...",
"tools": [
{"tool": "get_weather", "params": {"city": "Tokyo", "unit": "celsius"}}
],
"observations": [
{"tool": "get_weather", "result": "The weather in Tokyo is 22°C and sunny."}
]
}
],
"final_response": "The weather in Tokyo is 22°C and sunny.",
"error": null
}
Privacy Controls
By default, content is redacted — you see the structure but not the values. Enable fields individually:
history = AgentHistoryMiddleware(
include_query=False, # user query → [REDACTED: length=32]
include_tools=True, # tool params → written as JSON
include_observations=True, # tool results → written as JSON
include_final=True, # final answer → written as text
)
| Flag | Default | Controls |
|---|---|---|
include_query |
False |
Whether the user's query is written or replaced with [REDACTED: length=N] |
include_tools |
True |
Whether tool parameters are written or replaced with [REDACTED] |
include_observations |
True |
Whether tool results (observations) are written or replaced with [REDACTED] |
include_final |
True |
Whether the final answer is written or replaced with [REDACTED] |
Even with all flags set to True, automatic redaction still applies to sensitive keys and values. See Redaction Rules.
Custom File Location
Save to a specific folder
history = AgentHistoryMiddleware(folder="/var/log/agents")
# writes: /var/log/agents/Task_20260616_120000_abc12345.md
# /var/log/agents/Task_20260616_120000_abc12345.json
Save with a specific filename
history = AgentHistoryMiddleware(file_path="run_001.md")
# writes: ./run_001.md
# ./run_001.json
Combine folder + filename
history = AgentHistoryMiddleware(
folder="/var/log/agents",
file_path="my_task.md",
)
# writes: /var/log/agents/my_task.md
# /var/log/agents/my_task.json
Default (no arguments)
Files are auto-named and saved to ./Agent History/ in your working directory.
Using with ReactAgent
from autourgos_history import AgentHistoryMiddleware
from autourgos_react_agent import ReactAgent
from autourgos_openaichat import OpenAIChatModel
def search(query: str) -> str:
return f"Search results for: {query}"
search_tool = {
"name": "search",
"description": "Search the web.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search terms"}
},
"required": ["query"],
},
"func": search,
}
history = AgentHistoryMiddleware(
include_query=True,
include_tools=True,
include_observations=True,
include_final=True,
)
agent = ReactAgent(
llm=OpenAIChatModel(model="gpt-4o"),
middleware=[history],
)
agent.add_tools(search_tool)
result = agent.invoke("Find the latest Python release notes.")
print(result)
# history.flush() — optional, ensures files are fully written before process exits
Using with Any Agent
AgentHistoryMiddleware is a CallbackHandler. Any agent that accepts middleware / callback handlers will work.
Add it at construction time:
agent = MyAgent(llm=llm, middleware=[AgentHistoryMiddleware()])
Or after construction:
agent.add_middleware(AgentHistoryMiddleware())
The middleware listens for these lifecycle events fired by the agent:
| Event | When it fires |
|---|---|
on_agent_start |
Agent receives a new query |
on_iteration_start |
New Thought → Action → Observe cycle begins |
on_llm_end |
LLM returns its raw response |
on_tool_start |
Tool is about to be called |
on_tool_end |
Tool returned a result |
on_tool_error |
Tool raised an exception |
on_agent_end |
Agent produced a final answer |
on_agent_error |
Agent raised an unhandled exception |
Flushing Logs
File I/O is async (dispatched to a background thread). If your process might exit immediately after invoke(), call flush() to wait for all writes to complete:
result = agent.invoke("My task")
history.flush() # wait for files to finish writing
This is rarely needed in long-running applications but important in scripts and tests.
Constructor Reference
| Parameter | Type | Default | Description |
|---|---|---|---|
file_path |
str |
None |
Exact path for the Markdown file. JSON file uses the same name with .json extension |
folder |
str |
None |
Directory for auto-named files. Defaults to ./Agent History/ |
include_query |
bool |
False |
Write the user's query to the log |
include_tools |
bool |
True |
Write tool parameters to the log |
include_observations |
bool |
True |
Write tool results (observations) to the log |
include_final |
bool |
True |
Write the final answer to the log |
Markdown Output Format
# Task Session: <AgentName>
**Started At:** YYYY-MM-DD HH:MM:SS
## Initial Query
<query or [REDACTED: length=N]>
---
## Iteration 1
### Thought
<LLM reasoning>
### Action (Tools)
**Tool:** `tool_name`
**Parameters:**
```json
{ ... }
Observations
tool_name: <result or [REDACTED]>
Final Answer
<answer or [REDACTED]>
---
## JSON Output Format
```json
{
"query": "string | null",
"agent_name": "string",
"start_time": "ISO 8601 datetime",
"end_time": "ISO 8601 datetime",
"iterations": [
{
"iteration": 1,
"thought": "string | null",
"tools": [
{"tool": "tool_name", "params": { ... }}
],
"observations": [
{"tool": "tool_name", "result": "string"}
]
}
],
"final_response": "string | null",
"error": "string | null"
}
Redaction Rules
Applied automatically before any write, regardless of include_* flags.
By key name
Keys matching this pattern (case-insensitive) have their value replaced with [REDACTED]:
api_key, api-key, token, secret, password,
authorization, cookie, session, credential
Example:
{"api_key": "sk-abc123"} → {"api_key": "[REDACTED]"}
By value shape
Values that look like secrets are replaced regardless of key name:
| Pattern | Example |
|---|---|
sk-... |
OpenAI API keys |
AKIA... |
AWS access keys |
Bearer ... |
HTTP authorization headers |
ghp_... |
GitHub personal access tokens |
ya29.... |
Google OAuth tokens |
By length
String values longer than 512 characters are truncated:
"very long text..." → "first 512 chars... [TRUNCATED]"
Thread Safety
Each concurrent agent call gets its own thread-local state — query, iteration data, file paths, and the logger are all isolated per thread. Multiple agents can run concurrently with the same AgentHistoryMiddleware instance and their logs will never mix.
All disk writes are dispatched to a single-worker background executor per middleware instance, keeping agent execution fast and preventing file corruption from concurrent writes.
License
MIT — Copyright (c) 2026 Jitin Kumar Sengar
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file autourgos_history-1.0.0.tar.gz.
File metadata
- Download URL: autourgos_history-1.0.0.tar.gz
- Upload date:
- Size: 16.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf42bb343580fd751bfabb69509a170b8c19804dc37e8e6c164f56d9df69c019
|
|
| MD5 |
16df7b57a16173de73b3a451bedac4e6
|
|
| BLAKE2b-256 |
e60f32f747e38055f72099a99b5ed0278efcdc49c6b1fdc86c51129e48b1a9cc
|
File details
Details for the file autourgos_history-1.0.0-py3-none-any.whl.
File metadata
- Download URL: autourgos_history-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e93d859cb46937a005db689427f6f2b417445604c9f4f4a70cfa8e1bdcf171be
|
|
| MD5 |
f73658591e9ee010db4c897db80571d5
|
|
| BLAKE2b-256 |
3dd768e42772fd28497b273d99080dcbb16ee1f09674f469a5b3c8c8bfa88af3
|