atolat30 commited on
Commit
edf16da
·
1 Parent(s): e56bc79

Add comprehensive logging to the application

Browse files
Files changed (3) hide show
  1. app.py +35 -16
  2. logger_config.py +38 -0
  3. prompt_manager.py +10 -0
app.py CHANGED
@@ -8,8 +8,10 @@ from chainlit.prompt import Prompt, PromptMessage # importing prompt tools
8
  from chainlit.playground.providers import ChatOpenAI # importing ChatOpenAI tools
9
  from dotenv import load_dotenv
10
  from prompt_manager import PromptManager
 
11
 
12
  load_dotenv()
 
13
 
14
  # Initialize prompt manager
15
  prompt_manager = PromptManager()
@@ -128,6 +130,7 @@ USER_TEMPLATES = {
128
 
129
  @cl.on_chat_start
130
  async def start_chat():
 
131
  # Create aspect selection buttons with descriptions
132
  aspects = prompt_manager.get_aspect_names()
133
  actions = []
@@ -147,6 +150,7 @@ async def start_chat():
147
  content="Welcome! Please select an aspect for our conversation. Hover over each option to see examples and descriptions:",
148
  actions=actions
149
  ).send()
 
150
 
151
  @cl.action_callback("Concept Simplification")
152
  @cl.action_callback("Summarization")
@@ -157,16 +161,20 @@ async def start_chat():
157
  async def on_action(action):
158
  # Store the selected aspect in the user session
159
  cl.user_session.set("selected_aspect", action.value)
 
160
 
161
  # Send confirmation message with examples
162
  await cl.Message(
163
  content=prompt_manager.get_confirmation_message(action.value)
164
  ).send()
 
165
 
166
  @cl.on_message
167
  async def main(message: cl.Message):
168
  # Get the selected aspect from the session
169
  selected_aspect = cl.user_session.get("selected_aspect")
 
 
170
 
171
  settings = {
172
  "model": "gpt-4-turbo-preview", # Upgraded to GPT-4 Turbo
@@ -176,11 +184,13 @@ async def main(message: cl.Message):
176
  "frequency_penalty": 0.3, # Added to reduce repetition
177
  "presence_penalty": 0.3, # Added to encourage diverse topics
178
  }
 
179
 
180
  client = AsyncOpenAI()
181
 
182
  # Get the appropriate templates for the selected aspect
183
  system_template, user_template = prompt_manager.get_templates(selected_aspect)
 
184
 
185
  prompt = Prompt(
186
  provider=ChatOpenAI.id,
@@ -199,21 +209,30 @@ async def main(message: cl.Message):
199
  inputs={"input": message.content},
200
  settings=settings,
201
  )
 
202
 
203
  msg = cl.Message(content="")
204
-
205
- # Call OpenAI
206
- async for stream_resp in await client.chat.completions.create(
207
- messages=[m.to_openai() for m in prompt.messages], stream=True, **settings
208
- ):
209
- token = stream_resp.choices[0].delta.content
210
- if not token:
211
- token = ""
212
- await msg.stream_token(token)
213
-
214
- # Update the prompt object with the completion
215
- prompt.completion = msg.content
216
- msg.prompt = prompt
217
-
218
- # Send and close the message stream
219
- await msg.send()
 
 
 
 
 
 
 
 
 
8
  from chainlit.playground.providers import ChatOpenAI # importing ChatOpenAI tools
9
  from dotenv import load_dotenv
10
  from prompt_manager import PromptManager
11
+ from logger_config import logger
12
 
13
  load_dotenv()
14
+ logger.info("Environment variables loaded")
15
 
16
  # Initialize prompt manager
17
  prompt_manager = PromptManager()
 
130
 
131
  @cl.on_chat_start
132
  async def start_chat():
133
+ logger.info("Starting new chat session")
134
  # Create aspect selection buttons with descriptions
135
  aspects = prompt_manager.get_aspect_names()
136
  actions = []
 
150
  content="Welcome! Please select an aspect for our conversation. Hover over each option to see examples and descriptions:",
151
  actions=actions
152
  ).send()
153
+ logger.info("Welcome message sent with aspect selection buttons")
154
 
155
  @cl.action_callback("Concept Simplification")
156
  @cl.action_callback("Summarization")
 
161
  async def on_action(action):
