forked from julep-ai/julep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
13-Error_Handling_and_Recovery.py
163 lines (142 loc) · 4.45 KB
/
13-Error_Handling_and_Recovery.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Error Handling and Recovery Cookbook
#
# Plan:
# 1. Import necessary libraries and set up the Julep client
# 2. Create an agent for error handling demonstration
# 3. Define a task with potential errors and recovery mechanisms
# 4. Execute the task and demonstrate error handling
# 5. Implement a retry mechanism for failed steps
# 6. Show how to log and report errors
# 7. Demonstrate graceful degradation when a step fails
import uuid
import yaml
import time
from julep import Client
# Global UUID is generated for agent and task
AGENT_UUID = uuid.uuid4()
TASK_UUID = uuid.uuid4()
# Creating Julep Client with the API Key
api_key = "" # Your API key here
client = Client(api_key=api_key, environment="dev")
# Creating an agent for error handling demonstration
agent = client.agents.create_or_update(
agent_id=AGENT_UUID,
name="Error Handler",
about="An AI agent specialized in demonstrating error handling and recovery mechanisms.",
model="gpt-4-turbo",
)
# Defining a task with potential errors and recovery mechanisms
task_def = yaml.safe_load("""
name: Error Handling Demo
input_schema:
type: object
properties:
operation:
type: string
enum: ["divide", "api_call", "process_data"]
value:
type: number
tools:
- name: divide
type: function
function:
name: divide
description: Divide 100 by the given number
parameters:
type: object
properties:
divisor:
type: number
- name: api_call
type: integration
integration:
provider: httpbin
method: get
- name: process_data
type: function
function:
name: process_data
description: Process the given data
parameters:
type: object
properties:
data:
type: string
main:
- switch:
value: inputs[0].operation
cases:
divide:
- tool: divide
arguments:
divisor: inputs[0].value
on_error:
retry:
max_attempts: 3
delay: 2
fallback:
return: "Error: Division by zero or invalid input"
api_call:
- tool: api_call
arguments:
endpoint: "/status/{{inputs[0].value}}"
on_error:
retry:
max_attempts: 3
delay: 5
fallback:
return: "Error: API call failed after multiple attempts"
process_data:
- evaluate:
data: "'Sample data: ' + str(inputs[0].value)"
- tool: process_data
arguments:
data: _.data
on_error:
log: "Error occurred while processing data"
return: "Error: Data processing failed"
- prompt:
role: system
content: >-
Summarize the result of the operation:
Operation: {{inputs[0].operation}}
Result: {{_}}
""")
# Creating the task
task = client.tasks.create_or_update(
task_id=TASK_UUID,
agent_id=AGENT_UUID,
**task_def
)
# Function to execute task and handle errors
def execute_task_with_error_handling(operation, value):
try:
execution = client.executions.create(
task_id=TASK_UUID,
input={"operation": operation, "value": value}
)
print(f"Executing {operation} with value {value}...")
# Stream execution to show progress and potential retries
for step in client.executions.transitions.stream(execution_id=execution.id):
if step.type == "tool_call":
print(f"Step: {step.tool}")
if step.status == "error":
print(f"Error occurred: {step.error}")
if step.retry:
print(f"Retrying... (Attempt {step.retry.attempt})")
elif step.type == "error":
print(f"Task error: {step.error}")
# Get final execution result
result = client.executions.get(execution.id)
print(f"Final result: {result.output}")
except Exception as e:
print(f"An unexpected error occurred: {str(e)}")
# Demonstrate error handling for different scenarios
print("1. Division by zero (with retry and fallback):")
execute_task_with_error_handling("divide", 0)
print("\n2. API call with server error (with retry):")
execute_task_with_error_handling("api_call", 500)
print("\n3. Data processing error (with logging):")
execute_task_with_error_handling("process_data", "invalid_data")
print("\n4. Successful operation:")
execute_task_with_error_handling("divide", 4)