Observed since 20 Oct, 23:35 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agent-transparency
A comprehensive library for tracking the input, thought process, and output of AI agents
A comprehensive Python library for tracking the input, thought process, and output of AI agents. Provides extreme transparency into agent behavior for debugging, auditing, and understanding agent decisions.
pip install agent-transparency
# Install with UI viewer support
pip install agent-transparency[ui]
# Install with Kafka streaming support
pip install agent-transparency[kafka]
# Install with all optional features
pip install agent-transparency[all]
# Install with development dependencies
pip install agent-transparency[dev]
from transparency import (
TransparencyManager,
create_transparency_manager,
ThinkingPhase,
)
# Create a transparency manager
transparency = create_transparency_manager(
agent_id="my-agent",
file_path="./logs",
)
# Start the manager
await transparency.start()
# Log events
await transparency.log_input_received("User asks: What's the weather?")
await transparency.log_thinking_step(
ThinkingPhase.ANALYSIS,
"Analyzing user request for weather information"
)
await transparency.log_llm_request_start(
model_name="gpt-4",
prompt="Get weather for user location"
)
await transparency.log_output_generated(
"The weather is sunny, 72°F",
target="user"
)
# Stop when done (flushes remaining events)
await transparency.stop()
The library supports comprehensive event tracking across the entire agent lifecycle:
AGENT_STARTUP - Agent initializationAGENT_SHUTDOWN - Agent terminationINPUT_RECEIVED - Raw input receivedINPUT_PARSED - Input parsed and validatedINPUT_VALIDATED - Input validation completeINPUT_REJECTED - Input rejectedTHINKING_START - Begin thinking processTHINKING_STEP - Individual reasoning stepTHINKING_DECISION - Decision madeTHINKING_END - Thinking process completeGRAPH_INVOKE_START - Graph execution startsGRAPH_NODE_ENTER - Entering a nodeGRAPH_NODE_EXIT - Exiting a nodeGRAPH_CONDITIONAL_ROUTE - Conditional routing decisionGRAPH_INVOKE_END - Graph execution completeLLM_REQUEST_START - LLM call initiatedLLM_RESPONSE_RECEIVED - LLM response receivedLLM_ERROR - LLM call failedOUTPUT_GENERATED - Output createdOUTPUT_DISPATCHED - Output sent to targetACTION_PLANNED - Action plannedACTION_DISPATCHED - Action sentACTION_COMPLETED - Action finished successfullyACTION_FAILED - Action failedSTATE_SNAPSHOT - Full state captureSTATE_TRANSITION - State changedERROR_OCCURRED - Error detectedERROR_RECOVERED - Error recoveredERROR_FATAL - Fatal errorfrom transparency import TransparencyManager, LangGraphNodeType
transparency = TransparencyManager(agent_id="langgraph-agent")
await transparency.start()
# Track graph execution
await transparency.log_graph_invoke_start(initial_state={"messages": []})
# Track node execution
await transparency.log_node_enter(
node_name="planner",
node_type=LangGraphNodeType.PLANNER,
state_before=state
)
# Use context manager for automatic entry/exit tracking
async with transparency.trace_node("executor", LangGraphNodeType.EXECUTOR, state):
# Your node logic here
result = await execute_plan()
await transparency.log_graph_invoke_end(final_state=state)
# Manual tracking
await transparency.log_llm_request_start(
model_name="gpt-4",
prompt="Analyze this data",
system_prompt="You are a data analyst"
)
response = await llm.generate(prompt)
await transparency.log_llm_response(
model_name="gpt-4",
prompt="Analyze this data",
response=response.text,
input_tokens=response.usage.input_tokens,
output_tokens=response.usage.output_tokens,
latency_ms=response.latency
)
# Or use context manager
async with transparency.trace_llm_call("gpt-4", prompt) as ctx:
response = await llm.generate(prompt)
ctx["response"] = response.text
# Create a context for tracking related events
context = transparency.create_context(
session_id="session-123",
conversation_id="conv-456"
)
transparency.set_context(context)
# All subsequent events will include this context
await transparency.log_input_received("Hello")
# Or use context manager
async with transparency.context_scope(session_id="session-123"):
await transparency.log_input_received("Hello")
await transparency.log_thinking_step(...)
# Context automatically restored after block
# Track detailed reasoning
await transparency.log_thinking_start("Processing user request")
await transparency.log_thinking_step(
phase=ThinkingPhase.PERCEPTION,
description="Understanding user intent",
reasoning="User is asking about weather conditions"
)
await transparency.log_thinking_step(
phase=ThinkingPhase.PLANNING,
description="Planning data retrieval",
considerations=[
"Need user location",
"Check weather API availability",
"Format response appropriately"
]
)
await transparency.log_thinking_decision(
decision="Fetch weather data from OpenWeatherMap API",
rationale="Most reliable source with current conditions",
alternatives=[
{"option": "Weather.gov", "reason_rejected": "Limited coverage"},
{"option": "AccuWeather", "reason_rejected": "Requires premium API"}
],
confidence=0.95
)
await transparency.log_thinking_end("Request processing complete")
try:
result = await risky_operation()
except Exception as e:
await transparency.log_error(
error_type="APIError",
message=str(e),
exception=e,
context={"operation": "weather_fetch", "retry_count": 3},
recoverable=True
)
from transparency import SyncTransparencyManager
# Wrap async manager for sync contexts (like LangGraph nodes)
async_manager = TransparencyManager(agent_id="sync-agent")
sync_transparency = SyncTransparencyManager(async_manager)
# Use in synchronous functions
def my_langgraph_node(state):
sync_transparency.log_node_enter("my_node", LangGraphNodeType.CUSTOM, state)
# Do work...
sync_transparency.log_node_exit("my_node", LangGraphNodeType.CUSTOM, state, new_state)
return new_state
from transparency import TransparencyConfig, OutputDestination
config = TransparencyConfig(
enabled=True,
destinations=[
OutputDestination.FILE,
OutputDestination.CONSOLE,
OutputDestination.KAFKA
],
# File settings
file_path="./transparency_logs",
# Kafka settings (requires aiokafka)
kafka_topic="agent.transparency",
kafka_broker=kafka_broker_instance,
# Filtering
min_severity=Severity.DEBUG,
event_type_filter=[], # Empty = all events
# Performance
buffer_size=100,
flush_interval_seconds=1.0,
async_mode=True,
# Formatting
pretty_print=True,
include_stack_traces=True
)
transparency = TransparencyManager(agent_id="my-agent", config=config)
Events are logged with severity levels for filtering:
TRACE - Finest-grained debuggingDEBUG - Detailed diagnostic informationINFO - General informational messagesWARNING - Warning messagesERROR - Error eventsCRITICAL - Critical failures# Only log INFO and above
config.min_severity = Severity.INFO
The library includes an optional web-based viewer for monitoring agent activity in real-time.
# Watch a log file
transparency-viewer --log-path ./logs/my-agent_transparency.jsonl
# Or from Kafka
transparency-viewer --kafka-bootstrap localhost:9092 --kafka-topic agent.my-agent.transparency
# Custom port
transparency-viewer --log-path ./logs/my-agent_transparency.jsonl --port 8080
Then open http://localhost:8765 in your browser.
from viewer.viewer_server import TransparencyViewerServer, ServerConfig, SourceType
# File-based viewer
config = ServerConfig(
port=8765,
source_type=SourceType.FILE,
log_path="./logs/agent_transparency.jsonl"
)
server = TransparencyViewerServer(config)
await server.start()
# Keep running
await asyncio.Event().wait()
Events are logged in JSONL format (newline-delimited JSON):
{
"event_type": "thinking.step",
"metadata": {
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": "2024-01-10T15:30:45.123456Z",
"agent_id": "my-agent",
"session_id": "session-123",
"conversation_id": "conv-456",
"sequence_number": 42,
"severity": "debug",
"tags": ["thinking", "analysis"]
},
"payload": {
"phase": "analysis",
"description": "Analyzing user request",
"reasoning": "User wants weather information",
"considerations": ["Location needed", "API selection"],
"confidence_score": 0.95
}
}
start() and stop() to ensure proper buffering and flushingtrace_node(), trace_llm_call(), and context_scope() for automatic trackingmin_severity and event_type_filter in production to reduce overheadasync_mode=True for better performance in high-throughput scenariosbuffer_size based on event volumeaiohttp>=3.8.0aiokafka>=0.8.0MIT License - see LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.
Agent Squad - shine.six.s6@gmail.com
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
buildEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | build>=1.4.0 | runtime |
twineEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | twine>=6.2.0 | runtime |
aiohttpEnvironment{
"extras": "",
"marker": "extra == \"ui\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | aiohttp>=3.8.0; extra == "ui" | runtime |
aiokafkaEnvironment{
"extras": "",
"marker": "extra == \"kafka\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | aiokafka>=0.8.0; extra == "kafka" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.0.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.21.0; extra == "dev" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | black>=23.0.0; extra == "dev" | runtime |
mypyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | mypy>=1.0.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.1.0; extra == "dev" | runtime |
aiohttpEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | aiohttp>=3.8.0; extra == "all" | runtime |
aiokafkaEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.12",
"evaluation": "NOT_EVALUATED"
} | aiokafka>=0.8.0; extra == "all" | runtime |
bdist_wheel · 33.09 KB · Python py3
sdist · 31.56 KB · Python source
Observed since 20 Oct, 23:35 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:ec0da49a6e7fc2a8179ec68039a5b75df4c870b1588eacb30fc53aca5ac548ea