162
  # Store the selected aspect in the user session
163
  cl.user_session.set("selected_aspect", action.value)
164
+ logger.info(f"User selected aspect: {action.value}")
165
 
166
  # Send confirmation message with examples
167
  await cl.Message(
168
  content=prompt_manager.get_confirmation_message(action.value)
169
  ).send()
170
+ logger.debug(f"Confirmation message sent for aspect: {action.value}")
171
 
172
  @cl.on_message
173
  async def main(message: cl.Message):
174
  # Get the selected aspect from the session
175
  selected_aspect = cl.user_session.get("selected_aspect")
176
+ logger.info(f"Processing message with aspect: {selected_aspect}")
177
+ logger.debug(f"User message: {message.content}")
178
 
179
  settings = {
180
  "model": "gpt-4-turbo-preview", # Upgraded to GPT-4 Turbo
 
184
  "frequency_penalty": 0.3, # Added to reduce repetition
185
  "presence_penalty": 0.3, # Added to encourage diverse topics
186
  }
187
+ logger.debug(f"OpenAI settings: {settings}")
188
 
189
  client = AsyncOpenAI()
190
 
191
  # Get the appropriate templates for the selected aspect
192
  system_template, user_template = prompt_manager.get_templates(selected_aspect)
193
+ logger.debug("Templates retrieved for message processing")
194
 
195
  prompt = Prompt(
196
  provider=ChatOpenAI.id,
 
209
  inputs={"input": message.content},
210
  settings=settings,
211
  )
212
+ logger.debug("Prompt created for OpenAI API call")
213
 
214
  msg = cl.Message(content="")
215
+ logger.info("Starting OpenAI API call")
216
+
217
+ try:
218
+ # Call OpenAI
219
+ async for stream_resp in await client.chat.completions.create(
220
+ messages=[m.to_openai() for m in prompt.messages], stream=True, **settings
221
+ ):
222
+ token = stream_resp.choices[0].delta.content
223
+ if not token:
224
+ token = ""
225
+ await msg.stream_token(token)
226
+
227
+ # Update the prompt object with the completion
228
+ prompt.completion = msg.content
229
+ msg.prompt = prompt
230
+
231
+ # Send and close the message stream
232
+ await msg.send()
233
+ logger.info("Response successfully sent to user")
234
+ except Exception as e:
235
+ logger.error(f"Error during OpenAI API call: {str(e)}")
236
+ await cl.Message(
237
+ content="I apologize, but I encountered an error processing your request. Please try again."
238
+ ).send()
logger_config.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import os
3
+ from datetime import datetime
4
+
5
+ # Create logs directory if it doesn't exist
6
+ os.makedirs("logs", exist_ok=True)
7
+
8
+ # Configure logging
9
+ def setup_logger():
10
+ # Create a logger
11
+ logger = logging.getLogger("chainlit_chatbot")
12
+ logger.setLevel(logging.INFO)
13
+
14
+ # Create handlers
15
+ # Console handler
16
+ console_handler = logging.StreamHandler()
17
+ console_handler.setLevel(logging.INFO)
18
+
19
+ # File handler - log to file with timestamp
20
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
21
+ file_handler = logging.FileHandler(f"logs/chatbot_{timestamp}.log")
22
+ file_handler.setLevel(logging.DEBUG)
23
+
24
+ # Create formatters and add it to handlers
25
+ console_format = logging.Formatter('%(levelname)s - %(message)s')
26
+ file_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
27
+
28
+ console_handler.setFormatter(console_format)
29
+ file_handler.setFormatter(file_format)
30
+
31
+ # Add handlers to the logger
32
+ logger.addHandler(console_handler)
33
+ logger.addHandler(file_handler)
34
+
35
+ return logger
36
+
37
+ # Create and export the logger
38
+ logger = setup_logger()
prompt_manager.py CHANGED
@@ -1,5 +1,6 @@
1
  from dataclasses import dataclass
2
  from typing import Dict, List
 
3
 
4
  @dataclass
5
  class AspectInfo:
@@ -10,6 +11,7 @@ class AspectInfo:
10
 
11
  class PromptManager:
12
  def __init__(self):
 
13
  # Default template for when no aspect is selected
