diff --git a/rnd/autogpt_server/autogpt_server/blocks/basic.py b/rnd/autogpt_server/autogpt_server/blocks/basic.py index 6838f73c7..c0cb0c8ba 100644 --- a/rnd/autogpt_server/autogpt_server/blocks/basic.py +++ b/rnd/autogpt_server/autogpt_server/blocks/basic.py @@ -3,7 +3,13 @@ from typing import Any, Generic, List, TypeVar from pydantic import Field -from autogpt_server.data.block import Block, BlockCategory, BlockOutput, BlockSchema +from autogpt_server.data.block import ( + Block, + BlockCategory, + BlockOutput, + BlockSchema, + BlockUIType, +) from autogpt_server.data.model import SchemaField from autogpt_server.util.mock import MockObject @@ -174,17 +180,70 @@ class InputOutputBlockBase(Block, ABC, Generic[T]): yield "result", input_data.value -class InputBlock(InputOutputBlockBase[Any]): - def __init__(self): - super().__init__(categories={BlockCategory.INPUT, BlockCategory.BASIC}) +class InputBlock(Block): + """ + This block is used to provide input to the graph. - def block_id(self) -> str: - return "c0a8e994-ebf1-4a9c-a4d8-89d09c86741b" + It takes in a value, name, description, default values list and bool to limit selection to default values. + + It Outputs the value passed as input. + """ + + class Input(BlockSchema): + value: Any = SchemaField(description="The value to be passed as input.") + name: str = SchemaField(description="The name of the input.") + description: str = SchemaField(description="The description of the input.") + placeholder_values: List[Any] = SchemaField( + description="The placeholder values to be passed as input." + ) + limit_to_placeholder_values: bool = SchemaField( + description="Whether to limit the selection to placeholder values.", + default=False, + ) + + class Output(BlockSchema): + result: Any = SchemaField(description="The value passed as input.") + + def __init__(self): + super().__init__( + id="c0a8e994-ebf1-4a9c-a4d8-89d09c86741b", + description="This block is used to provide input to the graph.", + input_schema=InputBlock.Input, + output_schema=InputBlock.Output, + test_input=[ + { + "value": "Hello, World!", + "name": "input_1", + "description": "This is a test input.", + "placeholder_values": [], + "limit_to_placeholder_values": False, + }, + { + "value": "Hello, World!", + "name": "input_2", + "description": "This is a test input.", + "placeholder_values": ["Hello, World!"], + "limit_to_placeholder_values": True, + }, + ], + test_output=[ + ("result", "Hello, World!"), + ("result", "Hello, World!"), + ], + categories={BlockCategory.INPUT, BlockCategory.BASIC}, + ui_type=BlockUIType.INPUT, + ) + + def run(self, input_data: Input) -> BlockOutput: + yield "result", input_data.value class OutputBlock(InputOutputBlockBase[Any]): def __init__(self): - super().__init__(categories={BlockCategory.OUTPUT, BlockCategory.BASIC}) + super().__init__( + categories={BlockCategory.OUTPUT, BlockCategory.BASIC}, + ui_type=BlockUIType.OUTPUT, + ) def block_id(self) -> str: return "363ae599-353e-4804-937e-b2ee3cef3da4" @@ -323,3 +382,24 @@ class AddToListBlock(Block): yield "updated_list", updated_list except Exception as e: yield "error", f"Failed to add entry to list: {str(e)}" + + +class NoteBlock(Block): + class Input(BlockSchema): + text: str = SchemaField(description="The text to display in the sticky note.") + + class Output(BlockSchema): ... + + def __init__(self): + super().__init__( + id="31d1064e-7446-4693-o7d4-65e5ca9110d1", + description="This block is used to display a sticky note with the given text.", + categories={BlockCategory.BASIC}, + input_schema=NoteBlock.Input, + output_schema=NoteBlock.Output, + test_input={"text": "Hello, World!"}, + test_output=None, + ui_type=BlockUIType.NOTE, + ) + + def run(self, input_data: Input) -> BlockOutput: ... diff --git a/rnd/autogpt_server/autogpt_server/data/block.py b/rnd/autogpt_server/autogpt_server/data/block.py index 2d5637e66..0ecf56e49 100644 --- a/rnd/autogpt_server/autogpt_server/data/block.py +++ b/rnd/autogpt_server/autogpt_server/data/block.py @@ -16,6 +16,17 @@ BlockOutput = Generator[BlockData, None, None] # Output: 1 output pin produces CompletedBlockOutput = dict[str, list[Any]] # Completed stream, collected as a dict. +class BlockUIType(Enum): + """ + The type of Node UI to be displayed in the builder for this block. + """ + + STANDARD = "Standard" + INPUT = "Input" + OUTPUT = "Output" + NOTE = "Note" + + class BlockCategory(Enum): AI = "Block that leverages AI to perform a task." SOCIAL = "Block that interacts with social media platforms." @@ -134,6 +145,7 @@ class Block(ABC, Generic[BlockSchemaInputType, BlockSchemaOutputType]): test_mock: dict[str, Any] | None = None, disabled: bool = False, static_output: bool = False, + ui_type: BlockUIType = BlockUIType.STANDARD, ): """ Initialize the block with the given schema. @@ -163,6 +175,7 @@ class Block(ABC, Generic[BlockSchemaInputType, BlockSchemaOutputType]): self.contributors = contributors or set() self.disabled = disabled self.static_output = static_output + self.ui_type = ui_type @abstractmethod def run(self, input_data: BlockSchemaInputType) -> BlockOutput: @@ -193,6 +206,7 @@ class Block(ABC, Generic[BlockSchemaInputType, BlockSchemaOutputType]): contributor.model_dump() for contributor in self.contributors ], "staticOutput": self.static_output, + "uiType": self.ui_type.value, } def execute(self, input_data: BlockInput) -> BlockOutput: diff --git a/rnd/autogpt_server/autogpt_server/usecases/sample.py b/rnd/autogpt_server/autogpt_server/usecases/sample.py index a4ec519a0..6935e3fbc 100644 --- a/rnd/autogpt_server/autogpt_server/usecases/sample.py +++ b/rnd/autogpt_server/autogpt_server/usecases/sample.py @@ -20,20 +20,30 @@ async def create_test_user() -> User: def create_test_graph() -> graph.Graph: """ - StoreValueBlock + InputBlock \ ---- FillTextTemplateBlock ---- PrintToConsoleBlock / - StoreValueBlock + InputBlock """ nodes = [ graph.Node( block_id=InputBlock().id, - input_default={"name": "input_1"}, + input_default={ + "name": "input_1", + "description": "First input value", + "placeholder_values": [], + "limit_to_placeholder_values": False, + }, ), graph.Node( block_id=InputBlock().id, - input_default={"name": "input_2"}, + input_default={ + "name": "input_2", + "description": "Second input value", + "placeholder_values": [], + "limit_to_placeholder_values": False, + }, ), graph.Node( block_id=FillTextTemplateBlock().id, diff --git a/rnd/autogpt_server/test/executor/test_manager.py b/rnd/autogpt_server/test/executor/test_manager.py index 51debc789..40ba11c45 100644 --- a/rnd/autogpt_server/test/executor/test_manager.py +++ b/rnd/autogpt_server/test/executor/test_manager.py @@ -41,8 +41,20 @@ async def assert_sample_graph_executions( output_list = [{"result": ["Hello"]}, {"result": ["World"]}] input_list = [ - {"value": "Hello", "name": "input_1"}, - {"value": "World", "name": "input_2"}, + { + "name": "input_1", + "description": "First input value", + "placeholder_values": [], + "limit_to_placeholder_values": False, + "value": "Hello", + }, + { + "name": "input_2", + "description": "Second input value", + "placeholder_values": [], + "limit_to_placeholder_values": False, + "value": "World", + }, ] # Executing StoreValueBlock