Files
wehub-resource-sync b7f52be4c9
CI / Run CI (push) Has been cancelled
CI / check-backend (push) Has been cancelled
CI / check-frontend (push) Has been cancelled
CI / tests (push) Has been cancelled
CI / e2e-tests (push) Has been cancelled
Copilot Setup Steps / copilot-setup-steps (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:48:47 +08:00

362 lines
7.4 KiB
Python

from enum import Enum
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
Dict,
Generic,
List,
Literal,
Optional,
Protocol,
TypedDict,
TypeVar,
Union,
)
if TYPE_CHECKING:
from chainlit.element import ElementDict
from chainlit.step import StepDict
from dataclasses import field
from dataclasses_json import DataClassJsonMixin
from pydantic import BaseModel
from pydantic.dataclasses import dataclass
InputWidgetType = Literal[
"switch",
"slider",
"select",
"textinput",
"tags",
"numberinput",
"multiselect",
"checkbox",
"radio",
"datepicker",
]
ToastType = Literal["info", "success", "warning", "error"]
class ThreadDict(TypedDict):
id: str
createdAt: str
name: Optional[str]
userId: Optional[str]
userIdentifier: Optional[str]
tags: Optional[List[str]]
metadata: Optional[Dict]
steps: List["StepDict"]
elements: Optional[List["ElementDict"]]
class Pagination(BaseModel):
first: int
cursor: Optional[str] = None
class ThreadFilter(BaseModel):
feedback: Literal[0, 1] | None = None
userId: str | None = None
search: str | None = None
@dataclass
class PageInfo:
hasNextPage: bool
startCursor: Optional[str]
endCursor: Optional[str]
def to_dict(self):
return {
"hasNextPage": self.hasNextPage,
"startCursor": self.startCursor,
"endCursor": self.endCursor,
}
@classmethod
def from_dict(cls, page_info_dict: Dict) -> "PageInfo":
hasNextPage = page_info_dict.get("hasNextPage", False)
startCursor = page_info_dict.get("startCursor", None)
endCursor = page_info_dict.get("endCursor", None)
return cls(
hasNextPage=hasNextPage, startCursor=startCursor, endCursor=endCursor
)
T = TypeVar("T", covariant=True)
class HasFromDict(Protocol[T]):
@classmethod
def from_dict(cls, obj_dict: Any) -> T:
raise NotImplementedError
@dataclass
class PaginatedResponse(Generic[T]):
pageInfo: PageInfo
data: List[T]
def to_dict(self):
return {
"pageInfo": self.pageInfo.to_dict(),
"data": [
(d.to_dict() if hasattr(d, "to_dict") and callable(d.to_dict) else d)
for d in self.data
],
}
@classmethod
def from_dict(
cls, paginated_response_dict: Dict, the_class: HasFromDict[T]
) -> "PaginatedResponse[T]":
pageInfo = PageInfo.from_dict(paginated_response_dict.get("pageInfo", {}))
data = [the_class.from_dict(d) for d in paginated_response_dict.get("data", [])]
return cls(pageInfo=pageInfo, data=data)
@dataclass
class FileSpec(DataClassJsonMixin):
accept: Union[List[str], Dict[str, List[str]]]
max_files: int
max_size_mb: int
@dataclass
class ActionSpec(DataClassJsonMixin):
keys: List[str]
@dataclass
class AskSpec(DataClassJsonMixin):
"""Specification for asking the user."""
timeout: int
type: Literal["text", "file", "action", "element"]
step_id: str
@dataclass
class AskFileSpec(FileSpec, AskSpec, DataClassJsonMixin):
"""Specification for asking the user a file."""
@dataclass
class AskActionSpec(ActionSpec, AskSpec, DataClassJsonMixin):
"""Specification for asking the user an action"""
@dataclass
class AskElementSpec(AskSpec, DataClassJsonMixin):
"""Specification for asking the user a custom element"""
element_id: str
class FileReference(TypedDict):
id: str
class FileDict(TypedDict):
id: str
name: str
path: Path
size: int
type: str
class MessagePayload(TypedDict):
message: "StepDict"
fileReferences: Optional[List[FileReference]]
class InputAudioChunkPayload(TypedDict):
isStart: bool
mimeType: str
elapsedTime: float
data: bytes
@dataclass
class InputAudioChunk:
isStart: bool
mimeType: str
elapsedTime: float
data: bytes
class OutputAudioChunk(TypedDict):
track: str
mimeType: str
data: bytes
@dataclass
class AskFileResponse:
id: str
name: str
path: str
size: int
type: str
class AskActionResponse(TypedDict):
name: str
payload: Dict
label: str
tooltip: str
forId: str
id: str
class AskElementResponse(TypedDict, total=False):
submitted: bool
class UpdateThreadRequest(BaseModel):
threadId: str
name: str
class ShareThreadRequest(BaseModel):
threadId: str
isShared: bool
class DeleteThreadRequest(BaseModel):
threadId: str
class DeleteFeedbackRequest(BaseModel):
feedbackId: str
class GetThreadsRequest(BaseModel):
pagination: Pagination
filter: ThreadFilter
class CallActionRequest(BaseModel):
action: Dict
sessionId: str
class ConnectStdioMCPRequest(BaseModel):
sessionId: str
clientType: Literal["stdio"]
name: str
fullCommand: str
class ConnectSseMCPRequest(BaseModel):
sessionId: str
clientType: Literal["sse"]
name: str
url: str
# Optional HTTP headers to forward to the MCP transport (e.g. Authorization)
headers: Optional[Dict[str, str]] = None
class ConnectStreamableHttpMCPRequest(BaseModel):
sessionId: str
clientType: Literal["streamable-http"]
name: str
url: str
# Optional HTTP headers to forward to the MCP transport (e.g. Authorization)
headers: Dict[str, str] | None = None
ConnectMCPRequest = Union[
ConnectStdioMCPRequest, ConnectSseMCPRequest, ConnectStreamableHttpMCPRequest
]
class DisconnectMCPRequest(BaseModel):
sessionId: str
name: str
class ElementRequest(BaseModel):
element: Dict
sessionId: str
class Theme(str, Enum):
light = "light"
dark = "dark"
@dataclass
class Starter(DataClassJsonMixin):
"""Specification for a starter that can be chosen by the user at the thread start."""
label: str
message: str
command: Optional[str] = None
icon: Optional[str] = None
@dataclass
class StarterCategory(DataClassJsonMixin):
"""A category/group of starters with an optional icon."""
label: str
icon: Optional[str] = None
starters: List[Starter] = field(default_factory=list)
@dataclass
class ChatProfile(DataClassJsonMixin):
"""Specification for a chat profile that can be chosen by the user at the thread start."""
name: str
markdown_description: str
icon: Optional[str] = None
display_name: Optional[str] = None
default: bool = False
starters: Optional[List[Starter]] = None
config_overrides: Any = None
FeedbackStrategy = Literal["BINARY"]
class CommandDict(TypedDict):
# The identifier of the command, will be displayed in the UI
id: str
# The description of the command, will be displayed in the UI
description: str
# The lucide icon name
icon: str
# Display the command as a button in the composer
button: Optional[bool]
# Whether the command will be persistent unless the user toggles it
persistent: Optional[bool]
# Whether the command should be pre-selected when loaded
selected: Optional[bool]
class FeedbackDict(TypedDict):
forId: str
id: Optional[str]
value: Literal[0, 1]
comment: Optional[str]
@dataclass
class Feedback:
forId: str
value: Literal[0, 1]
threadId: Optional[str] = None
id: Optional[str] = None
comment: Optional[str] = None
class UpdateFeedbackRequest(BaseModel):
feedback: Feedback
sessionId: str