chainlit 1.0.401__py3-none-any.whl → 2.0.4__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 (113) hide show
  1. chainlit/__init__.py +98 -279
  2. chainlit/_utils.py +8 -0
  3. chainlit/action.py +12 -10
  4. chainlit/{auth.py → auth/__init__.py} +28 -36
  5. chainlit/auth/cookie.py +123 -0
  6. chainlit/auth/jwt.py +39 -0
  7. chainlit/cache.py +4 -6
  8. chainlit/callbacks.py +362 -0
  9. chainlit/chat_context.py +64 -0
  10. chainlit/chat_settings.py +3 -1
  11. chainlit/cli/__init__.py +77 -8
  12. chainlit/config.py +191 -102
  13. chainlit/context.py +42 -13
  14. chainlit/copilot/dist/index.js +8750 -903
  15. chainlit/data/__init__.py +101 -416
  16. chainlit/data/acl.py +6 -2
  17. chainlit/data/base.py +107 -0
  18. chainlit/data/chainlit_data_layer.py +614 -0
  19. chainlit/data/dynamodb.py +590 -0
  20. chainlit/data/literalai.py +500 -0
  21. chainlit/data/sql_alchemy.py +721 -0
  22. chainlit/data/storage_clients/__init__.py +0 -0
  23. chainlit/data/storage_clients/azure.py +81 -0
  24. chainlit/data/storage_clients/azure_blob.py +89 -0
  25. chainlit/data/storage_clients/base.py +26 -0
  26. chainlit/data/storage_clients/gcs.py +88 -0
  27. chainlit/data/storage_clients/s3.py +75 -0
  28. chainlit/data/utils.py +29 -0
  29. chainlit/discord/__init__.py +6 -0
  30. chainlit/discord/app.py +354 -0
  31. chainlit/element.py +91 -33
  32. chainlit/emitter.py +81 -29
  33. chainlit/frontend/dist/assets/DailyMotion-Ce9dQoqZ.js +1 -0
  34. chainlit/frontend/dist/assets/Dataframe-C1XonMcV.js +22 -0
  35. chainlit/frontend/dist/assets/Facebook-DVVt6lrr.js +1 -0
  36. chainlit/frontend/dist/assets/FilePlayer-c7stW4vz.js +1 -0
  37. chainlit/frontend/dist/assets/Kaltura-BmMmgorA.js +1 -0
  38. chainlit/frontend/dist/assets/Mixcloud-Cw8hDmiO.js +1 -0
  39. chainlit/frontend/dist/assets/Mux-DiRZfeUf.js +1 -0
  40. chainlit/frontend/dist/assets/Preview-6Jt2mRHx.js +1 -0
  41. chainlit/frontend/dist/assets/SoundCloud-DKwcT58_.js +1 -0
  42. chainlit/frontend/dist/assets/Streamable-BVdxrEeX.js +1 -0
  43. chainlit/frontend/dist/assets/Twitch-DFqZR7Gu.js +1 -0
  44. chainlit/frontend/dist/assets/Vidyard-0BQAAtVk.js +1 -0
  45. chainlit/frontend/dist/assets/Vimeo-CRFSH0Vu.js +1 -0
  46. chainlit/frontend/dist/assets/Wistia-CKrmdQaG.js +1 -0
  47. chainlit/frontend/dist/assets/YouTube-CQpL-rvU.js +1 -0
  48. chainlit/frontend/dist/assets/index-DQmLRKyv.css +1 -0
  49. chainlit/frontend/dist/assets/index-QdmxtIMQ.js +8665 -0
  50. chainlit/frontend/dist/assets/react-plotly-B9hvVpUG.js +3484 -0
  51. chainlit/frontend/dist/index.html +2 -4
  52. chainlit/haystack/callbacks.py +4 -7
  53. chainlit/input_widget.py +8 -4
  54. chainlit/langchain/callbacks.py +103 -68
  55. chainlit/langflow/__init__.py +1 -0
  56. chainlit/llama_index/callbacks.py +65 -40
  57. chainlit/markdown.py +22 -6
  58. chainlit/message.py +54 -56
  59. chainlit/mistralai/__init__.py +50 -0
  60. chainlit/oauth_providers.py +266 -8
  61. chainlit/openai/__init__.py +10 -18
  62. chainlit/secret.py +1 -1
  63. chainlit/server.py +789 -228
  64. chainlit/session.py +108 -90
  65. chainlit/slack/__init__.py +6 -0
  66. chainlit/slack/app.py +397 -0
  67. chainlit/socket.py +199 -116
  68. chainlit/step.py +141 -89
  69. chainlit/sync.py +2 -1
  70. chainlit/teams/__init__.py +6 -0
  71. chainlit/teams/app.py +338 -0
  72. chainlit/translations/bn.json +244 -0
  73. chainlit/translations/en-US.json +122 -8
  74. chainlit/translations/gu.json +244 -0
  75. chainlit/translations/he-IL.json +244 -0
  76. chainlit/translations/hi.json +244 -0
  77. chainlit/translations/ja.json +242 -0
  78. chainlit/translations/kn.json +244 -0
  79. chainlit/translations/ml.json +244 -0
  80. chainlit/translations/mr.json +244 -0
  81. chainlit/translations/nl-NL.json +242 -0
  82. chainlit/translations/ta.json +244 -0
  83. chainlit/translations/te.json +244 -0
  84. chainlit/translations/zh-CN.json +243 -0
  85. chainlit/translations.py +60 -0
  86. chainlit/types.py +133 -28
  87. chainlit/user.py +14 -3
  88. chainlit/user_session.py +6 -3
  89. chainlit/utils.py +52 -5
  90. chainlit/version.py +3 -2
  91. {chainlit-1.0.401.dist-info → chainlit-2.0.4.dist-info}/METADATA +48 -50
  92. chainlit-2.0.4.dist-info/RECORD +107 -0
  93. chainlit/cli/utils.py +0 -24
  94. chainlit/frontend/dist/assets/index-9711593e.js +0 -723
  95. chainlit/frontend/dist/assets/index-d088547c.css +0 -1
  96. chainlit/frontend/dist/assets/react-plotly-d8762cc2.js +0 -3602
  97. chainlit/playground/__init__.py +0 -2
  98. chainlit/playground/config.py +0 -40
  99. chainlit/playground/provider.py +0 -108
  100. chainlit/playground/providers/__init__.py +0 -13
  101. chainlit/playground/providers/anthropic.py +0 -118
  102. chainlit/playground/providers/huggingface.py +0 -75
  103. chainlit/playground/providers/langchain.py +0 -89
  104. chainlit/playground/providers/openai.py +0 -408
  105. chainlit/playground/providers/vertexai.py +0 -171
  106. chainlit/translations/pt-BR.json +0 -155
  107. chainlit-1.0.401.dist-info/RECORD +0 -66
  108. /chainlit/copilot/dist/assets/{logo_dark-2a3cf740.svg → logo_dark-IkGJ_IwC.svg} +0 -0
  109. /chainlit/copilot/dist/assets/{logo_light-b078e7bc.svg → logo_light-Bb_IPh6r.svg} +0 -0
  110. /chainlit/frontend/dist/assets/{logo_dark-2a3cf740.svg → logo_dark-IkGJ_IwC.svg} +0 -0
  111. /chainlit/frontend/dist/assets/{logo_light-b078e7bc.svg → logo_light-Bb_IPh6r.svg} +0 -0
  112. {chainlit-1.0.401.dist-info → chainlit-2.0.4.dist-info}/WHEEL +0 -0
  113. {chainlit-1.0.401.dist-info → chainlit-2.0.4.dist-info}/entry_points.txt +0 -0
