chainlit 1.1.305__py3-none-any.whl → 1.1.400__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of chainlit might be problematic. Click here for more details.

Files changed (48) hide show
  1. chainlit/__init__.py +19 -5
  2. chainlit/chat_context.py +64 -0
  3. chainlit/config.py +6 -3
  4. chainlit/context.py +9 -0
  5. chainlit/copilot/dist/index.js +150 -147
  6. chainlit/data/__init__.py +8 -12
  7. chainlit/data/sql_alchemy.py +0 -4
  8. chainlit/discord/app.py +44 -24
  9. chainlit/emitter.py +9 -11
  10. chainlit/frontend/dist/assets/{DailyMotion-4f715d15.js → DailyMotion-e2c926d0.js} +1 -1
  11. chainlit/frontend/dist/assets/{Facebook-25f45c09.js → Facebook-88f80aba.js} +1 -1
  12. chainlit/frontend/dist/assets/{FilePlayer-04482650.js → FilePlayer-febd1b0d.js} +1 -1
  13. chainlit/frontend/dist/assets/{Kaltura-37152a96.js → Kaltura-606fe0bd.js} +1 -1
  14. chainlit/frontend/dist/assets/{Mixcloud-914b75ee.js → Mixcloud-b3db090a.js} +1 -1
  15. chainlit/frontend/dist/assets/{Mux-fb751398.js → Mux-ca847a7d.js} +1 -1
  16. chainlit/frontend/dist/assets/{Preview-85fbb8da.js → Preview-7a3747b5.js} +1 -1
  17. chainlit/frontend/dist/assets/{SoundCloud-8afad6c0.js → SoundCloud-0da01fb1.js} +1 -1
  18. chainlit/frontend/dist/assets/{Streamable-08844d93.js → Streamable-4a6ab048.js} +1 -1
  19. chainlit/frontend/dist/assets/{Twitch-1b95f5c8.js → Twitch-3e260619.js} +1 -1
  20. chainlit/frontend/dist/assets/{Vidyard-5028fa2f.js → Vidyard-73692980.js} +1 -1
  21. chainlit/frontend/dist/assets/{Vimeo-ca732959.js → Vimeo-6627c7a8.js} +1 -1
  22. chainlit/frontend/dist/assets/{Wistia-74e58d71.js → Wistia-27df9c66.js} +1 -1
  23. chainlit/frontend/dist/assets/{YouTube-bdf4ca10.js → YouTube-a11d419d.js} +1 -1
  24. chainlit/frontend/dist/assets/index-d66d1800.js +730 -0
  25. chainlit/frontend/dist/assets/{react-plotly-cf9b99cc.js → react-plotly-012ed517.js} +1 -1
  26. chainlit/frontend/dist/index.html +1 -1
  27. chainlit/haystack/callbacks.py +1 -3
  28. chainlit/langchain/callbacks.py +39 -20
  29. chainlit/llama_index/callbacks.py +8 -28
  30. chainlit/message.py +4 -17
  31. chainlit/mistralai/__init__.py +2 -5
  32. chainlit/openai/__init__.py +0 -2
  33. chainlit/server.py +1 -1
  34. chainlit/session.py +2 -12
  35. chainlit/slack/app.py +38 -31
  36. chainlit/socket.py +37 -1
  37. chainlit/step.py +37 -32
  38. chainlit/teams/app.py +23 -18
  39. chainlit/translations/zh-CN.json +229 -0
  40. chainlit/types.py +0 -1
  41. chainlit/user_session.py +0 -3
  42. chainlit/utils.py +1 -0
  43. {chainlit-1.1.305.dist-info → chainlit-1.1.400.dist-info}/METADATA +1 -1
  44. chainlit-1.1.400.dist-info/RECORD +82 -0
  45. chainlit/frontend/dist/assets/index-621140f9.js +0 -727
  46. chainlit-1.1.305.dist-info/RECORD +0 -80
  47. {chainlit-1.1.305.dist-info → chainlit-1.1.400.dist-info}/WHEEL +0 -0
  48. {chainlit-1.1.305.dist-info → chainlit-1.1.400.dist-info}/entry_points.txt +0 -0
chainlit/slack/app.py CHANGED
@@ -2,12 +2,13 @@ import asyncio
2
2
  import os
3
3
  import re
4
4
  import uuid
5
+ from datetime import datetime
5
6
  from functools import partial
6
7
  from typing import Dict, List, Optional, Union
7
8
 
8
9
  import httpx
