Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions AGENTOPS_FIX_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# AgentOps Usage Fix

## The Problem

You encountered this error:
```
AttributeError: 'str' object has no attribute '__enter__'. Did you mean: '__iter__'?
```

This error occurs when you try to use `agentops.trace()` as a context manager:

```python
# ❌ INCORRECT - This causes the error
with agentops.trace("debug_test"):
print("This will fail!")
```

## The Root Cause

The issue is that `agentops.trace()` is a **decorator**, not a context manager. Decorators are used to wrap functions, not to create context managers.

## The Solution

Use `agentops.start_trace()` for context manager usage:

```python
# ✅ CORRECT - Use start_trace for context manager
with agentops.start_trace("debug_test") as trace:
print("This works correctly!")
# Your code here
# Trace automatically ends when exiting the context
```

## Complete Usage Guide

### 1. Context Manager Usage (for code blocks)
```python
import agentops

# Initialize AgentOps
agentops.init()

# Use as context manager
with agentops.start_trace("my_operation") as trace:
print("Working on my operation")
result = perform_some_work()
# Trace automatically ends here
```

### 2. Decorator Usage (for functions)
```python
import agentops
from agentops import trace

@trace("my_function")
def my_function():
print("This function is being traced")
return "result"

# Call the function
result = my_function()
```

### 3. Manual Trace Management
```python
import agentops
from agentops import start_trace, end_trace

# Start trace manually
trace_context = start_trace("manual_trace")

try:
print("Working on manual trace")
# Your code here
finally:
# End trace manually
end_trace(trace_context, "Success")
```

### 4. With Tags and Parameters
```python
# Context manager with tags
with agentops.start_trace("tagged_trace", tags=["production", "v1.0"]) as trace:
print("Working with tags")

# Decorator with parameters
@agentops.trace(name="complex_operation", tags=["complex", "calculation"])
def complex_function():
return "complex result"
```

## Key Differences

| Usage | Function | Purpose | Example |
|-------|----------|---------|---------|
| Context Manager | `agentops.start_trace()` | Wrap code blocks | `with start_trace("name"):` |
| Decorator | `agentops.trace()` | Wrap functions | `@trace("name")` |

## Common Patterns

### Nested Traces
```python
with agentops.start_trace("outer") as outer:
with agentops.start_trace("inner") as inner:
print("Nested tracing")
```

### Error Handling
```python
try:
with agentops.start_trace("error_example") as trace:
# This might fail
raise ValueError("Test error")
except ValueError:
# Trace automatically ends with error state
pass
```

### Multiple Concurrent Traces
```python
trace1 = agentops.start_trace("trace1")
trace2 = agentops.start_trace("trace2")

try:
# Work on both traces
pass
finally:
agentops.end_trace(trace1)
agentops.end_trace(trace2)
```

## Files in This Repository

- `main.py` - Basic example showing correct usage
- `agentops_usage_examples.py` - Comprehensive examples of all usage patterns
- `AGENTOPS_FIX_README.md` - This documentation

## Quick Fix for Your Code

Replace this:
```python
with agentops.trace("debug_test"):
# your code
```

With this:
```python
with agentops.start_trace("debug_test") as trace:
# your code
```

That's it! The trace will automatically end when you exit the context block.
130 changes: 130 additions & 0 deletions agentops_usage_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"""
AgentOps Usage Examples

This file demonstrates the correct ways to use AgentOps for tracing and monitoring.
The error you encountered was due to trying to use agentops.trace() as a context manager,
when it's actually a decorator. Use agentops.start_trace() for context manager usage.
"""

import agentops
from agentops import start_trace, end_trace, trace

# 1. Initialize AgentOps
agentops.init(
api_key="your_api_key_here", # or set AGENTOPS_API_KEY environment variable
trace_name="my_application",
default_tags=["production", "v1.0"]
)

