Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

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

pip install autourgos-history

Requires Python 3.10+. No other dependencies.


Quick Start

This example constructs an OpenAIChatModel, so set the OPENAI_API_KEY environment variable first (or pass api_key= directly).

from autourgos_history     import AgentHistoryMiddleware
from autourgos_react_agent import ReactAgent
from autourgos_openaichat  import OpenAIChatModel

def my_tool(city: str) -> str:
    """Look up the weather for a city."""
    return f"The weather in {city} is 22C and sunny."

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

If agent is a ReactAgent(verbose=True) (requires autourgos-react-agent>=1.5.0), one line announcing the file path is printed once per run, at the start, into the same verbose trace — nothing is printed per-iteration:

[History] Logging this run to ./Agent History/Task_20260616_120000_abc12345.md

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

Metadata

Release files for autourgos-history 2.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for autourgos-history 2.1.3
File Size Uploaded
autourgos_history-2.1.3.tar.gz 18.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for autourgos-history 2.1.3
File Interpreter ABI Platform
autourgos_history-2.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 32.4 kB

Release files / autourgos_history-2.1.3.tar.gz

Download URL autourgos_history-2.1.3.tar.gz
Size 18.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b769fdb1b09c91053da520b73aa660f474d9020fabab2c085d7775e727aa037b
BLAKE2b-256 checksum
How to use checksums
3f779e1e870776eeb937555303fa75ff91814fb4e06339aa13c22501eaadd1fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.9

Release files / autourgos_history-2.1.3-py3-none-any.whl

Download URL autourgos_history-2.1.3-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e3f5aac275a766be2cee26fede9defe3c25f22766f6cb38575ec514aab1da63
BLAKE2b-256 checksum
How to use checksums
9502ee3a3f53fea448eb16106817564e8f8b70405b1d5ae375bbcb7a8a2f505e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.9
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page