9
10
  from chainlit.config import config
10
- from chainlit.context import ChainlitContext, HTTPSession, context_var
11
+ from chainlit.context import ChainlitContext, HTTPSession, context, context_var
11
12
  from chainlit.data import get_data_layer
12
13
  from chainlit.element import Element, ElementDict
13
14
  from chainlit.emitter import BaseChainlitEmitter
@@ -28,18 +29,16 @@ class SlackEmitter(BaseChainlitEmitter):
28
29
  app: AsyncApp,
29
30
  channel_id: str,
30
31
  say,
31
- enabled=False,
32
32
  thread_ts: Optional[str] = None,
33
33
  ):
34
34
  super().__init__(session)
35
35
  self.app = app
36
36
  self.channel_id = channel_id
37
37
  self.say = say
38
- self.enabled = enabled
39
38
  self.thread_ts = thread_ts
40
39
 
41
40
  async def send_element(self, element_dict: ElementDict):
42
- if not self.enabled or element_dict.get("display") != "inline":
41
+ if element_dict.get("display") != "inline":
43
42
  return
44
43
 
45
44
  persisted_file = self.session.files.get(element_dict.get("chainlitKey") or "")
@@ -64,21 +63,14 @@ class SlackEmitter(BaseChainlitEmitter):
64
63
  )
65
64
 
66
65
  async def send_step(self, step_dict: StepDict):
67
- if not self.enabled:
68
- return
69
-
70
66
  step_type = step_dict.get("type")
71
- is_message = step_type in [
72
- "user_message",
73
- "assistant_message",
74
- ]
75
- is_chain_of_thought = bool(step_dict.get("parentId"))
67
+ is_assistant_message = step_type == "assistant_message"
76
68
  is_empty_output = not step_dict.get("output")
77
69
 
78
- if is_chain_of_thought or is_empty_output or not is_message:
70
+ if is_empty_output or not is_assistant_message:
79
71
  return
80
72
 
81
- enable_feedback = not step_dict.get("disableFeedback") and get_data_layer()
73
+ enable_feedback = get_data_layer()
82
74
  blocks: List[Dict] = [
83
75
  {
84
76
  "type": "section",
@@ -86,6 +78,8 @@ class SlackEmitter(BaseChainlitEmitter):
86
78
  }
87
79
  ]
88
80
  if enable_feedback:
81
+ current_run = context.current_run
82
+ scorable_id = current_run.id if current_run else step_dict.get("id")
89
83
  blocks.append(
90
84
  {
91
85
  "type": "actions",
@@ -98,7 +92,7 @@ class SlackEmitter(BaseChainlitEmitter):
98
92
  "emoji": True,
99
93
  "text": ":thumbsdown:",
100
94
  },
101
- "value": step_dict.get("id"),
95
+ "value": scorable_id,
102
96
  },
103
97
  {
104
98
  "action_id": "thumbup",
@@ -108,7 +102,7 @@ class SlackEmitter(BaseChainlitEmitter):
108
102
  "emoji": True,
109
103
  "text": ":thumbsup:",
110
104
  },
111
- "value": step_dict.get("id"),
105
+ "value": scorable_id,
112
106
  },
113
107
  ],
114
108
  }
@@ -118,7 +112,9 @@ class SlackEmitter(BaseChainlitEmitter):
118
112
  )
119
113
 
120
114
  async def update_step(self, step_dict: StepDict):
121
- if not self.enabled:
115
+ is_assistant_message = step_dict["type"] == "assistant_message"
116
+
117
+ if not is_assistant_message:
122
118
  return
123
119
 
124
120
  await self.send_step(step_dict)
@@ -247,6 +243,7 @@ async def download_slack_files(session: HTTPSession, files, token):
247
243
  async def process_slack_message(
248
244
  event,
249
245
  say,
246
+ thread_id: str,
250
247
  thread_name: Optional[str] = None,
251
248
  bind_thread_to_user=False,
252
249
  thread_ts: Optional[str] = None,
@@ -254,7 +251,6 @@ async def process_slack_message(
254
251
  user = await get_user(event["user"])
255
252
 
256
253
  channel_id = event["channel"]
257
- thread_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, thread_ts or channel_id))
258
254
 
259
255
  text = event.get("text")
260
256
  slack_files = event.get("files", [])
@@ -279,6 +275,9 @@ async def process_slack_message(
279
275
  session, slack_files, slack_app.client.token
280
276
  )
281
277
 
