File size: 3,859 Bytes
b99e403
c6421b9
7b3f35e
b99e403
 
 
7b3f35e
b99e403
 
 
 
 
 
21f1bdf
b99e403
0c0b2ef
 
b99e403
21f1bdf
 
7b3f35e
b99e403
 
 
21f1bdf
 
 
 
 
 
 
 
 
b99e403
7b3f35e
21f1bdf
b99e403
7b3f35e
b99e403
 
21f1bdf
0c0b2ef
 
b99e403
 
 
 
0c0b2ef
b99e403
 
 
 
 
 
 
 
 
 
 
21f1bdf
b99e403
21f1bdf
b99e403
 
 
 
0c0b2ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b99e403
 
21f1bdf
b99e403
 
 
21f1bdf
 
 
 
 
 
 
 
b99e403
 
21f1bdf
b99e403
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21f1bdf
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
from app.state.state import EmailAgentState
from app.nodes.triage_node import *
from langgraph.prebuilt import ToolNode ,tools_condition
from app.nodes.archive_node import  archive_node
from app.tools.email_writing_agent_tools import *
from app.nodes.email_writing_node import *
from langgraph.graph import StateGraph,END,START
from app.tools.email_writing_agent_tools import create_gmail_draft, send_draft_by_id
from app.nodes.safety_check_node import *
from app.nodes.parse_node import parse_response_node
from app.nodes.context_node import prepare_context_node
from app.nodes.store_memory_data_node import store_memory_and_data_node
from app.nodes.unsafe_email_node import unsafe_emails_node
from app.nodes.check_email_exist_node import *
from langgraph.types import RetryPolicy
from app.nodes.summarise_email_body_node import summarise_email_body_node
from app.nodes.check_token_count_node import *
from psycopg import OperationalError # Or sqlalchemy.exc.OperationalError depending on your driver
from IPython.display import Image, display


# Define a standard retry policy for database-heavy nodes
db_retry_policy = RetryPolicy(
    retry_on=OperationalError,
    max_attempts=4,
    backoff_factor=1 # Waits 2s, then 4s, then 8s between retries
)

tool_node_retry_policy = RetryPolicy(
    max_attempts=4,
    initial_interval=1.0,
    backoff_factor=2.0,
    jitter=True
)


builder = StateGraph(EmailAgentState)

# Nodes
builder.add_node("safety_check_node", safety_classifier_node)  
builder.add_node("check_previous_email_exist_node", check_previous_email_exist_node)
builder.add_node("check_token_count_node", check_token_count_node)
builder.add_node("summarise_email_body_node", summarise_email_body_node)
builder.add_node("triage_node", triage_node)
builder.add_node("prepare_context_node", prepare_context_node)
builder.add_node("email_writing_agent", email_writing_agent_node)

# --- APPLY RETRY POLICIES HERE ---
builder.add_node(
    "store_memory_and_data_node", 
    store_memory_and_data_node, 
    retry=db_retry_policy
)         
builder.add_node(
    "unsafe_emails_node", 
    unsafe_emails_node, 
    retry=db_retry_policy
)

builder.add_node("archive_node", archive_node,retry=db_retry_policy)   
builder.add_node("parse_node", parse_response_node)
builder.add_node("tools", ToolNode(email_writing_agent_tools), retry_policy=tool_node_retry_policy)

# Edges (Same as your original logic)
builder.add_edge(START, "safety_check_node")

builder.add_conditional_edges(
    "safety_check_node", 
    after_safety, 
    {
        "unsafe": "unsafe_emails_node",
        "safe": "check_token_count_node" 
    }
)

builder.add_conditional_edges(
    "check_token_count_node", 
    check_token_limit_router, 
    {
        "summarize": "summarise_email_body_node",
        "triage": "triage_node" 
    }
)

builder.add_edge("summarise_email_body_node", "triage_node")



builder.add_conditional_edges("triage_node", route_after_triage, {
    "check_previous_email_exist_node": "check_previous_email_exist_node", 
    "archive_node": "archive_node",
})

builder.add_conditional_edges(
    "check_previous_email_exist_node",
    after_mail_check,
    {
        "email_writing_agent": "email_writing_agent", 
        "prepare_context_node": "prepare_context_node" 
    }
)
builder.add_edge("prepare_context_node", "email_writing_agent")


builder.add_conditional_edges(
    "email_writing_agent",
    tools_condition,
    {
        "tools": "tools", 
        END: END
    }
)

builder.add_conditional_edges(
    "tools",
    route_after_tools,
    {
        "parse_node": "parse_node",
        "email_writing_agent": "email_writing_agent"
    }
)

builder.add_edge("parse_node", "store_memory_and_data_node")
builder.add_edge("store_memory_and_data_node", END)
builder.add_edge("unsafe_emails_node", END)
builder.add_edge("archive_node", END)