11import atexit
22import os
3+ import re
4+ from datetime import datetime
35from functools import lru_cache
46from typing import List , Optional
57
@@ -68,9 +70,7 @@ def get_agent():
6870 return _agent_executor
6971
7072
71- def chat_with_agent (
72- message : str , user_id : str = "default" , selected_images : Optional [List [dict ]] = None
73- ) -> str :
73+ def chat_with_agent (message : str , user_id : str = "default" , selected_images : Optional [List [dict ]] = None ) -> tuple [str , Optional [dict ]]:
7474 """
7575 Send a message to the agent and get a response.
7676
@@ -80,7 +80,7 @@ def chat_with_agent(
8080 selected_images: List of selected image objects (optional)
8181
8282 Returns:
83- The agent's response as a string
83+ Tuple of (agent_response, generated_image_data)
8484 """
8585 agent = get_agent ()
8686
@@ -89,9 +89,7 @@ def chat_with_agent(
8989 if selected_images and len (selected_images ) > 0 :
9090 image_context = "\n \n Selected Images:\n "
9191 for i , img in enumerate (selected_images , 1 ):
92- image_context += (
93- f"{ i } . { img .get ('title' , 'Untitled' )} (ID: { img .get ('id' , 'unknown' )} )\n "
94- )
92+ image_context += f"{ i } . { img .get ('title' , 'Untitled' )} (ID: { img .get ('id' , 'unknown' )} )\n "
9593 image_context += f" Type: { img .get ('type' , 'unknown' )} \n "
9694 image_context += f" Description: { img .get ('description' , 'No description' )} \n "
9795 if img .get ("url" ):
@@ -103,20 +101,86 @@ def chat_with_agent(
103101 config = {"configurable" : {"thread_id" : user_id }}
104102
105103 # Get response from agent
106- response = agent .invoke (
107- {"messages" : [{"role" : "user" , "content" : full_message }]}, config = config
108- )
104+ response = agent .invoke ({"messages" : [{"role" : "user" , "content" : full_message }]}, config = config )
109105
110106 # Extract the last message from the agent
107+ agent_response = "I'm sorry, I couldn't process your request. Please try again."
108+ generated_image_data = None
109+
111110 if response and "messages" in response and len (response ["messages" ]) > 0 :
112111 last_message = response ["messages" ][- 1 ]
113112 # Handle both AIMessage objects and dictionaries
114113 if hasattr (last_message , "content" ):
115- return last_message .content
114+ agent_response = last_message .content
116115 elif isinstance (last_message , dict ) and "content" in last_message :
117- return last_message ["content" ]
118-
119- return "I'm sorry, I couldn't process your request. Please try again."
116+ agent_response = last_message ["content" ]
117+
118+ # Check if any tools were used (image generation)
119+ if "intermediate_steps" in response and response ["intermediate_steps" ]:
120+ for step in response ["intermediate_steps" ]:
121+ if len (step ) >= 2 and "generate_image" in str (step [0 ]):
122+ # Extract image data from the tool result
123+ tool_result = step [1 ]
124+ if "Image ID:" in tool_result :
125+ # Parse the image ID and title from the response
126+ image_id_match = re .search (r"Image ID: ([a-f0-9-]+)" , tool_result )
127+ title_match = re .search (r"Title: (.+?)(?:\n|$)" , tool_result )
128+
129+ if image_id_match :
130+ image_id = image_id_match .group (1 )
131+ title = title_match .group (1 ) if title_match else "Generated Image"
132+
133+ # Get metadata from S3
134+ import boto3
135+
136+ s3_client = boto3 .client (
137+ "s3" ,
138+ region_name = os .environ .get ("AWS_REGION" , "us-east-1" ),
139+ aws_access_key_id = os .environ .get ("AWS_ACCESS_KEY_ID" ),
140+ aws_secret_access_key = os .environ .get ("AWS_SECRET_ACCESS_KEY" ),
141+ )
142+
143+ bucket_name = os .environ .get ("AWS_S3_BUCKET_NAME" )
144+ if bucket_name :
145+ try :
146+ # Get metadata from S3
147+ metadata_response = s3_client .head_object (Bucket = bucket_name , Key = f"users/{ user_id } /images/{ image_id } " )
148+ metadata = metadata_response .get ("Metadata" , {})
149+
150+ # Generate presigned URL
151+ presigned_url = s3_client .generate_presigned_url (
152+ "get_object" ,
153+ Params = {
154+ "Bucket" : bucket_name ,
155+ "Key" : f"users/{ user_id } /images/{ image_id } " ,
156+ },
157+ ExpiresIn = 7200 , # 2 hours
158+ )
159+
160+ generated_image_data = {
161+ "id" : image_id ,
162+ "url" : presigned_url ,
163+ "title" : metadata .get ("title" , title ),
164+ "description" : f"AI-generated image: { metadata .get ('generationPrompt' , 'Based on your request' )} " ,
165+ "timestamp" : metadata .get ("uploadedAt" , datetime .now ().isoformat ()),
166+ "type" : "generated" ,
167+ }
168+ except Exception as e :
169+ print (f"Error getting S3 metadata: { e } " )
170+ # Fallback to basic data
171+ generated_image_data = {
172+ "id" : image_id ,
173+ "url" : "" , # Will be empty if we can't generate URL
174+ "title" : title ,
175+ "description" : "AI-generated image" ,
176+ "timestamp" : datetime .now ().isoformat (),
177+ "type" : "generated" ,
178+ }
179+ # Add error message to agent response
180+ agent_response += "\n \n ⚠️ Note: I generated the image successfully,\
181+ but there was an issue retrieving it from the database."
182+
183+ return agent_response , generated_image_data
120184
121185
122186if __name__ == "__main__" :
0 commit comments