278
+ if on_chat_start := config.code.on_chat_start:
279
+ await on_chat_start()
280
+
282
281
  msg = Message(
283
282
  content=clean_content(text),
284
283
  elements=file_elements,
@@ -288,11 +287,6 @@ async def process_slack_message(
288
287
 
289
288
  await msg.send()
290
289
 
291
- ctx.emitter.enabled = True
292
-
293
- if on_chat_start := config.code.on_chat_start:
294
- await on_chat_start()
295
-
296
290
  if on_message := config.code.on_message:
297
291
  await on_message(msg)
298
292
 
@@ -325,14 +319,29 @@ async def handle_app_home_opened(event, say):
325
319
  @slack_app.event("app_mention")
326
320
  async def handle_app_mentions(event, say):
327
321
  thread_ts = event.get("thread_ts", event["ts"])
328
- await process_slack_message(event, say, thread_ts=thread_ts)
322
+ thread_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, thread_ts))
323
+
324
+ await process_slack_message(event, say, thread_id=thread_id, thread_ts=thread_ts)
329
325
 
330
326
 
331
327
  @slack_app.event("message")
332
328
  async def handle_message(message, say):
333
- user = await get_user(message["user"])
334
- thread_name = f"{user.identifier} Slack DM"
335
- await process_slack_message(message, say, thread_name)
329
+ thread_id = str(
330
+ uuid.uuid5(
331
+ uuid.NAMESPACE_DNS,
332
+ message["channel"] + datetime.today().strftime("%Y-%m-%d"),
333
+ )
334
+ )
335
+ thread_ts = message.get("thread_ts", message["ts"])
336
+ thread_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, thread_ts))
337
+
338
+ await process_slack_message(
339
+ event=message,
340
+ say=say,
341
+ thread_id=thread_id,
342
+ bind_thread_to_user=True,
343
+ thread_ts=thread_ts,
344
+ )
336
345
 
337
346
 
338
347
  @slack_app.block_action("thumbdown")
@@ -341,8 +350,7 @@ async def thumb_down(ack, context, body):
341
350
  step_id = body["actions"][0]["value"]
342
351
 
343
352
  if data_layer := get_data_layer():
344
- thread_id = context_var.get().session.thread_id
345
- feedback = Feedback(forId=step_id, threadId=thread_id, value=0)
353
+ feedback = Feedback(forId=step_id, value=0)
346
354
  await data_layer.upsert_feedback(feedback)
347
355
 
348
356
  text = body["message"]["text"]
@@ -368,8 +376,7 @@ async def thumb_up(ack, context, body):
368
376
  step_id = body["actions"][0]["value"]
369
377
 
370
378
  if data_layer := get_data_layer():
371
- thread_id = context_var.get().session.thread_id
372
- feedback = Feedback(forId=step_id, threadId=thread_id, value=1)
379
+ feedback = Feedback(forId=step_id, value=1)
373
380
  await data_layer.upsert_feedback(feedback)
374
381
 
375
382
  text = body["message"]["text"]
chainlit/socket.py CHANGED
@@ -7,6 +7,7 @@ from urllib.parse import unquote
7
7
 
8
8
  from chainlit.action import Action
9
9
  from chainlit.auth import get_current_user, require_login
10
+ from chainlit.chat_context import chat_context
10
11
  from chainlit.config import config
11
12
  from chainlit.context import init_ws_context
12
13
  from chainlit.data import get_data_layer
@@ -183,6 +184,11 @@ async def connection_successful(sid):
183
184
  {"interaction": "resume", "thread_id": thread.get("id")},
184
185
  )
185
186
  await config.code.on_chat_resume(thread)
187
+
188
+ for step in thread.get("steps", []):
189
+ if "message" in step["type"]:
190
+ chat_context.add(Message.from_dict(step))
191
+
186
192
  await context.emitter.resume_thread(thread)
187
193
  return
188
194
 
@@ -238,7 +244,7 @@ async def stop(sid):
238
244
  trace_event("stop_task")
239
245
 
240
246
  init_ws_context(session)
241
- await Message(content="Task manually stopped.", disable_feedback=True).send()
247
+ await Message(content="Task manually stopped.").send()
242
248
 
243
249
  if session.current_task:
244
250
  session.current_task.cancel()
@@ -269,6 +275,36 @@ async def process_message(session: WebsocketSession, payload: MessagePayload):
269
275
  await context.emitter.task_end()
270
276
 
271
277
 
