-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
108 lines (84 loc) · 2.95 KB
/
app.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
import os
import time
import json
import logging
import datetime
from dotenv import load_dotenv
# Flask imports
from flask import Flask, render_template, request, Response, stream_with_context
# LangChain imports
from langchain.agents import tool
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
# Load environment variables from a .env file
# Set up logging in the app.log file
log = logging.getLogger("assistant")
logging.basicConfig(filename="app.log", level=logging.INFO)
# Import and configure OpenAI
from langchain_openai import ChatOpenAI
api_key = "YOUR OPENAI API KEY HERE"
chat_llm = ChatOpenAI(model="gpt-4o-mini")
# Flask app setup
app = Flask(__name__)
# Define MemorySaver instance for langgraph agent
memory = MemorySaver()
# Routes
# Index route
@app.route("/", methods=["GET"])
def index():
return render_template("index.html") # Serve the chat interface
# Stream route
@app.route("/stream", methods=["GET"])
def stream():
graph = create_react_agent(
model=chat_llm,
tools=[],
checkpointer=memory,
debug=True
)
inputs = {"messages": [("user", request.args.get("query", ""))]}
config = {"configurable": {"thread_id": "thread-1"}}
HEARTBEAT_INTERVAL = 5
@stream_with_context
def generate():
stream_iterator = graph.stream(inputs, config, stream_mode="values")
last_sent_time = time.time()
while True:
# Check if we've been idle too long
if time.time() - last_sent_time > HEARTBEAT_INTERVAL:
# Send a heartbeat
yield "data: [heartbeat]\n\n"
last_sent_time = time.time()
try:
step = next(stream_iterator)
except StopIteration:
# No more data from the agent
break
except Exception as e:
# On any exception, report it and stop
yield f"data: Error: {str(e)}\n\n"
return
# We got a new message from the agent
message = step["messages"][-1]
if isinstance(message, tuple):
pass
# yield f"data: {message[1]}\n\n" # Uncomment to allow for user messages to be displayed
else:
if message.response_metadata.get("finish_reason") == "stop":
escaped_message = json.dumps(message.content)
yield f"data: {escaped_message}\n\n"
break
last_sent_time = time.time()
# Final marker
yield "data: [DONE]\n\n"
return Response(
generate(),
content_type="text/event-stream"
)
# Function to add to the log in the app.log file
def log_run(run_status):
if run_status in ["cancelled", "failed", "expired"]:
log.error(str(datetime.datetime.now()) + " Run " + run_status + "\n")
# Run the Flask server
if __name__ == "__main__":
app.run(debug=True)