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_agent       import Agent
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 = Agent(
    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 an Agent(verbose=True) (requires autourgos-agent), 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: Agent
**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": "Agent",
  "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 Agent

from autourgos_history     import AgentHistoryMiddleware
from autourgos_agent       import Agent
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 = Agent(
    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.4

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.4
File Size Uploaded
autourgos_history-2.1.4.tar.gz 18.5 kB Details

Built distribution (wheel)

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

Total release size: 32.3 kB

Release files / autourgos_history-2.1.4.tar.gz

Download URL autourgos_history-2.1.4.tar.gz
Size 18.5 kB
Tags Source
SHA-256 checksum
How to use checksums
b08edc920c7e45b60868ccbf3379510c82b53fd9343920c2d96fe0076266ebb6
BLAKE2b-256 checksum
How to use checksums
875f293345042da937b0e3711c2e93aa532f92b6e7fbd9082b67961e52eaad2b
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.4-py3-none-any.whl

Download URL autourgos_history-2.1.4-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3db37d8e01752e48f03fcc13e078a0a3949ba888957e02d4b4e17b746e6772c9
BLAKE2b-256 checksum
How to use checksums
69afe76c692b79cd7d33b7e1ada4bc1d5187f5f4c1077fe92bdaff18c3b2a0d9
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