chainlit 2.0.0__py3-none-any.whl → 2.0.dev0__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 (98) hide show
  1. chainlit/__init__.py +57 -56
  2. chainlit/action.py +10 -12
  3. chainlit/{auth/__init__.py → auth.py} +34 -26
  4. chainlit/cache.py +6 -4
  5. chainlit/callbacks.py +7 -52
  6. chainlit/chat_context.py +2 -2
  7. chainlit/chat_settings.py +1 -3
  8. chainlit/cli/__init__.py +2 -15
  9. chainlit/config.py +70 -41
  10. chainlit/context.py +9 -8
  11. chainlit/copilot/dist/index.js +874 -8533
  12. chainlit/data/__init__.py +8 -96
  13. chainlit/data/acl.py +2 -3
  14. chainlit/data/base.py +15 -1
  15. chainlit/data/dynamodb.py +4 -7
  16. chainlit/data/literalai.py +6 -4
  17. chainlit/data/sql_alchemy.py +9 -10
  18. chainlit/data/{storage_clients/azure.py → storage_clients.py} +33 -2
  19. chainlit/discord/__init__.py +4 -4
  20. chainlit/discord/app.py +1 -2
  21. chainlit/element.py +9 -41
  22. chainlit/emitter.py +21 -17
  23. chainlit/frontend/dist/assets/DailyMotion-b4b7af47.js +1 -0
  24. chainlit/frontend/dist/assets/Facebook-572972a0.js +1 -0
  25. chainlit/frontend/dist/assets/FilePlayer-85c69ca8.js +1 -0
  26. chainlit/frontend/dist/assets/Kaltura-dfc24672.js +1 -0
  27. chainlit/frontend/dist/assets/Mixcloud-705011f4.js +1 -0
  28. chainlit/frontend/dist/assets/Mux-4201a9e6.js +1 -0
  29. chainlit/frontend/dist/assets/Preview-23ba40a6.js +1 -0
  30. chainlit/frontend/dist/assets/SoundCloud-1a582d51.js +1 -0
  31. chainlit/frontend/dist/assets/Streamable-5017c4ba.js +1 -0
  32. chainlit/frontend/dist/assets/Twitch-bb2de2fa.js +1 -0
  33. chainlit/frontend/dist/assets/Vidyard-54e269b1.js +1 -0
  34. chainlit/frontend/dist/assets/Vimeo-d92c37dd.js +1 -0
  35. chainlit/frontend/dist/assets/Wistia-25a1363b.js +1 -0
  36. chainlit/frontend/dist/assets/YouTube-616e8cb7.js +1 -0
  37. chainlit/frontend/dist/assets/index-aaf974a9.css +1 -0
  38. chainlit/frontend/dist/assets/index-f5df2072.js +1027 -0
  39. chainlit/frontend/dist/assets/{react-plotly-BpxUS-ab.js → react-plotly-f0315f86.js} +94 -94
  40. chainlit/frontend/dist/index.html +3 -2
  41. chainlit/haystack/callbacks.py +4 -5
  42. chainlit/input_widget.py +4 -6
  43. chainlit/langchain/callbacks.py +47 -56
  44. chainlit/langflow/__init__.py +0 -1
  45. chainlit/llama_index/callbacks.py +7 -7
  46. chainlit/message.py +10 -8
  47. chainlit/mistralai/__init__.py +2 -3
  48. chainlit/oauth_providers.py +12 -113
  49. chainlit/openai/__init__.py +7 -6
  50. chainlit/secret.py +1 -1
  51. chainlit/server.py +181 -491
  52. chainlit/session.py +5 -7
  53. chainlit/slack/__init__.py +3 -3
  54. chainlit/slack/app.py +2 -3
  55. chainlit/socket.py +103 -78
  56. chainlit/step.py +29 -21
  57. chainlit/sync.py +1 -2
  58. chainlit/teams/__init__.py +3 -3
  59. chainlit/teams/app.py +0 -1
  60. chainlit/types.py +4 -20
  61. chainlit/user.py +1 -2
  62. chainlit/utils.py +2 -3
  63. chainlit/version.py +2 -3
  64. {chainlit-2.0.0.dist-info → chainlit-2.0.dev0.dist-info}/METADATA +39 -27
  65. chainlit-2.0.dev0.dist-info/RECORD +96 -0
  66. chainlit/auth/cookie.py +0 -123
  67. chainlit/auth/jwt.py +0 -37
  68. chainlit/data/chainlit_data_layer.py +0 -584
  69. chainlit/data/storage_clients/__init__.py +0 -0
  70. chainlit/data/storage_clients/azure_blob.py +0 -80
  71. chainlit/data/storage_clients/base.py +0 -22
  72. chainlit/data/storage_clients/gcs.py +0 -78
  73. chainlit/data/storage_clients/s3.py +0 -49
  74. chainlit/frontend/dist/assets/DailyMotion-DgRzV5GZ.js +0 -1
  75. chainlit/frontend/dist/assets/Dataframe-DVgwSMU2.js +0 -22
  76. chainlit/frontend/dist/assets/Facebook-C0vx6HWv.js +0 -1
  77. chainlit/frontend/dist/assets/FilePlayer-CdhzeHPP.js +0 -1
  78. chainlit/frontend/dist/assets/Kaltura-5iVmeUct.js +0 -1
  79. chainlit/frontend/dist/assets/Mixcloud-C2zi77Ex.js +0 -1
  80. chainlit/frontend/dist/assets/Mux-Vkebogdf.js +0 -1
  81. chainlit/frontend/dist/assets/Preview-DwY_sEIl.js +0 -1
  82. chainlit/frontend/dist/assets/SoundCloud-CREBXAWo.js +0 -1
  83. chainlit/frontend/dist/assets/Streamable-B5Lu25uy.js +0 -1
  84. chainlit/frontend/dist/assets/Twitch-y9iKCcM1.js +0 -1
  85. chainlit/frontend/dist/assets/Vidyard-ClYvcuEu.js +0 -1
  86. chainlit/frontend/dist/assets/Vimeo-D6HvM2jt.js +0 -1
  87. chainlit/frontend/dist/assets/Wistia-Cu4zZ2Ci.js +0 -1
  88. chainlit/frontend/dist/assets/YouTube-D10tR6CJ.js +0 -1
  89. chainlit/frontend/dist/assets/index-CI4qFOt5.js +0 -8665
  90. chainlit/frontend/dist/assets/index-CrrqM0nZ.css +0 -1
  91. chainlit/translations/nl-NL.json +0 -229
  92. chainlit-2.0.0.dist-info/RECORD +0 -106
  93. /chainlit/copilot/dist/assets/{logo_dark-IkGJ_IwC.svg → logo_dark-2a3cf740.svg} +0 -0
  94. /chainlit/copilot/dist/assets/{logo_light-Bb_IPh6r.svg → logo_light-b078e7bc.svg} +0 -0
  95. /chainlit/frontend/dist/assets/{logo_dark-IkGJ_IwC.svg → logo_dark-2a3cf740.svg} +0 -0
  96. /chainlit/frontend/dist/assets/{logo_light-Bb_IPh6r.svg → logo_light-b078e7bc.svg} +0 -0
  97. {chainlit-2.0.0.dist-info → chainlit-2.0.dev0.dist-info}/WHEEL +0 -0
  98. {chainlit-2.0.0.dist-info → chainlit-2.0.dev0.dist-info}/entry_points.txt +0 -0
