Skip to content

Commit

Permalink
Merge branch 'main' into pr-1162
Browse files Browse the repository at this point in the history
  • Loading branch information
jfperusse-bhvr authored Nov 12, 2024
2 parents cd98b75 + 45866b2 commit 0f41c32
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 158 deletions.
147 changes: 61 additions & 86 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,72 @@ All notable changes to Chainlit will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.3.2] - 2024-11-08

### Security Advisory
**IMPORTANT**:
- This release drops support for FastAPI versions before 0.115.3 and Starlette versions before 0.41.2 due to a severe security vulnerability (CVE-2024-47874). We strongly encourage all downstream dependencies to upgrade as well.
- This release still contains a known security vulnerability in the element feature that could allow unauthorized file access. We strongly recommend against using elements in production environments until a comprehensive fix is implemented in an upcoming release.

### Security
- **[breaking]** Updated dependencies to address critical issues (#1493):
- Upgraded fastapi to 0.115.3 to address CVE-2024-47874 in Starlette
- Upgraded starlette to 0.41.2 (required for security fix)
- Upgraded werkzeug to 3.0.6

Note: This is a breaking change as older FastAPI versions are no longer supported.
To prioritize security, we opted to break with semver on this particular occasion.

### Fixed
- Resolved incorrect message ordering in UI (#1501)

## [2.0rc0] - 2024-11-08

### Security Advisory
**IMPORTANT**:
- The element feature currently contains a known security vulnerability that could allow unauthorized file access. We strongly recommend against using elements in production environments until a comprehensive fix is implemented in an upcoming release.

### Changed
- **[breaking]**: Completely revamped audio implementation (#1401, #1410):
- Replaced `AudioChunk` with `InputAudioChunk` and `OutputAudioChunk`
- Changed default audio sampling rate from 44100 to 24000
- Removed several audio configuration options (`min_decibels`, `initial_silence_timeout`, `silence_timeout`, `chunk_duration`, `max_duration`)
- Removed `RecordScreen` component
- Factored storage clients into separate modules (#1363)

### Added
- Realtime audio streaming and processing (#1401, #1406, #1410):
- New `AudioPresence` component for visual representation
- Implemented `WavRecorder` and `WavStreamPlayer` classes
- Introduced new `on_audio_start` callback
- Added audio interruption functionality
- New audio connection signaling with `on` and `off` states
- Interactive DataFrame display with auto-fit content using MUI Data Grid (#1373, #1467)
- Optional websocket connection in react-client (#1379)
- Enhanced image interaction with popup view and download option (#1402)
- Current URL included in message payload (#1403)
- Allow empty chat input when submitting attachments (#1261)

### Fixes
- Various backend fixes and cleanup (#1432):
- Use importlib.util.find_spec to check if a package is installed
- Use `raise... from` to wrap exceptions
- Fix error message in Discord integration
- Several minor fixups/cleanup

### Development
- Implemented ruff for linting and formatting (#1495)
- Added mypy daemon for faster type-checking (#1495)
- Added GitHub Actions linting (#1445)
- Enabled direct installation from GitHub (#1423)
- Various build script improvements (#1462)

## [1.3.1] - 2024-10-25

### Security Advisory

- **IMPORTANT**: This release temporarily reverts the file access security improvements from 1.3.0 to restore element functionality. The element feature currently has a known security vulnerability that could allow unauthorized access to files. We strongly recommend against using elements in production environments until the next release.
- A comprehensive security fix using HTTP-only cookie authentication will be implemented in an upcoming release.
- A comprehensive security fix will be implemented in an upcoming release.

### Changed

Expand Down Expand Up @@ -59,91 +119,6 @@ override oauth prompt parameter. Enabling users to explicitly enable login/conse
- Improved Python code style and linting (#1353)
- Resolved various small text and documentation issues (#1347, #1348)

## [2.0.dev2] - 2024-10-25

### Security Advisory

- **IMPORTANT**: This release temporarily reverts the file access security improvements from 2.0.dev1 to restore element functionality. The element feature currently has a known security vulnerability that could allow unauthorized access to files. We strongly recommend against using elements in production environments until the next release.
- A comprehensive security fix using HTTP-only cookie authentication will be implemented in an upcoming release.

### Changed

- Reverted authentication requirements for file access endpoints to restore element functionality (#1474)

### Development

- Work in progress on implementing HTTP-only cookie authentication for proper security (#1472)

## [2.0.dev1] - 2024-10-22

### Added

- Interactive DataFrame display component using MUI Data Grid (#1373)
- Optional websocket connection in react-client (#1379)
- Current URL in message payload (#1403)
- Improved image interaction - clicking opens popup with download option (#1402)
- Configurable user session timeout (#1032)

### Security

- Fixed file access vulnerability in get_file and upload_file endpoints (#1441)
- Added authentication to /project/file endpoint (#1441)
- Addressed security vulnerabilities in frontend dependencies (#1431, #1414)

### Fixed

- Dialog boxes extending beyond window (#1446)
- Allow empty chat input when submitting attachments (#1261)
- Tasklist when Chainlit is submounted (#1433)
- Spaces in avatar filenames (#1418)
- Step argument input and concurrency issues (#1409)
- Display_name copying to PersistentUser during authentication (#1425)

### Development

- Refactored storage clients into separate modules (#1363)
- Support for IETF BCP 47 language tags (#1399)
- Improved GitHub Actions workflows and build process (#1445)
- Direct installation from GitHub support (#1423)
- Extended package metadata with homepage and documentation links (#1413)
- Various backend fixes and code cleanup (#1432)

## [2.0.dev0] - 2024-10-08

### Breaking Changes

- Completely revamped audio implementation:
- Removed `AudioChunk` type, replaced with `InputAudioChunk` and `OutputAudioChunk`
- Changed audio sampling rate from 44100 to 24000
- Removed several audio configuration options (`min_decibels`, `initial_silence_timeout`, `silence_timeout`, `chunk_duration`, `max_duration`)
- Introduced new `on_audio_start` callback
- Modified `on_audio_end` callback to no longer accept file elements as arguments

### Added

- New audio connection signaling with `on` and `off` states
- Introduced `AudioPresence` component for visual representation of audio state
- Added `WavRecorder` and `WavStreamPlayer` classes for improved audio handling
- New `startConversation` and `endConversation` methods in `useAudio` hook
- Implemented audio interruption functionality

### Changed

- Updated `useChatInteract` hook to include `startAudioStream` method
- Modified `useChatSession` to handle new audio streaming functionality
- Updated UI components to reflect new audio implementation, including new microphone icons and audio presence indicators
- Refactored `InputBoxFooter` to display audio presence when active

### Removed

- Eliminated `RecordScreen` component
- Removed several audio-related configuration options from `config.toml`

### Development

- Added new wavtools directory with various audio processing utilities
- Implemented new AudioWorklet processors for more efficient audio handling

## [1.2.0] - 2024-09-16

### Security
Expand Down
7 changes: 5 additions & 2 deletions backend/chainlit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import asyncio
from typing import TYPE_CHECKING, Any, Dict

from literalai import ChatGeneration, CompletionGeneration, GenerationMessage
from pydantic.dataclasses import dataclass

import chainlit.input_widget as input_widget
from chainlit.action import Action
from chainlit.cache import cache
Expand Down Expand Up @@ -49,12 +52,11 @@
from chainlit.user_session import user_session
from chainlit.utils import make_module_getattr
from chainlit.version import __version__
from literalai import ChatGeneration, CompletionGeneration, GenerationMessage
from pydantic.dataclasses import dataclass

from .callbacks import (
action_callback,
author_rename,
data_layer,
header_auth_callback,
oauth_callback,
on_audio_chunk,
Expand Down Expand Up @@ -190,6 +192,7 @@ def acall(self):
"on_stop",
"action_callback",
"on_settings_update",
"data_layer",
]


Expand Down
29 changes: 23 additions & 6 deletions backend/chainlit/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@
import inspect
from typing import Any, Awaitable, Callable, Dict, List, Optional

from fastapi import Request, Response
from starlette.datastructures import Headers

from chainlit.action import Action
from chainlit.config import config
from chainlit.context import context
from chainlit.data.base import BaseDataLayer
from chainlit.message import Message
from chainlit.oauth_providers import get_configured_oauth_providers
from chainlit.step import Step, step
from chainlit.telemetry import trace
from chainlit.types import ChatProfile, Starter, ThreadDict
from chainlit.user import User
from chainlit.utils import wrap_user_function
from fastapi import Request, Response
from starlette.datastructures import Headers


@trace
def password_auth_callback(
func: Callable[[str, str], Awaitable[Optional[User]]]
func: Callable[[str, str], Awaitable[Optional[User]]],
) -> Callable:
"""
Framework agnostic decorator to authenticate the user.
Expand All @@ -40,7 +42,7 @@ async def password_auth_callback(username: str, password: str) -> Optional[User]

@trace
def header_auth_callback(
func: Callable[[Headers], Awaitable[Optional[User]]]
func: Callable[[Headers], Awaitable[Optional[User]]],
) -> Callable:
"""
Framework agnostic decorator to authenticate the user via a header
Expand Down Expand Up @@ -206,7 +208,7 @@ def set_chat_profiles(

@trace
def set_starters(
func: Callable[[Optional["User"]], Awaitable[List["Starter"]]]
func: Callable[[Optional["User"]], Awaitable[List["Starter"]]],
) -> Callable:
"""
Programmatic declaration of the available starter (can depend on the User from the session if authentication is setup).
Expand Down Expand Up @@ -250,6 +252,7 @@ def on_audio_start(func: Callable) -> Callable:
config.code.on_audio_start = wrap_user_function(func, with_task=False)
return func


@trace
def on_audio_chunk(func: Callable) -> Callable:
"""
Expand Down Expand Up @@ -283,7 +286,7 @@ def on_audio_end(func: Callable) -> Callable:

@trace
def author_rename(
func: Callable[[str], Awaitable[str]]
func: Callable[[str], Awaitable[str]],
) -> Callable[[str], Awaitable[str]]:
"""
Useful to rename the author of message to display more friendly author names in the UI.
Expand Down Expand Up @@ -344,3 +347,17 @@ def on_settings_update(

config.code.on_settings_update = wrap_user_function(func, with_task=True)
return func


def data_layer(
func: Callable[[], BaseDataLayer],
) -> Callable[[], BaseDataLayer]:
"""
Hook to configure custom data layer.
"""

# We don't use wrap_user_function here because:
# 1. We don't need to support async here and;
# 2. We don't want to change the API for get_data_layer() to be async, everywhere (at this point).
config.code.data_layer = func
return func
26 changes: 15 additions & 11 deletions backend/chainlit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@
)

import tomli
from chainlit.logger import logger
from chainlit.translations import lint_translation_json
from chainlit.version import __version__
from dataclasses_json import DataClassJsonMixin
from pydantic.dataclasses import Field, dataclass
from starlette.datastructures import Headers

from chainlit.data.base import BaseDataLayer
from chainlit.logger import logger
from chainlit.translations import lint_translation_json
from chainlit.version import __version__

from ._utils import is_path_inside

if TYPE_CHECKING:
from fastapi import Request, Response

from chainlit.action import Action
from chainlit.message import Message
from chainlit.types import InputAudioChunk, ChatProfile, Starter, ThreadDict
from chainlit.types import ChatProfile, InputAudioChunk, Starter, ThreadDict
from chainlit.user import User
from fastapi import Request, Response


BACKEND_ROOT = os.path.dirname(__file__)
Expand Down Expand Up @@ -272,9 +275,9 @@ class CodeSettings:
password_auth_callback: Optional[
Callable[[str, str], Awaitable[Optional["User"]]]
] = None
header_auth_callback: Optional[
Callable[[Headers], Awaitable[Optional["User"]]]
] = None
header_auth_callback: Optional[Callable[[Headers], Awaitable[Optional["User"]]]] = (
None
)
oauth_callback: Optional[
Callable[[str, str, Dict[str, str], "User"], Awaitable[Optional["User"]]]
] = None
Expand All @@ -294,9 +297,10 @@ class CodeSettings:
set_chat_profiles: Optional[
Callable[[Optional["User"]], Awaitable[List["ChatProfile"]]]
] = None
set_starters: Optional[
Callable[[Optional["User"]], Awaitable[List["Starter"]]]
] = None
set_starters: Optional[Callable[[Optional["User"]], Awaitable[List["Starter"]]]] = (
None
)
data_layer: Optional[Callable[[], BaseDataLayer]] = None


@dataclass()
Expand Down
9 changes: 8 additions & 1 deletion backend/chainlit/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@

def get_data_layer():
global _data_layer
print("Getting data layer", _data_layer)

if not _data_layer:
if api_key := os.environ.get("LITERAL_API_KEY"):
from chainlit.config import config

if config.code.data_layer:
# When @data_layer is configured, call it to get data layer.
_data_layer = config.code.data_layer()
elif api_key := os.environ.get("LITERAL_API_KEY"):
# When LITERAL_API_KEY is defined, use LiteralAI data layer
from .literalai import LiteralDataLayer

# support legacy LITERAL_SERVER variable as fallback
Expand Down
2 changes: 1 addition & 1 deletion backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "chainlit"
version = "2.0.dev2"
version = "2.0rc0"
keywords = [
'LLM',
'Agents',
Expand Down
Loading

0 comments on commit 0f41c32

Please sign in to comment.