14
  self.default_aspect = AspectInfo(
15
  description="General purpose AI assistant with balanced capabilities",
@@ -24,6 +26,7 @@ Adapt your communication style based on the user's needs and the complexity of t
24
  user_template="""{input}
25
  Think through your response step by step."""
26
  )
 
27
 
28
  self.aspects = {
29
  "Concept Simplification": AspectInfo(
@@ -117,22 +120,27 @@ Adapt your communication style to match the user's level of expertise.""",
117
  - How does this relate to everyday experience?"""
118
  )
119
  }
 
120
 
121
  def get_aspect_names(self) -> List[str]:
122
  """Get list of available aspect names."""
 
123
  return list(self.aspects.keys())
124
 
125
  def get_aspect_info(self, aspect_name: str) -> AspectInfo:
126
  """Get information for a specific aspect."""
 
127
  return self.aspects.get(aspect_name, self.default_aspect)
128
 
129
  def get_action_description(self, aspect_name: str) -> str:
130
  """Get formatted description for action button."""
 
131
  info = self.aspects[aspect_name]
132
  return f"{info.description}\n\nExample tasks:\n" + "\n".join(f"• {example}" for example in info.examples)
133
 
134
  def get_confirmation_message(self, aspect_name: str) -> str:
135
  """Get formatted confirmation message for selected aspect."""
 
136
  info = self.aspects[aspect_name]
137
  examples = "\n".join(f"• {example}" for example in info.examples[:2])
138
  return f"""You've selected: {aspect_name}
@@ -145,7 +153,9 @@ Try asking something like:
145
  def get_templates(self, aspect_name: str | None) -> tuple[str, str]:
146
  """Get system and user templates for an aspect."""
147
  if aspect_name is None:
 
148
  info = self.default_aspect
149
  else:
 
150
  info = self.aspects.get(aspect_name, self.default_aspect)
151
  return info.system_template, info.user_template
 
1
  from dataclasses import dataclass
2
  from typing import Dict, List
3
+ from logger_config import logger
4
 
5
  @dataclass
6
  class AspectInfo:
 
11
 
12
  class PromptManager:
13
  def __init__(self):
14
+ logger.info("Initializing PromptManager")
15
  # Default template for when no aspect is selected
16
  self.default_aspect = AspectInfo(
17
  description="General purpose AI assistant with balanced capabilities",
 
26
  user_template="""{input}
27
  Think through your response step by step."""
28
  )
29
+ logger.debug("Default aspect template created")
30
 
31
  self.aspects = {
32
  "Concept Simplification": AspectInfo(
 
120
  - How does this relate to everyday experience?"""
121
  )
122
  }
123
+ logger.info(f"Initialized {len(self.aspects)} aspects")
124
 
125
  def get_aspect_names(self) -> List[str]:
126
  """Get list of available aspect names."""
127
+ logger.debug("Getting aspect names")
128
  return list(self.aspects.keys())
129
 
130
  def get_aspect_info(self, aspect_name: str) -> AspectInfo:
131
  """Get information for a specific aspect."""
132
+ logger.debug(f"Getting aspect info for: {aspect_name}")
133
  return self.aspects.get(aspect_name, self.default_aspect)
134
 
135
  def get_action_description(self, aspect_name: str) -> str:
136
  """Get formatted description for action button."""
137
+ logger.debug(f"Getting action description for: {aspect_name}")
138
  info = self.aspects[aspect_name]
139
  return f"{info.description}\n\nExample tasks:\n" + "\n".join(f"• {example}" for example in info.examples)
140
 
141
  def get_confirmation_message(self, aspect_name: str) -> str:
142
  """Get formatted confirmation message for selected aspect."""
143
+ logger.debug(f"Getting confirmation message for: {aspect_name}")
144
  info = self.aspects[aspect_name]
145
  examples = "\n".join(f"• {example}" for example in info.examples[:2])
146
  return f"""You've selected: {aspect_name}
 
153
  def get_templates(self, aspect_name: str | None) -> tuple[str, str]:
154
  """Get system and user templates for an aspect."""
155
  if aspect_name is None:
156
+ logger.info("No aspect selected, using default template")
157
  info = self.default_aspect
158
  else:
159
+ logger.info(f"Using templates for aspect: {aspect_name}")
160
  info = self.aspects.get(aspect_name, self.default_aspect)
161
  return info.system_template, info.user_template