diff --git a/dbgpt/core/awel/flow/ui.py b/dbgpt/core/awel/flow/ui.py index 875547e9a..c763859b0 100644 --- a/dbgpt/core/awel/flow/ui.py +++ b/dbgpt/core/awel/flow/ui.py @@ -11,6 +11,7 @@ "select", "cascader", "checkbox", + "radio", "date_picker", "input", "text_area", @@ -175,6 +176,12 @@ def check_parameter(self, parameter_dict: Dict[str, Any]): self._check_options(parameter_dict.get("options", {})) +class UIRadio(UICheckbox): + """Radio component.""" + + ui_type: Literal["radio"] = Field("radio", frozen=True) # type: ignore + + class UIDatePicker(UIComponent): """Date picker component.""" @@ -232,23 +239,31 @@ class UIAttribute(StatusMixin, UIComponent.UIAttribute): class UITextArea(PanelEditorMixin, UIInput): """Text area component.""" - class AutoSize(BaseModel): - """Auto size configuration.""" + class UIAttribute(UIInput.UIAttribute): + """Text area attribute.""" - min_rows: Optional[int] = Field( - None, - description="The minimum number of rows", - ) - max_rows: Optional[int] = Field( + class AutoSize(BaseModel): + """Auto size configuration.""" + + min_rows: Optional[int] = Field( + None, + description="The minimum number of rows", + ) + max_rows: Optional[int] = Field( + None, + description="The maximum number of rows", + ) + + auto_size: Optional[Union[bool, AutoSize]] = Field( None, - description="The maximum number of rows", + description="Whether the height of the textarea automatically adjusts " + "based on the content", ) ui_type: Literal["text_area"] = Field("text_area", frozen=True) # type: ignore - autosize: Optional[Union[bool, AutoSize]] = Field( + attr: Optional[UIAttribute] = Field( None, - description="Whether the height of the textarea automatically adjusts based " - "on the content", + description="The attributes of the component", ) @@ -430,8 +445,9 @@ class UICodeEditor(UITextArea): class DefaultUITextArea(UITextArea): """Default text area component.""" - autosize: Union[bool, UITextArea.AutoSize] = Field( - default_factory=lambda: UITextArea.AutoSize(min_rows=2, max_rows=40), - description="Whether the height of the textarea automatically adjusts based " - "on the content", + attr: Optional[UITextArea.UIAttribute] = Field( + default_factory=lambda: UITextArea.UIAttribute( + auto_size=UITextArea.UIAttribute.AutoSize(min_rows=2, max_rows=40) + ), + description="The attributes of the component", ) diff --git a/dbgpt/serve/flow/api/endpoints.py b/dbgpt/serve/flow/api/endpoints.py index 28c6a28c4..4b28641e8 100644 --- a/dbgpt/serve/flow/api/endpoints.py +++ b/dbgpt/serve/flow/api/endpoints.py @@ -1,20 +1,12 @@ import json from functools import cache -from typing import Dict, List, Literal, Optional, Union +from typing import Dict, List, Optional, Union from fastapi import APIRouter, Depends, HTTPException, Query, Request from fastapi.security.http import HTTPAuthorizationCredentials, HTTPBearer from dbgpt.component import SystemApp from dbgpt.core.awel.flow import ResourceMetadata, ViewMetadata -from dbgpt.core.interface.variables import ( - BUILTIN_VARIABLES_CORE_FLOW_NODES, - BUILTIN_VARIABLES_CORE_FLOWS, - BUILTIN_VARIABLES_CORE_SECRETS, - BUILTIN_VARIABLES_CORE_VARIABLES, - BuiltinVariablesProvider, - StorageVariables, -) from dbgpt.serve.core import Result, blocking_func_to_async from dbgpt.util import PaginationResult @@ -330,6 +322,12 @@ async def update_variables( return Result.succ(res) +@router.post("/flow/debug") +async def debug(): + """Debug the flow.""" + # TODO: Implement the debug endpoint + + def init_endpoints(system_app: SystemApp) -> None: """Initialize the endpoints""" from .variables_provider import ( diff --git a/dbgpt/serve/flow/api/schemas.py b/dbgpt/serve/flow/api/schemas.py index e63d3e6ce..537996fe7 100644 --- a/dbgpt/serve/flow/api/schemas.py +++ b/dbgpt/serve/flow/api/schemas.py @@ -1,6 +1,7 @@ -from typing import Any, List, Literal, Optional +from typing import Any, Dict, List, Literal, Optional, Union from dbgpt._private.pydantic import BaseModel, ConfigDict, Field +from dbgpt.core.awel import CommonLLMHttpRequestBody from dbgpt.core.awel.flow.flow_factory import FlowPanel from dbgpt.core.awel.util.parameter_util import RefreshOptionRequest @@ -113,3 +114,26 @@ class RefreshNodeRequest(BaseModel): title="The refresh options", description="The refresh options", ) + + +class FlowDebugRequest(BaseModel): + """Flow response model""" + + model_config = ConfigDict(title=f"FlowDebugRequest") + flow: ServeRequest = Field( + ..., + title="The flow to debug", + description="The flow to debug", + ) + request: Union[CommonLLMHttpRequestBody, Dict[str, Any]] = Field( + ..., + title="The request to debug", + description="The request to debug", + ) + variables: Optional[Dict[str, Any]] = Field( + None, + title="The variables to debug", + description="The variables to debug", + ) + user_name: Optional[str] = Field(None, description="User name") + sys_code: Optional[str] = Field(None, description="System code") diff --git a/examples/awel/awel_flow_ui_components.py b/examples/awel/awel_flow_ui_components.py index 9ce611c39..cba0c14df 100644 --- a/examples/awel/awel_flow_ui_components.py +++ b/examples/awel/awel_flow_ui_components.py @@ -206,7 +206,7 @@ class ExampleFlowCheckboxOperator(MapOperator[str, str]): OptionValue(label="Orange", name="orange", value="orange"), OptionValue(label="Pear", name="pear", value="pear"), ], - ui=ui.UICheckbox(attr=ui.UICheckbox.UIAttribute(show_search=True)), + ui=ui.UICheckbox(), ) ], inputs=[ @@ -236,6 +236,59 @@ async def map(self, user_name: str) -> str: return "Your name is %s, and you like %s." % (user_name, ", ".join(self.fruits)) +class ExampleFlowRadioOperator(MapOperator[str, str]): + """An example flow operator that includes a radio as parameter.""" + + metadata = ViewMetadata( + label="Example Flow Radio", + name="example_flow_radio", + category=OperatorCategory.EXAMPLE, + description="An example flow operator that includes a radio as parameter.", + parameters=[ + Parameter.build_from( + "Fruits Selector", + "fruits", + type=str, + optional=True, + default=None, + placeholder="Select the fruits", + description="The fruits you like.", + options=[ + OptionValue(label="Apple", name="apple", value="apple"), + OptionValue(label="Banana", name="banana", value="banana"), + OptionValue(label="Orange", name="orange", value="orange"), + OptionValue(label="Pear", name="pear", value="pear"), + ], + ui=ui.UIRadio(), + ) + ], + inputs=[ + IOField.build_from( + "User Name", + "user_name", + str, + description="The name of the user.", + ) + ], + outputs=[ + IOField.build_from( + "Fruits", + "fruits", + str, + description="User's favorite fruits.", + ) + ], + ) + + def __init__(self, fruits: Optional[str] = None, **kwargs): + super().__init__(**kwargs) + self.fruits = fruits + + async def map(self, user_name: str) -> str: + """Map the user name to the fruits.""" + return "Your name is %s, and you like %s." % (user_name, self.fruits) + + class ExampleFlowDatePickerOperator(MapOperator[str, str]): """An example flow operator that includes a date picker as parameter.""" @@ -348,8 +401,13 @@ class ExampleFlowTextAreaOperator(MapOperator[str, str]): placeholder="Please input your comment", description="The comment you want to say.", ui=ui.UITextArea( - attr=ui.UITextArea.UIAttribute(show_count=True, maxlength=1000), - autosize=ui.UITextArea.AutoSize(min_rows=2, max_rows=6), + attr=ui.UITextArea.UIAttribute( + show_count=True, + maxlength=1000, + auto_size=ui.UITextArea.UIAttribute.AutoSize( + min_rows=2, max_rows=6 + ), + ), ), ) ],