chore: import upstream snapshot with attribution
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

This commit is contained in:
wehub-resource-sync
2026-07-13 12:48:47 +08:00
commit b7f52be4c9
653 changed files with 105877 additions and 0 deletions
+425
View File
@@ -0,0 +1,425 @@
from abc import abstractmethod
from datetime import date
from typing import Any, Dict, List, Literal, Optional
from pydantic import Field
from pydantic.dataclasses import dataclass
from chainlit.types import InputWidgetType
@dataclass
class InputWidget:
id: str
label: str
initial: Any = None
tooltip: Optional[str] = None
description: Optional[str] = None
disabled: Optional[bool] = False
def __post_init__(
self,
) -> None:
if not self.id or not self.label:
raise ValueError("Must provide key and label to load InputWidget")
@abstractmethod
def to_dict(self) -> Dict[str, Any]:
pass
@dataclass
class Switch(InputWidget):
"""Useful to create a switch input."""
type: InputWidgetType = "switch"
initial: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Slider(InputWidget):
"""Useful to create a slider input."""
type: InputWidgetType = "slider"
initial: float = 0
min: float = 0
max: float = 10
step: float = 1
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"min": self.min,
"max": self.max,
"step": self.step,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Select(InputWidget):
"""Useful to create a select input."""
type: InputWidgetType = "select"
initial: Optional[str] = None
initial_index: Optional[int] = None
initial_value: Optional[str] = None
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a Select")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a Select"
)
if not self.values and self.initial_index is not None:
raise ValueError(
"Initial_index can only be used in combination with values to create a Select"
)
if self.items:
self.initial = self.initial_value
elif self.values:
self.items = {value: value for value in self.values}
self.initial = (
self.values[self.initial_index]
if self.initial_index is not None
else self.initial_value
)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class TextInput(InputWidget):
"""Useful to create a text input."""
type: InputWidgetType = "textinput"
initial: Optional[str] = None
placeholder: Optional[str] = None
multiline: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"placeholder": self.placeholder,
"tooltip": self.tooltip,
"description": self.description,
"multiline": self.multiline,
"disabled": self.disabled,
}
@dataclass
class NumberInput(InputWidget):
"""Useful to create a number input."""
type: InputWidgetType = "numberinput"
initial: Optional[float] = None
placeholder: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"placeholder": self.placeholder,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Tags(InputWidget):
"""Useful to create an input for an array of strings."""
type: InputWidgetType = "tags"
initial: List[str] = Field(default_factory=list)
values: List[str] = Field(default_factory=list)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class MultiSelect(InputWidget):
"""Useful to create a multi-select input."""
type: InputWidgetType = "multiselect"
initial: List[str] = Field(default_factory=list)
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a MultiSelect")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a MultiSelect"
)
if self.values:
self.items = {value: value for value in self.values}
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Checkbox(InputWidget):
"""Useful to create a checkbox input."""
type: InputWidgetType = "checkbox"
initial: bool = False
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class RadioGroup(InputWidget):
"""Useful to create a radio button input."""
type: InputWidgetType = "radio"
initial: Optional[str] = None
initial_index: Optional[int] = None
initial_value: Optional[str] = None
values: List[str] = Field(default_factory=list)
items: Dict[str, str] = Field(default_factory=dict)
def __post_init__(
self,
) -> None:
super().__post_init__()
if not self.values and not self.items:
raise ValueError("Must provide values or items to create a RadioButton")
if self.values and self.items:
raise ValueError(
"You can only provide either values or items to create a RadioButton"
)
if not self.values and self.initial_index is not None:
raise ValueError(
"Initial_index can only be used in combination with values to create a RadioButton"
)
if self.items:
self.initial = self.initial_value
elif self.values:
self.items = {value: value for value in self.values}
self.initial = (
self.values[self.initial_index]
if self.initial_index is not None
else self.initial_value
)
def to_dict(self) -> Dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"initial": self.initial,
"items": [
{"label": id, "value": value} for id, value in self.items.items()
],
"tooltip": self.tooltip,
"description": self.description,
"disabled": self.disabled,
}
@dataclass
class Tab:
id: str
label: str
inputs: list[InputWidget] = Field(default_factory=list, exclude=True)
def to_dict(self) -> dict[str, Any]:
return {
"id": self.id,
"label": self.label,
"inputs": [input.to_dict() for input in self.inputs],
}
@dataclass
class DatePicker(InputWidget):
"""
Datepicker input widget.
Supports both single date and date range selection.
"""
type: InputWidgetType = "datepicker"
mode: Literal["single", "range"] = "single"
initial: str | date | tuple[str | date, str | date] | None = None
min_date: str | date | None = None
max_date: str | date | None = None
format: str | None = None
"""date-fns format string"""
placeholder: str | None = None
"""Placeholder to use when no date is selected"""
def __post_init__(self) -> None:
super().__post_init__()
if self.mode not in ("single", "range"):
raise ValueError("mode must be 'single' or 'range'")
if (
self.mode == "range"
and self.initial is not None
and not isinstance(self.initial, tuple)
):
raise ValueError("'initial' must be a tuple for range mode")
(initial_start, initial_end), min_date, max_date = (
[
DatePicker._validate_iso_format(date, "initial")
for date in (
self.initial
if isinstance(self.initial, tuple)
else [self.initial, None]
)
],
DatePicker._validate_iso_format(self.min_date, "min_date"),
DatePicker._validate_iso_format(self.max_date, "max_date"),
)
if self.mode == "range":
self._validate_range(initial_start, initial_end, "initial")
self._validate_range(min_date, max_date, "[min_date, max_date]")
# Validate that initial value(s) are within min_date and max_date bounds
for d in [initial_start, initial_end]:
if d is not None and (
(min_date is not None and d < min_date)
or (max_date is not None and d > max_date)
):
raise ValueError(
"'initial' must be within 'min_date' and 'max_date' bounds"
)
@staticmethod
def _validate_range(
start: date | None,
end: date | None,
field_name: str,
) -> None:
if start is not None and end is not None and start > end:
raise ValueError(
f"'{field_name}' range is invalid, start must be before end."
)
@staticmethod
def _validate_iso_format(
date_value: str | date | None, field_name: str
) -> date | None:
if isinstance(date_value, str):
try:
return date.fromisoformat(date_value)
except ValueError as e:
raise ValueError(f"'{field_name}' must be in ISO format") from e
return date_value
@staticmethod
def _format_date(date_value: str | date | None) -> str | None:
if isinstance(date_value, date):
return date_value.isoformat()
return date_value
def to_dict(self) -> dict[str, Any]:
return {
"type": self.type,
"id": self.id,
"label": self.label,
"tooltip": self.tooltip,
"description": self.description,
"mode": self.mode,
"initial": (
self._format_date(self.initial[0]),
self._format_date(self.initial[1]),
)
if isinstance(self.initial, tuple)
else DatePicker._format_date(self.initial),
"min_date": DatePicker._format_date(self.min_date),
"max_date": DatePicker._format_date(self.max_date),
"format": self.format,
"placeholder": self.placeholder,
"disabled": self.disabled,
}