Skip to main content
Archived

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

autourgos-history

Framework: Autourgos Python License: Apache 2.0 Author Contributor Contributor

Agent execution history middleware for the Autourgos framework. Attach it to any 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.

from autourgos_history import AgentHistoryMiddleware
from autourgos_agent import Agent
from autourgos_openaichat import OpenAIChatModel

history = AgentHistoryMiddleware(include_query=True, include_tools=True, include_observations=True, include_final=True)
agent = Agent(llm=OpenAIChatModel(model="gpt-4o"), middleware=[history])

Features

  • Dual output: human-readable Markdown + structured JSON, one pair per run
  • Automatic redaction — by key name (api_key, token, secret, password/pwd/pass, auth, private_key, access_key, client_secret, ...), by value shape (sk-..., AKIA..., Bearer ..., ghp_..., ya29...., Slack xox[baprs]-... tokens, JWTs), and by length (>512 chars truncated)
  • Per-field privacy flags — choose exactly what gets written (include_query, include_tools, include_observations, include_final)
  • Concurrency-safe — per-run state isolated via contextvars.ContextVar, correct for both concurrent threads (invoke()) and concurrent asyncio tasks sharing one thread (ainvoke()); disk writes on a single-worker background executor
  • Works with any agent — it's a CallbackHandler, not autourgos-agent-specific
  • Zero required dependencies, pure Python 3.10+

Table of Contents


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 where the agent went wrong, audit every tool call, monitor reasoning in plain English, and control privacy with per-field flags.


Install

pip install autourgos-history

Requires Python 3.10+. No other dependencies.


Quick Start

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

With Agent(verbose=True), one line announcing the file path prints once per run:

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

Output Files

Markdown (.md)

# 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 (`.json`)

```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": "...", "tools": [{"tool": "get_weather", "params": {"city": "Tokyo"}}],
     "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 True, automatic redaction still applies to sensitive keys and values — see Redaction Rules.


Custom File Location

history = AgentHistoryMiddleware(folder="/var/log/agents")
# writes: /var/log/agents/Task_20260616_120000_abc12345.{md,json}

history = AgentHistoryMiddleware(file_path="run_001.md")
# writes: ./run_001.{md,json}

history = AgentHistoryMiddleware(folder="/var/log/agents", file_path="my_task.md")
# writes: /var/log/agents/my_task.{md,json}

Default (no arguments): auto-named files saved to ./Agent History/.


Using With Any Agent

AgentHistoryMiddleware is a CallbackHandler. Any agent that accepts middleware / callback handlers works.

agent = MyAgent(llm=llm, middleware=[AgentHistoryMiddleware()])
# or after construction:
agent.add_middleware(AgentHistoryMiddleware())

Listened events: on_agent_start, on_iteration_start, on_llm_end, on_tool_start, on_tool_end, on_tool_error, on_agent_end, on_agent_error.


Flushing Logs

File I/O is async (dispatched to a background thread). If your process might exit immediately after invoke(), call flush():

result = agent.invoke("My task")
history.flush()  # wait for files to finish writing

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

Redaction Rules

Applied automatically before any write, regardless of include_* flags.

By key name (case-insensitive): api_key, api-key, token, secret, password, pwd, pass, authorization, auth, cookie, session, credential, private_key, access_key, client_secret → value replaced with [REDACTED].

By value shape: OpenAI keys (sk-...), AWS keys (AKIA...), HTTP auth headers (Bearer ...), GitHub tokens (ghp_...), Google OAuth tokens (ya29....), Slack tokens (xox[baprs]-...), JWTs (eyJ...........).

By length: string values longer than 512 characters are truncated ("...[TRUNCATED]").

This is a best-effort, pattern-based scheme — a secret that matches neither a known key name nor a known value shape (e.g. a bare high-entropy string under an unrecognized key) will not be caught. Treat it as one layer of defense-in-depth, not a guarantee.


Thread Safety

Each concurrent agent call gets its own isolated per-run state — query, iteration data, file paths, and the logger — via contextvars.ContextVar rather than threading.local(). This isolates correctly both across OS threads (concurrent invoke() calls) and across concurrent asyncio tasks sharing one thread (concurrent ainvoke() calls); threading.local() alone only handles the former, so two interleaved ainvoke() runs on the same event-loop thread would otherwise clobber each other's state. 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.


License

Apache License 2.0, Copyright (c) 2026 Jitin Kumar Sengar

Metadata

Release files for autourgos-history 2.2.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.2.4
File Size Uploaded
autourgos_history-2.2.4.tar.gz 30.4 kB Details

Built distribution (wheel)

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

Total release size: 52.4 kB

Release files / autourgos_history-2.2.4.tar.gz

Download URL autourgos_history-2.2.4.tar.gz
Size 30.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8baeefa0daf72aa20cba9350f45e2e31aeaaf99d506d60738cea401ca26cc42f
BLAKE2b-256 checksum
How to use checksums
2b5495c451df0468bd5a66247fb34d7ea4da737d024771be9a16047a79f95e17
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.2.4-py3-none-any.whl

Download URL autourgos_history-2.2.4-py3-none-any.whl
Size 22.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ad6b9a2e0d29beb083173fcaf825fca6798fa17d5e438f0b7ee561c593e62e3
BLAKE2b-256 checksum
How to use checksums
68d6282a12b9b6d5705d182281702f5fd28c5bcd16df7070f5bb22e439e765fe
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