chainlit 0.4.1__py3-none-any.whl → 0.4.3__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 +41 -130
- chainlit/action.py +2 -4
- chainlit/cli/__init__.py +64 -9
- chainlit/cli/mock.py +1571 -7
- chainlit/client/base.py +152 -0
- chainlit/client/cloud.py +440 -0
- chainlit/client/local.py +257 -0
- chainlit/client/utils.py +23 -0
- chainlit/config.py +31 -5
- chainlit/context.py +29 -0
- chainlit/db/__init__.py +35 -0
- chainlit/db/prisma/schema.prisma +48 -0
- chainlit/element.py +54 -41
- chainlit/emitter.py +1 -30
- chainlit/frontend/dist/assets/{index-51a1a88f.js → index-37b5009c.js} +1 -1
- chainlit/frontend/dist/assets/index-51393291.js +523 -0
- chainlit/frontend/dist/index.html +1 -1
- chainlit/langflow/__init__.py +75 -0
- chainlit/lc/__init__.py +85 -0
- chainlit/lc/agent.py +9 -5
- chainlit/lc/callbacks.py +9 -24
- chainlit/llama_index/__init__.py +34 -0
- chainlit/llama_index/callbacks.py +99 -0
- chainlit/llama_index/run.py +34 -0
- chainlit/logger.py +7 -2
- chainlit/message.py +25 -19
- chainlit/server.py +149 -38
- chainlit/session.py +3 -3
- chainlit/sync.py +20 -27
- chainlit/types.py +26 -1
- chainlit/user_session.py +1 -1
- chainlit/utils.py +51 -0
- {chainlit-0.4.1.dist-info → chainlit-0.4.3.dist-info}/METADATA +7 -3
- chainlit-0.4.3.dist-info/RECORD +49 -0
- chainlit/client.py +0 -287
- chainlit/frontend/dist/assets/index-68c36c96.js +0 -707
- chainlit-0.4.1.dist-info/RECORD +0 -38
- {chainlit-0.4.1.dist-info → chainlit-0.4.3.dist-info}/WHEEL +0 -0
- {chainlit-0.4.1.dist-info → chainlit-0.4.3.dist-info}/entry_points.txt +0 -0
chainlit/client.py
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any, Optional
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
|
-
import uuid
|
|
4
|
-
|
|
5
|
-
import asyncio
|
|
6
|
-
import aiohttp
|
|
7
|
-
from python_graphql_client import GraphqlClient
|
|
8
|
-
|
|
9
|
-
from chainlit.types import ElementType, ElementSize
|
|
10
|
-
from chainlit.logger import logger
|
|
11
|
-
from chainlit.config import config
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class BaseClient(ABC):
|
|
15
|
-
project_id: str
|
|
16
|
-
session_id: str
|
|
17
|
-
|
|
18
|
-
@abstractmethod
|
|
19
|
-
async def is_project_member(self, access_token: str) -> bool:
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
@abstractmethod
|
|
23
|
-
async def create_conversation(self, session_id: str) -> int:
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
@abstractmethod
|
|
27
|
-
async def create_message(self, variables: Dict[str, Any]) -> int:
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
@abstractmethod
|
|
31
|
-
async def update_message(self, message_id: int, variables: Dict[str, Any]) -> bool:
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
|
-
@abstractmethod
|
|
35
|
-
async def delete_message(self, message_id: int) -> bool:
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
@abstractmethod
|
|
39
|
-
async def upload_element(self, content: bytes, mime: str) -> str:
|
|
40
|
-
pass
|
|
41
|
-
|
|
42
|
-
@abstractmethod
|
|
43
|
-
async def create_element(
|
|
44
|
-
self,
|
|
45
|
-
type: ElementType,
|
|
46
|
-
url: str,
|
|
47
|
-
name: str,
|
|
48
|
-
display: str,
|
|
49
|
-
size: ElementSize = None,
|
|
50
|
-
language: str = None,
|
|
51
|
-
for_id: str = None,
|
|
52
|
-
) -> Dict[str, Any]:
|
|
53
|
-
pass
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
conversation_lock = asyncio.Lock()
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
class CloudClient(BaseClient):
|
|
60
|
-
conversation_id: Optional[str] = None
|
|
61
|
-
|
|
62
|
-
def __init__(self, project_id: str, session_id: str, access_token: str):
|
|
63
|
-
self.project_id = project_id
|
|
64
|
-
self.session_id = session_id
|
|
65
|
-
self.headers = {
|
|
66
|
-
"Authorization": access_token,
|
|
67
|
-
"content-type": "application/json",
|
|
68
|
-
}
|
|
69
|
-
graphql_endpoint = f"{config.chainlit_server}/api/graphql"
|
|
70
|
-
self.graphql_client = GraphqlClient(
|
|
71
|
-
endpoint=graphql_endpoint, headers=self.headers
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
def query(self, query: str, variables: Dict[str, Any] = {}) -> Dict[str, Any]:
|
|
75
|
-
"""
|
|
76
|
-
Execute a GraphQL query.
|
|
77
|
-
|
|
78
|
-
:param query: The GraphQL query string.
|
|
79
|
-
:param variables: A dictionary of variables for the query.
|
|
80
|
-
:return: The response data as a dictionary.
|
|
81
|
-
"""
|
|
82
|
-
return self.graphql_client.execute_async(query=query, variables=variables)
|
|
83
|
-
|
|
84
|
-
def check_for_errors(self, response: Dict[str, Any]):
|
|
85
|
-
if "errors" in response:
|
|
86
|
-
logger.error(response["errors"])
|
|
87
|
-
return True
|
|
88
|
-
return False
|
|
89
|
-
|
|
90
|
-
def mutation(self, mutation: str, variables: Dict[str, Any] = {}) -> Dict[str, Any]:
|
|
91
|
-
"""
|
|
92
|
-
Execute a GraphQL mutation.
|
|
93
|
-
|
|
94
|
-
:param mutation: The GraphQL mutation string.
|
|
95
|
-
:param variables: A dictionary of variables for the mutation.
|
|
96
|
-
:return: The response data as a dictionary.
|
|
97
|
-
"""
|
|
98
|
-
return self.graphql_client.execute_async(query=mutation, variables=variables)
|
|
99
|
-
|
|
100
|
-
async def is_project_member(self) -> bool:
|
|
101
|
-
data = {"projectId": self.project_id}
|
|
102
|
-
async with aiohttp.ClientSession() as session:
|
|
103
|
-
async with session.post(
|
|
104
|
-
f"{config.chainlit_server}/api/role",
|
|
105
|
-
json=data,
|
|
106
|
-
headers=self.headers,
|
|
107
|
-
) as r:
|
|
108
|
-
if not r.ok:
|
|
109
|
-
reason = await r.text()
|
|
110
|
-
logger.error(f"Failed to get user role. {r.status}: {reason}")
|
|
111
|
-
return False
|
|
112
|
-
json = await r.json()
|
|
113
|
-
role = json.get("role", "ANONYMOUS")
|
|
114
|
-
return role != "ANONYMOUS"
|
|
115
|
-
|
|
116
|
-
async def create_conversation(self, session_id: str) -> int:
|
|
117
|
-
# If we run multiple send concurrently, we need to make sure we don't create multiple conversations.
|
|
118
|
-
async with conversation_lock:
|
|
119
|
-
if self.conversation_id:
|
|
120
|
-
return self.conversation_id
|
|
121
|
-
|
|
122
|
-
mutation = """
|
|
123
|
-
mutation ($projectId: String!, $sessionId: String!) {
|
|
124
|
-
createConversation(projectId: $projectId, sessionId: $sessionId) {
|
|
125
|
-
id
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
"""
|
|
129
|
-
variables = {"projectId": self.project_id, "sessionId": session_id}
|
|
130
|
-
res = await self.mutation(mutation, variables)
|
|
131
|
-
|
|
132
|
-
if self.check_for_errors(res):
|
|
133
|
-
logger.warning("Could not create conversation.")
|
|
134
|
-
return None
|
|
135
|
-
|
|
136
|
-
return int(res["data"]["createConversation"]["id"])
|
|
137
|
-
|
|
138
|
-
async def get_conversation_id(self):
|
|
139
|
-
self.conversation_id = await self.create_conversation(self.session_id)
|
|
140
|
-
|
|
141
|
-
return self.conversation_id
|
|
142
|
-
|
|
143
|
-
async def create_message(self, variables: Dict[str, Any]) -> int:
|
|
144
|
-
c_id = await self.get_conversation_id()
|
|
145
|
-
|
|
146
|
-
if not c_id:
|
|
147
|
-
logger.warning("Missing conversation ID, could not persist the message.")
|
|
148
|
-
return None
|
|
149
|
-
|
|
150
|
-
variables["conversationId"] = c_id
|
|
151
|
-
|
|
152
|
-
mutation = """
|
|
153
|
-
mutation ($conversationId: ID!, $author: String!, $content: String!, $language: String, $prompt: String, $llmSettings: Json, $isError: Boolean, $indent: Int, $authorIsUser: Boolean, $waitForAnswer: Boolean, $createdAt: Float) {
|
|
154
|
-
createMessage(conversationId: $conversationId, author: $author, content: $content, language: $language, prompt: $prompt, llmSettings: $llmSettings, isError: $isError, indent: $indent, authorIsUser: $authorIsUser, waitForAnswer: $waitForAnswer, createdAt: $createdAt) {
|
|
155
|
-
id
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
"""
|
|
159
|
-
res = await self.mutation(mutation, variables)
|
|
160
|
-
if self.check_for_errors(res):
|
|
161
|
-
logger.warning("Could not create message.")
|
|
162
|
-
return None
|
|
163
|
-
|
|
164
|
-
return int(res["data"]["createMessage"]["id"])
|
|
165
|
-
|
|
166
|
-
async def update_message(self, message_id: int, variables: Dict[str, Any]) -> bool:
|
|
167
|
-
mutation = """
|
|
168
|
-
mutation ($messageId: ID!, $author: String!, $content: String!, $language: String, $prompt: String, $llmSettings: Json) {
|
|
169
|
-
updateMessage(messageId: $messageId, author: $author, content: $content, language: $language, prompt: $prompt, llmSettings: $llmSettings) {
|
|
170
|
-
id
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
"""
|
|
174
|
-
variables["messageId"] = message_id
|
|
175
|
-
res = await self.mutation(mutation, variables)
|
|
176
|
-
|
|
177
|
-
if self.check_for_errors(res):
|
|
178
|
-
logger.warning("Could not update message.")
|
|
179
|
-
return False
|
|
180
|
-
|
|
181
|
-
return True
|
|
182
|
-
|
|
183
|
-
async def delete_message(self, message_id: int) -> bool:
|
|
184
|
-
mutation = """
|
|
185
|
-
mutation ($messageId: ID!) {
|
|
186
|
-
deleteMessage(messageId: $messageId) {
|
|
187
|
-
id
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
"""
|
|
191
|
-
res = await self.mutation(mutation, {"messageId": message_id})
|
|
192
|
-
|
|
193
|
-
if self.check_for_errors(res):
|
|
194
|
-
logger.warning("Could not delete message.")
|
|
195
|
-
return False
|
|
196
|
-
|
|
197
|
-
return True
|
|
198
|
-
|
|
199
|
-
async def create_element(
|
|
200
|
-
self,
|
|
201
|
-
type: ElementType,
|
|
202
|
-
url: str,
|
|
203
|
-
name: str,
|
|
204
|
-
display: str,
|
|
205
|
-
size: ElementSize = None,
|
|
206
|
-
language: str = None,
|
|
207
|
-
for_id: str = None,
|
|
208
|
-
) -> Dict[str, Any]:
|
|
209
|
-
c_id = await self.get_conversation_id()
|
|
210
|
-
|
|
211
|
-
if not c_id:
|
|
212
|
-
logger.warning("Missing conversation ID, could not persist the element.")
|
|
213
|
-
return None
|
|
214
|
-
|
|
215
|
-
mutation = """
|
|
216
|
-
mutation ($conversationId: ID!, $type: String!, $url: String!, $name: String!, $display: String!, $size: String, $language: String, $forId: String) {
|
|
217
|
-
createElement(conversationId: $conversationId, type: $type, url: $url, name: $name, display: $display, size: $size, language: $language, forId: $forId) {
|
|
218
|
-
id,
|
|
219
|
-
type,
|
|
220
|
-
url,
|
|
221
|
-
name,
|
|
222
|
-
display,
|
|
223
|
-
size,
|
|
224
|
-
language,
|
|
225
|
-
forId
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
"""
|
|
229
|
-
variables = {
|
|
230
|
-
"conversationId": c_id,
|
|
231
|
-
"type": type,
|
|
232
|
-
"url": url,
|
|
233
|
-
"name": name,
|
|
234
|
-
"display": display,
|
|
235
|
-
"size": size,
|
|
236
|
-
"language": language,
|
|
237
|
-
"forId": for_id,
|
|
238
|
-
}
|
|
239
|
-
res = await self.mutation(mutation, variables)
|
|
240
|
-
|
|
241
|
-
if self.check_for_errors(res):
|
|
242
|
-
logger.warning("Could not persist element.")
|
|
243
|
-
return None
|
|
244
|
-
|
|
245
|
-
return res["data"]["createElement"]
|
|
246
|
-
|
|
247
|
-
async def upload_element(self, content: bytes, mime: str) -> str:
|
|
248
|
-
id = f"{uuid.uuid4()}"
|
|
249
|
-
body = {"projectId": self.project_id, "fileName": id, "contentType": mime}
|
|
250
|
-
|
|
251
|
-
path = f"/api/upload/file"
|
|
252
|
-
|
|
253
|
-
async with aiohttp.ClientSession() as session:
|
|
254
|
-
async with session.post(
|
|
255
|
-
f"{config.chainlit_server}{path}",
|
|
256
|
-
json=body,
|
|
257
|
-
headers=self.headers,
|
|
258
|
-
) as r:
|
|
259
|
-
if not r.ok:
|
|
260
|
-
reason = await r.text()
|
|
261
|
-
logger.error(f"Failed to upload file: {reason}")
|
|
262
|
-
return ""
|
|
263
|
-
json_res = await r.json()
|
|
264
|
-
|
|
265
|
-
upload_details = json_res["post"]
|
|
266
|
-
permanent_url = json_res["permanentUrl"]
|
|
267
|
-
|
|
268
|
-
form_data = aiohttp.FormData()
|
|
269
|
-
|
|
270
|
-
# Add fields to the form_data
|
|
271
|
-
for field_name, field_value in upload_details["fields"].items():
|
|
272
|
-
form_data.add_field(field_name, field_value)
|
|
273
|
-
|
|
274
|
-
# Add file to the form_data
|
|
275
|
-
form_data.add_field("file", content, content_type="multipart/form-data")
|
|
276
|
-
async with aiohttp.ClientSession() as session:
|
|
277
|
-
async with session.post(
|
|
278
|
-
upload_details["url"],
|
|
279
|
-
data=form_data,
|
|
280
|
-
) as upload_response:
|
|
281
|
-
if not upload_response.ok:
|
|
282
|
-
reason = await upload_response.text()
|
|
283
|
-
logger.error(f"Failed to upload file: {reason}")
|
|
284
|
-
return ""
|
|
285
|
-
|
|
286
|
-
url = f'{upload_details["url"]}/{upload_details["fields"]["key"]}'
|
|
287
|
-
return permanent_url
|