# 2. CORRECT: Using start_trace as a context manager
print("=== Context Manager Usage ===")
with start_trace("debug_test") as trace_context:
print(f"Active trace: {trace_context}")
print("This is the correct way to use AgentOps as a context manager")

# Your application code here
result = "some operation result"

# The trace automatically ends when exiting the context
# No need to manually call end_trace()

# 3. CORRECT: Manual trace management
print("\n=== Manual Trace Management ===")
trace_context = start_trace("manual_trace", tags=["manual", "example"])
try:
print("Manual trace management example")
# Your application code here
result = "manual operation result"
finally:
end_trace(trace_context, "Success")

# 4. CORRECT: Using @trace decorator for functions
print("\n=== Decorator Usage ===")
@trace("function_trace")
def my_function(param1, param2):
print(f"Function called with {param1} and {param2}")
return param1 + param2

# Call the decorated function
result = my_function(10, 20)
print(f"Function result: {result}")

# 5. CORRECT: Using @trace decorator with parameters
print("\n=== Decorator with Parameters ===")
@trace(name="complex_operation", tags=["complex", "calculation"])
def complex_calculation(x, y):
print(f"Performing complex calculation with {x} and {y}")
return x * y + 100

result = complex_calculation(5, 10)
print(f"Complex calculation result: {result}")

# 6. CORRECT: Nested traces
print("\n=== Nested Traces ===")
with start_trace("outer_trace") as outer:
print("Outer trace started")

with start_trace("inner_trace") as inner:
print("Inner trace started")
# Inner trace code
print("Inner trace completed")

print("Outer trace completed")

# 7. CORRECT: Async function with decorator
print("\n=== Async Function with Decorator ===")
import asyncio

@trace("async_operation")
async def async_operation():
print("Async operation started")
await asyncio.sleep(0.1) # Simulate async work
print("Async operation completed")
return "async result"

# Run async function
async def main():
result = await async_operation()
print(f"Async result: {result}")

# Uncomment to run async example
# asyncio.run(main())

# 8. CORRECT: Error handling with traces
print("\n=== Error Handling ===")
try:
with start_trace("error_handling_example") as trace:
print("Starting operation that might fail")
# Simulate an error
raise ValueError("This is a test error")
except ValueError as e:
print(f"Caught error: {e}")
# The trace will automatically end with error state

# 9. CORRECT: Multiple concurrent traces
print("\n=== Multiple Concurrent Traces ===")
trace1 = start_trace("concurrent_trace_1", tags=["concurrent"])
trace2 = start_trace("concurrent_trace_2", tags=["concurrent"])

try:
print("Working on trace 1")
# Work for trace 1

print("Working on trace 2")
# Work for trace 2

finally:
end_trace(trace1, "Success")
end_trace(trace2, "Success")

print("\n=== All examples completed successfully! ===")

# 10. INCORRECT USAGE (what caused your error):
"""
# DON'T DO THIS - This will cause AttributeError:
with agentops.trace("debug_test"):
print("This will fail!")

# The error occurs because agentops.trace() returns a decorator function,
# not a context manager. Decorator functions don't have __enter__ and __exit__ methods.
"""
35 changes: 35 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import agentops

# Initialize AgentOps (if not already done)
agentops.init()

# INCORRECT USAGE (causes the error):
# with agentops.trace("debug_test"):
# print("This will cause an AttributeError")

# CORRECT USAGE - using start_trace as a context manager:
with agentops.start_trace("debug_test") as trace:
print("This is the correct way to use AgentOps as a context manager")
print(f"Trace context: {trace}")

# Your code here
result = "some operation"

# The trace will automatically end when exiting the context

# Alternative: Manual start/end
trace_context = agentops.start_trace("manual_trace")
try:
print("Manual trace management")
# Your code here
finally:
agentops.end_trace(trace_context)

# Using the @trace decorator (for functions):
@agentops.trace("function_trace")
def my_function():
print("This function is decorated with @agentops.trace")
return "function result"

# Call the decorated function
result = my_function()
Loading