278
+ @sio.on("edit_message")
279
+ async def edit_message(sid, payload: MessagePayload):
280
+ """Handle a message sent by the User."""
281
+ session = WebsocketSession.require(sid)
282
+ context = init_ws_context(session)
283
+
284
+ messages = chat_context.get()
285
+
286
+ orig_message = None
287
+
288
+ for message in messages:
289
+ if orig_message:
290
+ await message.remove()
291
+
292
+ if message.id == payload["message"]["id"]:
293
+ message.content = payload["message"]["output"]
294
+ await message.update()
295
+ orig_message = message
296
+
297
+ await context.emitter.task_start()
298
+
299
+ if config.code.on_message:
300
+ try:
301
+ await config.code.on_message(orig_message)
302
+ except asyncio.CancelledError:
303
+ pass
304
+ finally:
305
+ await context.emitter.task_end()
306
+
307
+
272
308
  @sio.on("client_message")
273
309
  async def message(sid, payload: MessagePayload):
274
310
  """Handle a message sent by the User."""
chainlit/step.py CHANGED
@@ -7,7 +7,7 @@ from functools import wraps
7
7
  from typing import Callable, Dict, List, Optional, TypedDict, Union
8
8
 
9
9
  from chainlit.config import config
10
- from chainlit.context import context, local_steps
10
+ from chainlit.context import CL_RUN_NAMES, context, local_steps
11
11
  from chainlit.data import get_data_layer
12
12
  from chainlit.element import Element
13
13
  from chainlit.logger import logger
@@ -18,13 +18,35 @@ from literalai.helper import utc_now
18
18
  from literalai.step import StepType, TrueStepType
19
19
 
20
20
 
21
+ def check_add_step_in_cot(step: "Step"):
22
+ is_message = step.type in [
23
+ "user_message",
24
+ "assistant_message",
25
+ ]
26
+ is_cl_run = step.name in CL_RUN_NAMES and step.type == "run"
27
+ if config.ui.cot == "hidden" and not is_message and not is_cl_run:
28
+ return False
29
+ return True
30
+
31
+
32
+ def stub_step(step: "Step"):
33
+ return {
34
+ "type": step.type,
35
+ "name": step.name,
36
+ "id": step.id,
37
+ "parentId": step.parent_id,
38
+ "threadId": step.thread_id,
39
+ "input": "",
40
+ "output": "",
41
+ }
42
+
43
+
21
44
  class StepDict(TypedDict, total=False):
22
45
  name: str
23
46
  type: StepType
24
47
  id: str
25
48
  threadId: str
26
49
  parentId: Optional[str]
27
- disableFeedback: bool
28
50
  streaming: bool
29
51
  waitForAnswer: Optional[bool]
30
52
  isError: Optional[bool]
@@ -48,8 +70,8 @@ def step(
48
70
  name: Optional[str] = "",
49
71
  type: TrueStepType = "undefined",
50
72
  id: Optional[str] = None,
73
+ parent_id: Optional[str] = None,
51
74
  tags: Optional[List[str]] = None,
52
- disable_feedback: bool = True,
53
75
  language: Optional[str] = None,
54
76
  show_input: Union[bool, str] = "json",
55
77
  ):