chainlit/teams/app.py ADDED
@@ -0,0 +1,338 @@
1
+ import asyncio
2
+ import base64
3
+ import mimetypes
4
+ import os
5
+ import uuid
6
+ from datetime import datetime
7
+ from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Union
8
+
9
+ import filetype
10
+
11
+ if TYPE_CHECKING:
12
+ from botbuilder.core import TurnContext
13
+ from botbuilder.schema import Activity
14
+
15
+ import httpx
16
+ from botbuilder.core import (
17
+ BotFrameworkAdapter,
18
+ BotFrameworkAdapterSettings,
19
+ MessageFactory,
20
+ TurnContext,
21
+ )
22
+ from botbuilder.schema import (
23
+ ActionTypes,
24
+ Activity,
25
+ ActivityTypes,
26
+ Attachment,
27
+ CardAction,
28
+ ChannelAccount,
29
+ HeroCard,
30
+ )
31
+
32
+ from chainlit.config import config
33
+ from chainlit.context import ChainlitContext, HTTPSession, context, context_var
34
+ from chainlit.data import get_data_layer
35
+ from chainlit.element import Element, ElementDict
36
+ from chainlit.emitter import BaseChainlitEmitter
37
+ from chainlit.logger import logger
38
+ from chainlit.message import Message, StepDict
39
+ from chainlit.telemetry import trace
40
+ from chainlit.types import Feedback
41
+ from chainlit.user import PersistedUser, User
42
+ from chainlit.user_session import user_session
43
+
44
+
45
+ class TeamsEmitter(BaseChainlitEmitter):
46
+ def __init__(self, session: HTTPSession, turn_context: TurnContext):
47
+ super().__init__(session)
48
+ self.turn_context = turn_context
49
+
50
+ async def send_element(self, element_dict: ElementDict):
51
+ if element_dict.get("display") != "inline":
52
+ return
53
+
54
+ persisted_file = self.session.files.get(element_dict.get("chainlitKey") or "")
55
+ attachment: Optional[Attachment] = None
56
+ mime: Optional[str] = None
57
+
58
+ element_name: str = element_dict.get("name", "Untitled")
59
+
60
+ if mime:
61
+ file_extension = mimetypes.guess_extension(mime)
62
+ if file_extension:
63
+ element_name += file_extension
64
+
65
+ if persisted_file:
66
+ mime = element_dict.get("mime")
67
+ with open(persisted_file["path"], "rb") as file:
68
+ dencoded_string = base64.b64encode(file.read()).decode()
69
+ content_url = f"data:{mime};base64,{dencoded_string}"
70
+ attachment = Attachment(
71
+ content_type=mime, content_url=content_url, name=element_name
72
+ )
73
+
74
+ elif url := element_dict.get("url"):
75
+ attachment = Attachment(
76
+ content_type=mime, content_url=url, name=element_name
77
+ )
78
+
79
+ if not attachment:
80
+ return
81
+
82
+ await self.turn_context.send_activity(Activity(attachments=[attachment]))
83
+
84
+ async def send_step(self, step_dict: StepDict):
85
+ if not step_dict["type"] == "assistant_message":
86
+ return
87
+
88
+ step_type = step_dict.get("type")
89
+ is_message = step_type in [
90
+ "user_message",
91
+ "assistant_message",
92
+ ]
93
+ is_empty_output = not step_dict.get("output")
94
+
95
+ if is_empty_output or not is_message:
96
+ return
97
+ else:
98
+ reply = MessageFactory.text(step_dict["output"])
99
+ enable_feedback = get_data_layer()
100
+ if enable_feedback:
101
+ current_run = context.current_run
102
+ scorable_id = current_run.id if current_run else step_dict["id"]
103
+ like_button = CardAction(
104
+ type=ActionTypes.message_back,
105
+ title="👍",
106
+ text="like",
107
+ value={"feedback": "like", "step_id": scorable_id},
108
+ )
109
+ dislike_button = CardAction(
110
+ type=ActionTypes.message_back,
111
+ title="👎",
112
+ text="dislike",
113
+ value={"feedback": "dislike", "step_id": scorable_id},
114
+ )
115
+ card = HeroCard(buttons=[like_button, dislike_button])
116
+ attachment = Attachment(
117
+ content_type="application/vnd.microsoft.card.hero", content=card
118
+ )
119
+ reply.attachments = [attachment]
120
+
121
+ await self.turn_context.send_activity(reply)
122
+
123
+ async def update_step(self, step_dict: StepDict):
124
+ if not step_dict["type"] == "assistant_message":
125
+ return
126
+
127
+ await self.send_step(step_dict)
128
+
129
+
130
+ adapter_settings = BotFrameworkAdapterSettings(
131
+ app_id=os.environ.get("TEAMS_APP_ID"),
132
+ app_password=os.environ.get("TEAMS_APP_PASSWORD"),
133
+ )
134
+ adapter = BotFrameworkAdapter(adapter_settings)
135
+
136
+
137
+ @trace
138
+ def init_teams_context(
139
+ session: HTTPSession,
140
+ turn_context: TurnContext,
141
+ ) -> ChainlitContext:
142
+ emitter = TeamsEmitter(session=session, turn_context=turn_context)
143
+ context = ChainlitContext(session=session, emitter=emitter)
144
+ context_var.set(context)
145
+ user_session.set("teams_turn_context", turn_context)
146
+ return context
147
+
148
+
149
+ users_by_teams_id: Dict[str, Union[User, PersistedUser]] = {}
150
+
151
+ USER_PREFIX = "teams_"
152
+
153
+
154
+ async def get_user(teams_user: ChannelAccount):
155
+ if teams_user.id in users_by_teams_id:
156
+ return users_by_teams_id[teams_user.id]
157
+
158
+ metadata = {
159
+ "name": teams_user.name,
160
+ "id": teams_user.id,
161
+ }
162
+ user = User(identifier=USER_PREFIX + str(teams_user.name), metadata=metadata)
163
+
164
+ users_by_teams_id[teams_user.id] = user
165
+
166
+ if data_layer := get_data_layer():
167
+ try:
168
+ persisted_user = await data_layer.create_user(user)
169
+ if persisted_user:
170
+ users_by_teams_id[teams_user.id] = persisted_user
171
+ except Exception as e:
172
+ logger.error(f"Error creating user: {e}")
173
+
174
+ return users_by_teams_id[teams_user.id]
175
+
176
+
177
+ async def download_teams_file(url: str):
178
+ async with httpx.AsyncClient() as client:
179
+ response = await client.get(url)
180
+ if response.status_code == 200:
181
+ return response.content
182
+ else:
183
+ return None
184
+
185
+
186
+ async def download_teams_files(
187
+ session: HTTPSession, attachments: Optional[List[Attachment]] = None
188
+ ):
189
+ if not attachments:
190
+ return []
191
+
192
+ attachments = [
193
+ attachment for attachment in attachments if isinstance(attachment.content, dict)
194
+ ]
195
+ download_coros = [
196
+ download_teams_file(attachment.content.get("downloadUrl"))
197
+ for attachment in attachments
198
+ ]
199
+ file_bytes_list = await asyncio.gather(*download_coros)
200
+ file_refs = []
201
+ for idx, file_bytes in enumerate(file_bytes_list):
202
+ if file_bytes:
203
+ name = attachments[idx].name
204
+ mime_type = filetype.guess_mime(file_bytes) or "application/octet-stream"
205
+ file_ref = await session.persist_file(
206
+ name=name, mime=mime_type, content=file_bytes
207
+ )
208
+ file_refs.append(file_ref)
209
+
210
+ files_dicts = [
211
+ session.files[file["id"]] for file in file_refs if file["id"] in session.files
212
+ ]
213
+
214
+ file_elements = [Element.from_dict(file_dict) for file_dict in files_dicts]
215
+
216
+ return file_elements
217
+
218
+
219
+ def clean_content(activity: Activity):
220
+ return activity.text.strip()
221
+
222
+
223
+ async def process_teams_message(
224
+ turn_context: TurnContext,
225
+ thread_name: str,
226
+ ):
227
+ user = await get_user(turn_context.activity.from_property)
228
+
229
+ thread_id = str(
230
+ uuid.uuid5(
231
+ uuid.NAMESPACE_DNS,
232
+ str(
233
+ turn_context.activity.conversation.id
234
+ + datetime.today().strftime("%Y-%m-%d")
235
+ ),
236
+ )
237
+ )
238
+
239
+ text = clean_content(turn_context.activity)
240
+ teams_files = turn_context.activity.attachments
241
+
242
+ session_id = str(uuid.uuid4())
243
+
244
+ session = HTTPSession(
245
+ id=session_id,
246
+ thread_id=thread_id,
247
+ user=user,
248
+ client_type="teams",
249
+ )
250
+
251
+ ctx = init_teams_context(
252
+ session=session,
253
+ turn_context=turn_context,
254
+ )
255
+
256
+ file_elements = await download_teams_files(session, teams_files)
257
+
258
+ if on_chat_start := config.code.on_chat_start:
259
+ await on_chat_start()
260
+
261
+ msg = Message(
262
+ content=text,
263
+ elements=file_elements,
264
+ type="user_message",
265
+ author=user.metadata.get("name"),
266
+ )
267
+
268
+ await msg.send()
269
+
270
+ if on_message := config.code.on_message:
271
+ await on_message(msg)
272
+
273
+ if on_chat_end := config.code.on_chat_end:
274
+ await on_chat_end()
275
+
276
+ if data_layer := get_data_layer():
277
+ if isinstance(user, PersistedUser):
278
+ try:
279
+ await data_layer.update_thread(
280
+ thread_id=thread_id,
281
+ name=thread_name,
282
+ metadata=ctx.session.to_persistable(),
283
+ user_id=user.id,
284
+ )
285
+ except Exception as e:
286
+ logger.error(f"Error updating thread: {e}")
287
+
288
+ ctx.session.delete()
289
+
290
+
291
+ async def handle_message(turn_context: TurnContext):
292
+ if turn_context.activity.type == ActivityTypes.message:
293
+ if (
294
+ turn_context.activity.text == "like"
295
+ or turn_context.activity.text == "dislike"
296
+ ):
297
+ feedback_value: Literal[0, 1] = (
298
+ 0 if turn_context.activity.text == "dislike" else 1
299
+ )
300
+ step_id = turn_context.activity.value.get("step_id")
301
+ if data_layer := get_data_layer():
302
+ await data_layer.upsert_feedback(
303
+ Feedback(forId=step_id, value=feedback_value)
304
+ )
305
+ updated_text = "👍" if turn_context.activity.text == "like" else "👎"
306
+ # Update the existing message to remove the buttons
307
+ updated_message = Activity(
308
+ type=ActivityTypes.message,
309
+ id=turn_context.activity.reply_to_id,
310
+ text=updated_text,
311
+ attachments=[],
312
+ )
313
+ await turn_context.update_activity(updated_message)
314
+ else:
315
+ # Send typing activity
316
+ typing_activity = Activity(
317
+ type=ActivityTypes.typing,
318
+ from_property=turn_context.activity.recipient,
319
+ recipient=turn_context.activity.from_property,
320
+ conversation=turn_context.activity.conversation,
321
+ )
322
+ await turn_context.send_activity(typing_activity)
323
+ thread_name = f"{turn_context.activity.from_property.name} Teams DM {datetime.today().strftime('%Y-%m-%d')}"
324
+ await process_teams_message(turn_context, thread_name)
325
+
326
+
327
+ async def on_turn(turn_context: TurnContext):
328
+ await handle_message(turn_context)
329
+
330
+
331
+ # Create the main bot class
332
+ class TeamsBot:
333
+ async def on_turn(self, turn_context: TurnContext):
334
+ await on_turn(turn_context)
335
+
336
+
337
+ # Create the bot instance
338
+ bot = TeamsBot()
@@ -0,0 +1,244 @@
1
+ {
2
+ "components": {
3
+ "atoms": {
4
+ "buttons": {
5
+ "userButton": {
6
+ "menu": {
7
+ "settings": "সেটিংস",
8
+ "settingsKey": "S",
9
+ "APIKeys": "এপিআই কী",
10
+ "logout": "লগআউট"
11
+ }
12
+ }
13
+ }
14
+ },
15
+ "molecules": {
16
+ "newChatButton": {
17
+ "newChat": "নতুন আড্ডা"
18
+ },
19
+ "tasklist": {
20
+ "TaskList": {
21
+ "title": "🗒️ কার্য তালিকা",
22
+ "loading": "লোড।।।",
23
+ "error": "একটি ত্রুটি সংঘটিত হয়েছে"
24
+ }
25
+ },
26
+ "attachments": {
27
+ "cancelUpload": "আপলোড বাতিল করুন",
28
+ "removeAttachment": "সংযুক্তি সরান"
29
+ },
30
+ "newChatDialog": {
31
+ "createNewChat": "নতুন চ্যাট তৈরি করবেন?",
32
+ "clearChat": "এটি বর্তমান বার্তাগুলি সাফ করবে এবং একটি নতুন চ্যাট শুরু করবে।",
33
+ "cancel": "বাতিল",
34
+ "confirm": "নিশ্চিত"
35
+ },
36
+ "settingsModal": {
37
+ "settings": "সেটিংস",
38
+ "expandMessages": "বার্তাগুলি প্রসারিত করুন",
39
+ "hideChainOfThought": "চিন্তার শৃঙ্খল লুকান",
40
+ "darkMode": "ডার্ক মোড"
41
+ },
42
+ "detailsButton": {
43
+ "using": "ব্যবহার",
44
+ "running": "চলমান",
45
+ "took_one": "{{count}} পদক্ষেপ নিয়েছে",
46
+ "took_other": "{{count}}টি পদক্ষেপ নিয়েছে"
47
+ },
48
+ "auth": {
49
+ "authLogin": {
50
+ "title": "অ্যাপটি অ্যাক্সেস করতে লগইন করুন।",
51
+ "form": {
52
+ "email": "ই-মেইল ঠিকানা",
53
+ "password": "পাসওয়ার্ড",
54
+ "noAccount": "কোনও অ্যাকাউন্ট নেই?",
55
+ "alreadyHaveAccount": "ইতিমধ্যে একটি অ্যাকাউন্ট আছে?",
56
+ "signup": "সাইন আপ করো",
57
+ "signin": "সাইন ইন করো",
58
+ "or": "বা",
59
+ "continue": "অবিরত",
60
+ "forgotPassword": "পাসওয়ার্ড ভুলে গেছেন?",
61
+ "passwordMustContain": "আপনার পাসওয়ার্ডে অবশ্যই থাকতে হবে:",
62
+ "emailRequired": "ইমেল একটি প্রয়োজনীয় ক্ষেত্র",
63
+ "passwordRequired": "পাসওয়ার্ড একটি আবশ্যক ক্ষেত্র"
64
+ },
65
+ "error": {
66
+ "default": "সাইন ইন করতে অক্ষম।",
67
+ "signin": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
68
+ "oauthsignin": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
69
+ "redirect_uri_mismatch": "পুনঃনির্দেশিত URI OAUTH অ্যাপ কনফিগারেশনের সাথে মিলছে না।",
70
+ "oauthcallbackerror": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
71
+ "oauthcreateaccount": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
72
+ "emailcreateaccount": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
73
+ "callback": "একটি ভিন্ন অ্যাকাউন্ট দিয়ে সাইন ইন করার চেষ্টা করুন।",
74
+ "oauthaccountnotlinked": "আপনার পরিচয় নিশ্চিত করতে, আপনি মূলত যে অ্যাকাউন্টটি ব্যবহার করেছেন সেই একই অ্যাকাউন্ট দিয়ে সাইন ইন করুন।",
75
+ "emailsignin": "ই-মেইলটি প্রেরণ করা যায়নি।",
76
+ "emailverify": "অনুগ্রহ করে আপনার ইমেলটি যাচাই করুন, একটি নতুন ইমেল প্রেরণ করা হয়েছে।",
77
+ "credentialssignin": "সাইন ইন ব্যর্থ হয়েছে। আপনার প্রদত্ত বিবরণগুলি সঠিক কিনা তা পরীক্ষা করুন।",
78
+ "sessionrequired": "এই পৃষ্ঠাটি অ্যাক্সেস করতে দয়া করে সাইন ইন করুন।"
79
+ }
80
+ },
81
+ "authVerifyEmail": {
82
+ "almostThere": "আপনি প্রায় সেখানে পৌঁছেছেন! আমরা একটি ইমেইল পাঠিয়েছি ",
83
+ "verifyEmailLink": "আপনার সাইনআপ সম্পূর্ণ করতে দয়া করে সেই ইমেলের লিঙ্কটিতে ক্লিক করুন।",
84
+ "didNotReceive": "ইমেইল খুঁজে পাচ্ছেন না?",
85
+ "resendEmail": "ইমেইল পুনরায় পাঠান",
86
+ "goBack": "ফিরে যাও",
87
+ "emailSent": "ইমেল সফলভাবে পাঠানো হয়েছে।",
88
+ "verifyEmail": "আপনার ইমেল ঠিকানা যাচাই করুন"
89
+ },
90
+ "providerButton": {
91
+ "continue": "{{provider}} দিয়ে চালিয়ে যান",
92
+ "signup": "{{provider}} দিয়ে সাইন আপ করুন"
93
+ },
94
+ "authResetPassword": {
95
+ "newPasswordRequired": "নতুন পাসওয়ার্ড একটি আবশ্যক ক্ষেত্র",
96
+ "passwordsMustMatch": "পাসওয়ার্ড অবশ্যই মিলতে হবে",
97
+ "confirmPasswordRequired": "পাসওয়ার্ড নিশ্চিত করা একটি আবশ্যক ক্ষেত্র",
98
+ "newPassword": "নতুন পাসওয়ার্ড",
99
+ "confirmPassword": "পাসওয়ার্ড নিশ্চিত করুন",
100
+ "resetPassword": "পাসওয়ার্ড রিসেট করুন"
101
+ },
102
+ "authForgotPassword": {
103
+ "email": "ই-মেইল ঠিকানা",
104
+ "emailRequired": "ইমেল একটি প্রয়োজনীয় ক্ষেত্র",
105
+ "emailSent": "আপনার পাসওয়ার্ডটি পুনরায় সেট করার নির্দেশাবলীর জন্য দয়া করে ইমেল ঠিকানা {{email}} পরীক্ষা করুন।",
106
+ "enterEmail": "আপনার ইমেল ঠিকানা লিখুন এবং আমরা আপনাকে আপনার পাসওয়ার্ড পুনরায় সেট করতে নির্দেশাবলী পাঠাব।",
107
+ "resendEmail": "ইমেইল পুনরায় পাঠান",
108
+ "continue": "অবিরত",
109
+ "goBack": "ফিরে যাও"
110
+ }
111
+ }
112
+ },
113
+ "organisms": {
114
+ "chat": {
115
+ "history": {
116
+ "index": {
117
+ "showHistory": "ইতিহাস দেখান",
118
+ "lastInputs": "সর্বশেষ ইনপুট",
119
+ "noInputs": "এত ফাঁকা...",
120
+ "loading": "লোড।।।"
121
+ }
122
+ },
123
+ "inputBox": {
124
+ "input": {
125
+ "placeholder": "এখানে আপনার বার্তা টাইপ করুন..."
126
+ },
127
+ "speechButton": {
128
+ "start": "রেকর্ডিং শুরু করুন",
129
+ "stop": "রেকর্ডিং বন্ধ করুন"
130
+ },
131
+ "SubmitButton": {
132
+ "sendMessage": "বার্তা প্রেরণ করুন",
133
+ "stopTask": "স্টপ টাস্ক"
134
+ },
135
+ "UploadButton": {
136
+ "attachFiles": "ফাইল সংযুক্ত করুন"
137
+ },
138
+ "waterMark": {
139
+ "text": "সঙ্গে নির্মিত"
140
+ }
141
+ },
142
+ "Messages": {
143
+ "index": {
144
+ "running": "চলমান",
145
+ "executedSuccessfully": "সফলভাবে সম্পাদিত হয়েছে",
146
+ "failed": "ব্যর্থ",
147
+ "feedbackUpdated": "ফিডব্যাক আপডেট হয়েছে",
148
+ "updating": "আধুনিকীকরণ"
149
+ },
150
+ "copyButton": {
151
+ "copyToClipboard": "Copy to clipboard",
152
+ "copied": "Copied!"
153
+ },
154
+ "feedbackButton": {
155
+ "helpful": "Helpful",
156
+ "notHelpful": "Not helpful",
157
+ "editFeedback": "Edit feedback"
158
+ },
159
+ "feedbackDialog": {
160
+ "dialogTitle": "Add a comment",
161
+ "submitButton": "Submit feedback"
162
+ }
163
+ },
164
+ "dropScreen": {
165
+ "dropYourFilesHere": "আপনার ফাইলগুলি এখানে ফেলে দিন"
166
+ },
167
+ "index": {
168
+ "failedToUpload": "আপলোড করতে ব্যর্থ হয়েছে",
169
+ "cancelledUploadOf": "এর আপলোড বাতিল",
170
+ "couldNotReachServer": "সার্ভারে পৌঁছানো যায়নি",
171
+ "continuingChat": "পূর্ববর্তী চ্যাট অবিরত রাখা"
172
+ },
173
+ "settings": {
174
+ "settingsPanel": "সেটিংস প্যানেল",
175
+ "reset": "রিসেট",
176
+ "cancel": "বাতিল",
177
+ "confirm": "নিশ্চিত"
178
+ }
179
+ },
180
+ "threadHistory": {
181
+ "sidebar": {
182
+ "filters": {
183
+ "FeedbackSelect": {
184
+ "feedbackAll": "প্রতিক্রিয়া: সব",
185
+ "feedbackPositive": "প্রতিক্রিয়া: ইতিবাচক",
186
+ "feedbackNegative": "প্রতিক্রিয়া: নেতিবাচক"
187
+ },
188
+ "SearchBar": {
189
+ "search": "সন্ধান"
190
+ }
191
+ },
192
+ "DeleteThreadButton": {
193
+ "confirmMessage": "এটি থ্রেডের পাশাপাশি এর বার্তা এবং উপাদানগুলিও মুছে ফেলবে।",
194
+ "cancel": "বাতিল",
195
+ "confirm": "নিশ্চিত",
196
+ "deletingChat": "চ্যাট মোছা হচ্ছে",
197
+ "chatDeleted": "চ্যাট মোছা হয়েছে"
198
+ },
199
+ "index": {
200
+ "pastChats": "অতীত চ্যাট"
201
+ },
202
+ "ThreadList": {
203
+ "empty": "খালি।।।",
204
+ "today": "আজ",
205
+ "yesterday": "গতকাল",
206
+ "previous7days": "Previous 7 দিন",
207
+ "previous30days": "পূর্ববর্তী 30 দিন"
208
+ },
209
+ "TriggerButton": {
210
+ "closeSidebar": "সাইডবার বন্ধ করুন",
211
+ "openSidebar": "সাইডবার খুলুন"
212
+ }
213
+ },
214
+ "Thread": {
215
+ "backToChat": "চ্যাটে ফিরে যান",
216
+ "chatCreatedOn": "এই চ্যাটটি তৈরি করা হয়েছিল"
217
+ }
218
+ },
219
+ "header": {
220
+ "chat": "আলাপ",
221
+ "readme": "রিডমি"
222
+ }
223
+ }
224
+ },
225
+ "hooks": {
226
+ "useLLMProviders": {
227
+ "failedToFetchProviders": "সরবরাহকারীদের আনতে ব্যর্থ:"
228
+ }
229
+ },
230
+ "pages": {
231
+ "Design": {},
232
+ "Env": {
233
+ "savedSuccessfully": "সফলভাবে সংরক্ষণ করা হয়েছে",
234
+ "requiredApiKeys": "আবশ্যক API কী",
235
+ "requiredApiKeysInfo": "এই অ্যাপটি ব্যবহার করতে, নিম্নলিখিত API কীগুলির প্রয়োজন। কীগুলি আপনার ডিভাইসের স্থানীয় স্টোরেজে সঞ্চিত রয়েছে।"
236
+ },
237
+ "Page": {
238
+ "notPartOfProject": "আপনি এই প্রকল্পের অংশ নন।"
239
+ },
240
+ "ResumeButton": {
241
+ "resumeChat": "চ্যাট পুনরায় শুরু করুন"
242
+ }
243
+ }
244
+ }