chainlit 1.1.306__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.
- chainlit/__init__.py +16 -3
- chainlit/config.py +4 -4
- chainlit/context.py +9 -0
- chainlit/copilot/dist/index.js +132 -129
- chainlit/data/__init__.py +8 -12
- chainlit/data/sql_alchemy.py +0 -4
- chainlit/discord/app.py +42 -20
- chainlit/emitter.py +5 -9
- chainlit/frontend/dist/assets/{DailyMotion-4ebdfef1.js → DailyMotion-e2c926d0.js} +1 -1
- chainlit/frontend/dist/assets/{Facebook-40982be3.js → Facebook-88f80aba.js} +1 -1
- chainlit/frontend/dist/assets/{FilePlayer-5b3a4ad0.js → FilePlayer-febd1b0d.js} +1 -1
- chainlit/frontend/dist/assets/{Kaltura-6c5cb748.js → Kaltura-606fe0bd.js} +1 -1
- chainlit/frontend/dist/assets/{Mixcloud-7a304880.js → Mixcloud-b3db090a.js} +1 -1
- chainlit/frontend/dist/assets/{Mux-1bd85c69.js → Mux-ca847a7d.js} +1 -1
- chainlit/frontend/dist/assets/{Preview-e91eb05e.js → Preview-7a3747b5.js} +1 -1
- chainlit/frontend/dist/assets/{SoundCloud-2f2116b2.js → SoundCloud-0da01fb1.js} +1 -1
- chainlit/frontend/dist/assets/{Streamable-b92c07ce.js → Streamable-4a6ab048.js} +1 -1
- chainlit/frontend/dist/assets/{Twitch-58a2eb9a.js → Twitch-3e260619.js} +1 -1
- chainlit/frontend/dist/assets/{Vidyard-ad5bffa0.js → Vidyard-73692980.js} +1 -1
- chainlit/frontend/dist/assets/{Vimeo-8fb43e9c.js → Vimeo-6627c7a8.js} +1 -1
- chainlit/frontend/dist/assets/{Wistia-d03e6237.js → Wistia-27df9c66.js} +1 -1
- chainlit/frontend/dist/assets/{YouTube-6b7d1dae.js → YouTube-a11d419d.js} +1 -1
- chainlit/frontend/dist/assets/{index-4f01eb67.js → index-d66d1800.js} +104 -101
- chainlit/frontend/dist/assets/{react-plotly-ef3ac5f0.js → react-plotly-012ed517.js} +1 -1
- chainlit/frontend/dist/index.html +1 -1
- chainlit/haystack/callbacks.py +1 -3
- chainlit/langchain/callbacks.py +37 -16
- chainlit/llama_index/callbacks.py +0 -6
- chainlit/message.py +0 -16
- chainlit/mistralai/__init__.py +2 -5
- chainlit/openai/__init__.py +0 -2
- chainlit/server.py +2 -2
- chainlit/session.py +2 -12
- chainlit/slack/app.py +36 -27
- chainlit/socket.py +10 -10
- chainlit/step.py +37 -32
- chainlit/teams/app.py +23 -18
- chainlit/translations/zh-CN.json +229 -0
- chainlit/user_session.py +0 -3
- {chainlit-1.1.306.dist-info → chainlit-1.1.400.dist-info}/METADATA +1 -1
- chainlit-1.1.400.dist-info/RECORD +82 -0
- chainlit-1.1.306.dist-info/RECORD +0 -81
- {chainlit-1.1.306.dist-info → chainlit-1.1.400.dist-info}/WHEEL +0 -0
- {chainlit-1.1.306.dist-info → chainlit-1.1.400.dist-info}/entry_points.txt +0 -0
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<script>
|
|
22
22
|
const global = globalThis;
|
|
23
23
|
</script>
|
|
24
|
-
<script type="module" crossorigin src="/assets/index-
|
|
24
|
+
<script type="module" crossorigin src="/assets/index-d66d1800.js"></script>
|
|
25
25
|
<link rel="stylesheet" href="/assets/index-aaf974a9.css">
|
|
26
26
|
</head>
|
|
27
27
|
<body>
|
chainlit/haystack/callbacks.py
CHANGED
|
@@ -68,9 +68,7 @@ class HaystackAgentCallbackHandler:
|
|
|
68
68
|
self.last_tokens: List[str] = []
|
|
69
69
|
self.answer_reached = False
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
parent_id = root_message.id if root_message else None
|
|
73
|
-
run_step = Step(name=self.agent_name, type="run", parent_id=parent_id)
|
|
71
|
+
run_step = Step(name=self.agent_name, type="run")
|
|
74
72
|
run_step.start = utc_now()
|
|
75
73
|
run_step.input = kwargs
|
|
76
74
|
|
chainlit/langchain/callbacks.py
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import time
|
|
3
|
-
from typing import Any, Dict, List, Optional, TypedDict, Union
|
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple, TypedDict, Union
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
|
-
from chainlit.context import context_var
|
|
7
|
-
from chainlit.message import Message
|
|
8
|
-
from chainlit.step import Step
|
|
9
6
|
from langchain.callbacks.tracers.base import BaseTracer
|
|
10
7
|
from langchain.callbacks.tracers.schemas import Run
|
|
11
8
|
from langchain.schema import BaseMessage
|
|
@@ -15,6 +12,10 @@ from literalai import ChatGeneration, CompletionGeneration, GenerationMessage
|
|
|
15
12
|
from literalai.helper import utc_now
|
|
16
13
|
from literalai.step import TrueStepType
|
|
17
14
|
|
|
15
|
+
from chainlit.context import context_var
|
|
16
|
+
from chainlit.message import Message
|
|
17
|
+
from chainlit.step import Step
|
|
18
|
+
|
|
18
19
|
DEFAULT_ANSWER_PREFIX_TOKENS = ["Final", "Answer", ":"]
|
|
19
20
|
|
|
20
21
|
|
|
@@ -229,7 +230,24 @@ class GenerationHelper:
|
|
|
229
230
|
return provider, model, tools, settings
|
|
230
231
|
|
|
231
232
|
|
|
232
|
-
|
|
233
|
+
def process_content(content: Any) -> Tuple[Dict, Optional[str]]:
|
|
234
|
+
if content is None:
|
|
235
|
+
return {}, None
|
|
236
|
+
if isinstance(content, dict):
|
|
237
|
+
return content, "json"
|
|
238
|
+
elif isinstance(content, str):
|
|
239
|
+
return {"content": content}, "text"
|
|
240
|
+
else:
|
|
241
|
+
return {"content": str(content)}, "text"
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
DEFAULT_TO_IGNORE = [
|
|
245
|
+
"RunnableSequence",
|
|
246
|
+
"RunnableParallel",
|
|
247
|
+
"RunnableAssign",
|
|
248
|
+
"RunnableLambda",
|
|
249
|
+
"<lambda>",
|
|
250
|
+
]
|
|
233
251
|
DEFAULT_TO_KEEP = ["retriever", "llm", "agent", "chain", "tool"]
|
|
234
252
|
|
|
235
253
|
|
|
@@ -267,8 +285,6 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
267
285
|
|
|
268
286
|
if self.context.current_step:
|
|
269
287
|
self.root_parent_id = self.context.current_step.id
|
|
270
|
-
elif self.context.session.root_message:
|
|
271
|
-
self.root_parent_id = self.context.session.root_message.id
|
|
272
288
|
else:
|
|
273
289
|
self.root_parent_id = None
|
|
274
290
|
|
|
@@ -431,9 +447,6 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
431
447
|
self.ignored_runs.add(str(run.id))
|
|
432
448
|
return ignore, parent_id
|
|
433
449
|
|
|
434
|
-
def _is_annotable(self, run: Run):
|
|
435
|
-
return run.run_type in ["retriever", "llm"]
|
|
436
|
-
|
|
437
450
|
def _start_trace(self, run: Run) -> None:
|
|
438
451
|
super()._start_trace(run)
|
|
439
452
|
context_var.set(self.context)
|
|
@@ -463,17 +476,18 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
463
476
|
elif run.run_type == "embedding":
|
|
464
477
|
step_type = "embedding"
|
|
465
478
|
|
|
466
|
-
disable_feedback = not self._is_annotable(run)
|
|
467
|
-
|
|
468
479
|
step = Step(
|
|
469
480
|
id=str(run.id),
|
|
470
481
|
name=run.name,
|
|
471
482
|
type=step_type,
|
|
472
483
|
parent_id=parent_id,
|
|
473
|
-
disable_feedback=disable_feedback,
|
|
474
484
|
)
|
|
475
485
|
step.start = utc_now()
|
|
476
|
-
step.input = run.inputs
|
|
486
|
+
step.input, language = process_content(run.inputs)
|
|
487
|
+
if language is not None:
|
|
488
|
+
if step.metadata is None:
|
|
489
|
+
step.metadata = {}
|
|
490
|
+
step.metadata["language"] = language
|
|
477
491
|
|
|
478
492
|
self.steps[str(run.id)] = step
|
|
479
493
|
|
|
@@ -497,6 +511,9 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
497
511
|
generations = (run.outputs or {}).get("generations", [])
|
|
498
512
|
generation = generations[0][0]
|
|
499
513
|
variables = self.generation_inputs.get(str(run.parent_run_id), {})
|
|
514
|
+
variables = {
|
|
515
|
+
k: process_content(v) for k, v in variables.items() if v is not None
|
|
516
|
+
}
|
|
500
517
|
if message := generation.get("message"):
|
|
501
518
|
chat_start = self.chat_generations[str(run.id)]
|
|
502
519
|
duration = time.time() - chat_start["start"]
|
|
@@ -527,7 +544,11 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
527
544
|
"prompt_id"
|
|
528
545
|
]
|
|
529
546
|
if custom_variables := m.additional_kwargs.get("variables"):
|
|
530
|
-
current_step.generation.variables =
|
|
547
|
+
current_step.generation.variables = {
|
|
548
|
+
k: process_content(v)
|
|
549
|
+
for k, v in custom_variables.items()
|
|
550
|
+
if v is not None
|
|
551
|
+
}
|
|
531
552
|
break
|
|
532
553
|
|
|
533
554
|
current_step.language = "json"
|
|
@@ -571,7 +592,7 @@ class LangchainTracer(BaseTracer, GenerationHelper, FinalStreamHelper):
|
|
|
571
592
|
output = outputs.get(output_keys[0], outputs)
|
|
572
593
|
|
|
573
594
|
if current_step:
|
|
574
|
-
current_step.output = output
|
|
595
|
+
current_step.output, _ = output
|
|
575
596
|
current_step.end = utc_now()
|
|
576
597
|
self._run_sync(current_step.update())
|
|
577
598
|
|
|
@@ -41,11 +41,6 @@ class LlamaIndexCallbackHandler(TokenCountingHandler):
|
|
|
41
41
|
return event_parent_id
|
|
42
42
|
elif context_var.get().current_step:
|
|
43
43
|
return context_var.get().current_step.id
|
|
44
|
-
elif context_var.get().session.root_message:
|
|
45
|
-
root_message = context_var.get().session.root_message
|
|
46
|
-
if root_message:
|
|
47
|
-
return root_message.id
|
|
48
|
-
return None
|
|
49
44
|
else:
|
|
50
45
|
return None
|
|
51
46
|
|
|
@@ -73,7 +68,6 @@ class LlamaIndexCallbackHandler(TokenCountingHandler):
|
|
|
73
68
|
type=step_type,
|
|
74
69
|
parent_id=self._get_parent_id(parent_id),
|
|
75
70
|
id=event_id,
|
|
76
|
-
disable_feedback=True,
|
|
77
71
|
)
|
|
78
72
|
|
|
79
73
|
self.steps[event_id] = step
|
chainlit/message.py
CHANGED
|
@@ -32,7 +32,6 @@ class MessageBase(ABC):
|
|
|
32
32
|
author: str
|
|
33
33
|
content: str = ""
|
|
34
34
|
type: MessageStepType = "assistant_message"
|
|
35
|
-
disable_feedback = False
|
|
36
35
|
streaming = False
|
|
37
36
|
created_at: Union[str, None] = None
|
|
38
37
|
fail_on_persist_error: bool = False
|
|
@@ -67,7 +66,6 @@ class MessageBase(ABC):
|
|
|
67
66
|
content=_dict["output"],
|
|
68
67
|
author=_dict.get("name", config.ui.name),
|
|
69
68
|
type=type, # type: ignore
|
|
70
|
-
disable_feedback=_dict.get("disableFeedback", False),
|
|
71
69
|
language=_dict.get("language"),
|
|
72
70
|
)
|
|
73
71
|
|
|
@@ -87,7 +85,6 @@ class MessageBase(ABC):
|
|
|
87
85
|
"createdAt": self.created_at,
|
|
88
86
|
"language": self.language,
|
|
89
87
|
"streaming": self.streaming,
|
|
90
|
-
"disableFeedback": self.disable_feedback,
|
|
91
88
|
"isError": self.is_error,
|
|
92
89
|
"waitForAnswer": self.wait_for_answer,
|
|
93
90
|
"indent": self.indent,
|
|
@@ -208,7 +205,6 @@ class Message(MessageBase):
|
|
|
208
205
|
language (str, optional): Language of the code is the content is code. See https://react-code-blocks-rajinwonderland.vercel.app/?path=/story/codeblock--supported-languages for a list of supported languages.
|
|
209
206
|
actions (List[Action], optional): A list of actions to send with the message.
|
|
210
207
|
elements (List[ElementBased], optional): A list of elements to send with the message.
|
|
211
|
-
disable_feedback (bool, optional): Hide the feedback buttons for this specific message
|
|
212
208
|
"""
|
|
213
209
|
|
|
214
210
|
def __init__(
|
|
@@ -218,7 +214,6 @@ class Message(MessageBase):
|
|
|
218
214
|
language: Optional[str] = None,
|
|
219
215
|
actions: Optional[List[Action]] = None,
|
|
220
216
|
elements: Optional[List[ElementBased]] = None,
|
|
221
|
-
disable_feedback: bool = False,
|
|
222
217
|
type: MessageStepType = "assistant_message",
|
|
223
218
|
metadata: Optional[Dict] = None,
|
|
224
219
|
tags: Optional[List[str]] = None,
|
|
@@ -257,7 +252,6 @@ class Message(MessageBase):
|
|
|
257
252
|
self.type = type
|
|
258
253
|
self.actions = actions if actions is not None else []
|
|
259
254
|
self.elements = elements if elements is not None else []
|
|
260
|
-
self.disable_feedback = disable_feedback
|
|
261
255
|
|
|
262
256
|
super().__post_init__()
|
|
263
257
|
|
|
@@ -269,8 +263,6 @@ class Message(MessageBase):
|
|
|
269
263
|
trace_event("send_message")
|
|
270
264
|
await super().send()
|
|
271
265
|
|
|
272
|
-
context.session.root_message = self
|
|
273
|
-
|
|
274
266
|
# Create tasks for all actions and elements
|
|
275
267
|
tasks = [action.send(for_id=self.id) for action in self.actions]
|
|
276
268
|
tasks.extend(element.send(for_id=self.id) for element in self.elements)
|
|
@@ -355,7 +347,6 @@ class AskUserMessage(AskMessageBase):
|
|
|
355
347
|
Args:
|
|
356
348
|
content (str): The content of the prompt.
|
|
357
349
|
author (str, optional): The author of the message, this will be used in the UI. Defaults to the assistant name (see config).
|
|
358
|
-
disable_feedback (bool, optional): Hide the feedback buttons for this specific message
|
|
359
350
|
timeout (int, optional): The number of seconds to wait for an answer before raising a TimeoutError.
|
|
360
351
|
raise_on_timeout (bool, optional): Whether to raise a socketio TimeoutError if the user does not answer in time.
|
|
361
352
|
"""
|
|
@@ -365,7 +356,6 @@ class AskUserMessage(AskMessageBase):
|
|
|
365
356
|
content: str,
|
|
366
357
|
author: str = config.ui.name,
|
|
367
358
|
type: MessageStepType = "assistant_message",
|
|
368
|
-
disable_feedback: bool = True,
|
|
369
359
|
timeout: int = 60,
|
|
370
360
|
raise_on_timeout: bool = False,
|
|
371
361
|
):
|
|
@@ -373,7 +363,6 @@ class AskUserMessage(AskMessageBase):
|
|
|
373
363
|
self.author = author
|
|
374
364
|
self.timeout = timeout
|
|
375
365
|
self.type = type
|
|
376
|
-
self.disable_feedback = disable_feedback
|
|
377
366
|
self.raise_on_timeout = raise_on_timeout
|
|
378
367
|
|
|
379
368
|
super().__post_init__()
|
|
@@ -420,7 +409,6 @@ class AskFileMessage(AskMessageBase):
|
|
|
420
409
|
max_size_mb (int, optional): Maximum size per file in MB. Maximum value is 100.
|
|
421
410
|
max_files (int, optional): Maximum number of files to upload. Maximum value is 10.
|
|
422
411
|
author (str, optional): The author of the message, this will be used in the UI. Defaults to the assistant name (see config).
|
|
423
|
-
disable_feedback (bool, optional): Hide the feedback buttons for this specific message
|
|
424
412
|
timeout (int, optional): The number of seconds to wait for an answer before raising a TimeoutError.
|
|
425
413
|
raise_on_timeout (bool, optional): Whether to raise a socketio TimeoutError if the user does not answer in time.
|
|
426
414
|
"""
|
|
@@ -433,7 +421,6 @@ class AskFileMessage(AskMessageBase):
|
|
|
433
421
|
max_files=1,
|
|
434
422
|
author=config.ui.name,
|
|
435
423
|
type: MessageStepType = "assistant_message",
|
|
436
|
-
disable_feedback: bool = True,
|
|
437
424
|
timeout=90,
|
|
438
425
|
raise_on_timeout=False,
|
|
439
426
|
):
|
|
@@ -445,7 +432,6 @@ class AskFileMessage(AskMessageBase):
|
|
|
445
432
|
self.author = author
|
|
446
433
|
self.timeout = timeout
|
|
447
434
|
self.raise_on_timeout = raise_on_timeout
|
|
448
|
-
self.disable_feedback = disable_feedback
|
|
449
435
|
|
|
450
436
|
super().__post_init__()
|
|
451
437
|
|
|
@@ -509,14 +495,12 @@ class AskActionMessage(AskMessageBase):
|
|
|
509
495
|
content: str,
|
|
510
496
|
actions: List[Action],
|
|
511
497
|
author=config.ui.name,
|
|
512
|
-
disable_feedback=True,
|
|
513
498
|
timeout=90,
|
|
514
499
|
raise_on_timeout=False,
|
|
515
500
|
):
|
|
516
501
|
self.content = content
|
|
517
502
|
self.actions = actions
|
|
518
503
|
self.author = author
|
|
519
|
-
self.disable_feedback = disable_feedback
|
|
520
504
|
self.timeout = timeout
|
|
521
505
|
self.raise_on_timeout = raise_on_timeout
|
|
522
506
|
|
chainlit/mistralai/__init__.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from typing import Union
|
|
3
3
|
|
|
4
|
-
from literalai import ChatGeneration, CompletionGeneration
|
|
5
|
-
from literalai.helper import timestamp_utc
|
|
6
|
-
|
|
7
4
|
from chainlit.context import get_context
|
|
8
5
|
from chainlit.step import Step
|
|
9
6
|
from chainlit.utils import check_module_version
|
|
7
|
+
from literalai import ChatGeneration, CompletionGeneration
|
|
8
|
+
from literalai.helper import timestamp_utc
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
def instrument_mistralai():
|
|
@@ -20,8 +19,6 @@ def instrument_mistralai():
|
|
|
20
19
|
parent_id = None
|
|
21
20
|
if context.current_step:
|
|
22
21
|
parent_id = context.current_step.id
|
|
23
|
-
elif context.session.root_message:
|
|
24
|
-
parent_id = context.session.root_message.id
|
|
25
22
|
|
|
26
23
|
step = Step(
|
|
27
24
|
name=generation.model if generation.model else generation.provider,
|
chainlit/openai/__init__.py
CHANGED
|
@@ -24,8 +24,6 @@ def instrument_openai():
|
|
|
24
24
|
parent_id = None
|
|
25
25
|
if context.current_step:
|
|
26
26
|
parent_id = context.current_step.id
|
|
27
|
-
elif context.session.root_message:
|
|
28
|
-
parent_id = context.session.root_message.id
|
|
29
27
|
|
|
30
28
|
step = Step(
|
|
31
29
|
name=generation.model if generation.model else generation.provider,
|
chainlit/server.py
CHANGED
|
@@ -266,7 +266,7 @@ def get_html_template():
|
|
|
266
266
|
)
|
|
267
267
|
url = config.ui.github or default_url
|
|
268
268
|
meta_image_url = config.ui.custom_meta_image_url or default_meta_image_url
|
|
269
|
-
favicon_path =
|
|
269
|
+
favicon_path = "/favicon"
|
|
270
270
|
|
|
271
271
|
tags = f"""<title>{config.ui.name}</title>
|
|
272
272
|
<link rel="icon" href="{favicon_path}" />
|
|
@@ -332,7 +332,7 @@ def get_user_facing_url(url: URL):
|
|
|
332
332
|
if config_url.path.endswith("/"):
|
|
333
333
|
config_url = config_url.replace(path=config_url.path[:-1])
|
|
334
334
|
|
|
335
|
-
return config_url.__str__()
|
|
335
|
+
return config_url.__str__() + url.path
|
|
336
336
|
|
|
337
337
|
|
|
338
338
|
@router.get("/auth/config")
|
chainlit/session.py
CHANGED
|
@@ -35,17 +35,16 @@ class JSONEncoderIgnoreNonSerializable(json.JSONEncoder):
|
|
|
35
35
|
return None
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
|
|
39
38
|
def clean_metadata(metadata: Dict, max_size: int = 1048576):
|
|
40
39
|
cleaned_metadata = json.loads(
|
|
41
40
|
json.dumps(metadata, cls=JSONEncoderIgnoreNonSerializable, ensure_ascii=False)
|
|
42
41
|
)
|
|
43
42
|
|
|
44
|
-
metadata_size = len(json.dumps(cleaned_metadata).encode(
|
|
43
|
+
metadata_size = len(json.dumps(cleaned_metadata).encode("utf-8"))
|
|
45
44
|
if metadata_size > max_size:
|
|
46
45
|
# Redact the metadata if it exceeds the maximum size
|
|
47
46
|
cleaned_metadata = {
|
|
48
|
-
|
|
47
|
+
"message": f"Metadata size exceeds the limit of {max_size} bytes. Redacted."
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
return cleaned_metadata
|
|
@@ -71,8 +70,6 @@ class BaseSession:
|
|
|
71
70
|
token: Optional[str],
|
|
72
71
|
# User specific environment variables. Empty if no user environment variables are required.
|
|
73
72
|
user_env: Optional[Dict[str, str]],
|
|
74
|
-
# Last message at the root of the chat
|
|
75
|
-
root_message: Optional["Message"] = None,
|
|
76
73
|
# Chat profile selected before the session was created
|
|
77
74
|
chat_profile: Optional[str] = None,
|
|
78
75
|
# Origin of the request
|
|
@@ -84,7 +81,6 @@ class BaseSession:
|
|
|
84
81
|
self.user = user
|
|
85
82
|
self.client_type = client_type
|
|
86
83
|
self.token = token
|
|
87
|
-
self.root_message = root_message
|
|
88
84
|
self.has_first_interaction = False
|
|
89
85
|
self.user_env = user_env or {}
|
|
90
86
|
self.chat_profile = chat_profile
|
|
@@ -178,8 +174,6 @@ class HTTPSession(BaseSession):
|
|
|
178
174
|
# Logged-in user token
|
|
179
175
|
token: Optional[str] = None,
|
|
180
176
|
user_env: Optional[Dict[str, str]] = None,
|
|
181
|
-
# Last message at the root of the chat
|
|
182
|
-
root_message: Optional["Message"] = None,
|
|
183
177
|
# Origin of the request
|
|
184
178
|
http_referer: Optional[str] = None,
|
|
185
179
|
):
|
|
@@ -190,7 +184,6 @@ class HTTPSession(BaseSession):
|
|
|
190
184
|
token=token,
|
|
191
185
|
client_type=client_type,
|
|
192
186
|
user_env=user_env,
|
|
193
|
-
root_message=root_message,
|
|
194
187
|
http_referer=http_referer,
|
|
195
188
|
)
|
|
196
189
|
|
|
@@ -233,8 +226,6 @@ class WebsocketSession(BaseSession):
|
|
|
233
226
|
user: Optional[Union["User", "PersistedUser"]] = None,
|
|
234
227
|
# Logged-in user token
|
|
235
228
|
token: Optional[str] = None,
|
|
236
|
-
# Last message at the root of the chat
|
|
237
|
-
root_message: Optional["Message"] = None,
|
|
238
229
|
# Chat profile selected before the session was created
|
|
239
230
|
chat_profile: Optional[str] = None,
|
|
240
231
|
# Languages of the user's browser
|
|
@@ -249,7 +240,6 @@ class WebsocketSession(BaseSession):
|
|
|
249
240
|
token=token,
|
|
250
241
|
user_env=user_env,
|
|
251
242
|
client_type=client_type,
|
|
252
|
-
root_message=root_message,
|
|
253
243
|
chat_profile=chat_profile,
|
|
254
244
|
http_referer=http_referer,
|
|
255
245
|
)
|
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
|
|
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
|
-
|
|
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
|
|
70
|
+
if is_empty_output or not is_assistant_message:
|
|
79
71
|
return
|
|
80
72
|
|
|
81
|
-
enable_feedback =
|
|
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":
|
|
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":
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
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")
|
chainlit/socket.py
CHANGED
|
@@ -7,9 +7,9 @@ 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
|
-
from chainlit.chat_context import chat_context
|
|
13
13
|
from chainlit.data import get_data_layer
|
|
14
14
|
from chainlit.element import Element
|
|
15
15
|
from chainlit.logger import logger
|
|
@@ -184,11 +184,11 @@ async def connection_successful(sid):
|
|
|
184
184
|
{"interaction": "resume", "thread_id": thread.get("id")},
|
|
185
185
|
)
|
|
186
186
|
await config.code.on_chat_resume(thread)
|
|
187
|
-
|
|
187
|
+
|
|
188
188
|
for step in thread.get("steps", []):
|
|
189
189
|
if "message" in step["type"]:
|
|
190
190
|
chat_context.add(Message.from_dict(step))
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
await context.emitter.resume_thread(thread)
|
|
193
193
|
return
|
|
194
194
|
|
|
@@ -244,7 +244,7 @@ async def stop(sid):
|
|
|
244
244
|
trace_event("stop_task")
|
|
245
245
|
|
|
246
246
|
init_ws_context(session)
|
|
247
|
-
await Message(content="Task manually stopped."
|
|
247
|
+
await Message(content="Task manually stopped.").send()
|
|
248
248
|
|
|
249
249
|
if session.current_task:
|
|
250
250
|
session.current_task.cancel()
|
|
@@ -282,18 +282,18 @@ async def edit_message(sid, payload: MessagePayload):
|
|
|
282
282
|
context = init_ws_context(session)
|
|
283
283
|
|
|
284
284
|
messages = chat_context.get()
|
|
285
|
-
|
|
285
|
+
|
|
286
286
|
orig_message = None
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
for message in messages:
|
|
289
289
|
if orig_message:
|
|
290
|
-
await message.remove()
|
|
291
|
-
|
|
290
|
+
await message.remove()
|
|
291
|
+
|
|
292
292
|
if message.id == payload["message"]["id"]:
|
|
293
293
|
message.content = payload["message"]["output"]
|
|
294
294
|
await message.update()
|
|
295
295
|
orig_message = message
|
|
296
|
-
|
|
296
|
+
|
|
297
297
|
await context.emitter.task_start()
|
|
298
298
|
|
|
299
299
|
if config.code.on_message:
|
|
@@ -303,7 +303,7 @@ async def edit_message(sid, payload: MessagePayload):
|
|
|
303
303
|
pass
|
|
304
304
|
finally:
|
|
305
305
|
await context.emitter.task_end()
|
|
306
|
-
|
|
306
|
+
|
|
307
307
|
|
|
308
308
|
@sio.on("client_message")
|
|
309
309
|
async def message(sid, payload: MessagePayload):
|