@@ -70,7 +92,7 @@ def step(
70
92
  type=type,
71
93
  name=name,
72
94
  id=id,
73
- disable_feedback=disable_feedback,
95
+ parent_id=parent_id,
74
96
  tags=tags,
75
97
  language=language,
76
98
  show_input=show_input,
@@ -97,7 +119,7 @@ def step(
97
119
  type=type,
98
120
  name=name,
99
121
  id=id,
100
- disable_feedback=disable_feedback,
122
+ parent_id=parent_id,
101
123
  tags=tags,
102
124
  language=language,
103
125
  show_input=show_input,
@@ -130,7 +152,6 @@ class Step:
130
152
  type: TrueStepType
131
153
  id: str
132
154
  parent_id: Optional[str]
133
- disable_feedback: bool
134
155
 
135
156
  streaming: bool
136
157
  persisted: bool
@@ -158,7 +179,6 @@ class Step:
158
179
  elements: Optional[List[Element]] = None,
159
180
  metadata: Optional[Dict] = None,
160
181
  tags: Optional[List[str]] = None,
161
- disable_feedback: bool = True,
162
182
  language: Optional[str] = None,
163
183
  show_input: Union[bool, str] = "json",
164
184
  ):
@@ -170,7 +190,6 @@ class Step:
170
190
  self.name = name or ""
171
191
  self.type = type
172
192
  self.id = id or str(uuid.uuid4())
173
- self.disable_feedback = disable_feedback
174
193
  self.metadata = metadata or {}
175
194
  self.tags = tags
176
195
  self.is_error = False
@@ -256,7 +275,6 @@ class Step:
256
275
  "id": self.id,
257
276
  "threadId": self.thread_id,
258
277
  "parentId": self.parent_id,
259
- "disableFeedback": self.disable_feedback,
260
278
  "streaming": self.streaming,
261
279
  "metadata": self.metadata,
262
280
  "tags": self.tags,
@@ -295,13 +313,10 @@ class Step:
295
313
  tasks = [el.send(for_id=self.id) for el in self.elements]
296
314
  await asyncio.gather(*tasks)
297
315
 
298
- if config.ui.hide_cot and self.type not in [
299
- "user_message",
300
- "assistant_message",
301
- ]:
302
- return True
303
-
304
- await context.emitter.update_step(step_dict)
316
+ if not check_add_step_in_cot(self):
317
+ await context.emitter.update_step(stub_step(self))
318
+ else:
319
+ await context.emitter.update_step(step_dict)
305
320
 
306
321
  return True
307
322
 
@@ -352,13 +367,10 @@ class Step:
352
367
  tasks = [el.send(for_id=self.id) for el in self.elements]
353
368
  await asyncio.gather(*tasks)
354
369
 
355
- if config.ui.hide_cot and self.type not in [
356
- "user_message",
357
- "assistant_message",
358
- ]:
359
- return self
360
-
361
- await context.emitter.send_step(step_dict)
370
+ if not check_add_step_in_cot(self):
371
+ await context.emitter.send_step(stub_step(self))
372
+ else:
373
+ await context.emitter.send_step(step_dict)
362
374
 
363
375
  return self
364
376
 
@@ -380,10 +392,8 @@ class Step:
380
392
 
381
393
  assert self.id
382
394
 
383
- if config.ui.hide_cot and self.type not in [
384
- "user_message",
385
- "assistant_message",
386
- ]:
395
+ if not check_add_step_in_cot(self):
396
+ await context.emitter.send_step(stub_step(self))
387
397
  return
388
398
 
389
399
  if not self.streaming:
@@ -404,7 +414,6 @@ class Step:
404
414
  id=self.id,
405
415
  parent_id=self.parent_id,
406
416
  thread_id=self.thread_id,
407
- disable_feedback=self.disable_feedback,
408
417
  )
409
418
 
410
419
  # Handle Context Manager Protocol
@@ -416,8 +425,6 @@ class Step:
416
425
  if not self.parent_id:
417
426
  if parent_step:
418
427
  self.parent_id = parent_step.id
419
- elif context.session.root_message:
420
- self.parent_id = context.session.root_message.id
421
428
  context.active_steps.append(self)
422
429
  local_steps.set(previous_steps + [self])
423
430
  await self.send()
@@ -449,8 +456,6 @@ class Step:
449
456
  if not self.parent_id:
450
457
  if parent_step:
451
458
  self.parent_id = parent_step.id
452
- elif context.session.root_message:
453
- self.parent_id = context.session.root_message.id
454
459
  context.active_steps.append(self)
455
460
  local_steps.set(previous_steps + [self])
456
461
 
chainlit/teams/app.py CHANGED
@@ -3,6 +3,7 @@ import base64
3
3
  import mimetypes
4
4
  import os
5
5
  import uuid
6
+ from datetime import datetime
6
7
  from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
7
8
 
8
9
  import filetype
@@ -28,7 +29,7 @@ from botbuilder.schema import (
28
29
  HeroCard,
29
30
  )
30
31
  from chainlit.config import config
31
- from chainlit.context import ChainlitContext, HTTPSession, context_var
32
+ from chainlit.context import ChainlitContext, HTTPSession, context, context_var
32
33
  from chainlit.data import get_data_layer
33
34
  from chainlit.element import Element, ElementDict
34
35
  from chainlit.emitter import BaseChainlitEmitter
@@ -41,13 +42,12 @@ from chainlit.user_session import user_session
41
42
 
42
43
 
43
44
  class TeamsEmitter(BaseChainlitEmitter):
44
- def __init__(self, session: HTTPSession, turn_context: TurnContext, enabled=False):
45
+ def __init__(self, session: HTTPSession, turn_context: TurnContext):
45
46
  super().__init__(session)
46
47
  self.turn_context = turn_context
47
- self.enabled = enabled
48
48
 
49
49
  async def send_element(self, element_dict: ElementDict):