chainlit/data/__init__.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import os
2
- import warnings
3
2
  from typing import Optional
4
3
 
5
4
  from .base import BaseDataLayer
@@ -8,106 +7,19 @@ from .utils import (
8
7
  )
9
8
 
10
9
  _data_layer: Optional[BaseDataLayer] = None
11
- _data_layer_initialized = False
12
10
 
13
11
 
14
12
  def get_data_layer():
15
- global _data_layer, _data_layer_initialized
13
+ global _data_layer
16
14
 
17
- if not _data_layer_initialized:
18
- if _data_layer:
19
- # Data layer manually set, warn user that this is deprecated.
15
+ if not _data_layer:
16
+ if api_key := os.environ.get("LITERAL_API_KEY"):
17
+ from .literalai import LiteralDataLayer
20
18
 
21
- warnings.warn(
22
- "Setting data layer manually is deprecated. Use @data_layer instead.",
23
- DeprecationWarning,
19
+ # support legacy LITERAL_SERVER variable as fallback
20
+ server = os.environ.get("LITERAL_API_URL") or os.environ.get(
21
+ "LITERAL_SERVER"
24
22
  )
25
-
26
- else:
27
- from chainlit.config import config
28
-
29
- if config.code.data_layer:
30
- # When @data_layer is configured, call it to get data layer.
31
- _data_layer = config.code.data_layer()
32
- elif database_url := os.environ.get("DATABASE_URL"):
33
- # Default to Chainlit data layer if DATABASE_URL specified.
34
- from .chainlit_data_layer import ChainlitDataLayer
35
-
36
- if os.environ.get("LITERAL_API_KEY"):
37
- warnings.warn(
38
- "Both LITERAL_API_KEY and DATABASE_URL specified. Ignoring Literal AI data layer and relying on data layer pointing to DATABASE_URL."
39
- )
40
- bucket_name = os.environ.get("BUCKET_NAME")
41
-
42
- # AWS S3
43
- aws_region = os.getenv("APP_AWS_REGION")
44
- aws_access_key = os.getenv("APP_AWS_ACCESS_KEY")
45
- aws_secret_key = os.getenv("APP_AWS_SECRET_KEY")
46
- dev_aws_endpoint = os.getenv("DEV_AWS_ENDPOINT")
47
- is_using_s3 = bool(aws_access_key and aws_secret_key and aws_region)
48
-
49
- # Google Cloud Storage
50
- gcs_project_id = os.getenv("APP_GCS_PROJECT_ID")
51
- gcs_client_email = os.getenv("APP_GCS_CLIENT_EMAIL")
52
- gcs_private_key = os.getenv("APP_GCS_PRIVATE_KEY")
53
- is_using_gcs = bool(
54
- gcs_project_id and gcs_client_email and gcs_private_key
55
- )
56
-
57
- # Azure Storage
58
- azure_storage_account = os.getenv("APP_AZURE_STORAGE_ACCOUNT")
59
- azure_storage_key = os.getenv("APP_AZURE_STORAGE_ACCESS_KEY")
60
- is_using_azure = bool(azure_storage_account and azure_storage_key)
61
-
62
- storage_client = None
63
-
64
- if sum([is_using_s3, is_using_gcs, is_using_azure]) > 1:
65
- warnings.warn(
66
- "Multiple storage configurations detected. Please use only one."
67
- )
68
- elif is_using_s3:
69
- from chainlit.data.storage_clients.s3 import S3StorageClient
70
-
71
- storage_client = S3StorageClient(
72
- bucket=bucket_name,
73
- region_name=aws_region,
74
- aws_access_key_id=aws_access_key,
75
- aws_secret_access_key=aws_secret_key,
76
- endpoint_url=dev_aws_endpoint,
77
- )
78
- elif is_using_gcs:
79
- from chainlit.data.storage_clients.gcs import GCSStorageClient
80
-
81
- storage_client = GCSStorageClient(
82
- project_id=gcs_project_id,
83
- client_email=gcs_client_email,
84
- private_key=gcs_private_key,
85
- bucket_name=bucket_name,
86
- )
87
- elif is_using_azure:
88
- from chainlit.data.storage_clients.azure_blob import (
89
- AzureBlobStorageClient,
90
- )
91
-
92
- storage_client = AzureBlobStorageClient(
93
- container_name=bucket_name,
94
- storage_account=azure_storage_account,
95
- storage_key=azure_storage_key,
96
- )
97
-
98
- _data_layer = ChainlitDataLayer(
99
- database_url=database_url, storage_client=storage_client
100
- )
101
- elif api_key := os.environ.get("LITERAL_API_KEY"):
102
- # When LITERAL_API_KEY is defined, use Literal AI data layer
103
- from .literalai import LiteralDataLayer
104
-
105
- # support legacy LITERAL_SERVER variable as fallback
106
- server = os.environ.get("LITERAL_API_URL") or os.environ.get(
107
- "LITERAL_SERVER"
108
- )
109
- _data_layer = LiteralDataLayer(api_key=api_key, server=server)
110
-
111
- _data_layer_initialized = True
23
+ _data_layer = LiteralDataLayer(api_key=api_key, server=server)
112
24
 
113
25
  return _data_layer
chainlit/data/acl.py CHANGED
@@ -1,6 +1,5 @@
1
- from fastapi import HTTPException
2
-
3
1
  from chainlit.data import get_data_layer
2
+ from fastapi import HTTPException
4
3
 
5
4
 
6
5
  async def is_thread_author(username: str, thread_id: str):
@@ -9,7 +8,7 @@ async def is_thread_author(username: str, thread_id: str):
9
8
  raise HTTPException(status_code=400, detail="Data layer not initialized")
10
9
 
11
10
  thread_author = await data_layer.get_thread_author(thread_id)
12
-
11
+
13
12
  if not thread_author:
14
13
  raise HTTPException(status_code=404, detail="Thread not found")
15
14
 
chainlit/data/base.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import TYPE_CHECKING, Dict, List, Optional
2
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
3
3
 
4
4
  from chainlit.types import (
5
5
  Feedback,
@@ -105,3 +105,17 @@ class BaseDataLayer(ABC):
105
105
  @abstractmethod
106
106
  async def build_debug_url(self) -> str:
107
107
  pass
108
+
109
+
110
+ class BaseStorageClient(ABC):
111
+ """Base class for non-text data persistence like Azure Data Lake, S3, Google Storage, etc."""
112
+
113
+ @abstractmethod
114
+ async def upload_file(
115
+ self,
116
+ object_key: str,
117
+ data: Union[bytes, str],
118
+ mime: str = "application/octet-stream",
119
+ overwrite: bool = True,
120
+ ) -> Dict[str, Any]:
121
+ pass
chainlit/data/dynamodb.py CHANGED
@@ -11,10 +11,8 @@ import aiofiles
11
11
  import aiohttp
12
12
  import boto3 # type: ignore
13
13
  from boto3.dynamodb.types import TypeDeserializer, TypeSerializer
14
-
15
14
  from chainlit.context import context
16
- from chainlit.data.base import BaseDataLayer
17
- from chainlit.data.storage_clients.base import BaseStorageClient
15
+ from chainlit.data.base import BaseDataLayer, BaseStorageClient
18
16
  from chainlit.data.utils import queue_until_user_message
19
17
  from chainlit.element import ElementDict
20
18
  from chainlit.logger import logger
@@ -30,9 +28,8 @@ from chainlit.types import (
30
28
  from chainlit.user import PersistedUser, User
31
29
 
32
30
  if TYPE_CHECKING:
33
- from mypy_boto3_dynamodb import DynamoDBClient
34
-
35
31
  from chainlit.element import Element
32
+ from mypy_boto3_dynamodb import DynamoDBClient
36
33
 
37
34
 
38
35
  _logger = logger.getChild("DynamoDB")
@@ -404,7 +401,7 @@ class DynamoDBDataLayer(BaseDataLayer):
404
401
 
405
402
  BATCH_ITEM_SIZE = 25 # pylint: disable=invalid-name
406
403
  for i in range(0, len(delete_requests), BATCH_ITEM_SIZE):
407
- chunk = delete_requests[i : i + BATCH_ITEM_SIZE]
404
+ chunk = delete_requests[i : i + BATCH_ITEM_SIZE] # noqa: E203
408
405
  response = self.client.batch_write_item(
409
406
  RequestItems={
410
407
  self.table_name: chunk, # type: ignore
@@ -412,7 +409,7 @@ class DynamoDBDataLayer(BaseDataLayer):
412
409
  )
413
410
 
414
411
  backoff_time = 1
415
- while response.get("UnprocessedItems"):
412
+ while "UnprocessedItems" in response and response["UnprocessedItems"]:
416
413
  backoff_time *= 2
417
414
  # Cap the backoff time at 32 seconds & add jitter
418
415
  delay = min(backoff_time, 32) + random.uniform(0, 1)
@@ -94,6 +94,7 @@ class LiteralToChainlitConverter:
94
94
  "input": input,
95
95
  "output": output,
96
96
  "showInput": metadata.get("showInput", False),
97
+ "indent": metadata.get("indent"),
97
98
  "language": metadata.get("language"),
98
99
  "isError": bool(step.error),
99
100
  "waitForAnswer": metadata.get("waitForAnswer", False),
@@ -109,7 +110,6 @@ class LiteralToChainlitConverter:
109
110
  "autoPlay": metadata.get("autoPlay", None),
110
111
  "playerConfig": metadata.get("playerConfig", None),
111
112
  "page": metadata.get("page"),
112
- "props": metadata.get("props"),
113
113
  "size": metadata.get("size"),
114
114
  "type": metadata.get("type", "file"),
115
115
  "forId": attachment.step_id,
@@ -349,9 +349,11 @@ class LiteralDataLayer(BaseDataLayer):
349
349
  async def create_step(self, step_dict: "StepDict"):
350
350
  metadata = dict(
351
351
  step_dict.get("metadata", {}),
352
- waitForAnswer=step_dict.get("waitForAnswer"),
353
- language=step_dict.get("language"),
354
- showInput=step_dict.get("showInput"),
352
+ **{
353
+ "waitForAnswer": step_dict.get("waitForAnswer"),
354
+ "language": step_dict.get("language"),
355
+ "showInput": step_dict.get("showInput"),
356
+ },
355
357
  )
356
358
 
357
359
  step: LiteralStepDict = {
@@ -7,13 +7,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
7
7
 
8
8
  import aiofiles
9
9
  import aiohttp
10
- from sqlalchemy import text
11
- from sqlalchemy.exc import SQLAlchemyError
12
- from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
13
- from sqlalchemy.orm import sessionmaker
14
10
 
15
- from chainlit.data.base import BaseDataLayer
16
- from chainlit.data.storage_clients.base import BaseStorageClient
11
+ from chainlit.data.base import BaseDataLayer, BaseStorageClient
17
12
  from chainlit.data.utils import queue_until_user_message
18
13
  from chainlit.element import ElementDict
19
14
  from chainlit.logger import logger
@@ -28,6 +23,10 @@ from chainlit.types import (
28
23
  ThreadFilter,
29
24
  )
30
25
  from chainlit.user import PersistedUser, User
26
+ from sqlalchemy import text
27
+ from sqlalchemy.exc import SQLAlchemyError
28
+ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
29
+ from sqlalchemy.orm import sessionmaker
31
30
 
32
31
  if TYPE_CHECKING:
33
32
  from chainlit.element import Element, ElementDict
@@ -156,7 +155,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
156
155
  async def _get_user_id_by_thread(self, thread_id: str) -> Optional[str]:
157
156
  if self.show_logger:
158
157
  logger.info(f"SQLAlchemy: _get_user_id_by_thread, thread_id={thread_id}")
159
- query = """SELECT "userId" FROM threads WHERE id = :thread_id"""
158
+ query = "SELECT userId FROM threads WHERE id = :thread_id"
160
159
  parameters = {"thread_id": thread_id}
161
160
  result = await self.execute_sql(query=query, parameters=parameters)
162
161
  if result:
@@ -168,7 +167,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
168
167
  async def create_user(self, user: User) -> Optional[PersistedUser]:
169
168
  if self.show_logger:
170
169
  logger.info(f"SQLAlchemy: create_user, user_identifier={user.identifier}")
171
- existing_user: Optional[PersistedUser] = await self.get_user(user.identifier)
170
+ existing_user: Optional["PersistedUser"] = await self.get_user(user.identifier)
172
171
  user_dict: Dict[str, Any] = {
173
172
  "identifier": str(user.identifier),
174
173
  "metadata": json.dumps(user.metadata) or {},
@@ -439,7 +438,6 @@ class SQLAlchemyDataLayer(BaseDataLayer):
439
438
  url=element_dict.get("url"),
440
439
  objectKey=element_dict.get("objectKey"),
441
440
  name=element_dict["name"],
442
- props=element_dict.get("props"),
443
441
  display=element_dict["display"],
444
442
  size=element_dict.get("size"),
445
443
  language=element_dict.get("language"),
@@ -578,6 +576,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
578
576
  s."generation" AS step_generation,
579
577
  s."showInput" AS step_showinput,
580
578
  s."language" AS step_language,
579
+ s."indent" AS step_indent,
581
580
  f."value" AS feedback_value,
582
581
  f."comment" AS feedback_comment,
583
582
  f."id" AS feedback_id
@@ -665,6 +664,7 @@ class SQLAlchemyDataLayer(BaseDataLayer):
665
664
  generation=step_feedback.get("step_generation"),
666
665
  showInput=step_feedback.get("step_showinput"),
667
666
  language=step_feedback.get("step_language"),
667
+ indent=step_feedback.get("step_indent"),
668
668
  feedback=feedback,
669
669
  )
670
670
  # Append the step to the steps list of the corresponding ThreadDict
@@ -688,7 +688,6 @@ class SQLAlchemyDataLayer(BaseDataLayer):
688
688
  autoPlay=element.get("element_autoPlay"),
689
689
  playerConfig=element.get("element_playerconfig"),
690
690
  page=element.get("element_page"),
691
- props=element.get("element_props"),
692
691
  forId=element.get("element_forid"),
693
692
  mime=element.get("element_mime"),
694
693
  )
@@ -1,13 +1,13 @@
1
1
  from typing import TYPE_CHECKING, Any, Dict, Optional, Union
2
2
 
3
+ import boto3 # type: ignore
3
4
  from azure.storage.filedatalake import (
4
5
  ContentSettings,
5
6
  DataLakeFileClient,
6
7
  DataLakeServiceClient,
7
8
  FileSystemClient,
8
9
  )
9
-
10
- from chainlit.data.storage_clients.base import BaseStorageClient
10
+ from chainlit.data.base import BaseStorageClient
11
11
  from chainlit.logger import logger
12
12
 
13
13
  if TYPE_CHECKING:
@@ -79,3 +79,34 @@ class AzureStorageClient(BaseStorageClient):
79
79
  except Exception as e:
80
80
  logger.warn(f"AzureStorageClient, upload_file error: {e}")
81
81
  return {}
82
+
83
+
84
+ class S3StorageClient(BaseStorageClient):
85
+ """
86
+ Class to enable Amazon S3 storage provider
87
+ """
88
+
89
+ def __init__(self, bucket: str):
90
+ try:
91
+ self.bucket = bucket
92
+ self.client = boto3.client("s3")
93
+ logger.info("S3StorageClient initialized")
94
+ except Exception as e:
95
+ logger.warn(f"S3StorageClient initialization error: {e}")
96
+
97
+ async def upload_file(
98
+ self,
99
+ object_key: str,
100
+ data: Union[bytes, str],
101
+ mime: str = "application/octet-stream",
102
+ overwrite: bool = True,
103
+ ) -> Dict[str, Any]:
104
+ try:
105
+ self.client.put_object(
106
+ Bucket=self.bucket, Key=object_key, Body=data, ContentType=mime
107
+ )
108
+ url = f"https://{self.bucket}.s3.amazonaws.com/{object_key}"
109
+ return {"object_key": object_key, "url": url}
110
+ except Exception as e:
111
+ logger.warn(f"S3StorageClient, upload_file error: {e}")
112
+ return {}
@@ -1,6 +1,6 @@
1
- import importlib.util
2
-
3
- if importlib.util.find_spec("discord") is None:
1
+ try:
2
+ import discord
3
+ except ModuleNotFoundError:
4
4
  raise ValueError(
5
- "The discord package is required to integrate Chainlit with a Discord app. Run `pip install discord --upgrade`"
5
+ "The discord package is required to integrate Chainlit with a Slack app. Run `pip install discord --upgrade`"
6
6
  )
chainlit/discord/app.py CHANGED
@@ -12,8 +12,6 @@ if TYPE_CHECKING:
12
12
  import discord
13
13
  import filetype
14
14
  import httpx
15
- from discord.ui import Button, View
16
-
17
15
  from chainlit.config import config
18
16
  from chainlit.context import ChainlitContext, HTTPSession, context, context_var
19
17
  from chainlit.data import get_data_layer
@@ -25,6 +23,7 @@ from chainlit.telemetry import trace
25
23
  from chainlit.types import Feedback
26
24
  from chainlit.user import PersistedUser, User
27
25
  from chainlit.user_session import user_session
26
+ from discord.ui import Button, View
28
27
 
29
28
 
30
29
  class FeedbackView(View):
chainlit/element.py CHANGED
@@ -16,15 +16,13 @@ from typing import (
16
16
  )
17
17
 
18
18
  import filetype
19
- from pydantic import Field
20
- from pydantic.dataclasses import dataclass
21
- from syncer import asyncio
22
-
23
19
  from chainlit.context import context
24
20
  from chainlit.data import get_data_layer
25
21
  from chainlit.logger import logger
26
22
  from chainlit.telemetry import trace_event
27
23
  from chainlit.types import FileDict
24
+ from pydantic.dataclasses import Field, dataclass
25
+ from syncer import asyncio
28
26
 
29
27
  mime_types = {
30
28
  "text": "text/plain",
@@ -33,16 +31,7 @@ mime_types = {
33
31
  }
34
32
 
35
33
  ElementType = Literal[
36
- "image",
37
- "text",
38
- "pdf",
39
- "tasklist",
40
- "audio",
41
- "video",
42
- "file",
43
- "plotly",
44
- "dataframe",
45
- "custom",
34
+ "image", "text", "pdf", "tasklist", "audio", "video", "file", "plotly", "component"
46
35
  ]
47
36
  ElementDisplay = Literal["inline", "side", "page"]
48
37
  ElementSize = Literal["small", "medium", "large"]
@@ -60,7 +49,6 @@ class ElementDict(TypedDict):
60
49
  size: Optional[ElementSize]
61
50
  language: Optional[str]
62
51
  page: Optional[int]
63
- props: Optional[Dict]
64
52
  autoPlay: Optional[bool]
65
53
  playerConfig: Optional[dict]
66
54
  forId: Optional[str]
@@ -118,7 +106,6 @@ class Element:
118
106
  "display": self.display,
119
107
  "objectKey": getattr(self, "object_key", None),
120
108
  "size": getattr(self, "size", None),
121
- "props": getattr(self, "props", None),
122
109
  "page": getattr(self, "page", None),
123
110
  "autoPlay": getattr(self, "auto_play", None),
124
111
  "playerConfig": getattr(self, "player_config", None),
@@ -158,7 +145,7 @@ class Element:
158
145
  try:
159
146
  asyncio.create_task(data_layer.create_element(self))
160
147
  except Exception as e:
161
- logger.error(f"Failed to create element: {e!s}")
148
+ logger.error(f"Failed to create element: {str(e)}")
162
149
  if not self.url and (not self.chainlit_key or self.updatable):
163
150
  file_dict = await context.session.persist_file(
164
151
  name=self.name,
@@ -356,7 +343,8 @@ class Plotly(Element):
356
343
  content: str = ""
357
344
 
358
345
  def __post_init__(self) -> None:
359
- from plotly import graph_objects as go, io as pio
346
+ from plotly import graph_objects as go
347
+ from plotly import io as pio
360
348
 
361
349
  if not isinstance(self.figure, go.Figure):
362
350
  raise TypeError("figure must be a plotly.graph_objects.Figure")
@@ -371,34 +359,14 @@ class Plotly(Element):
371
359
 
372
360
 
373
361
  @dataclass
374
- class Dataframe(Element):
375
- """Useful to send a pandas DataFrame to the UI."""
376
-
377
- type: ClassVar[ElementType] = "dataframe"
378
- size: ElementSize = "large"
379
- data: Any = None # The type is Any because it is checked in __post_init__.
380
-
381
- def __post_init__(self) -> None:
382
- """Ensures the data is a pandas DataFrame and converts it to JSON."""
383
- from pandas import DataFrame
384
-
385
- if not isinstance(self.data, DataFrame):
386
- raise TypeError("data must be a pandas.DataFrame")
362
+ class Component(Element):
363
+ """Useful to send a custom component to the UI."""
387
364
 
388
- self.content = self.data.to_json(orient="split", date_format="iso")
389
- super().__post_init__()
390
-
391
-
392
- @dataclass
393
- class CustomElement(Element):
394
- """Useful to send a custom element to the UI."""
395
-
396
- type: ClassVar[ElementType] = "custom"
365
+ type: ClassVar[ElementType] = "component"
397
366
  mime: str = "application/json"
398
367
  props: Dict = Field(default_factory=dict)
399
368
 
400
369
  def __post_init__(self) -> None:
401
370
  self.content = json.dumps(self.props)
402
- self.updatable = True
403
371
 
404
372
  super().__post_init__()
chainlit/emitter.py CHANGED
@@ -2,9 +2,6 @@ import asyncio
2
2
  import uuid
3
3
  from typing import Any, Dict, List, Literal, Optional, Union, cast
4
4
 
5
- from literalai.helper import utc_now
6
- from socketio.exceptions import TimeoutError
7
-
8
5
  from chainlit.chat_context import chat_context
9
6
  from chainlit.config import config
10
7
  from chainlit.data import get_data_layer
@@ -19,10 +16,12 @@ from chainlit.types import (
19
16
  FileDict,
20
17
  FileReference,
21
18
  MessagePayload,
22
- OutputAudioChunk,
23
19
  ThreadDict,
20
+ OutputAudioChunk
24
21
  )
25
22
  from chainlit.user import PersistedUser
23
+ from literalai.helper import utc_now
24
+ from socketio.exceptions import TimeoutError
26
25
 
27
26
 
28
27
  class BaseChainlitEmitter:
@@ -53,15 +52,15 @@ class BaseChainlitEmitter:
53
52
  async def send_element(self, element_dict: ElementDict):
54
53
  """Stub method to send an element to the UI."""
55
54
  pass
56
-
55
+
57
56
  async def update_audio_connection(self, state: Literal["on", "off"]):
58
57
  """Audio connection signaling."""
59
58
  pass
60
-
59
+
61
60
  async def send_audio_chunk(self, chunk: OutputAudioChunk):
62
61
  """Stub method to send an audio chunk to the UI."""
63
62
  pass
64
-
63
+
65
64
  async def send_audio_interrupt(self):
66
65
  """Stub method to interrupt the current audio response."""
67
66
  pass
@@ -128,8 +127,10 @@ class BaseChainlitEmitter:
128
127
  """Stub method to set chat settings."""
129
128
  pass
130
129
 
131
- async def send_window_message(self, data: Any):
132
- """Stub method to send custom data to the host window."""
130
+ async def send_action_response(
131
+ self, id: str, status: bool, response: Optional[str] = None
132
+ ):
133
+ """Send an action response to the UI."""
133
134
  pass
134
135
 
135
136
 
@@ -176,7 +177,7 @@ class ChainlitEmitter(BaseChainlitEmitter):
176
177
  async def send_audio_chunk(self, chunk: OutputAudioChunk):
177
178
  """Send an audio chunk to the UI."""
178
179
  await self.emit("audio_chunk", chunk)
179
-
180
+
180
181
  async def send_audio_interrupt(self):
181
182
  """Method to interrupt the current audio response."""
182
183
  await self.emit("audio_interrupt", {})
@@ -282,9 +283,9 @@ class ChainlitEmitter(BaseChainlitEmitter):
282
283
  # End the task temporarily so that the User can answer the prompt
283
284
  await self.task_end()
284
285
 
285
- final_res: Optional[Union[StepDict, AskActionResponse, List[FileDict]]] = (
286
- None
287
- )
286
+ final_res: Optional[
287
+ Union["StepDict", "AskActionResponse", List["FileDict"]]
288
+ ] = None
288
289
 
289
290
  if user_res:
290
291
  interaction: Union[str, None] = None
@@ -319,7 +320,7 @@ class ChainlitEmitter(BaseChainlitEmitter):
319
320
  elif spec.type == "action":
320
321
  action_res = cast(AskActionResponse, user_res)
321
322
  final_res = action_res
322
- interaction = action_res["name"]
323
+ interaction = action_res["value"]
323
324
 
324
325
  if not self.session.has_first_interaction and interaction:
325
326
  self.session.has_first_interaction = True
@@ -385,6 +386,9 @@ class ChainlitEmitter(BaseChainlitEmitter):
385
386
  def set_chat_settings(self, settings: Dict[str, Any]):
386
387
  self.session.chat_settings = settings
387
388
 
388
- def send_window_message(self, data: Any):
389
- """Send custom data to the host window."""
390
- return self.emit("window_message", data)
389
+ def send_action_response(
390
+ self, id: str, status: bool, response: Optional[str] = None
391
+ ):
392
+ return self.emit(
393
+ "action_response", {"id": id, "status": status, "response": response}
394
+ )
@@ -0,0 +1 @@
1
+ import{g as P,r as v,u as D,a as O}from"./index-f5df2072.js";function b(t,e){for(var r=0;r<e.length;r++){const o=e[r];if(typeof o!="string"&&!Array.isArray(o)){for(const a in o)if(a!=="default"&&!(a in t)){const i=Object.getOwnPropertyDescriptor(o,a);i&&Object.defineProperty(t,a,i.get?i:{enumerable:!0,get:()=>o[a]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var M=Object.create,s=Object.defineProperty,w=Object.getOwnPropertyDescriptor,S=Object.getOwnPropertyNames,j=Object.getPrototypeOf,T=Object.prototype.hasOwnProperty,E=(t,e,r)=>e in t?s(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,A=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},h=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of S(e))!T.call(t,a)&&a!==r&&s(t,a,{get:()=>e[a],enumerable:!(o=w(e,a))||o.enumerable});return t},L=(t,e,r)=>(r=t!=null?M(j(t)):{},h(e||!t||!t.__esModule?s(r,"default",{value:t,enumerable:!0}):r,t)),C=t=>h(s({},"__esModule",{value:!0}),t),n=(t,e,r)=>(E(t,typeof e!="symbol"?e+"":e,r),r),d={};A(d,{default:()=>p});var _=C(d),c=L(v),l=D,f=O;const x="https://api.dmcdn.net/all.js",N="DM",K="dmAsyncInit";class p extends c.Component{constructor(){super(...arguments),n(this,"callPlayer",l.callPlayer),n(this,"onDurationChange",()=>{const e=this.getDuration();this.props.onDuration(e)}),n(this,"mute",()=>{this.callPlayer("setMuted",!0)}),n(this,"unmute",()=>{this.callPlayer("setMuted",!1)}),n(this,"ref",e=>{this.container=e})}componentDidMount(){this.props.onMount&&this.props.onMount(this)}load(e){const{controls:r,config:o,onError:a,playing:i}=this.props,[,y]=e.match(f.MATCH_URL_DAILYMOTION);if(this.player){this.player.load(y,{start:(0,l.parseStartTime)(e),autoplay:i});return}(0,l.getSDK)(x,N,K,u=>u.player).then(u=>{if(!this.container)return;const g=u.player;this.player=new g(this.container,{width:"100%",height:"100%",video:y,params:{controls:r,autoplay:this.props.playing,mute:this.props.muted,start:(0,l.parseStartTime)(e),origin:window.location.origin,...o.params},events:{apiready:this.props.onReady,seeked:()=>this.props.onSeek(this.player.currentTime),video_end:this.props.onEnded,durationchange:this.onDurationChange,pause:this.props.onPause,playing:this.props.onPlay,waiting:this.props.onBuffer,error:m=>a(m)}})},a)}play(){this.callPlayer("play")}pause(){this.callPlayer("pause")}stop(){}seekTo(e,r=!0){this.callPlayer("seek",e),r||this.pause()}setVolume(e){this.callPlayer("setVolume",e)}getDuration(){return this.player.duration||null}getCurrentTime(){return this.player.currentTime}getSecondsLoaded(){return this.player.bufferedTime}render(){const{display:e}=this.props,r={width:"100%",height:"100%",display:e};return c.default.createElement("div",{style:r},c.default.createElement("div",{ref:this.ref}))}}n(p,"displayName","DailyMotion");n(p,"canPlay",f.canPlay.dailymotion);n(p,"loopOnEnded",!0);const R=P(_),I=b({__proto__:null,default:R},[_]);export{I as D};
@@ -0,0 +1 @@
1
+ import{g as _,r as g,u as P,a as m}from"./index-f5df2072.js";function v(t,e){for(var r=0;r<e.length;r++){const a=e[r];if(typeof a!="string"&&!Array.isArray(a)){for(const s in a)if(s!=="default"&&!(s in t)){const p=Object.getOwnPropertyDescriptor(a,s);p&&Object.defineProperty(t,s,p.get?p:{enumerable:!0,get:()=>a[s]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var O=Object.create,i=Object.defineProperty,D=Object.getOwnPropertyDescriptor,E=Object.getOwnPropertyNames,S=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty,I=(t,e,r)=>e in t?i(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,k=(t,e)=>{for(var r in e)i(t,r,{get:e[r],enumerable:!0})},h=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of E(e))!j.call(t,s)&&s!==r&&i(t,s,{get:()=>e[s],enumerable:!(a=D(e,s))||a.enumerable});return t},w=(t,e,r)=>(r=t!=null?O(S(t)):{},h(e||!t||!t.__esModule?i(r,"default",{value:t,enumerable:!0}):r,t)),F=t=>h(i({},"__esModule",{value:!0}),t),o=(t,e,r)=>(I(t,typeof e!="symbol"?e+"":e,r),r),b={};k(b,{default:()=>l});var d=F(b),u=w(g),n=P,x=m;const c="https://connect.facebook.net/en_US/sdk.js",y="FB",f="fbAsyncInit",L="facebook-player-";class l extends u.Component{constructor(){super(...arguments),o(this,"callPlayer",n.callPlayer),o(this,"playerID",this.props.config.playerId||`${L}${(0,n.randomString)()}`),o(this,"mute",()=>{this.callPlayer("mute")}),o(this,"unmute",()=>{this.callPlayer("unmute")})}componentDidMount(){this.props.onMount&&this.props.onMount(this)}load(e,r){if(r){(0,n.getSDK)(c,y,f).then(a=>a.XFBML.parse());return}(0,n.getSDK)(c,y,f).then(a=>{a.init({appId:this.props.config.appId,xfbml:!0,version:this.props.config.version}),a.Event.subscribe("xfbml.render",s=>{this.props.onLoaded()}),a.Event.subscribe("xfbml.ready",s=>{s.type==="video"&&s.id===this.playerID&&(this.player=s.instance,this.player.subscribe("startedPlaying",this.props.onPlay),this.player.subscribe("paused",this.props.onPause),this.player.subscribe("finishedPlaying",this.props.onEnded),this.player.subscribe("startedBuffering",this.props.onBuffer),this.player.subscribe("finishedBuffering",this.props.onBufferEnd),this.player.subscribe("error",this.props.onError),this.props.muted?this.callPlayer("mute"):this.callPlayer("unmute"),this.props.onReady(),document.getElementById(this.playerID).querySelector("iframe").style.visibility="visible")})})}play(){this.callPlayer("play")}pause(){this.callPlayer("pause")}stop(){}seekTo(e,r=!0){this.callPlayer("seek",e),r||this.pause()}setVolume(e){this.callPlayer("setVolume",e)}getDuration(){return this.callPlayer("getDuration")}getCurrentTime(){return this.callPlayer("getCurrentPosition")}getSecondsLoaded(){return null}render(){const{attributes:e}=this.props.config,r={width:"100%",height:"100%"};return u.default.createElement("div",{style:r,id:this.playerID,className:"fb-video","data-href":this.props.url,"data-autoplay":this.props.playing?"true":"false","data-allowfullscreen":"true","data-controls":this.props.controls?"true":"false",...e})}}o(l,"displayName","Facebook");o(l,"canPlay",x.canPlay.facebook);o(l,"loopOnEnded",!0);const M=_(d),B=v({__proto__:null,default:M},[d]);export{B as F};
@@ -0,0 +1 @@
1
+ import{g as b,r as _,u as O,a as A}from"./index-f5df2072.js";function R(s,e){for(var t=0;t<e.length;t++){const i=e[t];if(typeof i!="string"&&!Array.isArray(i)){for(const n in i)if(n!=="default"&&!(n in s)){const l=Object.getOwnPropertyDescriptor(i,n);l&&Object.defineProperty(s,n,l.get?l:{enumerable:!0,get:()=>i[n]})}}}return Object.freeze(Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}))}var I=Object.create,u=Object.defineProperty,D=Object.getOwnPropertyDescriptor,w=Object.getOwnPropertyNames,M=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty,U=(s,e,t)=>e in s?u(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,N=(s,e)=>{for(var t in e)u(s,t,{get:e[t],enumerable:!0})},E=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of w(e))!k.call(s,n)&&n!==t&&u(s,n,{get:()=>e[n],enumerable:!(i=D(e,n))||i.enumerable});return s},j=(s,e,t)=>(t=s!=null?I(M(s)):{},E(e||!s||!s.__esModule?u(t,"default",{value:s,enumerable:!0}):t,s)),H=s=>E(u({},"__esModule",{value:!0}),s),r=(s,e,t)=>(U(s,typeof e!="symbol"?e+"":e,t),t),m={};N(m,{default:()=>P});var g=H(m),c=j(_),a=O,d=A;const y=typeof navigator<"u",F=y&&navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1,v=y&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||F)&&!window.MSStream,V=y&&/^((?!chrome|android).)*safari/i.test(navigator.userAgent)&&!window.MSStream,T="https://cdn.jsdelivr.net/npm/hls.js@VERSION/dist/hls.min.js",C="Hls",B="https://cdnjs.cloudflare.com/ajax/libs/dashjs/VERSION/dash.all.min.js",x="dashjs",K="https://cdn.jsdelivr.net/npm/flv.js@VERSION/dist/flv.min.js",G="flvjs",X=/www\.dropbox\.com\/.+/,f=/https:\/\/watch\.cloudflarestream\.com\/([a-z0-9]+)/,W="https://videodelivery.net/{id}/manifest/video.m3u8";class P extends c.Component{constructor(){super(...arguments),r(this,"onReady",(...e)=>this.props.onReady(...e)),r(this,"onPlay",(...e)=>this.props.onPlay(...e)),r(this,"onBuffer",(...e)=>this.props.onBuffer(...e)),r(this,"onBufferEnd",(...e)=>this.props.onBufferEnd(...e)),r(this,"onPause",(...e)=>this.props.onPause(...e)),r(this,"onEnded",(...e)=>this.props.onEnded(...e)),r(this,"onError",(...e)=>this.props.onError(...e)),r(this,"onPlayBackRateChange",e=>this.props.onPlaybackRateChange(e.target.playbackRate)),r(this,"onEnablePIP",(...e)=>this.props.onEnablePIP(...e)),r(this,"onDisablePIP",e=>{const{onDisablePIP:t,playing:i}=this.props;t(e),i&&this.play()}),r(this,"onPresentationModeChange",e=>{if(this.player&&(0,a.supportsWebKitPresentationMode)(this.player)){const{webkitPresentationMode:t}=this.player;t==="picture-in-picture"?this.onEnablePIP(e):t==="inline"&&this.onDisablePIP(e)}}),r(this,"onSeek",e=>{this.props.onSeek(e.target.currentTime)}),r(this,"mute",()=>{this.player.muted=!0}),r(this,"unmute",()=>{this.player.muted=!1}),r(this,"renderSourceElement",(e,t)=>typeof e=="string"?c.default.createElement("source",{key:t,src:e}):c.default.createElement("source",{key:t,...e})),r(this,"renderTrack",(e,t)=>c.default.createElement("track",{key:t,...e})),r(this,"ref",e=>{this.player&&(this.prevPlayer=this.player),this.player=e})}componentDidMount(){this.props.onMount&&this.props.onMount(this),this.addListeners(this.player);const e=this.getSource(this.props.url);e&&(this.player.src=e),(v||this.props.config.forceDisableHls)&&this.player.load()}componentDidUpdate(e){this.shouldUseAudio(this.props)!==this.shouldUseAudio(e)&&(this.removeListeners(this.prevPlayer,e.url),this.addListeners(this.player)),this.props.url!==e.url&&!(0,a.isMediaStream)(this.props.url)&&!(this.props.url instanceof Array)&&(this.player.srcObject=null)}componentWillUnmount(){this.player.removeAttribute("src"),this.removeListeners(this.player),this.hls&&this.hls.destroy()}addListeners(e){const{url:t,playsinline:i}=this.props;e.addEventListener("play",this.onPlay),e.addEventListener("waiting",this.onBuffer),e.addEventListener("playing",this.onBufferEnd),e.addEventListener("pause",this.onPause),e.addEventListener("seeked",this.onSeek),e.addEventListener("ended",this.onEnded),e.addEventListener("error",this.onError),e.addEventListener("ratechange",this.onPlayBackRateChange),e.addEventListener("enterpictureinpicture",this.onEnablePIP),e.addEventListener("leavepictureinpicture",this.onDisablePIP),e.addEventListener("webkitpresentationmodechanged",this.onPresentationModeChange),this.shouldUseHLS(t)||e.addEventListener("canplay",this.onReady),i&&(e.setAttribute("playsinline",""),e.setAttribute("webkit-playsinline",""),e.setAttribute("x5-playsinline",""))}removeListeners(e,t){e.removeEventListener("canplay",this.onReady),e.removeEventListener("play",this.onPlay),e.removeEventListener("waiting",this.onBuffer),e.removeEventListener("playing",this.onBufferEnd),e.removeEventListener("pause",this.onPause),e.removeEventListener("seeked",this.onSeek),e.removeEventListener("ended",this.onEnded),e.removeEventListener("error",this.onError),e.removeEventListener("ratechange",this.onPlayBackRateChange),e.removeEventListener("enterpictureinpicture",this.onEnablePIP),e.removeEventListener("leavepictureinpicture",this.onDisablePIP),e.removeEventListener("webkitpresentationmodechanged",this.onPresentationModeChange),this.shouldUseHLS(t)||e.removeEventListener("canplay",this.onReady)}shouldUseAudio(e){return e.config.forceVideo||e.config.attributes.poster?!1:d.AUDIO_EXTENSIONS.test(e.url)||e.config.forceAudio}shouldUseHLS(e){return V&&this.props.config.forceSafariHLS||this.props.config.forceHLS?!0:v||this.props.config.forceDisableHls?!1:d.HLS_EXTENSIONS.test(e)||f.test(e)}shouldUseDASH(e){return d.DASH_EXTENSIONS.test(e)||this.props.config.forceDASH}shouldUseFLV(e){return d.FLV_EXTENSIONS.test(e)||this.props.config.forceFLV}load(e){const{hlsVersion:t,hlsOptions:i,dashVersion:n,flvVersion:l}=this.props.config;if(this.hls&&this.hls.destroy(),this.dash&&this.dash.reset(),this.shouldUseHLS(e)&&(0,a.getSDK)(T.replace("VERSION",t),C).then(o=>{if(this.hls=new o(i),this.hls.on(o.Events.MANIFEST_PARSED,()=>{this.props.onReady()}),this.hls.on(o.Events.ERROR,(h,p)=>{this.props.onError(h,p,this.hls,o)}),f.test(e)){const h=e.match(f)[1];this.hls.loadSource(W.replace("{id}",h))}else this.hls.loadSource(e);this.hls.attachMedia(this.player),this.props.onLoaded()}),this.shouldUseDASH(e)&&(0,a.getSDK)(B.replace("VERSION",n),x).then(o=>{this.dash=o.MediaPlayer().create(),this.dash.initialize(this.player,e,this.props.playing),this.dash.on("error",this.props.onError),parseInt(n)<3?this.dash.getDebug().setLogToBrowserConsole(!1):this.dash.updateSettings({debug:{logLevel:o.Debug.LOG_LEVEL_NONE}}),this.props.onLoaded()}),this.shouldUseFLV(e)&&(0,a.getSDK)(K.replace("VERSION",l),G).then(o=>{this.flv=o.createPlayer({type:"flv",url:e}),this.flv.attachMediaElement(this.player),this.flv.on(o.Events.ERROR,(h,p)=>{this.props.onError(h,p,this.flv,o)}),this.flv.load(),this.props.onLoaded()}),e instanceof Array)this.player.load();else if((0,a.isMediaStream)(e))try{this.player.srcObject=e}catch{this.player.src=window.URL.createObjectURL(e)}}play(){const e=this.player.play();e&&e.catch(this.props.onError)}pause(){this.player.pause()}stop(){this.player.removeAttribute("src"),this.dash&&this.dash.reset()}seekTo(e,t=!0){this.player.currentTime=e,t||this.pause()}setVolume(e){this.player.volume=e}enablePIP(){this.player.requestPictureInPicture&&document.pictureInPictureElement!==this.player?this.player.requestPictureInPicture():(0,a.supportsWebKitPresentationMode)(this.player)&&this.player.webkitPresentationMode!=="picture-in-picture"&&this.player.webkitSetPresentationMode("picture-in-picture")}disablePIP(){document.exitPictureInPicture&&document.pictureInPictureElement===this.player?document.exitPictureInPicture():(0,a.supportsWebKitPresentationMode)(this.player)&&this.player.webkitPresentationMode!=="inline"&&this.player.webkitSetPresentationMode("inline")}setPlaybackRate(e){try{this.player.playbackRate=e}catch(t){this.props.onError(t)}}getDuration(){if(!this.player)return null;const{duration:e,seekable:t}=this.player;return e===1/0&&t.length>0?t.end(t.length-1):e}getCurrentTime(){return this.player?this.player.currentTime:null}getSecondsLoaded(){if(!this.player)return null;const{buffered:e}=this.player;if(e.length===0)return 0;const t=e.end(e.length-1),i=this.getDuration();return t>i?i:t}getSource(e){const t=this.shouldUseHLS(e),i=this.shouldUseDASH(e),n=this.shouldUseFLV(e);if(!(e instanceof Array||(0,a.isMediaStream)(e)||t||i||n))return X.test(e)?e.replace("www.dropbox.com","dl.dropboxusercontent.com"):e}render(){const{url:e,playing:t,loop:i,controls:n,muted:l,config:o,width:h,height:p}=this.props,L=this.shouldUseAudio(this.props)?"audio":"video",S={width:h==="auto"?h:"100%",height:p==="auto"?p:"100%"};return c.default.createElement(L,{ref:this.ref,src:this.getSource(e),style:S,preload:"auto",autoPlay:t||void 0,controls:n,muted:l,loop:i,...o.attributes},e instanceof Array&&e.map(this.renderSourceElement),o.tracks.map(this.renderTrack))}}r(P,"displayName","FilePlayer");r(P,"canPlay",d.canPlay.file);const z=b(g),J=R({__proto__:null,default:z},[g]);export{J as F};
@@ -0,0 +1 @@
1
+ import{g as y,r as f,u as _,a as m}from"./index-f5df2072.js";function P(r,e){for(var t=0;t<e.length;t++){const s=e[t];if(typeof s!="string"&&!Array.isArray(s)){for(const a in s)if(a!=="default"&&!(a in r)){const l=Object.getOwnPropertyDescriptor(s,a);l&&Object.defineProperty(r,a,l.get?l:{enumerable:!0,get:()=>s[a]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}var g=Object.create,n=Object.defineProperty,b=Object.getOwnPropertyDescriptor,v=Object.getOwnPropertyNames,O=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,j=(r,e,t)=>e in r?n(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,L=(r,e)=>{for(var t in e)n(r,t,{get:e[t],enumerable:!0})},c=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of v(e))!w.call(r,a)&&a!==t&&n(r,a,{get:()=>e[a],enumerable:!(s=b(e,a))||s.enumerable});return r},K=(r,e,t)=>(t=r!=null?g(O(r)):{},c(e||!r||!r.__esModule?n(t,"default",{value:r,enumerable:!0}):t,r)),D=r=>c(n({},"__esModule",{value:!0}),r),o=(r,e,t)=>(j(r,typeof e!="symbol"?e+"":e,t),t),h={};L(h,{default:()=>i});var d=D(h),u=K(f),p=_,S=m;const T="https://cdn.embed.ly/player-0.1.0.min.js",E="playerjs";class i extends u.Component{constructor(){super(...arguments),o(this,"callPlayer",p.callPlayer),o(this,"duration",null),o(this,"currentTime",null),o(this,"secondsLoaded",null),o(this,"mute",()=>{this.callPlayer("mute")}),o(this,"unmute",()=>{this.callPlayer("unmute")}),o(this,"ref",e=>{this.iframe=e})}componentDidMount(){this.props.onMount&&this.props.onMount(this)}load(e){(0,p.getSDK)(T,E).then(t=>{this.iframe&&(this.player=new t.Player(this.iframe),this.player.on("ready",()=>{setTimeout(()=>{this.player.isReady=!0,this.player.setLoop(this.props.loop),this.props.muted&&this.player.mute(),this.addListeners(this.player,this.props),this.props.onReady()},500)}))},this.props.onError)}addListeners(e,t){e.on("play",t.onPlay),e.on("pause",t.onPause),e.on("ended",t.onEnded),e.on("error",t.onError),e.on("timeupdate",({duration:s,seconds:a})=>{this.duration=s,this.currentTime=a})}play(){this.callPlayer("play")}pause(){this.callPlayer("pause")}stop(){}seekTo(e,t=!0){this.callPlayer("setCurrentTime",e),t||this.pause()}setVolume(e){this.callPlayer("setVolume",e)}setLoop(e){this.callPlayer("setLoop",e)}getDuration(){return this.duration}getCurrentTime(){return this.currentTime}getSecondsLoaded(){return this.secondsLoaded}render(){const e={width:"100%",height:"100%"};return u.default.createElement("iframe",{ref:this.ref,src:this.props.url,frameBorder:"0",scrolling:"no",style:e,allow:"encrypted-media; autoplay; fullscreen;",referrerPolicy:"no-referrer-when-downgrade"})}}o(i,"displayName","Kaltura");o(i,"canPlay",S.canPlay.kaltura);const M=y(d),C=P({__proto__:null,default:M},[d]);export{C as K};
@@ -0,0 +1 @@
1
+ import{g as _,r as f,u as m,a as g}from"./index-f5df2072.js";function v(t,e){for(var r=0;r<e.length;r++){const s=e[r];if(typeof s!="string"&&!Array.isArray(s)){for(const o in s)if(o!=="default"&&!(o in t)){const n=Object.getOwnPropertyDescriptor(s,o);n&&Object.defineProperty(t,o,n.get?n:{enumerable:!0,get:()=>s[o]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var P=Object.create,i=Object.defineProperty,O=Object.getOwnPropertyDescriptor,b=Object.getOwnPropertyNames,M=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,x=(t,e,r)=>e in t?i(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,j=(t,e)=>{for(var r in e)i(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of b(e))!w.call(t,o)&&o!==r&&i(t,o,{get:()=>e[o],enumerable:!(s=O(e,o))||s.enumerable});return t},D=(t,e,r)=>(r=t!=null?P(M(t)):{},c(e||!t||!t.__esModule?i(r,"default",{value:t,enumerable:!0}):r,t)),S=t=>c(i({},"__esModule",{value:!0}),t),a=(t,e,r)=>(x(t,typeof e!="symbol"?e+"":e,r),r),d={};j(d,{default:()=>l});var h=S(d),p=D(f),u=m,y=g;const E="https://widget.mixcloud.com/media/js/widgetApi.js",L="Mixcloud";class l extends p.Component{constructor(){super(...arguments),a(this,"callPlayer",u.callPlayer),a(this,"duration",null),a(this,"currentTime",null),a(this,"secondsLoaded",null),a(this,"mute",()=>{}),a(this,"unmute",()=>{}),a(this,"ref",e=>{this.iframe=e})}componentDidMount(){this.props.onMount&&this.props.onMount(this)}load(e){(0,u.getSDK)(E,L).then(r=>{this.player=r.PlayerWidget(this.iframe),this.player.ready.then(()=>{this.player.events.play.on(this.props.onPlay),this.player.events.pause.on(this.props.onPause),this.player.events.ended.on(this.props.onEnded),this.player.events.error.on(this.props.error),this.player.events.progress.on((s,o)=>{this.currentTime=s,this.duration=o}),this.props.onReady()})},this.props.onError)}play(){this.callPlayer("play")}pause(){this.callPlayer("pause")}stop(){}seekTo(e,r=!0){this.callPlayer("seek",e),r||this.pause()}setVolume(e){}getDuration(){return this.duration}getCurrentTime(){return this.currentTime}getSecondsLoaded(){return null}render(){const{url:e,config:r}=this.props,s=e.match(y.MATCH_URL_MIXCLOUD)[1],o={width:"100%",height:"100%"},n=(0,u.queryString)({...r.options,feed:`/${s}/`});return p.default.createElement("iframe",{key:s,ref:this.ref,style:o,src:`https://www.mixcloud.com/widget/iframe/?${n}`,frameBorder:"0",allow:"autoplay"})}}a(l,"displayName","Mixcloud");a(l,"canPlay",y.canPlay.mixcloud);a(l,"loopOnEnded",!0);const T=_(h),A=v({__proto__:null,default:T},[h]);export{A as M};