ragbits-chat 1.4.0.dev202601170236__py3-none-any.whl → 1.4.0.dev202601300258__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.
- ragbits/chat/api.py +44 -45
- ragbits/chat/auth/backends.py +3 -7
- ragbits/chat/auth/oauth2_providers.py +68 -57
- ragbits/chat/config.py +14 -0
- ragbits/chat/interface/_interface.py +13 -0
- ragbits/chat/interface/types.py +15 -1
- ragbits/chat/ui-build/assets/AuthGuard-FL2hbNSz.js +1 -0
- ragbits/chat/ui-build/assets/{ChatHistory-B2hLBYMJ.js → ChatHistory-LRndyrq0.js} +2 -2
- ragbits/chat/ui-build/assets/{ChatOptionsForm-bfNG8UIW.js → ChatOptionsForm-C7AySsjS.js} +1 -1
- ragbits/chat/ui-build/assets/CredentialsLogin-CjWUo2_0.js +1 -0
- ragbits/chat/ui-build/assets/FeedbackForm-BLuzDSTy.js +1 -0
- ragbits/chat/ui-build/assets/{Login-DSW_CNFu.js → Login-CGHnIvPP.js} +1 -1
- ragbits/chat/ui-build/assets/{LogoutButton-BQE8NNsg.js → LogoutButton-C-wYL6PH.js} +1 -1
- ragbits/chat/ui-build/assets/{OAuth2Login-EmJ39PUe.js → OAuth2Login-CJdQ3WzG.js} +1 -1
- ragbits/chat/ui-build/assets/{ShareButton-B7DyIVH0.js → ShareButton-Cc7tfnmL.js} +1 -1
- ragbits/chat/ui-build/assets/UploadButton-_aV-toOW.js +1 -0
- ragbits/chat/ui-build/assets/{UsageButton-BABA7a-w.js → UsageButton-CE7BRQcH.js} +1 -1
- ragbits/chat/ui-build/assets/{authStore-BfGlL8rp.js → authStore-AVyfzjgs.js} +1 -1
- ragbits/chat/ui-build/assets/{chunk-IGSAU2ZA-NXd1g0Qd.js → chunk-IGSAU2ZA-BBfo0QFa.js} +1 -1
- ragbits/chat/ui-build/assets/{chunk-SSA7SXE4-CJa0HuAU.js → chunk-SSA7SXE4-D3GKTPj0.js} +1 -1
- ragbits/chat/ui-build/assets/{index-Ceq7Rkzy.js → index-B-LIlvZN.js} +1 -1
- ragbits/chat/ui-build/assets/index-B1u136LF.css +1 -0
- ragbits/chat/ui-build/assets/index-BcnaGCUm.js +1 -0
- ragbits/chat/ui-build/assets/{index-BZLU40Mk.js → index-CbVbgerL.js} +37 -37
- ragbits/chat/ui-build/assets/{index-Be0kkf3d.js → index-DTNGcmXG.js} +2 -2
- ragbits/chat/ui-build/assets/{useInitializeUserStore-DyHP7g8x.js → useInitializeUserStore-CVYyhiv3.js} +1 -1
- ragbits/chat/ui-build/assets/{useMenuTriggerState-SaFmATkk.js → useMenuTriggerState-C5916IcO.js} +1 -1
- ragbits/chat/ui-build/assets/{useSelectableItem-DhuFnc0W.js → useSelectableItem-BWC6EImE.js} +1 -1
- ragbits/chat/ui-build/index.html +2 -2
- {ragbits_chat-1.4.0.dev202601170236.dist-info → ragbits_chat-1.4.0.dev202601300258.dist-info}/METADATA +2 -2
- ragbits_chat-1.4.0.dev202601300258.dist-info/RECORD +60 -0
- ragbits/chat/ui-build/assets/AuthGuard-Bq7UOJ7y.js +0 -1
- ragbits/chat/ui-build/assets/CredentialsLogin-0g5-w2vR.js +0 -1
- ragbits/chat/ui-build/assets/FeedbackForm-oSbly5oN.js +0 -1
- ragbits/chat/ui-build/assets/index-Bvn9K6h_.js +0 -1
- ragbits/chat/ui-build/assets/index-ClAYkAiv.css +0 -1
- ragbits_chat-1.4.0.dev202601170236.dist-info/RECORD +0 -58
- {ragbits_chat-1.4.0.dev202601170236.dist-info → ragbits_chat-1.4.0.dev202601300258.dist-info}/WHEEL +0 -0
ragbits/chat/api.py
CHANGED
|
@@ -2,7 +2,6 @@ import asyncio
|
|
|
2
2
|
import importlib
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
|
-
import os
|
|
6
5
|
import re
|
|
7
6
|
import time
|
|
8
7
|
from collections.abc import AsyncGenerator
|
|
@@ -11,7 +10,7 @@ from pathlib import Path
|
|
|
11
10
|
from typing import Any, cast
|
|
12
11
|
|
|
13
12
|
import uvicorn
|
|
14
|
-
from fastapi import FastAPI, HTTPException, Request, status
|
|
13
|
+
from fastapi import FastAPI, HTTPException, Request, UploadFile, status
|
|
15
14
|
from fastapi.exceptions import RequestValidationError
|
|
16
15
|
from fastapi.middleware.cors import CORSMiddleware
|
|
17
16
|
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse, RedirectResponse, StreamingResponse
|
|
@@ -22,6 +21,7 @@ from ragbits.chat.auth import AuthenticationBackend, User
|
|
|
22
21
|
from ragbits.chat.auth.backends import MultiAuthenticationBackend, OAuth2AuthenticationBackend
|
|
23
22
|
from ragbits.chat.auth.provider_config import get_provider_visual_config
|
|
24
23
|
from ragbits.chat.auth.types import LoginRequest, LoginResponse, OAuth2Credentials
|
|
24
|
+
from ragbits.chat.config import BASE_URL, CHUNK_SIZE, IS_PRODUCTION, SESSION_COOKIE_NAME
|
|
25
25
|
from ragbits.chat.interface import ChatInterface
|
|
26
26
|
from ragbits.chat.interface.types import (
|
|
27
27
|
AuthenticationConfig,
|
|
@@ -46,17 +46,6 @@ from .metrics import ChatCounterMetric, ChatHistogramMetric
|
|
|
46
46
|
|
|
47
47
|
logger = logging.getLogger(__name__)
|
|
48
48
|
|
|
49
|
-
# Environment-aware cookie security: only require HTTPS in production
|
|
50
|
-
IS_PRODUCTION = os.getenv("ENVIRONMENT", "").lower() == "production"
|
|
51
|
-
|
|
52
|
-
# Session cookie name - used for storing session ID in HTTP-only cookie
|
|
53
|
-
SESSION_COOKIE_NAME = "ragbits_session"
|
|
54
|
-
|
|
55
|
-
# Chunk size for large base64 images to prevent SSE message size issues
|
|
56
|
-
# Keep chunks extremely small to avoid JSON string length limits in browsers and SSE parsing issues
|
|
57
|
-
# Account for JSON overhead: metadata + base64 data should fit comfortably in browser limits
|
|
58
|
-
CHUNK_SIZE = 102400 # ~100KB bytes base64 chunks for ultra-safe JSON parsing and SSE transmission
|
|
59
|
-
|
|
60
49
|
|
|
61
50
|
class RagbitsAPI:
|
|
62
51
|
"""
|
|
@@ -91,12 +80,7 @@ class RagbitsAPI:
|
|
|
91
80
|
self.auth_backend = self._load_auth_backend(auth_backend)
|
|
92
81
|
self.theme_path = Path(theme_path) if theme_path else None
|
|
93
82
|
|
|
94
|
-
|
|
95
|
-
frontend_base_url = os.getenv("FRONTEND_BASE_URL", "http://localhost:8000")
|
|
96
|
-
# remove trailing slash from frontend base URL
|
|
97
|
-
frontend_base_url = frontend_base_url.rstrip("/")
|
|
98
|
-
# set frontend base URL on the API
|
|
99
|
-
self.frontend_base_url = frontend_base_url
|
|
83
|
+
self.frontend_base_url = BASE_URL
|
|
100
84
|
|
|
101
85
|
@asynccontextmanager
|
|
102
86
|
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
@@ -197,34 +181,23 @@ class RagbitsAPI:
|
|
|
197
181
|
|
|
198
182
|
return await self._handle_oauth2_callback(code, state, backend)
|
|
199
183
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@self.app.post("/api/feedback", response_class=JSONResponse)
|
|
208
|
-
async def feedback(
|
|
209
|
-
request: Request,
|
|
210
|
-
feedback_request: FeedbackRequest,
|
|
211
|
-
) -> JSONResponse:
|
|
212
|
-
return await self._handle_feedback(feedback_request, request)
|
|
213
|
-
else:
|
|
184
|
+
@self.app.post("/api/chat", response_class=StreamingResponse)
|
|
185
|
+
async def chat_message(
|
|
186
|
+
request: Request,
|
|
187
|
+
chat_request: ChatMessageRequest,
|
|
188
|
+
) -> StreamingResponse:
|
|
189
|
+
return await self._handle_chat_message(chat_request, request)
|
|
214
190
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
191
|
+
@self.app.post("/api/feedback", response_class=JSONResponse)
|
|
192
|
+
async def feedback(
|
|
193
|
+
request: Request,
|
|
194
|
+
feedback_request: FeedbackRequest,
|
|
195
|
+
) -> JSONResponse:
|
|
196
|
+
return await self._handle_feedback(feedback_request, request)
|
|
221
197
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
feedback_request: FeedbackRequest,
|
|
226
|
-
) -> JSONResponse:
|
|
227
|
-
return await self._handle_feedback(feedback_request, request)
|
|
198
|
+
@self.app.post("/api/upload", response_class=JSONResponse)
|
|
199
|
+
async def upload_file(file: UploadFile) -> JSONResponse:
|
|
200
|
+
return await self._handle_file_upload(file)
|
|
228
201
|
|
|
229
202
|
@self.app.get("/api/config", response_class=JSONResponse)
|
|
230
203
|
async def config() -> JSONResponse:
|
|
@@ -294,6 +267,7 @@ class RagbitsAPI:
|
|
|
294
267
|
auth_types=auth_types,
|
|
295
268
|
oauth2_providers=oauth2_providers,
|
|
296
269
|
),
|
|
270
|
+
supports_upload=self.chat_interface.upload_handler is not None,
|
|
297
271
|
)
|
|
298
272
|
|
|
299
273
|
return JSONResponse(content=config_response.model_dump())
|
|
@@ -585,6 +559,31 @@ class RagbitsAPI:
|
|
|
585
559
|
)
|
|
586
560
|
raise HTTPException(status_code=500, detail="Internal server error") from None
|
|
587
561
|
|
|
562
|
+
async def _handle_file_upload(self, file: UploadFile) -> JSONResponse:
|
|
563
|
+
"""
|
|
564
|
+
Handle file upload requests.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
file: The uploaded file.
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
JSONResponse with status.
|
|
571
|
+
"""
|
|
572
|
+
if self.chat_interface.upload_handler is None:
|
|
573
|
+
raise HTTPException(status_code=400, detail="File upload not supported")
|
|
574
|
+
|
|
575
|
+
try:
|
|
576
|
+
# Check if handler is async and call it
|
|
577
|
+
if asyncio.iscoroutinefunction(self.chat_interface.upload_handler):
|
|
578
|
+
await self.chat_interface.upload_handler(file)
|
|
579
|
+
else:
|
|
580
|
+
await asyncio.to_thread(self.chat_interface.upload_handler, file)
|
|
581
|
+
|
|
582
|
+
return JSONResponse(content={"status": "success", "filename": file.filename})
|
|
583
|
+
except Exception as e:
|
|
584
|
+
logger.error(f"File upload error: {e}")
|
|
585
|
+
raise HTTPException(status_code=500, detail=str(e)) from e
|
|
586
|
+
|
|
588
587
|
async def get_current_user_from_cookie(self, request: Request) -> User | None:
|
|
589
588
|
"""
|
|
590
589
|
Get current user from session cookie.
|
ragbits/chat/auth/backends.py
CHANGED
|
@@ -11,6 +11,7 @@ import httpx
|
|
|
11
11
|
from ragbits.chat.auth.base import AuthenticationBackend, AuthenticationResponse, AuthOptions
|
|
12
12
|
from ragbits.chat.auth.oauth2_providers import OAuth2Provider
|
|
13
13
|
from ragbits.chat.auth.types import OAuth2Credentials, Session, SessionStore, User, UserCredentials
|
|
14
|
+
from ragbits.chat.config import BASE_URL
|
|
14
15
|
|
|
15
16
|
logger = logging.getLogger(__name__)
|
|
16
17
|
|
|
@@ -175,7 +176,7 @@ class OAuth2AuthenticationBackend(AuthenticationBackend):
|
|
|
175
176
|
|
|
176
177
|
Args:
|
|
177
178
|
session_store: Session storage backend
|
|
178
|
-
provider: OAuth2 provider implementation (e.g.,
|
|
179
|
+
provider: OAuth2 provider implementation (e.g., OAuth2Providers.DISCORD, OAuth2Providers.GOOGLE)
|
|
179
180
|
client_id: OAuth2 client ID (or set {PROVIDER}_CLIENT_ID env var)
|
|
180
181
|
client_secret: OAuth2 client secret (or set {PROVIDER}_CLIENT_SECRET env var)
|
|
181
182
|
redirect_uri: Callback URL for OAuth2 flow (or set OAUTH2_REDIRECT_URI env var,
|
|
@@ -203,12 +204,7 @@ class OAuth2AuthenticationBackend(AuthenticationBackend):
|
|
|
203
204
|
|
|
204
205
|
# Use provider-specific callback URL for better isolation and debugging
|
|
205
206
|
if not redirect_uri:
|
|
206
|
-
|
|
207
|
-
base_url = os.getenv("OAUTH2_CALLBACK_BASE_URL", "http://localhost:8000")
|
|
208
|
-
# Remove trailing slash from base URL
|
|
209
|
-
base_url = base_url.rstrip("/")
|
|
210
|
-
# Construct redirect URI with base URL and provider name
|
|
211
|
-
redirect_uri = f"{base_url}/api/auth/callback/{self.provider.name}"
|
|
207
|
+
redirect_uri = f"{BASE_URL}/api/auth/callback/{self.provider.name}"
|
|
212
208
|
|
|
213
209
|
# remove trailing slash from redirect URI
|
|
214
210
|
redirect_uri = redirect_uri.rstrip("/")
|
|
@@ -1,52 +1,65 @@
|
|
|
1
1
|
"""OAuth2 provider implementations for various authentication services."""
|
|
2
2
|
|
|
3
|
-
from abc import
|
|
4
|
-
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
|
|
5
|
+
from pydantic.config import JsonDict
|
|
5
6
|
|
|
6
7
|
from ragbits.chat.auth.types import User
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class OAuth2Provider
|
|
10
|
+
class OAuth2Provider:
|
|
10
11
|
"""Abstract base class for OAuth2 providers."""
|
|
11
12
|
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
name: str,
|
|
17
|
+
display_name: str,
|
|
18
|
+
authorize_url: str,
|
|
19
|
+
token_url: str,
|
|
20
|
+
user_info_url: str,
|
|
21
|
+
scopes: list[str],
|
|
22
|
+
user_factory: Callable[[JsonDict], User],
|
|
23
|
+
) -> None:
|
|
24
|
+
self._name = name
|
|
25
|
+
self._display_name = display_name
|
|
26
|
+
self._authorize_url = authorize_url
|
|
27
|
+
self._token_url = token_url
|
|
28
|
+
self._user_info_url = user_info_url
|
|
29
|
+
self._scopes = scopes
|
|
30
|
+
self._user_factory = user_factory
|
|
31
|
+
|
|
12
32
|
@property
|
|
13
|
-
@abstractmethod
|
|
14
33
|
def name(self) -> str:
|
|
15
34
|
"""Provider name (e.g., 'discord')."""
|
|
16
|
-
|
|
35
|
+
return self._name
|
|
17
36
|
|
|
18
37
|
@property
|
|
19
|
-
@abstractmethod
|
|
20
38
|
def display_name(self) -> str:
|
|
21
39
|
"""Human-readable provider name (e.g., 'Discord')."""
|
|
22
|
-
|
|
40
|
+
return self._display_name
|
|
23
41
|
|
|
24
42
|
@property
|
|
25
|
-
@abstractmethod
|
|
26
43
|
def authorize_url(self) -> str:
|
|
27
44
|
"""OAuth2 authorization endpoint."""
|
|
28
|
-
|
|
45
|
+
return self._authorize_url
|
|
29
46
|
|
|
30
47
|
@property
|
|
31
|
-
@abstractmethod
|
|
32
48
|
def token_url(self) -> str:
|
|
33
49
|
"""OAuth2 token exchange endpoint."""
|
|
34
|
-
|
|
50
|
+
return self._token_url
|
|
35
51
|
|
|
36
52
|
@property
|
|
37
|
-
@abstractmethod
|
|
38
53
|
def user_info_url(self) -> str:
|
|
39
54
|
"""User info endpoint."""
|
|
40
|
-
|
|
55
|
+
return self._user_info_url
|
|
41
56
|
|
|
42
57
|
@property
|
|
43
|
-
@abstractmethod
|
|
44
58
|
def scope(self) -> str:
|
|
45
59
|
"""OAuth2 scopes to request."""
|
|
46
|
-
|
|
60
|
+
return " ".join(self._scopes)
|
|
47
61
|
|
|
48
|
-
|
|
49
|
-
def create_user_from_data(self, user_data: dict[str, Any]) -> User:
|
|
62
|
+
def create_user_from_data(self, user_data: JsonDict) -> User:
|
|
50
63
|
"""
|
|
51
64
|
Create a User object from provider-specific user data.
|
|
52
65
|
|
|
@@ -56,53 +69,51 @@ class OAuth2Provider(ABC):
|
|
|
56
69
|
Returns:
|
|
57
70
|
User object
|
|
58
71
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class DiscordOAuth2Provider(OAuth2Provider):
|
|
63
|
-
"""Discord OAuth2 provider implementation."""
|
|
64
|
-
|
|
65
|
-
@property
|
|
66
|
-
def name(self) -> str:
|
|
67
|
-
"""Return the provider name."""
|
|
68
|
-
return "discord"
|
|
72
|
+
return self._user_factory(user_data)
|
|
69
73
|
|
|
70
|
-
@property
|
|
71
|
-
def display_name(self) -> str:
|
|
72
|
-
"""Return the human-readable provider name."""
|
|
73
|
-
return "Discord"
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"""Return the OAuth2 authorization URL."""
|
|
78
|
-
return "https://discord.com/api/oauth2/authorize"
|
|
75
|
+
class OAuth2Providers:
|
|
76
|
+
"""Namespace for built-in OAuth2 provider configurations."""
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return "https://discord.com/api/users/@me"
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def scope(self) -> str:
|
|
92
|
-
"""Return the OAuth2 scope to request."""
|
|
93
|
-
return "identify email"
|
|
94
|
-
|
|
95
|
-
def create_user_from_data(self, user_data: dict[str, Any]) -> User: # noqa: PLR6301
|
|
96
|
-
"""Create User object from Discord data."""
|
|
97
|
-
return User(
|
|
78
|
+
DISCORD = OAuth2Provider(
|
|
79
|
+
name="discord",
|
|
80
|
+
display_name="Discord",
|
|
81
|
+
authorize_url="https://discord.com/api/oauth2/authorize",
|
|
82
|
+
token_url="https://discord.com/api/oauth2/token", # noqa: S106
|
|
83
|
+
user_info_url="https://discord.com/api/users/@me",
|
|
84
|
+
scopes=["identify", "email"],
|
|
85
|
+
user_factory=lambda user_data: User(
|
|
98
86
|
user_id=f"discord_{user_data['id']}",
|
|
99
|
-
username=user_data.get("username", ""),
|
|
100
|
-
email=user_data.get("email"),
|
|
101
|
-
full_name=user_data.get("global_name"),
|
|
87
|
+
username=str(user_data.get("username", "")),
|
|
88
|
+
email=str(user_data["email"]) if user_data.get("email") else None,
|
|
89
|
+
full_name=str(user_data["global_name"]) if user_data.get("global_name") else None,
|
|
102
90
|
roles=["user"],
|
|
103
91
|
metadata={
|
|
104
92
|
"provider": "discord",
|
|
105
93
|
"avatar": user_data.get("avatar"),
|
|
106
94
|
"discriminator": user_data.get("discriminator"),
|
|
107
95
|
},
|
|
108
|
-
)
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
GOOGLE = OAuth2Provider(
|
|
100
|
+
name="google",
|
|
101
|
+
display_name="Google",
|
|
102
|
+
authorize_url="https://accounts.google.com/o/oauth2/v2/auth",
|
|
103
|
+
token_url="https://oauth2.googleapis.com/token", # noqa: S106
|
|
104
|
+
user_info_url="https://www.googleapis.com/oauth2/v2/userinfo",
|
|
105
|
+
scopes=["openid", "email", "profile"],
|
|
106
|
+
user_factory=lambda user_data: User(
|
|
107
|
+
user_id=f"google_{user_data['id']}",
|
|
108
|
+
username=str(user_data.get("email", "")).split("@")[0],
|
|
109
|
+
email=str(user_data["email"]) if user_data.get("email") else None,
|
|
110
|
+
full_name=str(user_data["name"]) if user_data.get("name") else None,
|
|
111
|
+
roles=["user"],
|
|
112
|
+
metadata={
|
|
113
|
+
"provider": "google",
|
|
114
|
+
"picture": user_data.get("picture"),
|
|
115
|
+
"verified_email": user_data.get("verified_email"),
|
|
116
|
+
"hd": user_data.get("hd"), # Google Workspace domain
|
|
117
|
+
},
|
|
118
|
+
),
|
|
119
|
+
)
|
ragbits/chat/config.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
# Environment-aware cookie security: only require HTTPS in production
|
|
4
|
+
IS_PRODUCTION = os.getenv("RAGBITS_ENVIRONMENT", "").lower() in ("production", "prod")
|
|
5
|
+
|
|
6
|
+
# Session cookie name - used for storing session ID in HTTP-only cookie
|
|
7
|
+
SESSION_COOKIE_NAME = os.getenv("RAGBITS_COOKIE", "ragbits_session")
|
|
8
|
+
|
|
9
|
+
BASE_URL = os.getenv("RAGBITS_BASE_URL", "http://localhost:8000").rstrip("/")
|
|
10
|
+
|
|
11
|
+
# Chunk size for large base64 images to prevent SSE message size issues
|
|
12
|
+
# Keep chunks extremely small to avoid JSON string length limits in browsers and SSE parsing issues
|
|
13
|
+
# Account for JSON overhead: metadata + base64 data should fit comfortably in browser limits
|
|
14
|
+
CHUNK_SIZE = 102400 # ~100KB bytes base64 chunks for ultra-safe JSON parsing and SSE transmissio
|
|
@@ -9,6 +9,8 @@ from abc import ABC, abstractmethod
|
|
|
9
9
|
from collections.abc import AsyncGenerator, Callable
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
|
+
from fastapi import UploadFile
|
|
13
|
+
|
|
12
14
|
from ragbits.agents.tools.todo import Task
|
|
13
15
|
from ragbits.chat.interface.summary import HeuristicSummaryGenerator, SummaryGenerator
|
|
14
16
|
from ragbits.chat.interface.ui_customization import UICustomization
|
|
@@ -202,6 +204,16 @@ class ChatInterface(ABC):
|
|
|
202
204
|
* Text: Regular text responses streamed chunk by chunk
|
|
203
205
|
* References: Source documents used to generate the answer
|
|
204
206
|
* State updates: Updates to the conversation state
|
|
207
|
+
|
|
208
|
+
Attributes:
|
|
209
|
+
upload_handler: Optional async callback for handling file uploads.
|
|
210
|
+
Should accept an UploadFile parameter.
|
|
211
|
+
|
|
212
|
+
Example::
|
|
213
|
+
|
|
214
|
+
async def upload_handler(self, file: UploadFile) -> None:
|
|
215
|
+
content = await file.read()
|
|
216
|
+
# process content
|
|
205
217
|
"""
|
|
206
218
|
|
|
207
219
|
feedback_config: FeedbackConfig = FeedbackConfig()
|
|
@@ -211,6 +223,7 @@ class ChatInterface(ABC):
|
|
|
211
223
|
ui_customization: UICustomization | None = None
|
|
212
224
|
history_persistence: HistoryPersistenceStrategy | None = None
|
|
213
225
|
summary_generator: SummaryGenerator = HeuristicSummaryGenerator()
|
|
226
|
+
upload_handler: Callable[[UploadFile], Any] | None = None
|
|
214
227
|
|
|
215
228
|
def __init_subclass__(cls, **kwargs: dict) -> None:
|
|
216
229
|
"""Automatically apply the with_chat_metadata decorator to the chat method in subclasses."""
|
ragbits/chat/interface/types.py
CHANGED
|
@@ -2,8 +2,9 @@ import warnings
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
from enum import Enum
|
|
4
4
|
from typing import Any, Generic, TypeVar, cast
|
|
5
|
+
from zoneinfo import available_timezones
|
|
5
6
|
|
|
6
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
7
8
|
|
|
8
9
|
from ragbits.agents.confirmation import ConfirmationRequest
|
|
9
10
|
from ragbits.agents.tools.todo import Task
|
|
@@ -314,8 +315,20 @@ class ChatContext(BaseModel):
|
|
|
314
315
|
default=None,
|
|
315
316
|
description="List of confirmed/declined tools from the frontend",
|
|
316
317
|
)
|
|
318
|
+
timezone: str | None = Field(
|
|
319
|
+
default=None,
|
|
320
|
+
description="User's timezone in IANA format (e.g., 'Europe/Warsaw', 'America/New_York')",
|
|
321
|
+
)
|
|
317
322
|
model_config = ConfigDict(extra="allow")
|
|
318
323
|
|
|
324
|
+
@field_validator("timezone")
|
|
325
|
+
@classmethod
|
|
326
|
+
def validate_timezone(cls, v: str | None) -> str | None:
|
|
327
|
+
"""Validate that timezone is a valid IANA timezone identifier."""
|
|
328
|
+
if v is not None and v not in available_timezones():
|
|
329
|
+
raise ValueError(f"Invalid timezone: {v}. Must be a valid IANA timezone.")
|
|
330
|
+
return v
|
|
331
|
+
|
|
319
332
|
|
|
320
333
|
# Generic type variable for content, bounded to ResponseContent
|
|
321
334
|
ChatResponseContentT = TypeVar("ChatResponseContentT", bound=ResponseContent)
|
|
@@ -888,6 +901,7 @@ class ConfigResponse(BaseModel):
|
|
|
888
901
|
feedback: FeedbackConfig = Field(..., description="Feedback configuration")
|
|
889
902
|
customization: UICustomization | None = Field(default=None, description="UI customization")
|
|
890
903
|
user_settings: UserSettings = Field(default_factory=UserSettings, description="User settings")
|
|
904
|
+
supports_upload: bool = Field(default=False, description="Flag indicating whether API supports file upload")
|
|
891
905
|
debug_mode: bool = Field(default=False, description="Debug mode flag")
|
|
892
906
|
conversation_history: bool = Field(default=False, description="Flag to enable conversation history")
|
|
893
907
|
show_usage: bool = Field(default=False, description="Flag to enable usage statistics")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as h,j as e,aW as c,aE as p,c as S,bo as x,bp as l,bq as d,br as m,bs as b}from"./index-CbVbgerL.js";import{a}from"./authStore-AVyfzjgs.js";import{u as j}from"./useInitializeUserStore-CVYyhiv3.js";const v=h.createContext(null);function y({children:t}){const[o]=h.useState(()=>a);return e.jsx(v.Provider,{value:o,children:t})}function U(){const{logout:t,login:o,setHydrated:u}=c(a,f=>f),i=j(),n=p(),s=S("/api/user"),g=x();return h.useEffect(()=>{(async()=>{try{const r=await s.call();r?(o(r),i?i(r.user_id):console.error("Failed to initialize store for user, initializeUserStore() is not defined. Check current HistoryStoreContextProvider implementation."),g.pathname==="/login"&&n("/")):t()}catch(r){console.error("Failed to check session:",r),t(),n("/login")}finally{u()}})()},[]),null}function P({children:t}){const o=x(),u=c(a,s=>s.isAuthenticated),i=c(a,s=>s.hasHydrated),n=c(a,s=>s.logout);return i?o.pathname==="/login"?e.jsx(l,{baseUrl:d,auth:{credentials:"include"},children:t}):u?e.jsx(y,{children:e.jsx(l,{baseUrl:d,auth:{onUnauthorized:n,credentials:"include"},children:t})}):e.jsx(b,{to:"/login",replace:!0}):e.jsxs(l,{baseUrl:d,auth:{credentials:"include"},children:[e.jsx(U,{}),e.jsx(m,{})]})}export{P as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-
|
|
2
|
-
import{r as P,t as ae,k as Xe,Z as W,ax as Me,$ as Ze,j as t,q as me,L as xe,_ as Ye,n as ye,T as Pe,s as et,v as R,V as tt,d as X,l as se,aq as Ie,o as ot,H as ke,a9 as rt,J as Ne,ay as at,ac as pe,U as st,X as _e,af as he,az as nt,aA as lt,ag as it,K as dt,O as be,Q as ct,W as ut,a0 as pt,ah as ft,a2 as K,a3 as Ae,ai as vt,R as ht,aB as bt,a8 as gt,aC as mt,aD as xt,a5 as yt,a as Pt,aE as Ct,i as fe,aF as Ce,aG as ve,D as we,I as Q,as as wt,aH as $t,aI as $e}from"./index-BZLU40Mk.js";import{u as jt,b as St,c as je,d as Dt,e as Mt,m as It,$ as kt,a as Nt}from"./useMenuTriggerState-SaFmATkk.js";import{$ as _t}from"./useSelectableItem-DhuFnc0W.js";import{i as At}from"./chunk-SSA7SXE4-CJa0HuAU.js";var Ot=(e,r)=>{var n;let s=[];const a=(n=P.Children.map(e,d=>P.isValidElement(d)&&d.type===r?(s.push(d),null):d))==null?void 0:n.filter(Boolean),u=s.length>=0?s:void 0;return[a,u]},Ft=ae({base:["w-full","p-1","min-w-[200px]"]});ae({slots:{base:["flex","group","gap-2","items-center","justify-between","relative","px-2","py-1.5","w-full","h-full","box-border","rounded-small","outline-hidden","cursor-pointer","tap-highlight-transparent","data-[pressed=true]:opacity-70",...Xe,"data-[focus-visible=true]:dark:ring-offset-background-content1"],wrapper:"w-full flex flex-col items-start justify-center",title:"flex-1 text-small font-normal truncate",description:["w-full","text-tiny","text-foreground-500","group-hover:text-current"],selectedIcon:["text-inherit","w-3","h-3","shrink-0"],shortcut:["px-1","py-0.5","rounded-sm","font-sans","text-foreground-500","text-tiny","border-small","border-default-300","group-hover:border-current"]},variants:{variant:{solid:{base:""},bordered:{base:"border-medium border-transparent bg-transparent"},light:{base:"bg-transparent"},faded:{base:"border-small border-transparent hover:border-default data-[hover=true]:bg-default-100"},flat:{base:""},shadow:{base:"data-[hover=true]:shadow-lg"}},color:{default:{},primary:{},secondary:{},success:{},warning:{},danger:{}},isDisabled:{true:{base:"opacity-disabled pointer-events-none"}},disableAnimation:{true:{},false:{}}},defaultVariants:{variant:"solid",color:"default"},compoundVariants:[{variant:"solid",color:"default",class:{base:"data-[hover=true]:bg-default data-[hover=true]:text-default-foreground"}},{variant:"solid",color:"primary",class:{base:"data-[hover=true]:bg-primary data-[hover=true]:text-primary-foreground"}},{variant:"solid",color:"secondary",class:{base:"data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-foreground"}},{variant:"solid",color:"success",class:{base:"data-[hover=true]:bg-success data-[hover=true]:text-success-foreground"}},{variant:"solid",color:"warning",class:{base:"data-[hover=true]:bg-warning data-[hover=true]:text-warning-foreground"}},{variant:"solid",color:"danger",class:{base:"data-[hover=true]:bg-danger data-[hover=true]:text-danger-foreground"}},{variant:"shadow",color:"default",class:{base:"data-[hover=true]:shadow-default/50 data-[hover=true]:bg-default data-[hover=true]:text-default-foreground"}},{variant:"shadow",color:"primary",class:{base:"data-[hover=true]:shadow-primary/30 data-[hover=true]:bg-primary data-[hover=true]:text-primary-foreground"}},{variant:"shadow",color:"secondary",class:{base:"data-[hover=true]:shadow-secondary/30 data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-foreground"}},{variant:"shadow",color:"success",class:{base:"data-[hover=true]:shadow-success/30 data-[hover=true]:bg-success data-[hover=true]:text-success-foreground"}},{variant:"shadow",color:"warning",class:{base:"data-[hover=true]:shadow-warning/30 data-[hover=true]:bg-warning data-[hover=true]:text-warning-foreground"}},{variant:"shadow",color:"danger",class:{base:"data-[hover=true]:shadow-danger/30 data-[hover=true]:bg-danger data-[hover=true]:text-danger-foreground"}},{variant:"bordered",color:"default",class:{base:"data-[hover=true]:border-default"}},{variant:"bordered",color:"primary",class:{base:"data-[hover=true]:border-primary data-[hover=true]:text-primary"}},{variant:"bordered",color:"secondary",class:{base:"data-[hover=true]:border-secondary data-[hover=true]:text-secondary"}},{variant:"bordered",color:"success",class:{base:"data-[hover=true]:border-success data-[hover=true]:text-success"}},{variant:"bordered",color:"warning",class:{base:"data-[hover=true]:border-warning data-[hover=true]:text-warning"}},{variant:"bordered",color:"danger",class:{base:"data-[hover=true]:border-danger data-[hover=true]:text-danger"}},{variant:"flat",color:"default",class:{base:"data-[hover=true]:bg-default/40 data-[hover=true]:text-default-foreground"}},{variant:"flat",color:"primary",class:{base:"data-[hover=true]:bg-primary/20 data-[hover=true]:text-primary"}},{variant:"flat",color:"secondary",class:{base:"data-[hover=true]:bg-secondary/20 data-[hover=true]:text-secondary"}},{variant:"flat",color:"success",class:{base:"data-[hover=true]:bg-success/20 data-[hover=true]:text-success "}},{variant:"flat",color:"warning",class:{base:"data-[hover=true]:bg-warning/20 data-[hover=true]:text-warning"}},{variant:"flat",color:"danger",class:{base:"data-[hover=true]:bg-danger/20 data-[hover=true]:text-danger"}},{variant:"faded",color:"default",class:{base:"data-[hover=true]:text-default-foreground"}},{variant:"faded",color:"primary",class:{base:"data-[hover=true]:text-primary"}},{variant:"faded",color:"secondary",class:{base:"data-[hover=true]:text-secondary"}},{variant:"faded",color:"success",class:{base:"data-[hover=true]:text-success"}},{variant:"faded",color:"warning",class:{base:"data-[hover=true]:text-warning"}},{variant:"faded",color:"danger",class:{base:"data-[hover=true]:text-danger"}},{variant:"light",color:"default",class:{base:"data-[hover=true]:text-default-500"}},{variant:"light",color:"primary",class:{base:"data-[hover=true]:text-primary"}},{variant:"light",color:"secondary",class:{base:"data-[hover=true]:text-secondary"}},{variant:"light",color:"success",class:{base:"data-[hover=true]:text-success"}},{variant:"light",color:"warning",class:{base:"data-[hover=true]:text-warning"}},{variant:"light",color:"danger",class:{base:"data-[hover=true]:text-danger"}}]});ae({slots:{base:"relative mb-2",heading:"pl-1 text-tiny text-foreground-500",group:"data-[has-title=true]:pt-1",divider:"mt-2"}});ae({base:"w-full flex flex-col gap-0.5 p-1"});var Et=(e,r)=>{if(!e&&!r)return{};const n=new Set([...Object.keys(e||{}),...Object.keys(r||{})]);return Array.from(n).reduce((s,a)=>({...s,[a]:W(e?.[a],r?.[a])}),{})},[Tt,Oe]=Me({name:"PopoverContext",errorMessage:"usePopoverContext: `context` is undefined. Seems you forgot to wrap all popover components within `<Popover />`"}),Se=()=>Ye(()=>import("./index-Bvn9K6h_.js"),__vite__mapDeps([0,1,2])).then(e=>e.default),Fe=e=>{const{as:r,children:n,className:s,...a}=e,{Component:u,placement:d,backdrop:h,motionProps:l,disableAnimation:c,getPopoverProps:p,getDialogProps:w,getBackdropProps:b,getContentProps:x,isNonModal:I,onClose:j}=Oe(),f=P.useRef(null),{dialogProps:M,titleProps:D}=Ze({},f),y=w({ref:f,...M,...a}),S=r||u||"div",i=t.jsxs(t.Fragment,{children:[!I&&t.jsx(me,{onDismiss:j}),t.jsx(S,{...y,children:t.jsx("div",{...x({className:s}),children:typeof n=="function"?n(D):n})}),t.jsx(me,{onDismiss:j})]}),v=P.useMemo(()=>h==="transparent"?null:c?t.jsx("div",{...b()}):t.jsx(xe,{features:Se,children:t.jsx(ye.div,{animate:"enter",exit:"exit",initial:"exit",variants:Pe.fade,...b()})}),[h,c,b]),k=d?et(d==="center"?"top":d):void 0,o=t.jsx(t.Fragment,{children:c?i:t.jsx(xe,{features:Se,children:t.jsx(ye.div,{animate:"enter",exit:"exit",initial:"initial",style:k,variants:Pe.scaleSpringOpacity,...l,children:i})})});return t.jsxs("div",{...p(),children:[v,o]})};Fe.displayName="HeroUI.PopoverContent";var Rt=Fe,Ee=e=>{var r;const{triggerRef:n,getTriggerProps:s}=Oe(),{children:a,...u}=e,d=P.useMemo(()=>typeof a=="string"?t.jsx("p",{children:a}):P.Children.only(a),[a]),h=(r=d.props.ref)!=null?r:d.ref,{onPress:l,isDisabled:c,...p}=P.useMemo(()=>s(R(u,d.props),h),[s,d.props,u,h]),[,w]=Ot(a,X),{buttonProps:b}=tt({onPress:l,isDisabled:c},n),x=P.useMemo(()=>w?.[0]!==void 0,[w]);return x||delete p.preventFocusOnPress,P.cloneElement(d,R(p,x?{onPress:l,isDisabled:c}:b))};Ee.displayName="HeroUI.PopoverTrigger";var Ht=Ee,Te=se((e,r)=>{const{children:n,...s}=e,a=jt({...s,ref:r}),[u,d]=P.Children.toArray(n),h=t.jsx(ot,{portalContainer:a.portalContainer,children:d});return t.jsxs(Tt,{value:a,children:[u,a.disableAnimation&&a.isOpen?h:t.jsx(Ie,{children:a.isOpen?h:null})]})});Te.displayName="HeroUI.Popover";var Ut=Te,[Kt,Re]=Me({name:"DropdownContext",errorMessage:"useDropdownContext: `context` is undefined. Seems you forgot to wrap all popover components within `<Dropdown />`"});function Bt(e){const{isSelected:r,disableAnimation:n,...s}=e;return t.jsx("svg",{"aria-hidden":"true","data-selected":r,role:"presentation",viewBox:"0 0 17 18",...s,children:t.jsx("polyline",{fill:"none",points:"1 9 7 14 15 4",stroke:"currentColor",strokeDasharray:22,strokeDashoffset:r?44:66,strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,style:n?{}:{transition:"stroke-dashoffset 200ms ease"}})})}const He=new WeakMap;function Vt(e,r,n){let{shouldFocusWrap:s=!0,onKeyDown:a,onKeyUp:u,...d}=e;!e["aria-label"]&&e["aria-labelledby"];let h=ke(e,{labelable:!0}),{listProps:l}=rt({...d,ref:n,selectionManager:r.selectionManager,collection:r.collection,disabledKeys:r.disabledKeys,shouldFocusWrap:s,linkBehavior:"override"});return He.set(r,{onClose:e.onClose,onAction:e.onAction,shouldUseVirtualFocus:e.shouldUseVirtualFocus}),{menuProps:Ne(h,{onKeyDown:a,onKeyUp:u},{role:"menu",...l,onKeyDown:c=>{var p;(c.key!=="Escape"||e.shouldUseVirtualFocus)&&((p=l.onKeyDown)===null||p===void 0||p.call(l,c))}})}}function Lt(e,r,n){let{id:s,key:a,closeOnSelect:u,isVirtualized:d,"aria-haspopup":h,onPressStart:l,onPressUp:c,onPress:p,onPressChange:w,onPressEnd:b,onHoverStart:x,onHoverChange:I,onHoverEnd:j,onKeyDown:f,onKeyUp:M,onFocus:D,onFocusChange:y,onBlur:S,selectionManager:i=r.selectionManager}=e,v=!!h,k=v&&e["aria-expanded"]==="true";var o;let C=(o=e.isDisabled)!==null&&o!==void 0?o:i.isDisabled(a);var _;let A=(_=e.isSelected)!==null&&_!==void 0?_:i.isSelected(a),N=He.get(r),g=r.collection.getItem(a),T=e.onClose||N.onClose,B=at(),$=m=>{var J;if(!v){if(!(g==null||(J=g.props)===null||J===void 0)&&J.onAction?g.props.onAction():e.onAction&&e.onAction(a),N.onAction){let ce=N.onAction;ce(a)}m.target instanceof HTMLAnchorElement&&g&&B.open(m.target,m,g.props.href,g.props.routerOptions)}},E="menuitem";v||(i.selectionMode==="single"?E="menuitemradio":i.selectionMode==="multiple"&&(E="menuitemcheckbox"));let O=pe(),H=pe(),q=pe(),V={id:s,"aria-disabled":C||void 0,role:E,"aria-label":e["aria-label"],"aria-labelledby":O,"aria-describedby":[H,q].filter(Boolean).join(" ")||void 0,"aria-controls":e["aria-controls"],"aria-haspopup":h,"aria-expanded":e["aria-expanded"]};i.selectionMode!=="none"&&!v&&(V["aria-checked"]=A),d&&(V["aria-posinset"]=g?.index,V["aria-setsize"]=St(r.collection));let G=m=>{m.pointerType==="keyboard"&&$(m),l?.(m)},Z=()=>{!v&&T&&(u??(i.selectionMode!=="multiple"||i.isLink(a)))&&T()},Y=m=>{m.pointerType==="mouse"&&($(m),Z()),c?.(m)},ne=m=>{m.pointerType!=="keyboard"&&m.pointerType!=="mouse"&&($(m),Z()),p?.(m)},{itemProps:L,isFocused:ee}=_t({id:s,selectionManager:i,key:a,ref:n,shouldSelectOnPressUp:!0,allowsDifferentPressOrigin:!0,linkBehavior:"none",shouldUseVirtualFocus:N.shouldUseVirtualFocus}),{pressProps:le,isPressed:te}=st({onPressStart:G,onPress:ne,onPressUp:Y,onPressChange:w,onPressEnd:b,isDisabled:C}),{hoverProps:ie}=_e({isDisabled:C,onHoverStart(m){!he()&&!(k&&h)&&(i.setFocused(!0),i.setFocusedKey(a)),x?.(m)},onHoverChange:I,onHoverEnd:j}),{keyboardProps:oe}=nt({onKeyDown:m=>{if(m.repeat){m.continuePropagation();return}switch(m.key){case" ":!C&&i.selectionMode==="none"&&!v&&u!==!1&&T&&T();break;case"Enter":!C&&u!==!1&&!v&&T&&T();break;default:v||m.continuePropagation(),f?.(m);break}},onKeyUp:M}),{focusProps:U}=lt({onBlur:S,onFocus:D,onFocusChange:y}),re=ke(g?.props);delete re.id;let de=it(g?.props);return{menuItemProps:{...V,...Ne(re,de,v?{onFocus:L.onFocus,"data-collection":L["data-collection"],"data-key":L["data-key"]}:L,le,ie,oe,U,N.shouldUseVirtualFocus||v?{onMouseDown:m=>m.preventDefault()}:void 0),tabIndex:L.tabIndex!=null&&k&&!N.shouldUseVirtualFocus?-1:L.tabIndex},labelProps:{id:O},descriptionProps:{id:H},keyboardShortcutProps:{id:q},isFocused:ee,isFocusVisible:ee&&i.isFocused&&he()&&!k,isSelected:A,isPressed:te,isDisabled:C}}function zt(e){let{heading:r,"aria-label":n}=e,s=dt();return{itemProps:{role:"presentation"},headingProps:r?{id:s,role:"presentation"}:{},groupProps:{role:"group","aria-label":n,"aria-labelledby":r?s:void 0}}}function Wt(e){var r,n;const s=be(),[a,u]=ct(e,je.variantKeys),{as:d,item:h,state:l,shortcut:c,description:p,startContent:w,endContent:b,isVirtualized:x,selectedIcon:I,className:j,classNames:f,onAction:M,autoFocus:D,onPress:y,onPressStart:S,onPressUp:i,onPressEnd:v,onPressChange:k,onHoverStart:o,onHoverChange:C,onHoverEnd:_,hideSelectedIcon:A=!1,isReadOnly:N=!1,closeOnSelect:g,onClose:T,onClick:B,...$}=a,E=(n=(r=e.disableAnimation)!=null?r:s?.disableAnimation)!=null?n:!1,O=P.useRef(null),H=d||($?.href?"a":"li"),q=typeof H=="string",{rendered:V,key:G}=h,Z=l.disabledKeys.has(G)||e.isDisabled,Y=l.selectionManager.selectionMode!=="none",ne=Dt(),{isFocusVisible:L,focusProps:ee}=ut({autoFocus:D}),le=P.useCallback(F=>{B?.(F),y?.(F)},[B,y]),{isPressed:te,isFocused:ie,isSelected:oe,isDisabled:U,menuItemProps:re,labelProps:de,descriptionProps:m,keyboardShortcutProps:J}=Lt({key:G,onClose:T,isDisabled:Z,onPress:le,onPressStart:S,onPressUp:i,onPressEnd:v,onPressChange:k,"aria-label":a["aria-label"],closeOnSelect:g,isVirtualized:x,onAction:M},l,O);let{hoverProps:ce,isHovered:ge}=_e({isDisabled:U,onHoverStart(F){he()||(l.selectionManager.setFocused(!0),l.selectionManager.setFocusedKey(G)),o?.(F)},onHoverChange:C,onHoverEnd:_}),ue=re;const z=P.useMemo(()=>je({...u,isDisabled:U,disableAnimation:E,hasTitleTextChild:typeof V=="string",hasDescriptionTextChild:typeof p=="string"}),[pt(u),U,E,V,p]),ze=W(f?.base,j);N&&(ue=ft(ue));const We=(F={})=>({ref:O,...R(N?{}:ee,Ae($,{enabled:q}),ue,ce,F),"data-focus":K(ie),"data-selectable":K(Y),"data-hover":K(ne?ge||te:ge),"data-disabled":K(U),"data-selected":K(oe),"data-pressed":K(te),"data-focus-visible":K(L),className:z.base({class:W(ze,F.className)})}),qe=(F={})=>({...R(de,F),className:z.title({class:f?.title})}),Ge=(F={})=>({...R(m,F),className:z.description({class:f?.description})}),Je=(F={})=>({...R(J,F),className:z.shortcut({class:f?.shortcut})}),Qe=P.useCallback((F={})=>({"aria-hidden":K(!0),"data-disabled":K(U),className:z.selectedIcon({class:f?.selectedIcon}),...F}),[U,z,f]);return{Component:H,domRef:O,slots:z,classNames:f,isSelectable:Y,isSelected:oe,isDisabled:U,rendered:V,shortcut:c,description:p,startContent:w,endContent:b,selectedIcon:I,disableAnimation:E,getItemProps:We,getLabelProps:qe,hideSelectedIcon:A,getDescriptionProps:Ge,getKeyboardShortcutProps:Je,getSelectedIconProps:Qe}}var Ue=e=>{const{Component:r,slots:n,classNames:s,rendered:a,shortcut:u,description:d,isSelectable:h,isSelected:l,isDisabled:c,selectedIcon:p,startContent:w,endContent:b,disableAnimation:x,hideSelectedIcon:I,getItemProps:j,getLabelProps:f,getDescriptionProps:M,getKeyboardShortcutProps:D,getSelectedIconProps:y}=Wt(e),S=P.useMemo(()=>{const i=t.jsx(Bt,{disableAnimation:x,isSelected:l});return typeof p=="function"?p({icon:i,isSelected:l,isDisabled:c}):p||i},[p,l,c,x]);return t.jsxs(r,{...j(),children:[w,d?t.jsxs("div",{className:n.wrapper({class:s?.wrapper}),children:[t.jsx("span",{...f(),children:a}),t.jsx("span",{...M(),children:d})]}):t.jsx("span",{...f(),children:a}),u&&t.jsx("kbd",{...D(),children:u}),h&&!I&&t.jsx("span",{...y(),children:S}),b]})};Ue.displayName="HeroUI.MenuItem";var Ke=Ue,Be=se(({item:e,state:r,as:n,variant:s,color:a,disableAnimation:u,onAction:d,closeOnSelect:h,className:l,classNames:c,showDivider:p=!1,hideSelectedIcon:w,dividerProps:b={},itemClasses:x,title:I,...j},f)=>{const M=n||"li",D=P.useMemo(()=>Mt(),[]),y=W(c?.base,l),S=W(c?.divider,b?.className),{itemProps:i,headingProps:v,groupProps:k}=zt({heading:e.rendered,"aria-label":e["aria-label"]});return t.jsxs(M,{"data-slot":"base",...R(i,j),className:D.base({class:y}),children:[e.rendered&&t.jsx("span",{...v,className:D.heading({class:c?.heading}),"data-slot":"heading",children:e.rendered}),t.jsxs("ul",{...k,className:D.group({class:c?.group}),"data-has-title":!!e.rendered,"data-slot":"group",children:[[...e.childNodes].map(o=>{const{key:C,props:_}=o;let A=t.jsx(Ke,{classNames:x,closeOnSelect:h,color:a,disableAnimation:u,hideSelectedIcon:w,item:o,state:r,variant:s,onAction:d,..._},C);return o.wrapper&&(A=o.wrapper(A)),A}),p&&t.jsx(vt,{as:"li",className:D.divider({class:S}),...b})]})]})});Be.displayName="HeroUI.MenuSection";var qt=Be;function Gt(e){var r;const n=be(),{as:s,ref:a,variant:u,color:d,children:h,disableAnimation:l=(r=n?.disableAnimation)!=null?r:!1,onAction:c,closeOnSelect:p,itemClasses:w,className:b,state:x,topContent:I,bottomContent:j,hideEmptyContent:f=!1,hideSelectedIcon:M=!1,emptyContent:D="No items.",menuProps:y,onClose:S,classNames:i,...v}=e,k=s||"ul",o=ht(a),C=typeof k=="string",_=bt({...v,...y,children:h}),A=x||_,{menuProps:N}=Vt({...v,...y,onAction:c},A,o),g=P.useMemo(()=>It({className:b}),[b]),T=W(i?.base,b);return{Component:k,state:A,variant:u,color:d,disableAnimation:l,onClose:S,topContent:I,bottomContent:j,closeOnSelect:p,className:b,itemClasses:w,getBaseProps:(O={})=>({ref:o,"data-slot":"base",className:g.base({class:T}),...Ae(v,{enabled:C}),...O}),getListProps:(O={})=>({"data-slot":"list",className:g.list({class:i?.list}),...N,...O}),hideEmptyContent:f,hideSelectedIcon:M,getEmptyContentProps:(O={})=>({children:D,className:g.emptyContent({class:i?.emptyContent}),...O})}}var Jt=se(function(r,n){const{Component:s,state:a,closeOnSelect:u,color:d,disableAnimation:h,hideSelectedIcon:l,hideEmptyContent:c,variant:p,onClose:w,topContent:b,bottomContent:x,itemClasses:I,getBaseProps:j,getListProps:f,getEmptyContentProps:M}=Gt({...r,ref:n}),D=t.jsxs(s,{...f(),children:[!a.collection.size&&!c&&t.jsx("li",{children:t.jsx("div",{...M()})}),[...a.collection].map(y=>{const S={closeOnSelect:u,color:d,disableAnimation:h,item:y,state:a,variant:p,onClose:w,hideSelectedIcon:l,...y.props},i=Et(I,S?.classNames);if(y.type==="section")return t.jsx(qt,{...S,itemClasses:i},y.key);let v=t.jsx(Ke,{...S,classNames:i},y.key);return y.wrapper&&(v=y.wrapper(v)),v})]});return t.jsxs("div",{...j(),children:[b,D,x]})}),Qt=Jt,Xt=gt,De=Xt,Zt=se(function(r,n){const{getMenuProps:s}=Re();return t.jsx(Rt,{children:t.jsx(mt,{contain:!0,restoreFocus:!0,children:t.jsx(Qt,{...s(r,n)})})})}),Yt=Zt,Ve=e=>{const{getMenuTriggerProps:r}=Re(),{children:n,...s}=e;return t.jsx(Ht,{...r(s),children:n})};Ve.displayName="HeroUI.DropdownTrigger";var eo=Ve,to=(e,r)=>{if(e){const n=Array.isArray(e.children)?e.children:[...e?.items||[]];if(n&&n.length)return n.find(a=>{if(a&&a.key===r)return a})||{}}return null},oo=(e,r,n)=>{const s=n||to(e,r);return s&&s.props&&"closeOnSelect"in s.props?s.props.closeOnSelect:e?.closeOnSelect};function ro(e){var r;const n=be(),{as:s,triggerRef:a,isOpen:u,defaultOpen:d,onOpenChange:h,isDisabled:l,type:c="menu",trigger:p="press",placement:w="bottom",closeOnSelect:b=!0,shouldBlockScroll:x=!0,classNames:I,disableAnimation:j=(r=n?.disableAnimation)!=null?r:!1,onClose:f,className:M,...D}=e,y=s||"div",S=P.useRef(null),i=a||S,v=P.useRef(null),k=P.useRef(null),o=kt({trigger:p,isOpen:u,defaultOpen:d,onOpenChange:$=>{h?.($),$||f?.()}}),{menuTriggerProps:C,menuProps:_}=Nt({type:c,trigger:p,isDisabled:l},o,i),A=P.useMemo(()=>Ft({className:M}),[M]),N=$=>{$!==void 0&&!$||b&&o.close()},g=($={})=>{const E=R(D,$);return{state:o,placement:w,ref:k,disableAnimation:j,shouldBlockScroll:x,scrollRef:v,triggerRef:i,...E,classNames:{...I,...$.classNames,content:W(A,I?.content,$.className)}}},T=($={})=>{const{onPress:E,onPressStart:O,...H}=C;return R(H,{isDisabled:l},$)},B=($,E=null)=>({ref:xt(E,v),menuProps:_,closeOnSelect:b,...R($,{onAction:(O,H)=>{const q=oo($,O,H);N(q)},onClose:o.close})});return{Component:y,menuRef:v,menuProps:_,closeOnSelect:b,onClose:o.close,autoFocus:o.focusStrategy||!0,disableAnimation:j,getPopoverProps:g,getMenuProps:B,getMenuTriggerProps:T}}var Le=e=>{const{children:r,...n}=e,s=ro(n),[a,u]=yt.Children.toArray(r);return t.jsx(Kt,{value:s,children:t.jsxs(Ut,{...s.getPopoverProps(),children:[a,u]})})};Le.displayName="HeroUI.Dropdown";var ao=Le;function co(){const{selectConversation:e,deleteConversation:r,newConversation:n,setConversationProperties:s}=Pt(),a=Ct(),u=fe(Ce(o=>Object.keys(o.conversations).reverse())),d=fe(Ce(o=>Object.values(o.conversations).reverse().map(C=>C.summary))),h=fe(o=>o.currentConversation),[l,c]=P.useState(!1),[p,w]=P.useState(null),[b,x]=P.useState(""),[I,j]=P.useState(!1),f=P.useRef(null),M=l?"Open sidebar":"Close sidebar",D=t.jsx(Q,{icon:"heroicons:pencil-square"}),y=(o,C)=>{w(o),x(C??""),j(!0),setTimeout(()=>{f.current?.focus?.(),setTimeout(()=>j(!1),120)},0)},S=o=>{if(p!==o)return;const C=(b||"").trim();C&&s(o,{summary:C}),w(null),x(""),j(!1)},i=()=>{w(null),x(""),j(!1)},v=()=>{const o=n();a($e(o))},k=o=>{e(o),a($e(o))};return t.jsx(ve.div,{initial:!1,animate:{maxWidth:l?"4.5rem":"16rem"},className:"rounded-l-medium border-small border-divider ml-4 flex h-full w-full min-w-[4.5rem] flex-grow flex-col space-y-2 overflow-hidden border-r-0 p-4 py-3",children:t.jsxs(Ie,{children:[t.jsx(we,{content:M,placement:"bottom",children:t.jsx(X,{isIconOnly:!0,"aria-label":M,variant:"ghost",onPress:()=>c(o=>!o),"data-testid":"chat-history-collapse-button",className:"ml-auto",children:t.jsx(Q,{icon:l?"heroicons:chevron-double-right":"heroicons:chevron-double-left"})})},"collapse-button"),!l&&t.jsx(ve.p,{initial:!1,animate:{opacity:1,width:"100%",height:"auto"},exit:{opacity:0,width:0,height:0,marginBottom:0},className:"text-small text-foreground truncate leading-5 font-semibold",children:"Conversations"},"conversations"),t.jsx(we,{content:"New conversation",placement:"right",children:t.jsx(X,{"aria-label":"New conversation",variant:"ghost",onPress:v,"data-testid":"chat-history-clear-chat-button",startContent:D,isIconOnly:l,children:!l&&"New conversation"})},"new-conversation-button"),!l&&t.jsx(ve.div,{className:"mt-2 flex flex-1 flex-col gap-2 overflow-auto overflow-x-hidden",initial:!1,animate:{opacity:1,width:"100%"},exit:{opacity:0,width:0},children:wt.zip(u,d).map(([o,C])=>{if(!o||$t(o))return null;const _=o===h,A=o===p,N=_?"solid":"light";return t.jsxs("div",{className:"flex w-full justify-between gap-2",children:[A?t.jsx(At,{ref:f,size:"sm",variant:"bordered",value:b,onChange:g=>x(g.target.value),onBlur:()=>{I||S(o)},onKeyDown:g=>{g.key==="Enter"&&S(o),g.key==="Escape"&&i()},className:"flex-1","data-testid":`input-conversation-${o}`}):t.jsx(X,{variant:N,"aria-label":`Select conversation ${o}`,"data-active":_,onPress:()=>k(o),title:C??o,"data-testid":`select-conversation-${o}`,className:"flex-1 justify-start",children:t.jsx("div",{className:"text-small truncate",children:C??o})}),t.jsxs(ao,{children:[t.jsx(eo,{children:t.jsx(X,{isIconOnly:!0,variant:"light","aria-label":`Conversation actions for ${o}`,"data-testid":`dropdown-conversation-${o}`,children:t.jsx(Q,{icon:"heroicons:ellipsis-vertical",className:"rotate-90"})})}),t.jsxs(Yt,{"aria-label":"Conversation actions",children:[t.jsx(De,{startContent:t.jsx(Q,{icon:"heroicons:pencil-square",className:"mb-0.5"}),onPress:()=>y(o,C??o),"data-testid":`edit-conversation-${o}`,children:"Edit"},"edit"),t.jsx(De,{className:"text-danger mb-0.5",color:"danger",startContent:t.jsx(Q,{icon:"heroicons:trash"}),onPress:()=>r(o),"data-testid":`delete-conversation-${o}`,children:"Delete conversation"},"delete")]})]})]},`${o}-${N}`)})},"conversation-list")]})})}export{co as default};
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BcnaGCUm.js","assets/index-CbVbgerL.js","assets/index-B1u136LF.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{r as P,t as ae,k as Xe,Z as W,ax as Me,$ as Ze,j as t,q as me,L as xe,_ as Ye,n as ye,T as Pe,s as et,v as R,V as tt,d as X,l as se,aq as Ie,o as ot,H as ke,a9 as rt,J as Ne,ay as at,ac as pe,U as st,X as _e,af as he,az as nt,aA as lt,ag as it,K as dt,O as be,Q as ct,W as ut,a0 as pt,ah as ft,a2 as K,a3 as Ae,ai as vt,R as ht,aB as bt,a8 as gt,aC as mt,aD as xt,a5 as yt,a as Pt,aE as Ct,i as fe,aF as Ce,aG as ve,D as we,I as Q,as as wt,aH as $t,aI as $e}from"./index-CbVbgerL.js";import{u as jt,b as St,c as je,d as Dt,e as Mt,m as It,$ as kt,a as Nt}from"./useMenuTriggerState-C5916IcO.js";import{$ as _t}from"./useSelectableItem-BWC6EImE.js";import{i as At}from"./chunk-SSA7SXE4-D3GKTPj0.js";var Ot=(e,r)=>{var n;let s=[];const a=(n=P.Children.map(e,d=>P.isValidElement(d)&&d.type===r?(s.push(d),null):d))==null?void 0:n.filter(Boolean),u=s.length>=0?s:void 0;return[a,u]},Ft=ae({base:["w-full","p-1","min-w-[200px]"]});ae({slots:{base:["flex","group","gap-2","items-center","justify-between","relative","px-2","py-1.5","w-full","h-full","box-border","rounded-small","outline-hidden","cursor-pointer","tap-highlight-transparent","data-[pressed=true]:opacity-70",...Xe,"data-[focus-visible=true]:dark:ring-offset-background-content1"],wrapper:"w-full flex flex-col items-start justify-center",title:"flex-1 text-small font-normal truncate",description:["w-full","text-tiny","text-foreground-500","group-hover:text-current"],selectedIcon:["text-inherit","w-3","h-3","shrink-0"],shortcut:["px-1","py-0.5","rounded-sm","font-sans","text-foreground-500","text-tiny","border-small","border-default-300","group-hover:border-current"]},variants:{variant:{solid:{base:""},bordered:{base:"border-medium border-transparent bg-transparent"},light:{base:"bg-transparent"},faded:{base:"border-small border-transparent hover:border-default data-[hover=true]:bg-default-100"},flat:{base:""},shadow:{base:"data-[hover=true]:shadow-lg"}},color:{default:{},primary:{},secondary:{},success:{},warning:{},danger:{}},isDisabled:{true:{base:"opacity-disabled pointer-events-none"}},disableAnimation:{true:{},false:{}}},defaultVariants:{variant:"solid",color:"default"},compoundVariants:[{variant:"solid",color:"default",class:{base:"data-[hover=true]:bg-default data-[hover=true]:text-default-foreground"}},{variant:"solid",color:"primary",class:{base:"data-[hover=true]:bg-primary data-[hover=true]:text-primary-foreground"}},{variant:"solid",color:"secondary",class:{base:"data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-foreground"}},{variant:"solid",color:"success",class:{base:"data-[hover=true]:bg-success data-[hover=true]:text-success-foreground"}},{variant:"solid",color:"warning",class:{base:"data-[hover=true]:bg-warning data-[hover=true]:text-warning-foreground"}},{variant:"solid",color:"danger",class:{base:"data-[hover=true]:bg-danger data-[hover=true]:text-danger-foreground"}},{variant:"shadow",color:"default",class:{base:"data-[hover=true]:shadow-default/50 data-[hover=true]:bg-default data-[hover=true]:text-default-foreground"}},{variant:"shadow",color:"primary",class:{base:"data-[hover=true]:shadow-primary/30 data-[hover=true]:bg-primary data-[hover=true]:text-primary-foreground"}},{variant:"shadow",color:"secondary",class:{base:"data-[hover=true]:shadow-secondary/30 data-[hover=true]:bg-secondary data-[hover=true]:text-secondary-foreground"}},{variant:"shadow",color:"success",class:{base:"data-[hover=true]:shadow-success/30 data-[hover=true]:bg-success data-[hover=true]:text-success-foreground"}},{variant:"shadow",color:"warning",class:{base:"data-[hover=true]:shadow-warning/30 data-[hover=true]:bg-warning data-[hover=true]:text-warning-foreground"}},{variant:"shadow",color:"danger",class:{base:"data-[hover=true]:shadow-danger/30 data-[hover=true]:bg-danger data-[hover=true]:text-danger-foreground"}},{variant:"bordered",color:"default",class:{base:"data-[hover=true]:border-default"}},{variant:"bordered",color:"primary",class:{base:"data-[hover=true]:border-primary data-[hover=true]:text-primary"}},{variant:"bordered",color:"secondary",class:{base:"data-[hover=true]:border-secondary data-[hover=true]:text-secondary"}},{variant:"bordered",color:"success",class:{base:"data-[hover=true]:border-success data-[hover=true]:text-success"}},{variant:"bordered",color:"warning",class:{base:"data-[hover=true]:border-warning data-[hover=true]:text-warning"}},{variant:"bordered",color:"danger",class:{base:"data-[hover=true]:border-danger data-[hover=true]:text-danger"}},{variant:"flat",color:"default",class:{base:"data-[hover=true]:bg-default/40 data-[hover=true]:text-default-foreground"}},{variant:"flat",color:"primary",class:{base:"data-[hover=true]:bg-primary/20 data-[hover=true]:text-primary"}},{variant:"flat",color:"secondary",class:{base:"data-[hover=true]:bg-secondary/20 data-[hover=true]:text-secondary"}},{variant:"flat",color:"success",class:{base:"data-[hover=true]:bg-success/20 data-[hover=true]:text-success "}},{variant:"flat",color:"warning",class:{base:"data-[hover=true]:bg-warning/20 data-[hover=true]:text-warning"}},{variant:"flat",color:"danger",class:{base:"data-[hover=true]:bg-danger/20 data-[hover=true]:text-danger"}},{variant:"faded",color:"default",class:{base:"data-[hover=true]:text-default-foreground"}},{variant:"faded",color:"primary",class:{base:"data-[hover=true]:text-primary"}},{variant:"faded",color:"secondary",class:{base:"data-[hover=true]:text-secondary"}},{variant:"faded",color:"success",class:{base:"data-[hover=true]:text-success"}},{variant:"faded",color:"warning",class:{base:"data-[hover=true]:text-warning"}},{variant:"faded",color:"danger",class:{base:"data-[hover=true]:text-danger"}},{variant:"light",color:"default",class:{base:"data-[hover=true]:text-default-500"}},{variant:"light",color:"primary",class:{base:"data-[hover=true]:text-primary"}},{variant:"light",color:"secondary",class:{base:"data-[hover=true]:text-secondary"}},{variant:"light",color:"success",class:{base:"data-[hover=true]:text-success"}},{variant:"light",color:"warning",class:{base:"data-[hover=true]:text-warning"}},{variant:"light",color:"danger",class:{base:"data-[hover=true]:text-danger"}}]});ae({slots:{base:"relative mb-2",heading:"pl-1 text-tiny text-foreground-500",group:"data-[has-title=true]:pt-1",divider:"mt-2"}});ae({base:"w-full flex flex-col gap-0.5 p-1"});var Et=(e,r)=>{if(!e&&!r)return{};const n=new Set([...Object.keys(e||{}),...Object.keys(r||{})]);return Array.from(n).reduce((s,a)=>({...s,[a]:W(e?.[a],r?.[a])}),{})},[Tt,Oe]=Me({name:"PopoverContext",errorMessage:"usePopoverContext: `context` is undefined. Seems you forgot to wrap all popover components within `<Popover />`"}),Se=()=>Ye(()=>import("./index-BcnaGCUm.js"),__vite__mapDeps([0,1,2])).then(e=>e.default),Fe=e=>{const{as:r,children:n,className:s,...a}=e,{Component:u,placement:d,backdrop:h,motionProps:l,disableAnimation:c,getPopoverProps:p,getDialogProps:w,getBackdropProps:b,getContentProps:x,isNonModal:I,onClose:j}=Oe(),f=P.useRef(null),{dialogProps:M,titleProps:D}=Ze({},f),y=w({ref:f,...M,...a}),S=r||u||"div",i=t.jsxs(t.Fragment,{children:[!I&&t.jsx(me,{onDismiss:j}),t.jsx(S,{...y,children:t.jsx("div",{...x({className:s}),children:typeof n=="function"?n(D):n})}),t.jsx(me,{onDismiss:j})]}),v=P.useMemo(()=>h==="transparent"?null:c?t.jsx("div",{...b()}):t.jsx(xe,{features:Se,children:t.jsx(ye.div,{animate:"enter",exit:"exit",initial:"exit",variants:Pe.fade,...b()})}),[h,c,b]),k=d?et(d==="center"?"top":d):void 0,o=t.jsx(t.Fragment,{children:c?i:t.jsx(xe,{features:Se,children:t.jsx(ye.div,{animate:"enter",exit:"exit",initial:"initial",style:k,variants:Pe.scaleSpringOpacity,...l,children:i})})});return t.jsxs("div",{...p(),children:[v,o]})};Fe.displayName="HeroUI.PopoverContent";var Rt=Fe,Ee=e=>{var r;const{triggerRef:n,getTriggerProps:s}=Oe(),{children:a,...u}=e,d=P.useMemo(()=>typeof a=="string"?t.jsx("p",{children:a}):P.Children.only(a),[a]),h=(r=d.props.ref)!=null?r:d.ref,{onPress:l,isDisabled:c,...p}=P.useMemo(()=>s(R(u,d.props),h),[s,d.props,u,h]),[,w]=Ot(a,X),{buttonProps:b}=tt({onPress:l,isDisabled:c},n),x=P.useMemo(()=>w?.[0]!==void 0,[w]);return x||delete p.preventFocusOnPress,P.cloneElement(d,R(p,x?{onPress:l,isDisabled:c}:b))};Ee.displayName="HeroUI.PopoverTrigger";var Ht=Ee,Te=se((e,r)=>{const{children:n,...s}=e,a=jt({...s,ref:r}),[u,d]=P.Children.toArray(n),h=t.jsx(ot,{portalContainer:a.portalContainer,children:d});return t.jsxs(Tt,{value:a,children:[u,a.disableAnimation&&a.isOpen?h:t.jsx(Ie,{children:a.isOpen?h:null})]})});Te.displayName="HeroUI.Popover";var Ut=Te,[Kt,Re]=Me({name:"DropdownContext",errorMessage:"useDropdownContext: `context` is undefined. Seems you forgot to wrap all popover components within `<Dropdown />`"});function Bt(e){const{isSelected:r,disableAnimation:n,...s}=e;return t.jsx("svg",{"aria-hidden":"true","data-selected":r,role:"presentation",viewBox:"0 0 17 18",...s,children:t.jsx("polyline",{fill:"none",points:"1 9 7 14 15 4",stroke:"currentColor",strokeDasharray:22,strokeDashoffset:r?44:66,strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5,style:n?{}:{transition:"stroke-dashoffset 200ms ease"}})})}const He=new WeakMap;function Vt(e,r,n){let{shouldFocusWrap:s=!0,onKeyDown:a,onKeyUp:u,...d}=e;!e["aria-label"]&&e["aria-labelledby"];let h=ke(e,{labelable:!0}),{listProps:l}=rt({...d,ref:n,selectionManager:r.selectionManager,collection:r.collection,disabledKeys:r.disabledKeys,shouldFocusWrap:s,linkBehavior:"override"});return He.set(r,{onClose:e.onClose,onAction:e.onAction,shouldUseVirtualFocus:e.shouldUseVirtualFocus}),{menuProps:Ne(h,{onKeyDown:a,onKeyUp:u},{role:"menu",...l,onKeyDown:c=>{var p;(c.key!=="Escape"||e.shouldUseVirtualFocus)&&((p=l.onKeyDown)===null||p===void 0||p.call(l,c))}})}}function Lt(e,r,n){let{id:s,key:a,closeOnSelect:u,isVirtualized:d,"aria-haspopup":h,onPressStart:l,onPressUp:c,onPress:p,onPressChange:w,onPressEnd:b,onHoverStart:x,onHoverChange:I,onHoverEnd:j,onKeyDown:f,onKeyUp:M,onFocus:D,onFocusChange:y,onBlur:S,selectionManager:i=r.selectionManager}=e,v=!!h,k=v&&e["aria-expanded"]==="true";var o;let C=(o=e.isDisabled)!==null&&o!==void 0?o:i.isDisabled(a);var _;let A=(_=e.isSelected)!==null&&_!==void 0?_:i.isSelected(a),N=He.get(r),g=r.collection.getItem(a),T=e.onClose||N.onClose,B=at(),$=m=>{var J;if(!v){if(!(g==null||(J=g.props)===null||J===void 0)&&J.onAction?g.props.onAction():e.onAction&&e.onAction(a),N.onAction){let ce=N.onAction;ce(a)}m.target instanceof HTMLAnchorElement&&g&&B.open(m.target,m,g.props.href,g.props.routerOptions)}},E="menuitem";v||(i.selectionMode==="single"?E="menuitemradio":i.selectionMode==="multiple"&&(E="menuitemcheckbox"));let O=pe(),H=pe(),q=pe(),V={id:s,"aria-disabled":C||void 0,role:E,"aria-label":e["aria-label"],"aria-labelledby":O,"aria-describedby":[H,q].filter(Boolean).join(" ")||void 0,"aria-controls":e["aria-controls"],"aria-haspopup":h,"aria-expanded":e["aria-expanded"]};i.selectionMode!=="none"&&!v&&(V["aria-checked"]=A),d&&(V["aria-posinset"]=g?.index,V["aria-setsize"]=St(r.collection));let G=m=>{m.pointerType==="keyboard"&&$(m),l?.(m)},Z=()=>{!v&&T&&(u??(i.selectionMode!=="multiple"||i.isLink(a)))&&T()},Y=m=>{m.pointerType==="mouse"&&($(m),Z()),c?.(m)},ne=m=>{m.pointerType!=="keyboard"&&m.pointerType!=="mouse"&&($(m),Z()),p?.(m)},{itemProps:L,isFocused:ee}=_t({id:s,selectionManager:i,key:a,ref:n,shouldSelectOnPressUp:!0,allowsDifferentPressOrigin:!0,linkBehavior:"none",shouldUseVirtualFocus:N.shouldUseVirtualFocus}),{pressProps:le,isPressed:te}=st({onPressStart:G,onPress:ne,onPressUp:Y,onPressChange:w,onPressEnd:b,isDisabled:C}),{hoverProps:ie}=_e({isDisabled:C,onHoverStart(m){!he()&&!(k&&h)&&(i.setFocused(!0),i.setFocusedKey(a)),x?.(m)},onHoverChange:I,onHoverEnd:j}),{keyboardProps:oe}=nt({onKeyDown:m=>{if(m.repeat){m.continuePropagation();return}switch(m.key){case" ":!C&&i.selectionMode==="none"&&!v&&u!==!1&&T&&T();break;case"Enter":!C&&u!==!1&&!v&&T&&T();break;default:v||m.continuePropagation(),f?.(m);break}},onKeyUp:M}),{focusProps:U}=lt({onBlur:S,onFocus:D,onFocusChange:y}),re=ke(g?.props);delete re.id;let de=it(g?.props);return{menuItemProps:{...V,...Ne(re,de,v?{onFocus:L.onFocus,"data-collection":L["data-collection"],"data-key":L["data-key"]}:L,le,ie,oe,U,N.shouldUseVirtualFocus||v?{onMouseDown:m=>m.preventDefault()}:void 0),tabIndex:L.tabIndex!=null&&k&&!N.shouldUseVirtualFocus?-1:L.tabIndex},labelProps:{id:O},descriptionProps:{id:H},keyboardShortcutProps:{id:q},isFocused:ee,isFocusVisible:ee&&i.isFocused&&he()&&!k,isSelected:A,isPressed:te,isDisabled:C}}function zt(e){let{heading:r,"aria-label":n}=e,s=dt();return{itemProps:{role:"presentation"},headingProps:r?{id:s,role:"presentation"}:{},groupProps:{role:"group","aria-label":n,"aria-labelledby":r?s:void 0}}}function Wt(e){var r,n;const s=be(),[a,u]=ct(e,je.variantKeys),{as:d,item:h,state:l,shortcut:c,description:p,startContent:w,endContent:b,isVirtualized:x,selectedIcon:I,className:j,classNames:f,onAction:M,autoFocus:D,onPress:y,onPressStart:S,onPressUp:i,onPressEnd:v,onPressChange:k,onHoverStart:o,onHoverChange:C,onHoverEnd:_,hideSelectedIcon:A=!1,isReadOnly:N=!1,closeOnSelect:g,onClose:T,onClick:B,...$}=a,E=(n=(r=e.disableAnimation)!=null?r:s?.disableAnimation)!=null?n:!1,O=P.useRef(null),H=d||($?.href?"a":"li"),q=typeof H=="string",{rendered:V,key:G}=h,Z=l.disabledKeys.has(G)||e.isDisabled,Y=l.selectionManager.selectionMode!=="none",ne=Dt(),{isFocusVisible:L,focusProps:ee}=ut({autoFocus:D}),le=P.useCallback(F=>{B?.(F),y?.(F)},[B,y]),{isPressed:te,isFocused:ie,isSelected:oe,isDisabled:U,menuItemProps:re,labelProps:de,descriptionProps:m,keyboardShortcutProps:J}=Lt({key:G,onClose:T,isDisabled:Z,onPress:le,onPressStart:S,onPressUp:i,onPressEnd:v,onPressChange:k,"aria-label":a["aria-label"],closeOnSelect:g,isVirtualized:x,onAction:M},l,O);let{hoverProps:ce,isHovered:ge}=_e({isDisabled:U,onHoverStart(F){he()||(l.selectionManager.setFocused(!0),l.selectionManager.setFocusedKey(G)),o?.(F)},onHoverChange:C,onHoverEnd:_}),ue=re;const z=P.useMemo(()=>je({...u,isDisabled:U,disableAnimation:E,hasTitleTextChild:typeof V=="string",hasDescriptionTextChild:typeof p=="string"}),[pt(u),U,E,V,p]),ze=W(f?.base,j);N&&(ue=ft(ue));const We=(F={})=>({ref:O,...R(N?{}:ee,Ae($,{enabled:q}),ue,ce,F),"data-focus":K(ie),"data-selectable":K(Y),"data-hover":K(ne?ge||te:ge),"data-disabled":K(U),"data-selected":K(oe),"data-pressed":K(te),"data-focus-visible":K(L),className:z.base({class:W(ze,F.className)})}),qe=(F={})=>({...R(de,F),className:z.title({class:f?.title})}),Ge=(F={})=>({...R(m,F),className:z.description({class:f?.description})}),Je=(F={})=>({...R(J,F),className:z.shortcut({class:f?.shortcut})}),Qe=P.useCallback((F={})=>({"aria-hidden":K(!0),"data-disabled":K(U),className:z.selectedIcon({class:f?.selectedIcon}),...F}),[U,z,f]);return{Component:H,domRef:O,slots:z,classNames:f,isSelectable:Y,isSelected:oe,isDisabled:U,rendered:V,shortcut:c,description:p,startContent:w,endContent:b,selectedIcon:I,disableAnimation:E,getItemProps:We,getLabelProps:qe,hideSelectedIcon:A,getDescriptionProps:Ge,getKeyboardShortcutProps:Je,getSelectedIconProps:Qe}}var Ue=e=>{const{Component:r,slots:n,classNames:s,rendered:a,shortcut:u,description:d,isSelectable:h,isSelected:l,isDisabled:c,selectedIcon:p,startContent:w,endContent:b,disableAnimation:x,hideSelectedIcon:I,getItemProps:j,getLabelProps:f,getDescriptionProps:M,getKeyboardShortcutProps:D,getSelectedIconProps:y}=Wt(e),S=P.useMemo(()=>{const i=t.jsx(Bt,{disableAnimation:x,isSelected:l});return typeof p=="function"?p({icon:i,isSelected:l,isDisabled:c}):p||i},[p,l,c,x]);return t.jsxs(r,{...j(),children:[w,d?t.jsxs("div",{className:n.wrapper({class:s?.wrapper}),children:[t.jsx("span",{...f(),children:a}),t.jsx("span",{...M(),children:d})]}):t.jsx("span",{...f(),children:a}),u&&t.jsx("kbd",{...D(),children:u}),h&&!I&&t.jsx("span",{...y(),children:S}),b]})};Ue.displayName="HeroUI.MenuItem";var Ke=Ue,Be=se(({item:e,state:r,as:n,variant:s,color:a,disableAnimation:u,onAction:d,closeOnSelect:h,className:l,classNames:c,showDivider:p=!1,hideSelectedIcon:w,dividerProps:b={},itemClasses:x,title:I,...j},f)=>{const M=n||"li",D=P.useMemo(()=>Mt(),[]),y=W(c?.base,l),S=W(c?.divider,b?.className),{itemProps:i,headingProps:v,groupProps:k}=zt({heading:e.rendered,"aria-label":e["aria-label"]});return t.jsxs(M,{"data-slot":"base",...R(i,j),className:D.base({class:y}),children:[e.rendered&&t.jsx("span",{...v,className:D.heading({class:c?.heading}),"data-slot":"heading",children:e.rendered}),t.jsxs("ul",{...k,className:D.group({class:c?.group}),"data-has-title":!!e.rendered,"data-slot":"group",children:[[...e.childNodes].map(o=>{const{key:C,props:_}=o;let A=t.jsx(Ke,{classNames:x,closeOnSelect:h,color:a,disableAnimation:u,hideSelectedIcon:w,item:o,state:r,variant:s,onAction:d,..._},C);return o.wrapper&&(A=o.wrapper(A)),A}),p&&t.jsx(vt,{as:"li",className:D.divider({class:S}),...b})]})]})});Be.displayName="HeroUI.MenuSection";var qt=Be;function Gt(e){var r;const n=be(),{as:s,ref:a,variant:u,color:d,children:h,disableAnimation:l=(r=n?.disableAnimation)!=null?r:!1,onAction:c,closeOnSelect:p,itemClasses:w,className:b,state:x,topContent:I,bottomContent:j,hideEmptyContent:f=!1,hideSelectedIcon:M=!1,emptyContent:D="No items.",menuProps:y,onClose:S,classNames:i,...v}=e,k=s||"ul",o=ht(a),C=typeof k=="string",_=bt({...v,...y,children:h}),A=x||_,{menuProps:N}=Vt({...v,...y,onAction:c},A,o),g=P.useMemo(()=>It({className:b}),[b]),T=W(i?.base,b);return{Component:k,state:A,variant:u,color:d,disableAnimation:l,onClose:S,topContent:I,bottomContent:j,closeOnSelect:p,className:b,itemClasses:w,getBaseProps:(O={})=>({ref:o,"data-slot":"base",className:g.base({class:T}),...Ae(v,{enabled:C}),...O}),getListProps:(O={})=>({"data-slot":"list",className:g.list({class:i?.list}),...N,...O}),hideEmptyContent:f,hideSelectedIcon:M,getEmptyContentProps:(O={})=>({children:D,className:g.emptyContent({class:i?.emptyContent}),...O})}}var Jt=se(function(r,n){const{Component:s,state:a,closeOnSelect:u,color:d,disableAnimation:h,hideSelectedIcon:l,hideEmptyContent:c,variant:p,onClose:w,topContent:b,bottomContent:x,itemClasses:I,getBaseProps:j,getListProps:f,getEmptyContentProps:M}=Gt({...r,ref:n}),D=t.jsxs(s,{...f(),children:[!a.collection.size&&!c&&t.jsx("li",{children:t.jsx("div",{...M()})}),[...a.collection].map(y=>{const S={closeOnSelect:u,color:d,disableAnimation:h,item:y,state:a,variant:p,onClose:w,hideSelectedIcon:l,...y.props},i=Et(I,S?.classNames);if(y.type==="section")return t.jsx(qt,{...S,itemClasses:i},y.key);let v=t.jsx(Ke,{...S,classNames:i},y.key);return y.wrapper&&(v=y.wrapper(v)),v})]});return t.jsxs("div",{...j(),children:[b,D,x]})}),Qt=Jt,Xt=gt,De=Xt,Zt=se(function(r,n){const{getMenuProps:s}=Re();return t.jsx(Rt,{children:t.jsx(mt,{contain:!0,restoreFocus:!0,children:t.jsx(Qt,{...s(r,n)})})})}),Yt=Zt,Ve=e=>{const{getMenuTriggerProps:r}=Re(),{children:n,...s}=e;return t.jsx(Ht,{...r(s),children:n})};Ve.displayName="HeroUI.DropdownTrigger";var eo=Ve,to=(e,r)=>{if(e){const n=Array.isArray(e.children)?e.children:[...e?.items||[]];if(n&&n.length)return n.find(a=>{if(a&&a.key===r)return a})||{}}return null},oo=(e,r,n)=>{const s=n||to(e,r);return s&&s.props&&"closeOnSelect"in s.props?s.props.closeOnSelect:e?.closeOnSelect};function ro(e){var r;const n=be(),{as:s,triggerRef:a,isOpen:u,defaultOpen:d,onOpenChange:h,isDisabled:l,type:c="menu",trigger:p="press",placement:w="bottom",closeOnSelect:b=!0,shouldBlockScroll:x=!0,classNames:I,disableAnimation:j=(r=n?.disableAnimation)!=null?r:!1,onClose:f,className:M,...D}=e,y=s||"div",S=P.useRef(null),i=a||S,v=P.useRef(null),k=P.useRef(null),o=kt({trigger:p,isOpen:u,defaultOpen:d,onOpenChange:$=>{h?.($),$||f?.()}}),{menuTriggerProps:C,menuProps:_}=Nt({type:c,trigger:p,isDisabled:l},o,i),A=P.useMemo(()=>Ft({className:M}),[M]),N=$=>{$!==void 0&&!$||b&&o.close()},g=($={})=>{const E=R(D,$);return{state:o,placement:w,ref:k,disableAnimation:j,shouldBlockScroll:x,scrollRef:v,triggerRef:i,...E,classNames:{...I,...$.classNames,content:W(A,I?.content,$.className)}}},T=($={})=>{const{onPress:E,onPressStart:O,...H}=C;return R(H,{isDisabled:l},$)},B=($,E=null)=>({ref:xt(E,v),menuProps:_,closeOnSelect:b,...R($,{onAction:(O,H)=>{const q=oo($,O,H);N(q)},onClose:o.close})});return{Component:y,menuRef:v,menuProps:_,closeOnSelect:b,onClose:o.close,autoFocus:o.focusStrategy||!0,disableAnimation:j,getPopoverProps:g,getMenuProps:B,getMenuTriggerProps:T}}var Le=e=>{const{children:r,...n}=e,s=ro(n),[a,u]=yt.Children.toArray(r);return t.jsx(Kt,{value:s,children:t.jsxs(Ut,{...s.getPopoverProps(),children:[a,u]})})};Le.displayName="HeroUI.Dropdown";var ao=Le;function co(){const{selectConversation:e,deleteConversation:r,newConversation:n,setConversationProperties:s}=Pt(),a=Ct(),u=fe(Ce(o=>Object.keys(o.conversations).reverse())),d=fe(Ce(o=>Object.values(o.conversations).reverse().map(C=>C.summary))),h=fe(o=>o.currentConversation),[l,c]=P.useState(!1),[p,w]=P.useState(null),[b,x]=P.useState(""),[I,j]=P.useState(!1),f=P.useRef(null),M=l?"Open sidebar":"Close sidebar",D=t.jsx(Q,{icon:"heroicons:pencil-square"}),y=(o,C)=>{w(o),x(C??""),j(!0),setTimeout(()=>{f.current?.focus?.(),setTimeout(()=>j(!1),120)},0)},S=o=>{if(p!==o)return;const C=(b||"").trim();C&&s(o,{summary:C}),w(null),x(""),j(!1)},i=()=>{w(null),x(""),j(!1)},v=()=>{const o=n();a($e(o))},k=o=>{e(o),a($e(o))};return t.jsx(ve.div,{initial:!1,animate:{maxWidth:l?"4.5rem":"16rem"},className:"rounded-l-medium border-small border-divider ml-4 flex h-full w-full min-w-[4.5rem] flex-grow flex-col space-y-2 overflow-hidden border-r-0 p-4 py-3",children:t.jsxs(Ie,{children:[t.jsx(we,{content:M,placement:"bottom",children:t.jsx(X,{isIconOnly:!0,"aria-label":M,variant:"ghost",onPress:()=>c(o=>!o),"data-testid":"chat-history-collapse-button",className:"ml-auto",children:t.jsx(Q,{icon:l?"heroicons:chevron-double-right":"heroicons:chevron-double-left"})})},"collapse-button"),!l&&t.jsx(ve.p,{initial:!1,animate:{opacity:1,width:"100%",height:"auto"},exit:{opacity:0,width:0,height:0,marginBottom:0},className:"text-small text-foreground truncate leading-5 font-semibold",children:"Conversations"},"conversations"),t.jsx(we,{content:"New conversation",placement:"right",children:t.jsx(X,{"aria-label":"New conversation",variant:"ghost",onPress:v,"data-testid":"chat-history-clear-chat-button",startContent:D,isIconOnly:l,children:!l&&"New conversation"})},"new-conversation-button"),!l&&t.jsx(ve.div,{className:"mt-2 flex flex-1 flex-col gap-2 overflow-auto overflow-x-hidden",initial:!1,animate:{opacity:1,width:"100%"},exit:{opacity:0,width:0},children:wt.zip(u,d).map(([o,C])=>{if(!o||$t(o))return null;const _=o===h,A=o===p,N=_?"solid":"light";return t.jsxs("div",{className:"flex w-full justify-between gap-2",children:[A?t.jsx(At,{ref:f,size:"sm",variant:"bordered",value:b,onChange:g=>x(g.target.value),onBlur:()=>{I||S(o)},onKeyDown:g=>{g.key==="Enter"&&S(o),g.key==="Escape"&&i()},className:"flex-1","data-testid":`input-conversation-${o}`}):t.jsx(X,{variant:N,"aria-label":`Select conversation ${o}`,"data-active":_,onPress:()=>k(o),title:C??o,"data-testid":`select-conversation-${o}`,className:"flex-1 justify-start",children:t.jsx("div",{className:"text-small truncate",children:C??o})}),t.jsxs(ao,{children:[t.jsx(eo,{children:t.jsx(X,{isIconOnly:!0,variant:"light","aria-label":`Conversation actions for ${o}`,"data-testid":`dropdown-conversation-${o}`,children:t.jsx(Q,{icon:"heroicons:ellipsis-vertical",className:"rotate-90"})})}),t.jsxs(Yt,{"aria-label":"Conversation actions",children:[t.jsx(De,{startContent:t.jsx(Q,{icon:"heroicons:pencil-square",className:"mb-0.5"}),onPress:()=>y(o,C??o),"data-testid":`edit-conversation-${o}`,children:"Edit"},"edit"),t.jsx(De,{className:"text-danger mb-0.5",color:"danger",startContent:t.jsx(Q,{icon:"heroicons:trash"}),onPress:()=>r(o),"data-testid":`delete-conversation-${o}`,children:"Delete conversation"},"delete")]})]})]},`${o}-${N}`)})},"conversation-list")]})})}export{co as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as z,r as f,u as ie,h as ce,a as ue,i as le,b as fe,p as Y,C as Q,j as l,D as de,d as A,I as me,m as ge,e as he,f as pe}from"./index-
|
|
1
|
+
import{g as z,r as f,u as ie,h as ce,a as ue,i as le,b as fe,p as Y,C as Q,j as l,D as de,d as A,I as me,m as ge,e as he,f as pe}from"./index-CbVbgerL.js";import{g as Z,v as W,F as ve,t as be}from"./index-DTNGcmXG.js";import{m as Se}from"./chunk-IGSAU2ZA-BBfo0QFa.js";import"./chunk-SSA7SXE4-D3GKTPj0.js";import"./useMenuTriggerState-C5916IcO.js";import"./useSelectableItem-BWC6EImE.js";import"./index-B-LIlvZN.js";var B,V;function xe(){if(V)return B;V=1;var n="Expected a function",t=NaN,s="[object Symbol]",m=/^\s+|\s+$/g,g=/^[-+]0x[0-9a-f]+$/i,h=/^0b[01]+$/i,i=/^0o[0-7]+$/i,b=parseInt,S=typeof z=="object"&&z&&z.Object===Object&&z,y=typeof self=="object"&&self&&self.Object===Object&&self,C=S||y||Function("return this")(),d=Object.prototype,r=d.toString,c=Math.max,O=Math.min,E=function(){return C.Date.now()};function $(e,u,v){var T,L,P,I,p,j,R=0,G=!1,D=!1,k=!0;if(typeof e!="function")throw new TypeError(n);u=q(u)||0,_(v)&&(G=!!v.leading,D="maxWait"in v,P=D?c(q(v.maxWait)||0,u):P,k="trailing"in v?!!v.trailing:k);function H(o){var x=T,F=L;return T=L=void 0,R=o,I=e.apply(F,x),I}function re(o){return R=o,p=setTimeout(N,u),G?H(o):I}function oe(o){var x=o-j,F=o-R,X=u-x;return D?O(X,P-F):X}function U(o){var x=o-j,F=o-R;return j===void 0||x>=u||x<0||D&&F>=P}function N(){var o=E();if(U(o))return K(o);p=setTimeout(N,oe(o))}function K(o){return p=void 0,k&&T?H(o):(T=L=void 0,I)}function se(){p!==void 0&&clearTimeout(p),R=0,T=j=L=p=void 0}function ae(){return p===void 0?I:K(E())}function M(){var o=E(),x=U(o);if(T=arguments,L=this,j=o,x){if(p===void 0)return re(j);if(D)return p=setTimeout(N,u),H(j)}return p===void 0&&(p=setTimeout(N,u)),I}return M.cancel=se,M.flush=ae,M}function _(e){var u=typeof e;return!!e&&(u=="object"||u=="function")}function a(e){return!!e&&typeof e=="object"}function w(e){return typeof e=="symbol"||a(e)&&r.call(e)==s}function q(e){if(typeof e=="number")return e;if(w(e))return t;if(_(e)){var u=typeof e.valueOf=="function"?e.valueOf():e;e=_(u)?u+"":u}if(typeof e!="string")return e===0?e:+e;e=e.replace(m,"");var v=h.test(e);return v||i.test(e)?b(e.slice(2),v?2:8):g.test(e)?t:+e}return B=$,B}xe();var ne=typeof window<"u"?f.useLayoutEffect:f.useEffect;function ee(n,t,s,m){const g=f.useRef(t);ne(()=>{g.current=t},[t]),f.useEffect(()=>{const h=window;if(!(h&&h.addEventListener))return;const i=b=>{g.current(b)};return h.addEventListener(n,i,m),()=>{h.removeEventListener(n,i,m)}},[n,s,m])}function te(n){const t=f.useRef(()=>{throw new Error("Cannot call an event handler while rendering.")});return ne(()=>{t.current=n},[n]),f.useCallback((...s)=>{var m;return(m=t.current)==null?void 0:m.call(t,...s)},[t])}var J=typeof window>"u";function ye(n,t,s={}){const{initializeWithValue:m=!0}=s,g=f.useCallback(r=>s.serializer?s.serializer(r):JSON.stringify(r),[s]),h=f.useCallback(r=>{if(s.deserializer)return s.deserializer(r);if(r==="undefined")return;const c=t instanceof Function?t():t;let O;try{O=JSON.parse(r)}catch(E){return console.error("Error parsing JSON:",E),c}return O},[s,t]),i=f.useCallback(()=>{const r=t instanceof Function?t():t;if(J)return r;try{const c=window.localStorage.getItem(n);return c?h(c):r}catch(c){return console.warn(`Error reading localStorage key “${n}”:`,c),r}},[t,n,h]),[b,S]=f.useState(()=>m?i():t instanceof Function?t():t),y=te(r=>{J&&console.warn(`Tried setting localStorage key “${n}” even though environment is not a client`);try{const c=r instanceof Function?r(i()):r;window.localStorage.setItem(n,g(c)),S(c),window.dispatchEvent(new StorageEvent("local-storage",{key:n}))}catch(c){console.warn(`Error setting localStorage key “${n}”:`,c)}}),C=te(()=>{J&&console.warn(`Tried removing localStorage key “${n}” even though environment is not a client`);const r=t instanceof Function?t():t;window.localStorage.removeItem(n),S(r),window.dispatchEvent(new StorageEvent("local-storage",{key:n}))});f.useEffect(()=>{S(i())},[n]);const d=f.useCallback(r=>{r.key&&r.key!==n||S(i())},[n,i]);return ee("storage",d),ee("local-storage",d),[b,y,C]}const Ce="ragbits-no-history-chat-options";function Le(){const{isOpen:n,onOpen:t,onClose:s}=ie(),m=ce(a=>a.chatOptions),g=f.useRef(null),{setConversationProperties:h,initializeChatOptions:i}=ue(),b=le(a=>a.currentConversation),{config:{user_settings:S}}=fe(),[y,C]=ye(Ce,null),d=S?.form,r=a=>{Y.isPluginActivated(Q.name)||C(a)},c=()=>{t()},O=(a,w)=>{w.preventDefault(),g.current=a.formData,s()},E=()=>{if(!d)return;const a=Z(W,d);g.current=a,s()},$=()=>{s()},_=a=>{if(a!=="exit"||!g.current)return;const w=g.current;h(b,{chatOptions:w}),r(w),g.current=null};return f.useEffect(()=>{if(!d)return;const a=Z(W,d);Y.isPluginActivated(Q.name)?i(a):y!==null?i(y):(i(a),C(a))},[i,d,b,y,C]),d?l.jsxs(l.Fragment,{children:[l.jsx(de,{content:"Chat Options",placement:"bottom",children:l.jsx(A,{isIconOnly:!0,variant:"ghost",className:"p-0","aria-label":"Open chat options",onPress:c,"data-testid":"open-chat-options",children:l.jsx(me,{icon:"heroicons:cog-6-tooth"})})}),l.jsx(ge,{isOpen:n,onOpenChange:$,motionProps:{onAnimationComplete:_},children:l.jsxs(he,{children:[l.jsx(Se,{className:"text-default-900 flex flex-col gap-1",children:d.title||"Chat Options"}),l.jsx(pe,{children:l.jsx("div",{className:"flex flex-col gap-4",children:l.jsx(ve,{schema:d,validator:W,formData:m,onSubmit:O,transformErrors:be,liveValidate:!0,children:l.jsxs("div",{className:"flex justify-end gap-4 py-4",children:[l.jsx(A,{className:"mr-auto",color:"primary",variant:"light",onPress:E,"aria-label":"Restore default user settings",children:"Restore defaults"}),l.jsx(A,{color:"danger",variant:"light",onPress:s,"aria-label":"Close chat options form",children:"Cancel"}),l.jsx(A,{color:"primary",type:"submit","aria-label":"Save chat options","data-testid":"chat-options-submit",children:"Save"})]})})})})]})})]}):null}export{Le as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as c,c as x,aW as w,aE as S,j as t,aq as b,aG as j,d as v,bm as C}from"./index-CbVbgerL.js";import{a as P}from"./authStore-AVyfzjgs.js";import{u as q}from"./useInitializeUserStore-CVYyhiv3.js";import{i as m}from"./chunk-SSA7SXE4-D3GKTPj0.js";function z(){const[s,p]=c.useState({username:"",password:""}),l=x("/api/auth/login",{headers:{"Content-Type":"application/json"},method:"POST"}),f=w(P,e=>e.login),g=S(),u=q(),[y,o]=c.useState(!1),h=async e=>{o(!1),e.preventDefault(),e.stopPropagation();const r=new FormData(e.currentTarget),n=r.get("username"),i=r.get("password");try{const a=await l.call({body:{username:n,password:i}});if(!a.success||!a.user){o(!0);return}f(a.user),u?u(a.user.user_id):console.error("Failed to initialize store for user, initializeUserStore() is not defined. Check current HistoryStoreContextProvider implementation."),g("/")}catch(a){console.error("Failed to login",a),o(!0)}},d=e=>r=>p(n=>C(n,i=>{i[e]=r.target.value}));return t.jsxs("form",{className:"flex w-full flex-col gap-4",onSubmit:h,children:[t.jsx(m,{label:"Username",name:"username",labelPlacement:"outside",placeholder:"Your username",required:!0,isRequired:!0,value:s.username,onChange:d("username")}),t.jsx(m,{label:"Password",labelPlacement:"outside",id:"password",name:"password",type:"password",placeholder:"••••••••",required:!0,isRequired:!0,value:s.password,onChange:d("password")}),t.jsx(b,{children:y&&!l.isLoading&&t.jsx(j.div,{className:"text-small text-danger",initial:{opacity:0,y:-10},animate:{opacity:1,y:0},exit:{opacity:0,y:-10},transition:{duration:.3,ease:"easeOut"},children:"We couldn't sign you in. Please verify your credentials and try again."})}),t.jsx(v,{type:"submit",color:s.password&&s.username?"primary":"default",children:"Sign in"})]})}export{z as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{u as g,a as v,b as C,r as _,F as t,c as I,j as e,D as u,d as n,I as b,m as T,e as w,f as D}from"./index-CbVbgerL.js";import{F as O,t as S,v as E}from"./index-DTNGcmXG.js";import{m as N}from"./chunk-IGSAU2ZA-BBfo0QFa.js";import"./chunk-SSA7SXE4-D3GKTPj0.js";import"./useMenuTriggerState-C5916IcO.js";import"./useSelectableItem-BWC6EImE.js";import"./index-B-LIlvZN.js";function z({message:s}){const{isOpen:f,onOpen:h,onClose:r}=g(),{mergeExtensions:p}=v(),{config:{feedback:o}}=C(),[i,x]=_.useState(t.Like),k=I("/api/feedback",{headers:{"Content-Type":"application/json"},method:"POST"});if(!s.serverId)return null;const l=o[i].form,j=()=>{r()},c=async a=>{if(!s.serverId)throw new Error('Feedback is only available for messages with "serverId" set');try{await k.call({body:{message_id:s.serverId,feedback:i,payload:a??{}}})}catch(F){console.error(F)}},y=a=>{p(s.id,{feedbackType:i}),c(a.formData),r()},d=async a=>{if(x(a),o[a].form===null){await c(null);return}h()};if(!l)return null;const m=s.extensions?.feedbackType;return e.jsxs(e.Fragment,{children:[o.like.enabled&&e.jsx(u,{content:"Like",placement:"bottom",children:e.jsx(n,{isIconOnly:!0,variant:"ghost",className:"p-0","aria-label":"Rate message as helpful",onPress:()=>d(t.Like),"data-testid":"feedback-like",children:e.jsx(b,{icon:m===t.Like?"heroicons:hand-thumb-up-solid":"heroicons:hand-thumb-up"})})}),o.dislike.enabled&&e.jsx(u,{content:"Dislike",placement:"bottom",children:e.jsx(n,{isIconOnly:!0,variant:"ghost",className:"p-0","aria-label":"Rate message as unhelpful",onPress:()=>d(t.Dislike),"data-testid":"feedback-dislike",children:e.jsx(b,{icon:m===t.Dislike?"heroicons:hand-thumb-down-solid":"heroicons:hand-thumb-down"})})}),e.jsx(T,{isOpen:f,onOpenChange:j,children:e.jsx(w,{children:a=>e.jsxs(e.Fragment,{children:[e.jsx(N,{className:"text-default-900 flex flex-col gap-1",children:l.title}),e.jsx(D,{children:e.jsx("div",{className:"flex flex-col gap-4",children:e.jsx(O,{schema:l,validator:E,onSubmit:y,transformErrors:S,liveValidate:!0,children:e.jsxs("div",{className:"flex justify-end gap-4 py-4",children:[e.jsx(n,{color:"danger",variant:"light",onPress:a,"aria-label":"Close feedback form",children:"Cancel"}),e.jsx(n,{color:"primary",type:"submit","aria-label":"Submit feedback","data-testid":"feedback-submit",children:"Submit"})]})})})})]})})})]})}export{z as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,j as e}from"./index-
|
|
1
|
+
import{r as s,j as e}from"./index-CbVbgerL.js";function n({children:t}){return s.useEffect(()=>{document.title="Login"},[]),e.jsx("div",{className:"flex h-screen w-screen",children:e.jsxs("div",{className:"rounded-medium border-small border-divider m-auto flex w-full max-w-xs flex-col gap-4 p-4",children:[e.jsxs("div",{className:"text-small",children:[e.jsx("div",{className:"text-foreground truncate leading-5 font-semibold",children:"Sign in"}),e.jsx("div",{className:"text-default-500 truncate leading-5 font-normal",children:"Sign in to start chatting."})]}),t]})})}export{n as default};
|