50
- if not self.enabled or element_dict.get("display") != "inline":
50
+ if element_dict.get("display") != "inline":
51
51
  return
52
52
 
53
53
  persisted_file = self.session.files.get(element_dict.get("chainlitKey") or "")
@@ -81,7 +81,7 @@ class TeamsEmitter(BaseChainlitEmitter):
81
81
  await self.turn_context.send_activity(Activity(attachments=[attachment]))
82
82
 
83
83
  async def send_step(self, step_dict: StepDict):
84
- if not self.enabled:
84
+ if not step_dict["type"] == "assistant_message":
85
85
  return
86
86
 
87
87
  step_type = step_dict.get("type")
@@ -89,26 +89,27 @@ class TeamsEmitter(BaseChainlitEmitter):
89
89
  "user_message",
90
90
  "assistant_message",
91
91
  ]
92
- is_chain_of_thought = bool(step_dict.get("parentId"))
93
92
  is_empty_output = not step_dict.get("output")
94
93
 
95
- if is_chain_of_thought or is_empty_output or not is_message:
94
+ if is_empty_output or not is_message:
96
95
  return
97
96
  else:
98
97
  reply = MessageFactory.text(step_dict["output"])
99
- enable_feedback = not step_dict.get("disableFeedback") and get_data_layer()
98
+ enable_feedback = get_data_layer()
100
99
  if enable_feedback:
100
+ current_run = context.current_run
101
+ scorable_id = current_run.id if current_run else step_dict["id"]
101
102
  like_button = CardAction(
102
103
  type=ActionTypes.message_back,
103
104
  title="👍",
104
105
  text="like",
105
- value={"feedback": "like", "step_id": step_dict["id"]},
106
+ value={"feedback": "like", "step_id": scorable_id},
106
107
  )
107
108
  dislike_button = CardAction(
108
109
  type=ActionTypes.message_back,
109
110
  title="👎",
110
111
  text="dislike",
111
- value={"feedback": "dislike", "step_id": step_dict["id"]},
112
+ value={"feedback": "dislike", "step_id": scorable_id},
112
113
  )
113
114
  card = HeroCard(buttons=[like_button, dislike_button])
114
115
  attachment = Attachment(
@@ -119,7 +120,7 @@ class TeamsEmitter(BaseChainlitEmitter):
119
120
  await self.turn_context.send_activity(reply)
120
121
 
121
122
  async def update_step(self, step_dict: StepDict):
122
- if not self.enabled:
123
+ if not step_dict["type"] == "assistant_message":
123
124
  return
124
125
 
125
126
  await self.send_step(step_dict)
@@ -225,7 +226,13 @@ async def process_teams_message(
225
226
  user = await get_user(turn_context.activity.from_property)
226
227
 
227
228
  thread_id = str(
228
- uuid.uuid5(uuid.NAMESPACE_DNS, str(turn_context.activity.conversation.id))
229
+ uuid.uuid5(
230
+ uuid.NAMESPACE_DNS,
231
+ str(
232
+ turn_context.activity.conversation.id
233
+ + datetime.today().strftime("%Y-%m-%d")
234
+ ),
235
+ )
229
236
  )
230
237
 
231
238
  text = clean_content(turn_context.activity)
@@ -247,6 +254,9 @@ async def process_teams_message(
247
254
 
248
255
  file_elements = await download_teams_files(session, teams_files)
249
256
 
257
+ if on_chat_start := config.code.on_chat_start:
258
+ await on_chat_start()
259
+
250
260
  msg = Message(
251
261
  content=text,
252
262
  elements=file_elements,
@@ -256,11 +266,6 @@ async def process_teams_message(
256
266
 
257
267
  await msg.send()
258
268
 
259
- ctx.emitter.enabled = True
260
-
261
- if on_chat_start := config.code.on_chat_start:
262
- await on_chat_start()
263
-
264
269
  if on_message := config.code.on_message:
265
270
  await on_message(msg)
266
271
 
@@ -314,7 +319,7 @@ async def handle_message(turn_context: TurnContext):
314
319
  conversation=turn_context.activity.conversation,
315
320
  )
316
321
  await turn_context.send_activity(typing_activity)
317
- thread_name = f"{turn_context.activity.from_property.name} Teams DM"
322
+ thread_name = f"{turn_context.activity.from_property.name} Teams DM {datetime.today().strftime('%Y-%m-%d')}"
318
323
  await process_teams_message(turn_context, thread_name)
319
324
 
320
325