feat(backend): Standardize error handling with BlockSchemaInput & BlockSchemaOutput base class (#11257)

<!-- Clearly explain the need for these changes: -->

This PR addresses the need for consistent error handling across all
blocks in the AutoGPT platform. Previously, each block had to manually
define an `error` field in their output schema, leading to code
duplication and potential inconsistencies. Some blocks might forget to
include the error field, making error handling unpredictable.

### Changes 🏗️

<!-- Concisely describe all of the changes made in this pull request:
-->

- **Created `BlockSchemaOutput` base class**: New base class that
extends `BlockSchema` with a standardized `error` field
- **Created `BlockSchemaInput` base class**: Added for consistency and
future extensibility
- **Updated 140+ block implementations**: Changed all block `Output`
classes from `class Output(BlockSchema):` to `class
Output(BlockSchemaOutput):`
- **Removed manual error field definitions**: Eliminated hundreds of
duplicate `error: str = SchemaField(...)` definitions
- **Updated type annotations**: Changed `Block[BlockSchema,
BlockSchema]` to `Block[BlockSchemaInput, BlockSchemaOutput]` throughout
the codebase
- **Fixed imports**: Added `BlockSchemaInput` and `BlockSchemaOutput`
imports to all relevant files
- **Maintained backward compatibility**: Updated `EmptySchema` to
inherit from `BlockSchemaOutput`

**Key Benefits:**
- Consistent error handling across all blocks
- Reduced code duplication (removed ~200 lines of repetitive error field
definitions)
- Type safety improvements with distinct input/output schema types
- Blocks can still override error field with more specific descriptions
when needed

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  <!-- Put your test plan here: -->
- [x] Verified `poetry run format` passes (all linting, formatting, and
type checking)
- [x] Tested block instantiation works correctly (MediaDurationBlock,
UnrealTextToSpeechBlock)
- [x] Confirmed error fields are automatically present in all updated
blocks
- [x] Verified block loading system works (successfully loads 353+
blocks)
  - [x] Tested backward compatibility with EmptySchema
- [x] Confirmed blocks can still override error field with custom
descriptions
  - [x] Validated core schema inheritance chain works correctly

#### For configuration changes:

- [x] `.env.default` is updated or already compatible with my changes
- [x] `docker-compose.yml` is updated or already compatible with my
changes
- [x] I have included a list of my configuration changes in the PR
description (under **Changes**)

*Note: No configuration changes were needed for this refactoring.*

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Lluis Agusti <hi@llu.lu>
Co-authored-by: Ubbe <hi@ubbe.dev>
This commit is contained in:
Zamil Majdy
2025-10-30 19:28:08 +07:00
committed by GitHub
parent 3dc5208f71
commit 2f8cdf62ba
164 changed files with 1678 additions and 1074 deletions

View File

@@ -7,6 +7,7 @@ from backend.data.block import (
BlockInput, BlockInput,
BlockOutput, BlockOutput,
BlockSchema, BlockSchema,
BlockSchemaInput,
BlockType, BlockType,
get_block, get_block,
) )
@@ -19,7 +20,7 @@ _logger = logging.getLogger(__name__)
class AgentExecutorBlock(Block): class AgentExecutorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
user_id: str = SchemaField(description="User ID") user_id: str = SchemaField(description="User ID")
graph_id: str = SchemaField(description="Graph ID") graph_id: str = SchemaField(description="Graph ID")
graph_version: int = SchemaField(description="Graph Version") graph_version: int = SchemaField(description="Graph Version")
@@ -53,6 +54,7 @@ class AgentExecutorBlock(Block):
return validate_with_jsonschema(cls.get_input_schema(data), data) return validate_with_jsonschema(cls.get_input_schema(data), data)
class Output(BlockSchema): class Output(BlockSchema):
# Use BlockSchema to avoid automatic error field that could clash with graph outputs
pass pass
def __init__(self): def __init__(self):

View File

@@ -10,7 +10,12 @@ from backend.blocks.llm import (
LLMResponse, LLMResponse,
llm_call, llm_call,
) )
from backend.data.block import BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import APIKeyCredentials, NodeExecutionStats, SchemaField from backend.data.model import APIKeyCredentials, NodeExecutionStats, SchemaField
@@ -23,7 +28,7 @@ class AIConditionBlock(AIBlockBase):
It provides the same yes/no data pass-through functionality as the standard ConditionBlock. It provides the same yes/no data pass-through functionality as the standard ConditionBlock.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
input_value: Any = SchemaField( input_value: Any = SchemaField(
description="The input value to evaluate with the AI condition", description="The input value to evaluate with the AI condition",
placeholder="Enter the value to be evaluated (text, number, or any data)", placeholder="Enter the value to be evaluated (text, number, or any data)",
@@ -50,7 +55,7 @@ class AIConditionBlock(AIBlockBase):
) )
credentials: AICredentials = AICredentialsField() credentials: AICredentials = AICredentialsField()
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: bool = SchemaField( result: bool = SchemaField(
description="The result of the AI condition evaluation (True or False)" description="The result of the AI condition evaluation (True or False)"
) )

View File

@@ -5,7 +5,13 @@ from pydantic import SecretStr
from replicate.client import Client as ReplicateClient from replicate.client import Client as ReplicateClient
from replicate.helpers import FileOutput from replicate.helpers import FileOutput
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -42,7 +48,7 @@ TEST_CREDENTIALS_INPUT = {
class AIImageCustomizerBlock(Block): class AIImageCustomizerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REPLICATE], Literal["api_key"] Literal[ProviderName.REPLICATE], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -68,9 +74,8 @@ class AIImageCustomizerBlock(Block):
title="Output Format", title="Output Format",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
image_url: MediaFileType = SchemaField(description="URL of the generated image") image_url: MediaFileType = SchemaField(description="URL of the generated image")
error: str = SchemaField(description="Error message if generation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -5,7 +5,7 @@ from pydantic import SecretStr
from replicate.client import Client as ReplicateClient from replicate.client import Client as ReplicateClient
from replicate.helpers import FileOutput from replicate.helpers import FileOutput
from backend.data.block import Block, BlockCategory, BlockSchema from backend.data.block import Block, BlockCategory, BlockSchemaInput, BlockSchemaOutput
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -101,7 +101,7 @@ class ImageGenModel(str, Enum):
class AIImageGeneratorBlock(Block): class AIImageGeneratorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REPLICATE], Literal["api_key"] Literal[ProviderName.REPLICATE], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -135,9 +135,8 @@ class AIImageGeneratorBlock(Block):
title="Image Style", title="Image Style",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
image_url: str = SchemaField(description="URL of the generated image") image_url: str = SchemaField(description="URL of the generated image")
error: str = SchemaField(description="Error message if generation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -6,7 +6,13 @@ from typing import Literal
from pydantic import SecretStr from pydantic import SecretStr
from replicate.client import Client as ReplicateClient from replicate.client import Client as ReplicateClient
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -54,7 +60,7 @@ class NormalizationStrategy(str, Enum):
class AIMusicGeneratorBlock(Block): class AIMusicGeneratorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REPLICATE], Literal["api_key"] Literal[ProviderName.REPLICATE], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -107,9 +113,8 @@ class AIMusicGeneratorBlock(Block):
title="Normalization Strategy", title="Normalization Strategy",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: str = SchemaField(description="URL of the generated audio file") result: str = SchemaField(description="URL of the generated audio file")
error: str = SchemaField(description="Error message if the model run failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -6,7 +6,13 @@ from typing import Literal
from pydantic import SecretStr from pydantic import SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -148,7 +154,7 @@ logger = logging.getLogger(__name__)
class AIShortformVideoCreatorBlock(Block): class AIShortformVideoCreatorBlock(Block):
"""Creates a shortform texttovideo clip using stock or AI imagery.""" """Creates a shortform texttovideo clip using stock or AI imagery."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REVID], Literal["api_key"] Literal[ProviderName.REVID], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -187,9 +193,8 @@ class AIShortformVideoCreatorBlock(Block):
placeholder=VisualMediaType.STOCK_VIDEOS, placeholder=VisualMediaType.STOCK_VIDEOS,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_url: str = SchemaField(description="The URL of the created video") video_url: str = SchemaField(description="The URL of the created video")
error: str = SchemaField(description="Error message if the request failed")
async def create_webhook(self) -> tuple[str, str]: async def create_webhook(self) -> tuple[str, str]:
"""Create a new webhook URL for receiving notifications.""" """Create a new webhook URL for receiving notifications."""
@@ -336,7 +341,7 @@ class AIShortformVideoCreatorBlock(Block):
class AIAdMakerVideoCreatorBlock(Block): class AIAdMakerVideoCreatorBlock(Block):
"""Generates a 30second vertical AI advert using optional usersupplied imagery.""" """Generates a 30second vertical AI advert using optional usersupplied imagery."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REVID], Literal["api_key"] Literal[ProviderName.REVID], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -364,9 +369,8 @@ class AIAdMakerVideoCreatorBlock(Block):
description="Restrict visuals to supplied images only.", default=True description="Restrict visuals to supplied images only.", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_url: str = SchemaField(description="URL of the finished advert") video_url: str = SchemaField(description="URL of the finished advert")
error: str = SchemaField(description="Error message on failure")
async def create_webhook(self) -> tuple[str, str]: async def create_webhook(self) -> tuple[str, str]:
"""Create a new webhook URL for receiving notifications.""" """Create a new webhook URL for receiving notifications."""
@@ -524,7 +528,7 @@ class AIAdMakerVideoCreatorBlock(Block):
class AIScreenshotToVideoAdBlock(Block): class AIScreenshotToVideoAdBlock(Block):
"""Creates an advert where the supplied screenshot is narrated by an AI avatar.""" """Creates an advert where the supplied screenshot is narrated by an AI avatar."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REVID], Literal["api_key"] Literal[ProviderName.REVID], Literal["api_key"]
] = CredentialsField(description="Revid.ai API key") ] = CredentialsField(description="Revid.ai API key")
@@ -542,9 +546,8 @@ class AIScreenshotToVideoAdBlock(Block):
default=AudioTrack.DONT_STOP_ME_ABSTRACT_FUTURE_BASS default=AudioTrack.DONT_STOP_ME_ABSTRACT_FUTURE_BASS
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_url: str = SchemaField(description="Rendered video URL") video_url: str = SchemaField(description="Rendered video URL")
error: str = SchemaField(description="Error, if encountered")
async def create_webhook(self) -> tuple[str, str]: async def create_webhook(self) -> tuple[str, str]:
"""Create a new webhook URL for receiving notifications.""" """Create a new webhook URL for receiving notifications."""

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -23,7 +24,7 @@ class AirtableCreateBaseBlock(Block):
Creates a new base in an Airtable workspace, or returns existing base if one with the same name exists. Creates a new base in an Airtable workspace, or returns existing base if one with the same name exists.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -53,7 +54,7 @@ class AirtableCreateBaseBlock(Block):
], ],
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
base_id: str = SchemaField(description="The ID of the created or found base") base_id: str = SchemaField(description="The ID of the created or found base")
tables: list[dict] = SchemaField(description="Array of table objects") tables: list[dict] = SchemaField(description="Array of table objects")
table: dict = SchemaField(description="A single table object") table: dict = SchemaField(description="A single table object")
@@ -118,7 +119,7 @@ class AirtableListBasesBlock(Block):
Lists all bases in an Airtable workspace that the user has access to. Lists all bases in an Airtable workspace that the user has access to.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -129,7 +130,7 @@ class AirtableListBasesBlock(Block):
description="Pagination offset from previous request", default="" description="Pagination offset from previous request", default=""
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
bases: list[dict] = SchemaField(description="Array of base objects") bases: list[dict] = SchemaField(description="Array of base objects")
offset: Optional[str] = SchemaField( offset: Optional[str] = SchemaField(
description="Offset for next page (null if no more bases)", default=None description="Offset for next page (null if no more bases)", default=None

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -31,7 +32,7 @@ class AirtableListRecordsBlock(Block):
Lists records from an Airtable table with optional filtering, sorting, and pagination. Lists records from an Airtable table with optional filtering, sorting, and pagination.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -65,7 +66,7 @@ class AirtableListRecordsBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
records: list[dict] = SchemaField(description="Array of record objects") records: list[dict] = SchemaField(description="Array of record objects")
offset: Optional[str] = SchemaField( offset: Optional[str] = SchemaField(
description="Offset for next page (null if no more records)", default=None description="Offset for next page (null if no more records)", default=None
@@ -137,7 +138,7 @@ class AirtableGetRecordBlock(Block):
Retrieves a single record from an Airtable table by its ID. Retrieves a single record from an Airtable table by its ID.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -153,7 +154,7 @@ class AirtableGetRecordBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
id: str = SchemaField(description="The record ID") id: str = SchemaField(description="The record ID")
fields: dict = SchemaField(description="The record fields") fields: dict = SchemaField(description="The record fields")
created_time: str = SchemaField(description="The record created time") created_time: str = SchemaField(description="The record created time")
@@ -217,7 +218,7 @@ class AirtableCreateRecordsBlock(Block):
Creates one or more records in an Airtable table. Creates one or more records in an Airtable table.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -239,7 +240,7 @@ class AirtableCreateRecordsBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
records: list[dict] = SchemaField(description="Array of created record objects") records: list[dict] = SchemaField(description="Array of created record objects")
details: dict = SchemaField(description="Details of the created records") details: dict = SchemaField(description="Details of the created records")
@@ -290,7 +291,7 @@ class AirtableUpdateRecordsBlock(Block):
Updates one or more existing records in an Airtable table. Updates one or more existing records in an Airtable table.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -306,7 +307,7 @@ class AirtableUpdateRecordsBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
records: list[dict] = SchemaField(description="Array of updated record objects") records: list[dict] = SchemaField(description="Array of updated record objects")
def __init__(self): def __init__(self):
@@ -339,7 +340,7 @@ class AirtableDeleteRecordsBlock(Block):
Deletes one or more records from an Airtable table. Deletes one or more records from an Airtable table.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -351,7 +352,7 @@ class AirtableDeleteRecordsBlock(Block):
description="Array of upto 10 record IDs to delete" description="Array of upto 10 record IDs to delete"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
records: list[dict] = SchemaField(description="Array of deletion results") records: list[dict] = SchemaField(description="Array of deletion results")
def __init__(self): def __init__(self):

View File

@@ -7,7 +7,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -23,13 +24,13 @@ class AirtableListSchemaBlock(Block):
fields, and views. fields, and views.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
base_id: str = SchemaField(description="The Airtable base ID") base_id: str = SchemaField(description="The Airtable base ID")
class Output(BlockSchema): class Output(BlockSchemaOutput):
base_schema: dict = SchemaField( base_schema: dict = SchemaField(
description="Complete base schema with tables, fields, and views" description="Complete base schema with tables, fields, and views"
) )
@@ -66,7 +67,7 @@ class AirtableCreateTableBlock(Block):
Creates a new table in an Airtable base with specified fields and views. Creates a new table in an Airtable base with specified fields and views.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -77,7 +78,7 @@ class AirtableCreateTableBlock(Block):
default=[{"name": "Name", "type": "singleLineText"}], default=[{"name": "Name", "type": "singleLineText"}],
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
table: dict = SchemaField(description="Created table object") table: dict = SchemaField(description="Created table object")
table_id: str = SchemaField(description="ID of the created table") table_id: str = SchemaField(description="ID of the created table")
@@ -109,7 +110,7 @@ class AirtableUpdateTableBlock(Block):
Updates an existing table's properties such as name or description. Updates an existing table's properties such as name or description.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -125,7 +126,7 @@ class AirtableUpdateTableBlock(Block):
description="The date dependency of the table to update", default=None description="The date dependency of the table to update", default=None
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
table: dict = SchemaField(description="Updated table object") table: dict = SchemaField(description="Updated table object")
def __init__(self): def __init__(self):
@@ -157,7 +158,7 @@ class AirtableCreateFieldBlock(Block):
Adds a new field (column) to an existing Airtable table. Adds a new field (column) to an existing Airtable table.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -176,7 +177,7 @@ class AirtableCreateFieldBlock(Block):
description="The options of the field to create", default=None description="The options of the field to create", default=None
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
field: dict = SchemaField(description="Created field object") field: dict = SchemaField(description="Created field object")
field_id: str = SchemaField(description="ID of the created field") field_id: str = SchemaField(description="ID of the created field")
@@ -209,7 +210,7 @@ class AirtableUpdateFieldBlock(Block):
Updates an existing field's properties in an Airtable table. Updates an existing field's properties in an Airtable table.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -225,7 +226,7 @@ class AirtableUpdateFieldBlock(Block):
advanced=False, advanced=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
field: dict = SchemaField(description="Updated field object") field: dict = SchemaField(description="Updated field object")
def __init__(self): def __init__(self):

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
BlockType, BlockType,
BlockWebhookConfig, BlockWebhookConfig,
CredentialsMetaInput, CredentialsMetaInput,
@@ -32,7 +33,7 @@ class AirtableWebhookTriggerBlock(Block):
Thin wrapper just forwards the payloads one at a time to the next block. Thin wrapper just forwards the payloads one at a time to the next block.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = airtable.credentials_field( credentials: CredentialsMetaInput = airtable.credentials_field(
description="Airtable API credentials" description="Airtable API credentials"
) )
@@ -43,7 +44,7 @@ class AirtableWebhookTriggerBlock(Block):
description="Airtable webhook event filter" description="Airtable webhook event filter"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
payload: WebhookPayload = SchemaField(description="Airtable webhook payload") payload: WebhookPayload = SchemaField(description="Airtable webhook payload")
def __init__(self): def __init__(self):

View File

@@ -10,14 +10,20 @@ from backend.blocks.apollo.models import (
PrimaryPhone, PrimaryPhone,
SearchOrganizationsRequest, SearchOrganizationsRequest,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import CredentialsField, SchemaField from backend.data.model import CredentialsField, SchemaField
class SearchOrganizationsBlock(Block): class SearchOrganizationsBlock(Block):
"""Search for organizations in Apollo""" """Search for organizations in Apollo"""
class Input(BlockSchema): class Input(BlockSchemaInput):
organization_num_employees_range: list[int] = SchemaField( organization_num_employees_range: list[int] = SchemaField(
description="""The number range of employees working for the company. This enables you to find companies based on headcount. You can add multiple ranges to expand your search results. description="""The number range of employees working for the company. This enables you to find companies based on headcount. You can add multiple ranges to expand your search results.
@@ -69,7 +75,7 @@ To find IDs, identify the values for organization_id when you call this endpoint
description="Apollo credentials", description="Apollo credentials",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
organizations: list[Organization] = SchemaField( organizations: list[Organization] = SchemaField(
description="List of organizations found", description="List of organizations found",
default_factory=list, default_factory=list,

View File

@@ -14,14 +14,20 @@ from backend.blocks.apollo.models import (
SearchPeopleRequest, SearchPeopleRequest,
SenorityLevels, SenorityLevels,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import CredentialsField, SchemaField from backend.data.model import CredentialsField, SchemaField
class SearchPeopleBlock(Block): class SearchPeopleBlock(Block):
"""Search for people in Apollo""" """Search for people in Apollo"""
class Input(BlockSchema): class Input(BlockSchemaInput):
person_titles: list[str] = SchemaField( person_titles: list[str] = SchemaField(
description="""Job titles held by the people you want to find. For a person to be included in search results, they only need to match 1 of the job titles you add. Adding more job titles expands your search results. description="""Job titles held by the people you want to find. For a person to be included in search results, they only need to match 1 of the job titles you add. Adding more job titles expands your search results.
@@ -109,7 +115,7 @@ class SearchPeopleBlock(Block):
description="Apollo credentials", description="Apollo credentials",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
people: list[Contact] = SchemaField( people: list[Contact] = SchemaField(
description="List of people found", description="List of people found",
default_factory=list, default_factory=list,

View File

@@ -6,14 +6,20 @@ from backend.blocks.apollo._auth import (
ApolloCredentialsInput, ApolloCredentialsInput,
) )
from backend.blocks.apollo.models import Contact, EnrichPersonRequest from backend.blocks.apollo.models import Contact, EnrichPersonRequest
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import CredentialsField, SchemaField from backend.data.model import CredentialsField, SchemaField
class GetPersonDetailBlock(Block): class GetPersonDetailBlock(Block):
"""Get detailed person data with Apollo API, including email reveal""" """Get detailed person data with Apollo API, including email reveal"""
class Input(BlockSchema): class Input(BlockSchemaInput):
person_id: str = SchemaField( person_id: str = SchemaField(
description="Apollo person ID to enrich (most accurate method)", description="Apollo person ID to enrich (most accurate method)",
default="", default="",
@@ -68,7 +74,7 @@ class GetPersonDetailBlock(Block):
description="Apollo credentials", description="Apollo credentials",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
contact: Contact = SchemaField( contact: Contact = SchemaField(
description="Enriched contact information", description="Enriched contact information",
) )

View File

@@ -3,7 +3,7 @@ from typing import Optional
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from backend.data.block import BlockSchema from backend.data.block import BlockSchemaInput
from backend.data.model import SchemaField, UserIntegrations from backend.data.model import SchemaField, UserIntegrations
from backend.integrations.ayrshare import AyrshareClient from backend.integrations.ayrshare import AyrshareClient
from backend.util.clients import get_database_manager_async_client from backend.util.clients import get_database_manager_async_client
@@ -17,7 +17,7 @@ async def get_profile_key(user_id: str):
return user_integrations.managed_credentials.ayrshare_profile_key return user_integrations.managed_credentials.ayrshare_profile_key
class BaseAyrshareInput(BlockSchema): class BaseAyrshareInput(BlockSchemaInput):
"""Base input model for Ayrshare social media posts with common fields.""" """Base input model for Ayrshare social media posts with common fields."""
post: str = SchemaField( post: str = SchemaField(

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -38,7 +38,7 @@ class PostToBlueskyBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -101,7 +101,7 @@ class PostToFacebookBlock(Block):
description="URL for custom link preview", default="", advanced=True description="URL for custom link preview", default="", advanced=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -94,7 +94,7 @@ class PostToGMBBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -5,7 +5,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -94,7 +94,7 @@ class PostToInstagramBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -94,7 +94,7 @@ class PostToLinkedInBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -73,7 +73,7 @@ class PostToPinterestBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -19,7 +19,7 @@ class PostToRedditBlock(Block):
pass # Uses all base fields pass # Uses all base fields
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -43,7 +43,7 @@ class PostToSnapchatBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -38,7 +38,7 @@ class PostToTelegramBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -31,7 +31,7 @@ class PostToThreadsBlock(Block):
advanced=False, advanced=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -5,7 +5,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -98,7 +98,7 @@ class PostToTikTokBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -3,7 +3,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -97,7 +97,7 @@ class PostToXBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -6,7 +6,7 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaOutput,
BlockType, BlockType,
SchemaField, SchemaField,
) )
@@ -119,7 +119,7 @@ class PostToYouTubeBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_result: PostResponse = SchemaField(description="The result of the post") post_result: PostResponse = SchemaField(description="The result of the post")
post: PostIds = SchemaField(description="The result of the post") post: PostIds = SchemaField(description="The result of the post")

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -23,7 +24,7 @@ class BaasBotJoinMeetingBlock(Block):
Deploy a bot immediately or at a scheduled start_time to join and record a meeting. Deploy a bot immediately or at a scheduled start_time to join and record a meeting.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = baas.credentials_field( credentials: CredentialsMetaInput = baas.credentials_field(
description="Meeting BaaS API credentials" description="Meeting BaaS API credentials"
) )
@@ -57,7 +58,7 @@ class BaasBotJoinMeetingBlock(Block):
description="Custom metadata to attach to the bot", default={} description="Custom metadata to attach to the bot", default={}
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
bot_id: str = SchemaField(description="UUID of the deployed bot") bot_id: str = SchemaField(description="UUID of the deployed bot")
join_response: dict = SchemaField( join_response: dict = SchemaField(
description="Full response from join operation" description="Full response from join operation"
@@ -103,13 +104,13 @@ class BaasBotLeaveMeetingBlock(Block):
Force the bot to exit the call. Force the bot to exit the call.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = baas.credentials_field( credentials: CredentialsMetaInput = baas.credentials_field(
description="Meeting BaaS API credentials" description="Meeting BaaS API credentials"
) )
bot_id: str = SchemaField(description="UUID of the bot to remove from meeting") bot_id: str = SchemaField(description="UUID of the bot to remove from meeting")
class Output(BlockSchema): class Output(BlockSchemaOutput):
left: bool = SchemaField(description="Whether the bot successfully left") left: bool = SchemaField(description="Whether the bot successfully left")
def __init__(self): def __init__(self):
@@ -138,7 +139,7 @@ class BaasBotFetchMeetingDataBlock(Block):
Pull MP4 URL, transcript & metadata for a completed meeting. Pull MP4 URL, transcript & metadata for a completed meeting.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = baas.credentials_field( credentials: CredentialsMetaInput = baas.credentials_field(
description="Meeting BaaS API credentials" description="Meeting BaaS API credentials"
) )
@@ -147,7 +148,7 @@ class BaasBotFetchMeetingDataBlock(Block):
description="Include transcript data in response", default=True description="Include transcript data in response", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
mp4_url: str = SchemaField( mp4_url: str = SchemaField(
description="URL to download the meeting recording (time-limited)" description="URL to download the meeting recording (time-limited)"
) )
@@ -185,13 +186,13 @@ class BaasBotDeleteRecordingBlock(Block):
Purge MP4 + transcript data for privacy or storage management. Purge MP4 + transcript data for privacy or storage management.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = baas.credentials_field( credentials: CredentialsMetaInput = baas.credentials_field(
description="Meeting BaaS API credentials" description="Meeting BaaS API credentials"
) )
bot_id: str = SchemaField(description="UUID of the bot whose data to delete") bot_id: str = SchemaField(description="UUID of the bot whose data to delete")
class Output(BlockSchema): class Output(BlockSchemaOutput):
deleted: bool = SchemaField( deleted: bool = SchemaField(
description="Whether the data was successfully deleted" description="Whether the data was successfully deleted"
) )

View File

@@ -11,7 +11,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -27,7 +28,7 @@ TEST_CREDENTIALS = APIKeyCredentials(
) )
class TextModification(BlockSchema): class TextModification(BlockSchemaInput):
name: str = SchemaField( name: str = SchemaField(
description="The name of the layer to modify in the template" description="The name of the layer to modify in the template"
) )
@@ -60,7 +61,7 @@ class TextModification(BlockSchema):
class BannerbearTextOverlayBlock(Block): class BannerbearTextOverlayBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = bannerbear.credentials_field( credentials: CredentialsMetaInput = bannerbear.credentials_field(
description="API credentials for Bannerbear" description="API credentials for Bannerbear"
) )
@@ -96,7 +97,7 @@ class BannerbearTextOverlayBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
success: bool = SchemaField( success: bool = SchemaField(
description="Whether the image generation was successfully initiated" description="Whether the image generation was successfully initiated"
) )
@@ -105,7 +106,6 @@ class BannerbearTextOverlayBlock(Block):
) )
uid: str = SchemaField(description="Unique identifier for the generated image") uid: str = SchemaField(description="Unique identifier for the generated image")
status: str = SchemaField(description="Status of the image generation") status: str = SchemaField(description="Status of the image generation")
error: str = SchemaField(description="Error message if the operation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -1,14 +1,21 @@
import enum import enum
from typing import Any from typing import Any
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema, BlockType from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
BlockType,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.file import store_media_file from backend.util.file import store_media_file
from backend.util.type import MediaFileType, convert from backend.util.type import MediaFileType, convert
class FileStoreBlock(Block): class FileStoreBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
file_in: MediaFileType = SchemaField( file_in: MediaFileType = SchemaField(
description="The file to store in the temporary directory, it can be a URL, data URI, or local path." description="The file to store in the temporary directory, it can be a URL, data URI, or local path."
) )
@@ -19,7 +26,7 @@ class FileStoreBlock(Block):
title="Produce Base64 Output", title="Produce Base64 Output",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
file_out: MediaFileType = SchemaField( file_out: MediaFileType = SchemaField(
description="The relative path to the stored file in the temporary directory." description="The relative path to the stored file in the temporary directory."
) )
@@ -57,7 +64,7 @@ class StoreValueBlock(Block):
The block output will be static, the output can be consumed multiple times. The block output will be static, the output can be consumed multiple times.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
input: Any = SchemaField( input: Any = SchemaField(
description="Trigger the block to produce the output. " description="Trigger the block to produce the output. "
"The value is only used when `data` is None." "The value is only used when `data` is None."
@@ -68,7 +75,7 @@ class StoreValueBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
output: Any = SchemaField(description="The stored data retained in the block.") output: Any = SchemaField(description="The stored data retained in the block.")
def __init__(self): def __init__(self):
@@ -94,10 +101,10 @@ class StoreValueBlock(Block):
class PrintToConsoleBlock(Block): class PrintToConsoleBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: Any = SchemaField(description="The data to print to the console.") text: Any = SchemaField(description="The data to print to the console.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
output: Any = SchemaField(description="The data printed to the console.") output: Any = SchemaField(description="The data printed to the console.")
status: str = SchemaField(description="The status of the print operation.") status: str = SchemaField(description="The status of the print operation.")
@@ -121,10 +128,10 @@ class PrintToConsoleBlock(Block):
class NoteBlock(Block): class NoteBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: str = SchemaField(description="The text to display in the sticky note.") text: str = SchemaField(description="The text to display in the sticky note.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
output: str = SchemaField(description="The text to display in the sticky note.") output: str = SchemaField(description="The text to display in the sticky note.")
def __init__(self): def __init__(self):
@@ -154,15 +161,14 @@ class TypeOptions(enum.Enum):
class UniversalTypeConverterBlock(Block): class UniversalTypeConverterBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
value: Any = SchemaField( value: Any = SchemaField(
description="The value to convert to a universal type." description="The value to convert to a universal type."
) )
type: TypeOptions = SchemaField(description="The type to convert the value to.") type: TypeOptions = SchemaField(description="The type to convert the value to.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
value: Any = SchemaField(description="The converted value.") value: Any = SchemaField(description="The converted value.")
error: str = SchemaField(description="Error message if conversion failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -195,10 +201,10 @@ class ReverseListOrderBlock(Block):
A block which takes in a list and returns it in the opposite order. A block which takes in a list and returns it in the opposite order.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
input_list: list[Any] = SchemaField(description="The list to reverse") input_list: list[Any] = SchemaField(description="The list to reverse")
class Output(BlockSchema): class Output(BlockSchemaOutput):
reversed_list: list[Any] = SchemaField(description="The list in reversed order") reversed_list: list[Any] = SchemaField(description="The list in reversed order")
def __init__(self): def __init__(self):

View File

@@ -2,7 +2,13 @@ import os
import re import re
from typing import Type from typing import Type
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
@@ -15,12 +21,12 @@ class BlockInstallationBlock(Block):
for development purposes only. for development purposes only.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
code: str = SchemaField( code: str = SchemaField(
description="Python code of the block to be installed", description="Python code of the block to be installed",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
success: str = SchemaField( success: str = SchemaField(
description="Success message if the block is installed successfully", description="Success message if the block is installed successfully",
) )

View File

@@ -1,7 +1,13 @@
from enum import Enum from enum import Enum
from typing import Any from typing import Any
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.type import convert from backend.util.type import convert
@@ -16,7 +22,7 @@ class ComparisonOperator(Enum):
class ConditionBlock(Block): class ConditionBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
value1: Any = SchemaField( value1: Any = SchemaField(
description="Enter the first value for comparison", description="Enter the first value for comparison",
placeholder="For example: 10 or 'hello' or True", placeholder="For example: 10 or 'hello' or True",
@@ -40,7 +46,7 @@ class ConditionBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: bool = SchemaField( result: bool = SchemaField(
description="The result of the condition evaluation (True or False)" description="The result of the condition evaluation (True or False)"
) )
@@ -111,7 +117,7 @@ class ConditionBlock(Block):
class IfInputMatchesBlock(Block): class IfInputMatchesBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
input: Any = SchemaField( input: Any = SchemaField(
description="The input to match against", description="The input to match against",
placeholder="For example: 10 or 'hello' or True", placeholder="For example: 10 or 'hello' or True",
@@ -131,7 +137,7 @@ class IfInputMatchesBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: bool = SchemaField( result: bool = SchemaField(
description="The result of the condition evaluation (True or False)" description="The result of the condition evaluation (True or False)"
) )

View File

@@ -6,7 +6,13 @@ from e2b_code_interpreter import Result as E2BExecutionResult
from e2b_code_interpreter.charts import Chart as E2BExecutionResultChart from e2b_code_interpreter.charts import Chart as E2BExecutionResultChart
from pydantic import BaseModel, Field, JsonValue, SecretStr from pydantic import BaseModel, Field, JsonValue, SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -159,7 +165,7 @@ class ExecuteCodeBlock(Block, BaseE2BExecutorMixin):
# TODO : Add support to upload and download files # TODO : Add support to upload and download files
# NOTE: Currently, you can only customize the CPU and Memory # NOTE: Currently, you can only customize the CPU and Memory
# by creating a pre customized sandbox template # by creating a pre customized sandbox template
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.E2B], Literal["api_key"] Literal[ProviderName.E2B], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -217,7 +223,7 @@ class ExecuteCodeBlock(Block, BaseE2BExecutorMixin):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
main_result: MainCodeExecutionResult = SchemaField( main_result: MainCodeExecutionResult = SchemaField(
title="Main Result", description="The main result from the code execution" title="Main Result", description="The main result from the code execution"
) )
@@ -232,7 +238,6 @@ class ExecuteCodeBlock(Block, BaseE2BExecutorMixin):
description="Standard output logs from execution" description="Standard output logs from execution"
) )
stderr_logs: str = SchemaField(description="Standard error logs from execution") stderr_logs: str = SchemaField(description="Standard error logs from execution")
error: str = SchemaField(description="Error message if execution failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -296,7 +301,7 @@ class ExecuteCodeBlock(Block, BaseE2BExecutorMixin):
class InstantiateCodeSandboxBlock(Block, BaseE2BExecutorMixin): class InstantiateCodeSandboxBlock(Block, BaseE2BExecutorMixin):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.E2B], Literal["api_key"] Literal[ProviderName.E2B], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -346,7 +351,7 @@ class InstantiateCodeSandboxBlock(Block, BaseE2BExecutorMixin):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
sandbox_id: str = SchemaField(description="ID of the sandbox instance") sandbox_id: str = SchemaField(description="ID of the sandbox instance")
response: str = SchemaField( response: str = SchemaField(
title="Text Result", title="Text Result",
@@ -356,7 +361,6 @@ class InstantiateCodeSandboxBlock(Block, BaseE2BExecutorMixin):
description="Standard output logs from execution" description="Standard output logs from execution"
) )
stderr_logs: str = SchemaField(description="Standard error logs from execution") stderr_logs: str = SchemaField(description="Standard error logs from execution")
error: str = SchemaField(description="Error message if execution failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -421,7 +425,7 @@ class InstantiateCodeSandboxBlock(Block, BaseE2BExecutorMixin):
class ExecuteCodeStepBlock(Block, BaseE2BExecutorMixin): class ExecuteCodeStepBlock(Block, BaseE2BExecutorMixin):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.E2B], Literal["api_key"] Literal[ProviderName.E2B], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -454,7 +458,7 @@ class ExecuteCodeStepBlock(Block, BaseE2BExecutorMixin):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
main_result: MainCodeExecutionResult = SchemaField( main_result: MainCodeExecutionResult = SchemaField(
title="Main Result", description="The main result from the code execution" title="Main Result", description="The main result from the code execution"
) )
@@ -469,7 +473,6 @@ class ExecuteCodeStepBlock(Block, BaseE2BExecutorMixin):
description="Standard output logs from execution" description="Standard output logs from execution"
) )
stderr_logs: str = SchemaField(description="Standard error logs from execution") stderr_logs: str = SchemaField(description="Standard error logs from execution")
error: str = SchemaField(description="Error message if execution failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -1,17 +1,23 @@
import re import re
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
class CodeExtractionBlock(Block): class CodeExtractionBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: str = SchemaField( text: str = SchemaField(
description="Text containing code blocks to extract (e.g., AI response)", description="Text containing code blocks to extract (e.g., AI response)",
placeholder="Enter text containing code blocks", placeholder="Enter text containing code blocks",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
html: str = SchemaField(description="Extracted HTML code") html: str = SchemaField(description="Extracted HTML code")
css: str = SchemaField(description="Extracted CSS code") css: str = SchemaField(description="Extracted CSS code")
javascript: str = SchemaField(description="Extracted JavaScript code") javascript: str = SchemaField(description="Extracted JavaScript code")

View File

@@ -5,7 +5,8 @@ from backend.data.block import (
BlockCategory, BlockCategory,
BlockManualWebhookConfig, BlockManualWebhookConfig,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
) )
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.integrations.providers import ProviderName from backend.integrations.providers import ProviderName
@@ -27,10 +28,10 @@ class TranscriptionDataModel(BaseModel):
class CompassAITriggerBlock(Block): class CompassAITriggerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
payload: TranscriptionDataModel = SchemaField(hidden=True) payload: TranscriptionDataModel = SchemaField(hidden=True)
class Output(BlockSchema): class Output(BlockSchemaOutput):
transcription: str = SchemaField( transcription: str = SchemaField(
description="The contents of the compass transcription." description="The contents of the compass transcription."
) )

View File

@@ -1,16 +1,22 @@
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
class WordCharacterCountBlock(Block): class WordCharacterCountBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: str = SchemaField( text: str = SchemaField(
description="Input text to count words and characters", description="Input text to count words and characters",
placeholder="Enter your text here", placeholder="Enter your text here",
advanced=False, advanced=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
word_count: int = SchemaField(description="Number of words in the input text") word_count: int = SchemaField(description="Number of words in the input text")
character_count: int = SchemaField( character_count: int = SchemaField(
description="Number of characters in the input text" description="Number of characters in the input text"

View File

@@ -1,6 +1,12 @@
from typing import Any, List from typing import Any, List
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.json import loads from backend.util.json import loads
from backend.util.mock import MockObject from backend.util.mock import MockObject
@@ -12,13 +18,13 @@ from backend.util.prompt import estimate_token_count_str
class CreateDictionaryBlock(Block): class CreateDictionaryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
values: dict[str, Any] = SchemaField( values: dict[str, Any] = SchemaField(
description="Key-value pairs to create the dictionary with", description="Key-value pairs to create the dictionary with",
placeholder="e.g., {'name': 'Alice', 'age': 25}", placeholder="e.g., {'name': 'Alice', 'age': 25}",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
dictionary: dict[str, Any] = SchemaField( dictionary: dict[str, Any] = SchemaField(
description="The created dictionary containing the specified key-value pairs" description="The created dictionary containing the specified key-value pairs"
) )
@@ -62,7 +68,7 @@ class CreateDictionaryBlock(Block):
class AddToDictionaryBlock(Block): class AddToDictionaryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
dictionary: dict[Any, Any] = SchemaField( dictionary: dict[Any, Any] = SchemaField(
default_factory=dict, default_factory=dict,
description="The dictionary to add the entry to. If not provided, a new dictionary will be created.", description="The dictionary to add the entry to. If not provided, a new dictionary will be created.",
@@ -86,11 +92,10 @@ class AddToDictionaryBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_dictionary: dict = SchemaField( updated_dictionary: dict = SchemaField(
description="The dictionary with the new entry added." description="The dictionary with the new entry added."
) )
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -141,11 +146,11 @@ class AddToDictionaryBlock(Block):
class FindInDictionaryBlock(Block): class FindInDictionaryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
input: Any = SchemaField(description="Dictionary to lookup from") input: Any = SchemaField(description="Dictionary to lookup from")
key: str | int = SchemaField(description="Key to lookup in the dictionary") key: str | int = SchemaField(description="Key to lookup in the dictionary")
class Output(BlockSchema): class Output(BlockSchemaOutput):
output: Any = SchemaField(description="Value found for the given key") output: Any = SchemaField(description="Value found for the given key")
missing: Any = SchemaField( missing: Any = SchemaField(
description="Value of the input that missing the key" description="Value of the input that missing the key"
@@ -201,7 +206,7 @@ class FindInDictionaryBlock(Block):
class RemoveFromDictionaryBlock(Block): class RemoveFromDictionaryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
dictionary: dict[Any, Any] = SchemaField( dictionary: dict[Any, Any] = SchemaField(
description="The dictionary to modify." description="The dictionary to modify."
) )
@@ -210,12 +215,11 @@ class RemoveFromDictionaryBlock(Block):
default=False, description="Whether to return the removed value." default=False, description="Whether to return the removed value."
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_dictionary: dict[Any, Any] = SchemaField( updated_dictionary: dict[Any, Any] = SchemaField(
description="The dictionary after removal." description="The dictionary after removal."
) )
removed_value: Any = SchemaField(description="The removed value if requested.") removed_value: Any = SchemaField(description="The removed value if requested.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -251,19 +255,18 @@ class RemoveFromDictionaryBlock(Block):
class ReplaceDictionaryValueBlock(Block): class ReplaceDictionaryValueBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
dictionary: dict[Any, Any] = SchemaField( dictionary: dict[Any, Any] = SchemaField(
description="The dictionary to modify." description="The dictionary to modify."
) )
key: str | int = SchemaField(description="Key to replace the value for.") key: str | int = SchemaField(description="Key to replace the value for.")
value: Any = SchemaField(description="The new value for the given key.") value: Any = SchemaField(description="The new value for the given key.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_dictionary: dict[Any, Any] = SchemaField( updated_dictionary: dict[Any, Any] = SchemaField(
description="The dictionary after replacement." description="The dictionary after replacement."
) )
old_value: Any = SchemaField(description="The value that was replaced.") old_value: Any = SchemaField(description="The value that was replaced.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -300,10 +303,10 @@ class ReplaceDictionaryValueBlock(Block):
class DictionaryIsEmptyBlock(Block): class DictionaryIsEmptyBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
dictionary: dict[Any, Any] = SchemaField(description="The dictionary to check.") dictionary: dict[Any, Any] = SchemaField(description="The dictionary to check.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
is_empty: bool = SchemaField(description="True if the dictionary is empty.") is_empty: bool = SchemaField(description="True if the dictionary is empty.")
def __init__(self): def __init__(self):
@@ -327,7 +330,7 @@ class DictionaryIsEmptyBlock(Block):
class CreateListBlock(Block): class CreateListBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
values: List[Any] = SchemaField( values: List[Any] = SchemaField(
description="A list of values to be combined into a new list.", description="A list of values to be combined into a new list.",
placeholder="e.g., ['Alice', 25, True]", placeholder="e.g., ['Alice', 25, True]",
@@ -343,11 +346,10 @@ class CreateListBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
list: List[Any] = SchemaField( list: List[Any] = SchemaField(
description="The created list containing the specified values." description="The created list containing the specified values."
) )
error: str = SchemaField(description="Error message if list creation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -404,7 +406,7 @@ class CreateListBlock(Block):
class AddToListBlock(Block): class AddToListBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField( list: List[Any] = SchemaField(
default_factory=list, default_factory=list,
advanced=False, advanced=False,
@@ -425,11 +427,10 @@ class AddToListBlock(Block):
description="The position to insert the new entry. If not provided, the entry will be appended to the end of the list.", description="The position to insert the new entry. If not provided, the entry will be appended to the end of the list.",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_list: List[Any] = SchemaField( updated_list: List[Any] = SchemaField(
description="The list with the new entry added." description="The list with the new entry added."
) )
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -484,11 +485,11 @@ class AddToListBlock(Block):
class FindInListBlock(Block): class FindInListBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField(description="The list to search in.") list: List[Any] = SchemaField(description="The list to search in.")
value: Any = SchemaField(description="The value to search for.") value: Any = SchemaField(description="The value to search for.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
index: int = SchemaField(description="The index of the value in the list.") index: int = SchemaField(description="The index of the value in the list.")
found: bool = SchemaField( found: bool = SchemaField(
description="Whether the value was found in the list." description="Whether the value was found in the list."
@@ -526,15 +527,14 @@ class FindInListBlock(Block):
class GetListItemBlock(Block): class GetListItemBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField(description="The list to get the item from.") list: List[Any] = SchemaField(description="The list to get the item from.")
index: int = SchemaField( index: int = SchemaField(
description="The 0-based index of the item (supports negative indices)." description="The 0-based index of the item (supports negative indices)."
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
item: Any = SchemaField(description="The item at the specified index.") item: Any = SchemaField(description="The item at the specified index.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -561,7 +561,7 @@ class GetListItemBlock(Block):
class RemoveFromListBlock(Block): class RemoveFromListBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField(description="The list to modify.") list: List[Any] = SchemaField(description="The list to modify.")
value: Any = SchemaField( value: Any = SchemaField(
default=None, description="Value to remove from the list." default=None, description="Value to remove from the list."
@@ -574,10 +574,9 @@ class RemoveFromListBlock(Block):
default=False, description="Whether to return the removed item." default=False, description="Whether to return the removed item."
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_list: List[Any] = SchemaField(description="The list after removal.") updated_list: List[Any] = SchemaField(description="The list after removal.")
removed_item: Any = SchemaField(description="The removed item if requested.") removed_item: Any = SchemaField(description="The removed item if requested.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -618,17 +617,16 @@ class RemoveFromListBlock(Block):
class ReplaceListItemBlock(Block): class ReplaceListItemBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField(description="The list to modify.") list: List[Any] = SchemaField(description="The list to modify.")
index: int = SchemaField( index: int = SchemaField(
description="Index of the item to replace (supports negative indices)." description="Index of the item to replace (supports negative indices)."
) )
value: Any = SchemaField(description="The new value for the given index.") value: Any = SchemaField(description="The new value for the given index.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
updated_list: List[Any] = SchemaField(description="The list after replacement.") updated_list: List[Any] = SchemaField(description="The list after replacement.")
old_item: Any = SchemaField(description="The item that was replaced.") old_item: Any = SchemaField(description="The item that was replaced.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -663,10 +661,10 @@ class ReplaceListItemBlock(Block):
class ListIsEmptyBlock(Block): class ListIsEmptyBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
list: List[Any] = SchemaField(description="The list to check.") list: List[Any] = SchemaField(description="The list to check.")
class Output(BlockSchema): class Output(BlockSchemaOutput):
is_empty: bool = SchemaField(description="True if the list is empty.") is_empty: bool = SchemaField(description="True if the list is empty.")
def __init__(self): def __init__(self):

View File

@@ -8,7 +8,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
UserPasswordCredentials, UserPasswordCredentials,
@@ -18,7 +19,7 @@ from ._api import DataForSeoClient
from ._config import dataforseo from ._config import dataforseo
class KeywordSuggestion(BlockSchema): class KeywordSuggestion(BlockSchemaInput):
"""Schema for a keyword suggestion result.""" """Schema for a keyword suggestion result."""
keyword: str = SchemaField(description="The keyword suggestion") keyword: str = SchemaField(description="The keyword suggestion")
@@ -45,7 +46,7 @@ class KeywordSuggestion(BlockSchema):
class DataForSeoKeywordSuggestionsBlock(Block): class DataForSeoKeywordSuggestionsBlock(Block):
"""Block for getting keyword suggestions from DataForSEO Labs.""" """Block for getting keyword suggestions from DataForSEO Labs."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = dataforseo.credentials_field( credentials: CredentialsMetaInput = dataforseo.credentials_field(
description="DataForSEO credentials (username and password)" description="DataForSEO credentials (username and password)"
) )
@@ -77,7 +78,7 @@ class DataForSeoKeywordSuggestionsBlock(Block):
le=3000, le=3000,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
suggestions: List[KeywordSuggestion] = SchemaField( suggestions: List[KeywordSuggestion] = SchemaField(
description="List of keyword suggestions with metrics" description="List of keyword suggestions with metrics"
) )
@@ -90,7 +91,6 @@ class DataForSeoKeywordSuggestionsBlock(Block):
seed_keyword: str = SchemaField( seed_keyword: str = SchemaField(
description="The seed keyword used for the query" description="The seed keyword used for the query"
) )
error: str = SchemaField(description="Error message if the API call failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -213,12 +213,12 @@ class DataForSeoKeywordSuggestionsBlock(Block):
class KeywordSuggestionExtractorBlock(Block): class KeywordSuggestionExtractorBlock(Block):
"""Extracts individual fields from a KeywordSuggestion object.""" """Extracts individual fields from a KeywordSuggestion object."""
class Input(BlockSchema): class Input(BlockSchemaInput):
suggestion: KeywordSuggestion = SchemaField( suggestion: KeywordSuggestion = SchemaField(
description="The keyword suggestion object to extract fields from" description="The keyword suggestion object to extract fields from"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
keyword: str = SchemaField(description="The keyword suggestion") keyword: str = SchemaField(description="The keyword suggestion")
search_volume: Optional[int] = SchemaField( search_volume: Optional[int] = SchemaField(
description="Monthly search volume", default=None description="Monthly search volume", default=None

View File

@@ -8,7 +8,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
UserPasswordCredentials, UserPasswordCredentials,
@@ -18,7 +19,7 @@ from ._api import DataForSeoClient
from ._config import dataforseo from ._config import dataforseo
class RelatedKeyword(BlockSchema): class RelatedKeyword(BlockSchemaInput):
"""Schema for a related keyword result.""" """Schema for a related keyword result."""
keyword: str = SchemaField(description="The related keyword") keyword: str = SchemaField(description="The related keyword")
@@ -45,7 +46,7 @@ class RelatedKeyword(BlockSchema):
class DataForSeoRelatedKeywordsBlock(Block): class DataForSeoRelatedKeywordsBlock(Block):
"""Block for getting related keywords from DataForSEO Labs.""" """Block for getting related keywords from DataForSEO Labs."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = dataforseo.credentials_field( credentials: CredentialsMetaInput = dataforseo.credentials_field(
description="DataForSEO credentials (username and password)" description="DataForSEO credentials (username and password)"
) )
@@ -85,7 +86,7 @@ class DataForSeoRelatedKeywordsBlock(Block):
le=4, le=4,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
related_keywords: List[RelatedKeyword] = SchemaField( related_keywords: List[RelatedKeyword] = SchemaField(
description="List of related keywords with metrics" description="List of related keywords with metrics"
) )
@@ -98,7 +99,6 @@ class DataForSeoRelatedKeywordsBlock(Block):
seed_keyword: str = SchemaField( seed_keyword: str = SchemaField(
description="The seed keyword used for the query" description="The seed keyword used for the query"
) )
error: str = SchemaField(description="Error message if the API call failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -231,12 +231,12 @@ class DataForSeoRelatedKeywordsBlock(Block):
class RelatedKeywordExtractorBlock(Block): class RelatedKeywordExtractorBlock(Block):
"""Extracts individual fields from a RelatedKeyword object.""" """Extracts individual fields from a RelatedKeyword object."""
class Input(BlockSchema): class Input(BlockSchemaInput):
related_keyword: RelatedKeyword = SchemaField( related_keyword: RelatedKeyword = SchemaField(
description="The related keyword object to extract fields from" description="The related keyword object to extract fields from"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
keyword: str = SchemaField(description="The related keyword") keyword: str = SchemaField(description="The related keyword")
search_volume: Optional[int] = SchemaField( search_volume: Optional[int] = SchemaField(
description="Monthly search volume", default=None description="Monthly search volume", default=None

View File

@@ -1,17 +1,23 @@
import codecs import codecs
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
class TextDecoderBlock(Block): class TextDecoderBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: str = SchemaField( text: str = SchemaField(
description="A string containing escaped characters to be decoded", description="A string containing escaped characters to be decoded",
placeholder='Your entire text block with \\n and \\" escaped characters', placeholder='Your entire text block with \\n and \\" escaped characters',
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
decoded_text: str = SchemaField( decoded_text: str = SchemaField(
description="The decoded text with escape sequences processed" description="The decoded text with escape sequences processed"
) )

View File

@@ -7,7 +7,13 @@ from typing import Any
import discord import discord
from pydantic import SecretStr from pydantic import SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import APIKeyCredentials, SchemaField from backend.data.model import APIKeyCredentials, SchemaField
from backend.util.file import store_media_file from backend.util.file import store_media_file
from backend.util.request import Requests from backend.util.request import Requests
@@ -28,10 +34,10 @@ TEST_CREDENTIALS_INPUT = TEST_BOT_CREDENTIALS_INPUT
class ReadDiscordMessagesBlock(Block): class ReadDiscordMessagesBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
class Output(BlockSchema): class Output(BlockSchemaOutput):
message_content: str = SchemaField( message_content: str = SchemaField(
description="The content of the message received" description="The content of the message received"
) )
@@ -164,7 +170,7 @@ class ReadDiscordMessagesBlock(Block):
class SendDiscordMessageBlock(Block): class SendDiscordMessageBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
message_content: str = SchemaField( message_content: str = SchemaField(
description="The content of the message to send" description="The content of the message to send"
@@ -178,7 +184,7 @@ class SendDiscordMessageBlock(Block):
default="", default="",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="The status of the operation (e.g., 'Message sent', 'Error')" description="The status of the operation (e.g., 'Message sent', 'Error')"
) )
@@ -310,7 +316,7 @@ class SendDiscordMessageBlock(Block):
class SendDiscordDMBlock(Block): class SendDiscordDMBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
user_id: str = SchemaField( user_id: str = SchemaField(
description="The Discord user ID to send the DM to (e.g., '123456789012345678')" description="The Discord user ID to send the DM to (e.g., '123456789012345678')"
@@ -319,7 +325,7 @@ class SendDiscordDMBlock(Block):
description="The content of the direct message to send" description="The content of the direct message to send"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="The status of the operation") status: str = SchemaField(description="The status of the operation")
message_id: str = SchemaField(description="The ID of the sent message") message_id: str = SchemaField(description="The ID of the sent message")
@@ -399,7 +405,7 @@ class SendDiscordDMBlock(Block):
class SendDiscordEmbedBlock(Block): class SendDiscordEmbedBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
channel_identifier: str = SchemaField( channel_identifier: str = SchemaField(
description="Channel ID or channel name to send the embed to" description="Channel ID or channel name to send the embed to"
@@ -436,7 +442,7 @@ class SendDiscordEmbedBlock(Block):
default=[], default=[],
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")
message_id: str = SchemaField(description="ID of the sent embed message") message_id: str = SchemaField(description="ID of the sent embed message")
@@ -586,7 +592,7 @@ class SendDiscordEmbedBlock(Block):
class SendDiscordFileBlock(Block): class SendDiscordFileBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
channel_identifier: str = SchemaField( channel_identifier: str = SchemaField(
description="Channel ID or channel name to send the file to" description="Channel ID or channel name to send the file to"
@@ -607,7 +613,7 @@ class SendDiscordFileBlock(Block):
description="Optional message to send with the file", default="" description="Optional message to send with the file", default=""
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")
message_id: str = SchemaField(description="ID of the sent message") message_id: str = SchemaField(description="ID of the sent message")
@@ -788,7 +794,7 @@ class SendDiscordFileBlock(Block):
class ReplyToDiscordMessageBlock(Block): class ReplyToDiscordMessageBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
channel_id: str = SchemaField( channel_id: str = SchemaField(
description="The channel ID where the message to reply to is located" description="The channel ID where the message to reply to is located"
@@ -799,7 +805,7 @@ class ReplyToDiscordMessageBlock(Block):
description="Whether to mention the original message author", default=True description="Whether to mention the original message author", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")
reply_id: str = SchemaField(description="ID of the reply message") reply_id: str = SchemaField(description="ID of the reply message")
@@ -913,13 +919,13 @@ class ReplyToDiscordMessageBlock(Block):
class DiscordUserInfoBlock(Block): class DiscordUserInfoBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
user_id: str = SchemaField( user_id: str = SchemaField(
description="The Discord user ID to get information about" description="The Discord user ID to get information about"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
user_id: str = SchemaField( user_id: str = SchemaField(
description="The user's ID (passed through for chaining)" description="The user's ID (passed through for chaining)"
) )
@@ -1030,7 +1036,7 @@ class DiscordUserInfoBlock(Block):
class DiscordChannelInfoBlock(Block): class DiscordChannelInfoBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordCredentials = DiscordCredentialsField() credentials: DiscordCredentials = DiscordCredentialsField()
channel_identifier: str = SchemaField( channel_identifier: str = SchemaField(
description="Channel name or channel ID to look up" description="Channel name or channel ID to look up"
@@ -1041,7 +1047,7 @@ class DiscordChannelInfoBlock(Block):
default="", default="",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
channel_id: str = SchemaField(description="The channel's ID") channel_id: str = SchemaField(description="The channel's ID")
channel_name: str = SchemaField(description="The channel's name") channel_name: str = SchemaField(description="The channel's name")
server_id: str = SchemaField(description="The server's ID") server_id: str = SchemaField(description="The server's ID")

View File

@@ -2,7 +2,13 @@
Discord OAuth-based blocks. Discord OAuth-based blocks.
""" """
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import DiscordOAuthUser, get_current_user from ._api import DiscordOAuthUser, get_current_user
@@ -21,12 +27,12 @@ class DiscordGetCurrentUserBlock(Block):
This block requires Discord OAuth2 credentials (not bot tokens). This block requires Discord OAuth2 credentials (not bot tokens).
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: DiscordOAuthCredentialsInput = DiscordOAuthCredentialsField( credentials: DiscordOAuthCredentialsInput = DiscordOAuthCredentialsField(
["identify"] ["identify"]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
user_id: str = SchemaField(description="The authenticated user's Discord ID") user_id: str = SchemaField(description="The authenticated user's Discord ID")
username: str = SchemaField(description="The user's username") username: str = SchemaField(description="The user's username")
avatar_url: str = SchemaField(description="URL to the user's avatar image") avatar_url: str = SchemaField(description="URL to the user's avatar image")

View File

@@ -5,7 +5,13 @@ from typing import Literal
from pydantic import BaseModel, ConfigDict, SecretStr from pydantic import BaseModel, ConfigDict, SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
CredentialsField, CredentialsField,
CredentialsMetaInput, CredentialsMetaInput,
@@ -51,7 +57,7 @@ class SMTPConfig(BaseModel):
class SendEmailBlock(Block): class SendEmailBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
to_email: str = SchemaField( to_email: str = SchemaField(
description="Recipient email address", placeholder="recipient@example.com" description="Recipient email address", placeholder="recipient@example.com"
) )
@@ -67,7 +73,7 @@ class SendEmailBlock(Block):
) )
credentials: SMTPCredentialsInput = SMTPCredentialsField() credentials: SMTPCredentialsInput = SMTPCredentialsField()
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Status of the email sending operation") status: str = SchemaField(description="Status of the email sending operation")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the email sending failed" description="Error message if the email sending failed"

View File

@@ -8,7 +8,13 @@ which provides access to LinkedIn profile data and related information.
import logging import logging
from typing import Optional from typing import Optional
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import APIKeyCredentials, CredentialsField, SchemaField from backend.data.model import APIKeyCredentials, CredentialsField, SchemaField
from backend.util.type import MediaFileType from backend.util.type import MediaFileType
@@ -29,7 +35,7 @@ logger = logging.getLogger(__name__)
class GetLinkedinProfileBlock(Block): class GetLinkedinProfileBlock(Block):
"""Block to fetch LinkedIn profile data using Enrichlayer API.""" """Block to fetch LinkedIn profile data using Enrichlayer API."""
class Input(BlockSchema): class Input(BlockSchemaInput):
"""Input schema for GetLinkedinProfileBlock.""" """Input schema for GetLinkedinProfileBlock."""
linkedin_url: str = SchemaField( linkedin_url: str = SchemaField(
@@ -80,13 +86,12 @@ class GetLinkedinProfileBlock(Block):
description="Enrichlayer API credentials" description="Enrichlayer API credentials"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
"""Output schema for GetLinkedinProfileBlock.""" """Output schema for GetLinkedinProfileBlock."""
profile: PersonProfileResponse = SchemaField( profile: PersonProfileResponse = SchemaField(
description="LinkedIn profile data" description="LinkedIn profile data"
) )
error: str = SchemaField(description="Error message if the request failed")
def __init__(self): def __init__(self):
"""Initialize GetLinkedinProfileBlock.""" """Initialize GetLinkedinProfileBlock."""
@@ -199,7 +204,7 @@ class GetLinkedinProfileBlock(Block):
class LinkedinPersonLookupBlock(Block): class LinkedinPersonLookupBlock(Block):
"""Block to look up LinkedIn profiles by person's information using Enrichlayer API.""" """Block to look up LinkedIn profiles by person's information using Enrichlayer API."""
class Input(BlockSchema): class Input(BlockSchemaInput):
"""Input schema for LinkedinPersonLookupBlock.""" """Input schema for LinkedinPersonLookupBlock."""
first_name: str = SchemaField( first_name: str = SchemaField(
@@ -242,13 +247,12 @@ class LinkedinPersonLookupBlock(Block):
description="Enrichlayer API credentials" description="Enrichlayer API credentials"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
"""Output schema for LinkedinPersonLookupBlock.""" """Output schema for LinkedinPersonLookupBlock."""
lookup_result: PersonLookupResponse = SchemaField( lookup_result: PersonLookupResponse = SchemaField(
description="LinkedIn profile lookup result" description="LinkedIn profile lookup result"
) )
error: str = SchemaField(description="Error message if the request failed")
def __init__(self): def __init__(self):
"""Initialize LinkedinPersonLookupBlock.""" """Initialize LinkedinPersonLookupBlock."""
@@ -346,7 +350,7 @@ class LinkedinPersonLookupBlock(Block):
class LinkedinRoleLookupBlock(Block): class LinkedinRoleLookupBlock(Block):
"""Block to look up LinkedIn profiles by role in a company using Enrichlayer API.""" """Block to look up LinkedIn profiles by role in a company using Enrichlayer API."""
class Input(BlockSchema): class Input(BlockSchemaInput):
"""Input schema for LinkedinRoleLookupBlock.""" """Input schema for LinkedinRoleLookupBlock."""
role: str = SchemaField( role: str = SchemaField(
@@ -366,13 +370,12 @@ class LinkedinRoleLookupBlock(Block):
description="Enrichlayer API credentials" description="Enrichlayer API credentials"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
"""Output schema for LinkedinRoleLookupBlock.""" """Output schema for LinkedinRoleLookupBlock."""
role_lookup_result: RoleLookupResponse = SchemaField( role_lookup_result: RoleLookupResponse = SchemaField(
description="LinkedIn role lookup result" description="LinkedIn role lookup result"
) )
error: str = SchemaField(description="Error message if the request failed")
def __init__(self): def __init__(self):
"""Initialize LinkedinRoleLookupBlock.""" """Initialize LinkedinRoleLookupBlock."""
@@ -449,7 +452,7 @@ class LinkedinRoleLookupBlock(Block):
class GetLinkedinProfilePictureBlock(Block): class GetLinkedinProfilePictureBlock(Block):
"""Block to get LinkedIn profile pictures using Enrichlayer API.""" """Block to get LinkedIn profile pictures using Enrichlayer API."""
class Input(BlockSchema): class Input(BlockSchemaInput):
"""Input schema for GetLinkedinProfilePictureBlock.""" """Input schema for GetLinkedinProfilePictureBlock."""
linkedin_profile_url: str = SchemaField( linkedin_profile_url: str = SchemaField(
@@ -460,13 +463,12 @@ class GetLinkedinProfilePictureBlock(Block):
description="Enrichlayer API credentials" description="Enrichlayer API credentials"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
"""Output schema for GetLinkedinProfilePictureBlock.""" """Output schema for GetLinkedinProfilePictureBlock."""
profile_picture_url: MediaFileType = SchemaField( profile_picture_url: MediaFileType = SchemaField(
description="LinkedIn profile picture URL" description="LinkedIn profile picture URL"
) )
error: str = SchemaField(description="Error message if the request failed")
def __init__(self): def __init__(self):
"""Initialize GetLinkedinProfilePictureBlock.""" """Initialize GetLinkedinProfilePictureBlock."""

View File

@@ -4,7 +4,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -49,7 +50,7 @@ class CostDollars(BaseModel):
class ExaAnswerBlock(Block): class ExaAnswerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -69,7 +70,7 @@ class ExaAnswerBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
answer: str = SchemaField( answer: str = SchemaField(
description="The generated answer based on search results" description="The generated answer based on search results"
) )

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -14,7 +15,7 @@ from .helpers import ContentSettings
class ExaContentsBlock(Block): class ExaContentsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -27,7 +28,7 @@ class ExaContentsBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: list = SchemaField( results: list = SchemaField(
description="List of document contents", default_factory=list description="List of document contents", default_factory=list
) )

View File

@@ -5,7 +5,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -16,7 +17,7 @@ from .helpers import ContentSettings
class ExaSearchBlock(Block): class ExaSearchBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -63,7 +64,7 @@ class ExaSearchBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: list = SchemaField( results: list = SchemaField(
description="List of search results", default_factory=list description="List of search results", default_factory=list
) )

View File

@@ -6,7 +6,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -17,7 +18,7 @@ from .helpers import ContentSettings
class ExaFindSimilarBlock(Block): class ExaFindSimilarBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -65,7 +66,7 @@ class ExaFindSimilarBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: list[Any] = SchemaField( results: list[Any] = SchemaField(
description="List of similar documents with title, URL, published date, author, and score", description="List of similar documents with title, URL, published date, author, and score",
default_factory=list, default_factory=list,

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
BlockType, BlockType,
BlockWebhookConfig, BlockWebhookConfig,
CredentialsMetaInput, CredentialsMetaInput,
@@ -84,7 +85,7 @@ class ExaWebsetWebhookBlock(Block):
including creation, updates, searches, and exports. including creation, updates, searches, and exports.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="Exa API credentials for webhook management" description="Exa API credentials for webhook management"
) )
@@ -104,7 +105,7 @@ class ExaWebsetWebhookBlock(Block):
description="Webhook payload data", default={}, hidden=True description="Webhook payload data", default={}, hidden=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
event_type: str = SchemaField(description="Type of event that occurred") event_type: str = SchemaField(description="Type of event that occurred")
event_id: str = SchemaField(description="Unique identifier for this event") event_id: str = SchemaField(description="Unique identifier for this event")
webset_id: str = SchemaField(description="ID of the affected webset") webset_id: str = SchemaField(description="ID of the affected webset")

View File

@@ -31,7 +31,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
Requests, Requests,
SchemaField, SchemaField,
@@ -104,7 +105,7 @@ class Webset(BaseModel):
class ExaCreateWebsetBlock(Block): class ExaCreateWebsetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -219,7 +220,7 @@ class ExaCreateWebsetBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
webset: Webset = SchemaField( webset: Webset = SchemaField(
description="The unique identifier for the created webset" description="The unique identifier for the created webset"
) )
@@ -404,7 +405,7 @@ class ExaCreateWebsetBlock(Block):
class ExaUpdateWebsetBlock(Block): class ExaUpdateWebsetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -417,7 +418,7 @@ class ExaUpdateWebsetBlock(Block):
description="Key-value pairs to associate with this webset (set to null to clear)", description="Key-value pairs to associate with this webset (set to null to clear)",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
webset_id: str = SchemaField(description="The unique identifier for the webset") webset_id: str = SchemaField(description="The unique identifier for the webset")
status: str = SchemaField(description="The status of the webset") status: str = SchemaField(description="The status of the webset")
external_id: Optional[str] = SchemaField( external_id: Optional[str] = SchemaField(
@@ -475,7 +476,7 @@ class ExaUpdateWebsetBlock(Block):
class ExaListWebsetsBlock(Block): class ExaListWebsetsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -497,7 +498,7 @@ class ExaListWebsetsBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
websets: list[Webset] = SchemaField( websets: list[Webset] = SchemaField(
description="List of websets", default_factory=list description="List of websets", default_factory=list
) )
@@ -550,7 +551,7 @@ class ExaListWebsetsBlock(Block):
class ExaGetWebsetBlock(Block): class ExaGetWebsetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -559,7 +560,7 @@ class ExaGetWebsetBlock(Block):
placeholder="webset-id-or-external-id", placeholder="webset-id-or-external-id",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
webset_id: str = SchemaField(description="The unique identifier for the webset") webset_id: str = SchemaField(description="The unique identifier for the webset")
status: str = SchemaField(description="The status of the webset") status: str = SchemaField(description="The status of the webset")
external_id: Optional[str] = SchemaField( external_id: Optional[str] = SchemaField(
@@ -637,7 +638,7 @@ class ExaGetWebsetBlock(Block):
class ExaDeleteWebsetBlock(Block): class ExaDeleteWebsetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -646,7 +647,7 @@ class ExaDeleteWebsetBlock(Block):
placeholder="webset-id-or-external-id", placeholder="webset-id-or-external-id",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
webset_id: str = SchemaField( webset_id: str = SchemaField(
description="The unique identifier for the deleted webset" description="The unique identifier for the deleted webset"
) )
@@ -695,7 +696,7 @@ class ExaDeleteWebsetBlock(Block):
class ExaCancelWebsetBlock(Block): class ExaCancelWebsetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = exa.credentials_field( credentials: CredentialsMetaInput = exa.credentials_field(
description="The Exa integration requires an API Key." description="The Exa integration requires an API Key."
) )
@@ -704,7 +705,7 @@ class ExaCancelWebsetBlock(Block):
placeholder="webset-id-or-external-id", placeholder="webset-id-or-external-id",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
webset_id: str = SchemaField(description="The unique identifier for the webset") webset_id: str = SchemaField(description="The unique identifier for the webset")
status: str = SchemaField( status: str = SchemaField(
description="The status of the webset after cancellation" description="The status of the webset after cancellation"

View File

@@ -10,7 +10,13 @@ from backend.blocks.fal._auth import (
FalCredentialsField, FalCredentialsField,
FalCredentialsInput, FalCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import ClientResponseError, Requests from backend.util.request import ClientResponseError, Requests
@@ -24,7 +30,7 @@ class FalModel(str, Enum):
class AIVideoGeneratorBlock(Block): class AIVideoGeneratorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
prompt: str = SchemaField( prompt: str = SchemaField(
description="Description of the video to generate.", description="Description of the video to generate.",
placeholder="A dog running in a field.", placeholder="A dog running in a field.",
@@ -36,7 +42,7 @@ class AIVideoGeneratorBlock(Block):
) )
credentials: FalCredentialsInput = FalCredentialsField() credentials: FalCredentialsInput = FalCredentialsField()
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_url: str = SchemaField(description="The URL of the generated video.") video_url: str = SchemaField(description="The URL of the generated video.")
error: str = SchemaField( error: str = SchemaField(
description="Error message if video generation failed." description="Error message if video generation failed."

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -19,7 +20,7 @@ from ._format_utils import convert_to_format_options
class FirecrawlCrawlBlock(Block): class FirecrawlCrawlBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = firecrawl.credentials_field() credentials: CredentialsMetaInput = firecrawl.credentials_field()
url: str = SchemaField(description="The URL to crawl") url: str = SchemaField(description="The URL to crawl")
limit: int = SchemaField(description="The number of pages to crawl", default=10) limit: int = SchemaField(description="The number of pages to crawl", default=10)
@@ -39,7 +40,7 @@ class FirecrawlCrawlBlock(Block):
description="The format of the crawl", default=[ScrapeFormat.MARKDOWN] description="The format of the crawl", default=[ScrapeFormat.MARKDOWN]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
data: list[dict[str, Any]] = SchemaField(description="The result of the crawl") data: list[dict[str, Any]] = SchemaField(description="The result of the crawl")
markdown: str = SchemaField(description="The markdown of the crawl") markdown: str = SchemaField(description="The markdown of the crawl")
html: str = SchemaField(description="The html of the crawl") html: str = SchemaField(description="The html of the crawl")

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
BlockCost, BlockCost,
BlockCostType, BlockCostType,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
cost, cost,
@@ -20,7 +21,7 @@ from ._config import firecrawl
@cost(BlockCost(2, BlockCostType.RUN)) @cost(BlockCost(2, BlockCostType.RUN))
class FirecrawlExtractBlock(Block): class FirecrawlExtractBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = firecrawl.credentials_field() credentials: CredentialsMetaInput = firecrawl.credentials_field()
urls: list[str] = SchemaField( urls: list[str] = SchemaField(
description="The URLs to crawl - at least one is required. Wildcards are supported. (/*)" description="The URLs to crawl - at least one is required. Wildcards are supported. (/*)"
@@ -37,7 +38,7 @@ class FirecrawlExtractBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
data: dict[str, Any] = SchemaField(description="The result of the crawl") data: dict[str, Any] = SchemaField(description="The result of the crawl")
def __init__(self): def __init__(self):

View File

@@ -7,7 +7,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -16,12 +17,12 @@ from ._config import firecrawl
class FirecrawlMapWebsiteBlock(Block): class FirecrawlMapWebsiteBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = firecrawl.credentials_field() credentials: CredentialsMetaInput = firecrawl.credentials_field()
url: str = SchemaField(description="The website url to map") url: str = SchemaField(description="The website url to map")
class Output(BlockSchema): class Output(BlockSchemaOutput):
links: list[str] = SchemaField(description="List of URLs found on the website") links: list[str] = SchemaField(description="List of URLs found on the website")
results: list[dict[str, Any]] = SchemaField( results: list[dict[str, Any]] = SchemaField(
description="List of search results with url, title, and description" description="List of search results with url, title, and description"

View File

@@ -8,7 +8,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -18,7 +19,7 @@ from ._format_utils import convert_to_format_options
class FirecrawlScrapeBlock(Block): class FirecrawlScrapeBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = firecrawl.credentials_field() credentials: CredentialsMetaInput = firecrawl.credentials_field()
url: str = SchemaField(description="The URL to crawl") url: str = SchemaField(description="The URL to crawl")
limit: int = SchemaField(description="The number of pages to crawl", default=10) limit: int = SchemaField(description="The number of pages to crawl", default=10)
@@ -38,7 +39,7 @@ class FirecrawlScrapeBlock(Block):
description="The format of the crawl", default=[ScrapeFormat.MARKDOWN] description="The format of the crawl", default=[ScrapeFormat.MARKDOWN]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
data: dict[str, Any] = SchemaField(description="The result of the crawl") data: dict[str, Any] = SchemaField(description="The result of the crawl")
markdown: str = SchemaField(description="The markdown of the crawl") markdown: str = SchemaField(description="The markdown of the crawl")
html: str = SchemaField(description="The html of the crawl") html: str = SchemaField(description="The html of the crawl")

View File

@@ -9,7 +9,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
SchemaField, SchemaField,
) )
@@ -19,7 +20,7 @@ from ._format_utils import convert_to_format_options
class FirecrawlSearchBlock(Block): class FirecrawlSearchBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = firecrawl.credentials_field() credentials: CredentialsMetaInput = firecrawl.credentials_field()
query: str = SchemaField(description="The query to search for") query: str = SchemaField(description="The query to search for")
limit: int = SchemaField(description="The number of pages to crawl", default=10) limit: int = SchemaField(description="The number of pages to crawl", default=10)
@@ -35,7 +36,7 @@ class FirecrawlSearchBlock(Block):
description="Returns the content of the search if specified", default=[] description="Returns the content of the search if specified", default=[]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
data: dict[str, Any] = SchemaField(description="The result of the search") data: dict[str, Any] = SchemaField(description="The result of the search")
site: dict[str, Any] = SchemaField(description="The site of the search") site: dict[str, Any] = SchemaField(description="The site of the search")

View File

@@ -5,7 +5,13 @@ from pydantic import SecretStr
from replicate.client import Client as ReplicateClient from replicate.client import Client as ReplicateClient
from replicate.helpers import FileOutput from replicate.helpers import FileOutput
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -57,7 +63,7 @@ class AspectRatio(str, Enum):
class AIImageEditorBlock(Block): class AIImageEditorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.REPLICATE], Literal["api_key"] Literal[ProviderName.REPLICATE], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -90,11 +96,10 @@ class AIImageEditorBlock(Block):
title="Model", title="Model",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
output_image: MediaFileType = SchemaField( output_image: MediaFileType = SchemaField(
description="URL of the transformed image" description="URL of the transformed image"
) )
error: str = SchemaField(description="Error message if generation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
BlockCategory, BlockCategory,
BlockManualWebhookConfig, BlockManualWebhookConfig,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
ProviderBuilder, ProviderBuilder,
ProviderName, ProviderName,
SchemaField, SchemaField,
@@ -19,14 +20,14 @@ generic_webhook = (
class GenericWebhookTriggerBlock(Block): class GenericWebhookTriggerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
payload: dict = SchemaField(hidden=True, default_factory=dict) payload: dict = SchemaField(hidden=True, default_factory=dict)
constants: dict = SchemaField( constants: dict = SchemaField(
description="The constants to be set when the block is put on the graph", description="The constants to be set when the block is put on the graph",
default_factory=dict, default_factory=dict,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
payload: dict = SchemaField( payload: dict = SchemaField(
description="The complete webhook payload that was received from the generic webhook." description="The complete webhook payload that was received from the generic webhook."
) )

View File

@@ -3,7 +3,13 @@ from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -39,7 +45,7 @@ class ChecksConclusion(Enum):
class GithubCreateCheckRunBlock(Block): class GithubCreateCheckRunBlock(Block):
"""Block for creating a new check run on a GitHub repository.""" """Block for creating a new check run on a GitHub repository."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo:status") credentials: GithubCredentialsInput = GithubCredentialsField("repo:status")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -76,7 +82,7 @@ class GithubCreateCheckRunBlock(Block):
default="", default="",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class CheckRunResult(BaseModel): class CheckRunResult(BaseModel):
id: int id: int
html_url: str html_url: str
@@ -211,7 +217,7 @@ class GithubCreateCheckRunBlock(Block):
class GithubUpdateCheckRunBlock(Block): class GithubUpdateCheckRunBlock(Block):
"""Block for updating an existing check run on a GitHub repository.""" """Block for updating an existing check run on a GitHub repository."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo:status") credentials: GithubCredentialsInput = GithubCredentialsField("repo:status")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -239,7 +245,7 @@ class GithubUpdateCheckRunBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class CheckRunResult(BaseModel): class CheckRunResult(BaseModel):
id: int id: int
html_url: str html_url: str
@@ -249,7 +255,6 @@ class GithubUpdateCheckRunBlock(Block):
check_run: CheckRunResult = SchemaField( check_run: CheckRunResult = SchemaField(
description="Details of the updated check run" description="Details of the updated check run"
) )
error: str = SchemaField(description="Error message if check run update failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -5,7 +5,13 @@ from typing import Optional
from typing_extensions import TypedDict from typing_extensions import TypedDict
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -37,7 +43,7 @@ class CheckRunConclusion(Enum):
class GithubGetCIResultsBlock(Block): class GithubGetCIResultsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description="GitHub repository", description="GitHub repository",
@@ -60,7 +66,7 @@ class GithubGetCIResultsBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class CheckRunItem(TypedDict, total=False): class CheckRunItem(TypedDict, total=False):
id: int id: int
name: str name: str
@@ -104,7 +110,6 @@ class GithubGetCIResultsBlock(Block):
total_checks: int = SchemaField(description="Total number of CI checks") total_checks: int = SchemaField(description="Total number of CI checks")
passed_checks: int = SchemaField(description="Number of passed checks") passed_checks: int = SchemaField(description="Number of passed checks")
failed_checks: int = SchemaField(description="Number of failed checks") failed_checks: int = SchemaField(description="Number of failed checks")
error: str = SchemaField(description="Error message if the operation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -3,7 +3,13 @@ from urllib.parse import urlparse
from typing_extensions import TypedDict from typing_extensions import TypedDict
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import convert_comment_url_to_api_endpoint, get_api from ._api import convert_comment_url_to_api_endpoint, get_api
@@ -24,7 +30,7 @@ def is_github_url(url: str) -> bool:
# --8<-- [start:GithubCommentBlockExample] # --8<-- [start:GithubCommentBlockExample]
class GithubCommentBlock(Block): class GithubCommentBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue or pull request", description="URL of the GitHub issue or pull request",
@@ -35,7 +41,7 @@ class GithubCommentBlock(Block):
placeholder="Enter your comment", placeholder="Enter your comment",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
id: int = SchemaField(description="ID of the created comment") id: int = SchemaField(description="ID of the created comment")
url: str = SchemaField(description="URL to the comment on GitHub") url: str = SchemaField(description="URL to the comment on GitHub")
error: str = SchemaField( error: str = SchemaField(
@@ -112,7 +118,7 @@ class GithubCommentBlock(Block):
class GithubUpdateCommentBlock(Block): class GithubUpdateCommentBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
comment_url: str = SchemaField( comment_url: str = SchemaField(
description="URL of the GitHub comment", description="URL of the GitHub comment",
@@ -135,7 +141,7 @@ class GithubUpdateCommentBlock(Block):
placeholder="Enter your comment", placeholder="Enter your comment",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
id: int = SchemaField(description="ID of the updated comment") id: int = SchemaField(description="ID of the updated comment")
url: str = SchemaField(description="URL to the comment on GitHub") url: str = SchemaField(description="URL to the comment on GitHub")
error: str = SchemaField( error: str = SchemaField(
@@ -219,14 +225,14 @@ class GithubUpdateCommentBlock(Block):
class GithubListCommentsBlock(Block): class GithubListCommentsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue or pull request", description="URL of the GitHub issue or pull request",
placeholder="https://github.com/owner/repo/issues/1", placeholder="https://github.com/owner/repo/issues/1",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class CommentItem(TypedDict): class CommentItem(TypedDict):
id: int id: int
body: str body: str
@@ -239,7 +245,6 @@ class GithubListCommentsBlock(Block):
comments: list[CommentItem] = SchemaField( comments: list[CommentItem] = SchemaField(
description="List of comments with their ID, body, user, and URL" description="List of comments with their ID, body, user, and URL"
) )
error: str = SchemaField(description="Error message if listing comments failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -335,7 +340,7 @@ class GithubListCommentsBlock(Block):
class GithubMakeIssueBlock(Block): class GithubMakeIssueBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -348,7 +353,7 @@ class GithubMakeIssueBlock(Block):
description="Body of the issue", placeholder="Enter the issue body" description="Body of the issue", placeholder="Enter the issue body"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
number: int = SchemaField(description="Number of the created issue") number: int = SchemaField(description="Number of the created issue")
url: str = SchemaField(description="URL of the created issue") url: str = SchemaField(description="URL of the created issue")
error: str = SchemaField( error: str = SchemaField(
@@ -410,14 +415,14 @@ class GithubMakeIssueBlock(Block):
class GithubReadIssueBlock(Block): class GithubReadIssueBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue", description="URL of the GitHub issue",
placeholder="https://github.com/owner/repo/issues/1", placeholder="https://github.com/owner/repo/issues/1",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
title: str = SchemaField(description="Title of the issue") title: str = SchemaField(description="Title of the issue")
body: str = SchemaField(description="Body of the issue") body: str = SchemaField(description="Body of the issue")
user: str = SchemaField(description="User who created the issue") user: str = SchemaField(description="User who created the issue")
@@ -483,14 +488,14 @@ class GithubReadIssueBlock(Block):
class GithubListIssuesBlock(Block): class GithubListIssuesBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class IssueItem(TypedDict): class IssueItem(TypedDict):
title: str title: str
url: str url: str
@@ -501,7 +506,6 @@ class GithubListIssuesBlock(Block):
issues: list[IssueItem] = SchemaField( issues: list[IssueItem] = SchemaField(
description="List of issues with their title and URL" description="List of issues with their title and URL"
) )
error: str = SchemaField(description="Error message if listing issues failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -573,7 +577,7 @@ class GithubListIssuesBlock(Block):
class GithubAddLabelBlock(Block): class GithubAddLabelBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue or pull request", description="URL of the GitHub issue or pull request",
@@ -584,7 +588,7 @@ class GithubAddLabelBlock(Block):
placeholder="Enter the label", placeholder="Enter the label",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Status of the label addition operation") status: str = SchemaField(description="Status of the label addition operation")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the label addition failed" description="Error message if the label addition failed"
@@ -633,7 +637,7 @@ class GithubAddLabelBlock(Block):
class GithubRemoveLabelBlock(Block): class GithubRemoveLabelBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue or pull request", description="URL of the GitHub issue or pull request",
@@ -644,7 +648,7 @@ class GithubRemoveLabelBlock(Block):
placeholder="Enter the label", placeholder="Enter the label",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Status of the label removal operation") status: str = SchemaField(description="Status of the label removal operation")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the label removal failed" description="Error message if the label removal failed"
@@ -694,7 +698,7 @@ class GithubRemoveLabelBlock(Block):
class GithubAssignIssueBlock(Block): class GithubAssignIssueBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue", description="URL of the GitHub issue",
@@ -705,7 +709,7 @@ class GithubAssignIssueBlock(Block):
placeholder="Enter the username", placeholder="Enter the username",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="Status of the issue assignment operation" description="Status of the issue assignment operation"
) )
@@ -760,7 +764,7 @@ class GithubAssignIssueBlock(Block):
class GithubUnassignIssueBlock(Block): class GithubUnassignIssueBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
issue_url: str = SchemaField( issue_url: str = SchemaField(
description="URL of the GitHub issue", description="URL of the GitHub issue",
@@ -771,7 +775,7 @@ class GithubUnassignIssueBlock(Block):
placeholder="Enter the username", placeholder="Enter the username",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="Status of the issue unassignment operation" description="Status of the issue unassignment operation"
) )

View File

@@ -2,7 +2,13 @@ import re
from typing_extensions import TypedDict from typing_extensions import TypedDict
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -16,14 +22,14 @@ from ._auth import (
class GithubListPullRequestsBlock(Block): class GithubListPullRequestsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class PRItem(TypedDict): class PRItem(TypedDict):
title: str title: str
url: str url: str
@@ -108,7 +114,7 @@ class GithubListPullRequestsBlock(Block):
class GithubMakePullRequestBlock(Block): class GithubMakePullRequestBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -135,7 +141,7 @@ class GithubMakePullRequestBlock(Block):
placeholder="Enter the base branch", placeholder="Enter the base branch",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
number: int = SchemaField(description="Number of the created pull request") number: int = SchemaField(description="Number of the created pull request")
url: str = SchemaField(description="URL of the created pull request") url: str = SchemaField(description="URL of the created pull request")
error: str = SchemaField( error: str = SchemaField(
@@ -209,7 +215,7 @@ class GithubMakePullRequestBlock(Block):
class GithubReadPullRequestBlock(Block): class GithubReadPullRequestBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
pr_url: str = SchemaField( pr_url: str = SchemaField(
description="URL of the GitHub pull request", description="URL of the GitHub pull request",
@@ -221,7 +227,7 @@ class GithubReadPullRequestBlock(Block):
advanced=False, advanced=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
title: str = SchemaField(description="Title of the pull request") title: str = SchemaField(description="Title of the pull request")
body: str = SchemaField(description="Body of the pull request") body: str = SchemaField(description="Body of the pull request")
author: str = SchemaField(description="User who created the pull request") author: str = SchemaField(description="User who created the pull request")
@@ -325,7 +331,7 @@ class GithubReadPullRequestBlock(Block):
class GithubAssignPRReviewerBlock(Block): class GithubAssignPRReviewerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
pr_url: str = SchemaField( pr_url: str = SchemaField(
description="URL of the GitHub pull request", description="URL of the GitHub pull request",
@@ -336,7 +342,7 @@ class GithubAssignPRReviewerBlock(Block):
placeholder="Enter the reviewer's username", placeholder="Enter the reviewer's username",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="Status of the reviewer assignment operation" description="Status of the reviewer assignment operation"
) )
@@ -392,7 +398,7 @@ class GithubAssignPRReviewerBlock(Block):
class GithubUnassignPRReviewerBlock(Block): class GithubUnassignPRReviewerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
pr_url: str = SchemaField( pr_url: str = SchemaField(
description="URL of the GitHub pull request", description="URL of the GitHub pull request",
@@ -403,7 +409,7 @@ class GithubUnassignPRReviewerBlock(Block):
placeholder="Enter the reviewer's username", placeholder="Enter the reviewer's username",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="Status of the reviewer unassignment operation" description="Status of the reviewer unassignment operation"
) )
@@ -459,14 +465,14 @@ class GithubUnassignPRReviewerBlock(Block):
class GithubListPRReviewersBlock(Block): class GithubListPRReviewersBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
pr_url: str = SchemaField( pr_url: str = SchemaField(
description="URL of the GitHub pull request", description="URL of the GitHub pull request",
placeholder="https://github.com/owner/repo/pull/1", placeholder="https://github.com/owner/repo/pull/1",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class ReviewerItem(TypedDict): class ReviewerItem(TypedDict):
username: str username: str
url: str url: str

View File

@@ -2,7 +2,13 @@ import base64
from typing_extensions import TypedDict from typing_extensions import TypedDict
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -16,14 +22,14 @@ from ._auth import (
class GithubListTagsBlock(Block): class GithubListTagsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class TagItem(TypedDict): class TagItem(TypedDict):
name: str name: str
url: str url: str
@@ -34,7 +40,6 @@ class GithubListTagsBlock(Block):
tags: list[TagItem] = SchemaField( tags: list[TagItem] = SchemaField(
description="List of tags with their name and file tree browser URL" description="List of tags with their name and file tree browser URL"
) )
error: str = SchemaField(description="Error message if listing tags failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -111,14 +116,14 @@ class GithubListTagsBlock(Block):
class GithubListBranchesBlock(Block): class GithubListBranchesBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class BranchItem(TypedDict): class BranchItem(TypedDict):
name: str name: str
url: str url: str
@@ -130,7 +135,6 @@ class GithubListBranchesBlock(Block):
branches: list[BranchItem] = SchemaField( branches: list[BranchItem] = SchemaField(
description="List of branches with their name and file tree browser URL" description="List of branches with their name and file tree browser URL"
) )
error: str = SchemaField(description="Error message if listing branches failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -207,7 +211,7 @@ class GithubListBranchesBlock(Block):
class GithubListDiscussionsBlock(Block): class GithubListDiscussionsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -217,7 +221,7 @@ class GithubListDiscussionsBlock(Block):
description="Number of discussions to fetch", default=5 description="Number of discussions to fetch", default=5
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class DiscussionItem(TypedDict): class DiscussionItem(TypedDict):
title: str title: str
url: str url: str
@@ -323,14 +327,14 @@ class GithubListDiscussionsBlock(Block):
class GithubListReleasesBlock(Block): class GithubListReleasesBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class ReleaseItem(TypedDict): class ReleaseItem(TypedDict):
name: str name: str
url: str url: str
@@ -342,7 +346,6 @@ class GithubListReleasesBlock(Block):
releases: list[ReleaseItem] = SchemaField( releases: list[ReleaseItem] = SchemaField(
description="List of releases with their name and file tree browser URL" description="List of releases with their name and file tree browser URL"
) )
error: str = SchemaField(description="Error message if listing releases failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -414,7 +417,7 @@ class GithubListReleasesBlock(Block):
class GithubReadFileBlock(Block): class GithubReadFileBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -430,7 +433,7 @@ class GithubReadFileBlock(Block):
default="master", default="master",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
text_content: str = SchemaField( text_content: str = SchemaField(
description="Content of the file (decoded as UTF-8 text)" description="Content of the file (decoded as UTF-8 text)"
) )
@@ -438,7 +441,6 @@ class GithubReadFileBlock(Block):
description="Raw base64-encoded content of the file" description="Raw base64-encoded content of the file"
) )
size: int = SchemaField(description="The size of the file (in bytes)") size: int = SchemaField(description="The size of the file (in bytes)")
error: str = SchemaField(description="Error message if the file reading failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -501,7 +503,7 @@ class GithubReadFileBlock(Block):
class GithubReadFolderBlock(Block): class GithubReadFolderBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -517,7 +519,7 @@ class GithubReadFolderBlock(Block):
default="master", default="master",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class DirEntry(TypedDict): class DirEntry(TypedDict):
name: str name: str
path: str path: str
@@ -625,7 +627,7 @@ class GithubReadFolderBlock(Block):
class GithubMakeBranchBlock(Block): class GithubMakeBranchBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -640,7 +642,7 @@ class GithubMakeBranchBlock(Block):
placeholder="source_branch_name", placeholder="source_branch_name",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Status of the branch creation operation") status: str = SchemaField(description="Status of the branch creation operation")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the branch creation failed" description="Error message if the branch creation failed"
@@ -705,7 +707,7 @@ class GithubMakeBranchBlock(Block):
class GithubDeleteBranchBlock(Block): class GithubDeleteBranchBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -716,7 +718,7 @@ class GithubDeleteBranchBlock(Block):
placeholder="branch_name", placeholder="branch_name",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField(description="Status of the branch deletion operation") status: str = SchemaField(description="Status of the branch deletion operation")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the branch deletion failed" description="Error message if the branch deletion failed"
@@ -766,7 +768,7 @@ class GithubDeleteBranchBlock(Block):
class GithubCreateFileBlock(Block): class GithubCreateFileBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -789,7 +791,7 @@ class GithubCreateFileBlock(Block):
default="Create new file", default="Create new file",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
url: str = SchemaField(description="URL of the created file") url: str = SchemaField(description="URL of the created file")
sha: str = SchemaField(description="SHA of the commit") sha: str = SchemaField(description="SHA of the commit")
error: str = SchemaField( error: str = SchemaField(
@@ -868,7 +870,7 @@ class GithubCreateFileBlock(Block):
class GithubUpdateFileBlock(Block): class GithubUpdateFileBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
@@ -891,10 +893,9 @@ class GithubUpdateFileBlock(Block):
default="Update file", default="Update file",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
url: str = SchemaField(description="URL of the updated file") url: str = SchemaField(description="URL of the updated file")
sha: str = SchemaField(description="SHA of the commit") sha: str = SchemaField(description="SHA of the commit")
error: str = SchemaField(description="Error message if the file update failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -974,7 +975,7 @@ class GithubUpdateFileBlock(Block):
class GithubCreateRepositoryBlock(Block): class GithubCreateRepositoryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
name: str = SchemaField( name: str = SchemaField(
description="Name of the repository to create", description="Name of the repository to create",
@@ -998,7 +999,7 @@ class GithubCreateRepositoryBlock(Block):
default="", default="",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
url: str = SchemaField(description="URL of the created repository") url: str = SchemaField(description="URL of the created repository")
clone_url: str = SchemaField(description="Git clone URL of the repository") clone_url: str = SchemaField(description="Git clone URL of the repository")
error: str = SchemaField( error: str = SchemaField(
@@ -1077,14 +1078,14 @@ class GithubCreateRepositoryBlock(Block):
class GithubListStargazersBlock(Block): class GithubListStargazersBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo_url: str = SchemaField( repo_url: str = SchemaField(
description="URL of the GitHub repository", description="URL of the GitHub repository",
placeholder="https://github.com/owner/repo", placeholder="https://github.com/owner/repo",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class StargazerItem(TypedDict): class StargazerItem(TypedDict):
username: str username: str
url: str url: str

View File

@@ -4,7 +4,13 @@ from typing import Any, List, Optional
from typing_extensions import TypedDict from typing_extensions import TypedDict
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -26,7 +32,7 @@ class ReviewEvent(Enum):
class GithubCreatePRReviewBlock(Block): class GithubCreatePRReviewBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
class ReviewComment(TypedDict, total=False): class ReviewComment(TypedDict, total=False):
path: str path: str
position: Optional[int] position: Optional[int]
@@ -61,7 +67,7 @@ class GithubCreatePRReviewBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
review_id: int = SchemaField(description="ID of the created review") review_id: int = SchemaField(description="ID of the created review")
state: str = SchemaField( state: str = SchemaField(
description="State of the review (e.g., PENDING, COMMENTED, APPROVED, CHANGES_REQUESTED)" description="State of the review (e.g., PENDING, COMMENTED, APPROVED, CHANGES_REQUESTED)"
@@ -197,7 +203,7 @@ class GithubCreatePRReviewBlock(Block):
class GithubListPRReviewsBlock(Block): class GithubListPRReviewsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description="GitHub repository", description="GitHub repository",
@@ -208,7 +214,7 @@ class GithubListPRReviewsBlock(Block):
placeholder="123", placeholder="123",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class ReviewItem(TypedDict): class ReviewItem(TypedDict):
id: int id: int
user: str user: str
@@ -223,7 +229,6 @@ class GithubListPRReviewsBlock(Block):
reviews: list[ReviewItem] = SchemaField( reviews: list[ReviewItem] = SchemaField(
description="List of all reviews on the pull request" description="List of all reviews on the pull request"
) )
error: str = SchemaField(description="Error message if listing reviews failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -317,7 +322,7 @@ class GithubListPRReviewsBlock(Block):
class GithubSubmitPendingReviewBlock(Block): class GithubSubmitPendingReviewBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description="GitHub repository", description="GitHub repository",
@@ -336,7 +341,7 @@ class GithubSubmitPendingReviewBlock(Block):
default=ReviewEvent.COMMENT, default=ReviewEvent.COMMENT,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
state: str = SchemaField(description="State of the submitted review") state: str = SchemaField(description="State of the submitted review")
html_url: str = SchemaField(description="URL of the submitted review") html_url: str = SchemaField(description="URL of the submitted review")
error: str = SchemaField( error: str = SchemaField(
@@ -415,7 +420,7 @@ class GithubSubmitPendingReviewBlock(Block):
class GithubResolveReviewDiscussionBlock(Block): class GithubResolveReviewDiscussionBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description="GitHub repository", description="GitHub repository",
@@ -434,9 +439,8 @@ class GithubResolveReviewDiscussionBlock(Block):
default=True, default=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
success: bool = SchemaField(description="Whether the operation was successful") success: bool = SchemaField(description="Whether the operation was successful")
error: str = SchemaField(description="Error message if the operation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -579,7 +583,7 @@ class GithubResolveReviewDiscussionBlock(Block):
class GithubGetPRReviewCommentsBlock(Block): class GithubGetPRReviewCommentsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description="GitHub repository", description="GitHub repository",
@@ -596,7 +600,7 @@ class GithubGetPRReviewCommentsBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class CommentItem(TypedDict): class CommentItem(TypedDict):
id: int id: int
user: str user: str
@@ -616,7 +620,6 @@ class GithubGetPRReviewCommentsBlock(Block):
comments: list[CommentItem] = SchemaField( comments: list[CommentItem] = SchemaField(
description="List of all review comments on the pull request" description="List of all review comments on the pull request"
) )
error: str = SchemaField(description="Error message if getting comments failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -744,7 +747,7 @@ class GithubGetPRReviewCommentsBlock(Block):
class GithubCreateCommentObjectBlock(Block): class GithubCreateCommentObjectBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
path: str = SchemaField( path: str = SchemaField(
description="The file path to comment on", description="The file path to comment on",
placeholder="src/main.py", placeholder="src/main.py",
@@ -781,7 +784,7 @@ class GithubCreateCommentObjectBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
comment_object: dict = SchemaField( comment_object: dict = SchemaField(
description="The comment object formatted for GitHub API" description="The comment object formatted for GitHub API"
) )

View File

@@ -3,7 +3,13 @@ from typing import Optional
from pydantic import BaseModel from pydantic import BaseModel
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from ._api import get_api from ._api import get_api
@@ -26,7 +32,7 @@ class StatusState(Enum):
class GithubCreateStatusBlock(Block): class GithubCreateStatusBlock(Block):
"""Block for creating a commit status on a GitHub repository.""" """Block for creating a commit status on a GitHub repository."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubFineGrainedAPICredentialsInput = ( credentials: GithubFineGrainedAPICredentialsInput = (
GithubFineGrainedAPICredentialsField("repo:status") GithubFineGrainedAPICredentialsField("repo:status")
) )
@@ -54,7 +60,7 @@ class GithubCreateStatusBlock(Block):
advanced=False, advanced=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
class StatusResult(BaseModel): class StatusResult(BaseModel):
id: int id: int
url: str url: str
@@ -66,7 +72,6 @@ class GithubCreateStatusBlock(Block):
updated_at: str updated_at: str
status: StatusResult = SchemaField(description="Details of the created status") status: StatusResult = SchemaField(description="Details of the created status")
error: str = SchemaField(description="Error message if status creation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -8,7 +8,8 @@ from backend.data.block import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
BlockWebhookConfig, BlockWebhookConfig,
) )
from backend.data.model import SchemaField from backend.data.model import SchemaField
@@ -26,7 +27,7 @@ logger = logging.getLogger(__name__)
# --8<-- [start:GithubTriggerExample] # --8<-- [start:GithubTriggerExample]
class GitHubTriggerBase: class GitHubTriggerBase:
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GithubCredentialsInput = GithubCredentialsField("repo") credentials: GithubCredentialsInput = GithubCredentialsField("repo")
repo: str = SchemaField( repo: str = SchemaField(
description=( description=(
@@ -40,7 +41,7 @@ class GitHubTriggerBase:
payload: dict = SchemaField(hidden=True, default_factory=dict) payload: dict = SchemaField(hidden=True, default_factory=dict)
# --8<-- [end:example-payload-field] # --8<-- [end:example-payload-field]
class Output(BlockSchema): class Output(BlockSchemaOutput):
payload: dict = SchemaField( payload: dict = SchemaField(
description="The complete webhook payload that was received from GitHub. " description="The complete webhook payload that was received from GitHub. "
"Includes information about the affected resource (e.g. pull request), " "Includes information about the affected resource (e.g. pull request), "

View File

@@ -8,7 +8,13 @@ from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build from googleapiclient.discovery import build
from pydantic import BaseModel from pydantic import BaseModel
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.settings import Settings from backend.util.settings import Settings
@@ -43,7 +49,7 @@ class CalendarEvent(BaseModel):
class GoogleCalendarReadEventsBlock(Block): class GoogleCalendarReadEventsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/calendar.readonly"] ["https://www.googleapis.com/auth/calendar.readonly"]
) )
@@ -73,7 +79,7 @@ class GoogleCalendarReadEventsBlock(Block):
description="Include events you've declined", default=False description="Include events you've declined", default=False
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
events: list[CalendarEvent] = SchemaField( events: list[CalendarEvent] = SchemaField(
description="List of calendar events in the requested time range", description="List of calendar events in the requested time range",
default_factory=list, default_factory=list,
@@ -379,7 +385,7 @@ class RecurringEvent(BaseModel):
class GoogleCalendarCreateEventBlock(Block): class GoogleCalendarCreateEventBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/calendar"] ["https://www.googleapis.com/auth/calendar"]
) )
@@ -433,12 +439,11 @@ class GoogleCalendarCreateEventBlock(Block):
default_factory=lambda: [ReminderPreset.TEN_MINUTES], default_factory=lambda: [ReminderPreset.TEN_MINUTES],
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
event_id: str = SchemaField(description="ID of the created event") event_id: str = SchemaField(description="ID of the created event")
event_link: str = SchemaField( event_link: str = SchemaField(
description="Link to view the event in Google Calendar" description="Link to view the event in Google Calendar"
) )
error: str = SchemaField(description="Error message if event creation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -14,7 +14,13 @@ from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build from googleapiclient.discovery import build
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.file import MediaFileType, get_exec_file_path, store_media_file from backend.util.file import MediaFileType, get_exec_file_path, store_media_file
from backend.util.settings import Settings from backend.util.settings import Settings
@@ -320,7 +326,7 @@ class GmailBase(Block, ABC):
class GmailReadBlock(GmailBase): class GmailReadBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.readonly"] ["https://www.googleapis.com/auth/gmail.readonly"]
) )
@@ -333,7 +339,7 @@ class GmailReadBlock(GmailBase):
default=10, default=10,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
email: Email = SchemaField( email: Email = SchemaField(
description="Email data", description="Email data",
) )
@@ -516,7 +522,7 @@ class GmailSendBlock(GmailBase):
- Attachment support for multiple files - Attachment support for multiple files
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.send"] ["https://www.googleapis.com/auth/gmail.send"]
) )
@@ -540,7 +546,7 @@ class GmailSendBlock(GmailBase):
description="Files to attach", default_factory=list, advanced=True description="Files to attach", default_factory=list, advanced=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: GmailSendResult = SchemaField( result: GmailSendResult = SchemaField(
description="Send confirmation", description="Send confirmation",
) )
@@ -618,7 +624,7 @@ class GmailCreateDraftBlock(GmailBase):
- Attachment support for multiple files - Attachment support for multiple files
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.modify"] ["https://www.googleapis.com/auth/gmail.modify"]
) )
@@ -642,7 +648,7 @@ class GmailCreateDraftBlock(GmailBase):
description="Files to attach", default_factory=list, advanced=True description="Files to attach", default_factory=list, advanced=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: GmailDraftResult = SchemaField( result: GmailDraftResult = SchemaField(
description="Draft creation result", description="Draft creation result",
) )
@@ -721,12 +727,12 @@ class GmailCreateDraftBlock(GmailBase):
class GmailListLabelsBlock(GmailBase): class GmailListLabelsBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.labels"] ["https://www.googleapis.com/auth/gmail.labels"]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: list[dict] = SchemaField( result: list[dict] = SchemaField(
description="List of labels", description="List of labels",
) )
@@ -779,7 +785,7 @@ class GmailListLabelsBlock(GmailBase):
class GmailAddLabelBlock(GmailBase): class GmailAddLabelBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.modify"] ["https://www.googleapis.com/auth/gmail.modify"]
) )
@@ -790,7 +796,7 @@ class GmailAddLabelBlock(GmailBase):
description="Label name to add", description="Label name to add",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: GmailLabelResult = SchemaField( result: GmailLabelResult = SchemaField(
description="Label addition result", description="Label addition result",
) )
@@ -865,7 +871,7 @@ class GmailAddLabelBlock(GmailBase):
class GmailRemoveLabelBlock(GmailBase): class GmailRemoveLabelBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.modify"] ["https://www.googleapis.com/auth/gmail.modify"]
) )
@@ -876,7 +882,7 @@ class GmailRemoveLabelBlock(GmailBase):
description="Label name to remove", description="Label name to remove",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: GmailLabelResult = SchemaField( result: GmailLabelResult = SchemaField(
description="Label removal result", description="Label removal result",
) )
@@ -941,17 +947,16 @@ class GmailRemoveLabelBlock(GmailBase):
class GmailGetThreadBlock(GmailBase): class GmailGetThreadBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.readonly"] ["https://www.googleapis.com/auth/gmail.readonly"]
) )
threadId: str = SchemaField(description="Gmail thread ID") threadId: str = SchemaField(description="Gmail thread ID")
class Output(BlockSchema): class Output(BlockSchemaOutput):
thread: Thread = SchemaField( thread: Thread = SchemaField(
description="Gmail thread with decoded message bodies" description="Gmail thread with decoded message bodies"
) )
error: str = SchemaField(description="Error message if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1218,7 +1223,7 @@ class GmailReplyBlock(GmailBase):
- Full Unicode/emoji support with UTF-8 encoding - Full Unicode/emoji support with UTF-8 encoding
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
[ [
"https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.send",
@@ -1246,14 +1251,13 @@ class GmailReplyBlock(GmailBase):
description="Files to attach", default_factory=list, advanced=True description="Files to attach", default_factory=list, advanced=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
messageId: str = SchemaField(description="Sent message ID") messageId: str = SchemaField(description="Sent message ID")
threadId: str = SchemaField(description="Thread ID") threadId: str = SchemaField(description="Thread ID")
message: dict = SchemaField(description="Raw Gmail message object") message: dict = SchemaField(description="Raw Gmail message object")
email: Email = SchemaField( email: Email = SchemaField(
description="Parsed email object with decoded body and attachments" description="Parsed email object with decoded body and attachments"
) )
error: str = SchemaField(description="Error message if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1368,7 +1372,7 @@ class GmailDraftReplyBlock(GmailBase):
- Full Unicode/emoji support with UTF-8 encoding - Full Unicode/emoji support with UTF-8 encoding
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
[ [
"https://www.googleapis.com/auth/gmail.modify", "https://www.googleapis.com/auth/gmail.modify",
@@ -1396,12 +1400,11 @@ class GmailDraftReplyBlock(GmailBase):
description="Files to attach", default_factory=list, advanced=True description="Files to attach", default_factory=list, advanced=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
draftId: str = SchemaField(description="Created draft ID") draftId: str = SchemaField(description="Created draft ID")
messageId: str = SchemaField(description="Draft message ID") messageId: str = SchemaField(description="Draft message ID")
threadId: str = SchemaField(description="Thread ID") threadId: str = SchemaField(description="Thread ID")
status: str = SchemaField(description="Draft creation status") status: str = SchemaField(description="Draft creation status")
error: str = SchemaField(description="Error message if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1482,14 +1485,13 @@ class GmailDraftReplyBlock(GmailBase):
class GmailGetProfileBlock(GmailBase): class GmailGetProfileBlock(GmailBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/gmail.readonly"] ["https://www.googleapis.com/auth/gmail.readonly"]
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
profile: Profile = SchemaField(description="Gmail user profile information") profile: Profile = SchemaField(description="Gmail user profile information")
error: str = SchemaField(description="Error message if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1555,7 +1557,7 @@ class GmailForwardBlock(GmailBase):
- Manual content type override option - Manual content type override option
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
[ [
"https://www.googleapis.com/auth/gmail.send", "https://www.googleapis.com/auth/gmail.send",
@@ -1589,11 +1591,10 @@ class GmailForwardBlock(GmailBase):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
messageId: str = SchemaField(description="Forwarded message ID") messageId: str = SchemaField(description="Forwarded message ID")
threadId: str = SchemaField(description="Thread ID") threadId: str = SchemaField(description="Thread ID")
status: str = SchemaField(description="Forward status") status: str = SchemaField(description="Forward status")
error: str = SchemaField(description="Error message if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -5,7 +5,13 @@ from typing import Any
from google.oauth2.credentials import Credentials from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build from googleapiclient.discovery import build
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.settings import Settings from backend.util.settings import Settings
@@ -195,7 +201,7 @@ class BatchOperationType(str, Enum):
CLEAR = "clear" CLEAR = "clear"
class BatchOperation(BlockSchema): class BatchOperation(BlockSchemaInput):
type: BatchOperationType = SchemaField( type: BatchOperationType = SchemaField(
description="The type of operation to perform" description="The type of operation to perform"
) )
@@ -206,7 +212,7 @@ class BatchOperation(BlockSchema):
class GoogleSheetsReadBlock(Block): class GoogleSheetsReadBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets.readonly"] ["https://www.googleapis.com/auth/spreadsheets.readonly"]
) )
@@ -218,7 +224,7 @@ class GoogleSheetsReadBlock(Block):
description="The A1 notation of the range to read", description="The A1 notation of the range to read",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: list[list[str]] = SchemaField( result: list[list[str]] = SchemaField(
description="The data read from the spreadsheet", description="The data read from the spreadsheet",
) )
@@ -274,7 +280,7 @@ class GoogleSheetsReadBlock(Block):
class GoogleSheetsWriteBlock(Block): class GoogleSheetsWriteBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -289,7 +295,7 @@ class GoogleSheetsWriteBlock(Block):
description="The data to write to the spreadsheet", description="The data to write to the spreadsheet",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result of the write operation", description="The result of the write operation",
) )
@@ -363,7 +369,7 @@ class GoogleSheetsWriteBlock(Block):
class GoogleSheetsAppendBlock(Block): class GoogleSheetsAppendBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -403,9 +409,8 @@ class GoogleSheetsAppendBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField(description="Append API response") result: dict = SchemaField(description="Append API response")
error: str = SchemaField(description="Error message, if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -503,7 +508,7 @@ class GoogleSheetsAppendBlock(Block):
class GoogleSheetsClearBlock(Block): class GoogleSheetsClearBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -515,7 +520,7 @@ class GoogleSheetsClearBlock(Block):
description="The A1 notation of the range to clear", description="The A1 notation of the range to clear",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result of the clear operation", description="The result of the clear operation",
) )
@@ -571,7 +576,7 @@ class GoogleSheetsClearBlock(Block):
class GoogleSheetsMetadataBlock(Block): class GoogleSheetsMetadataBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets.readonly"] ["https://www.googleapis.com/auth/spreadsheets.readonly"]
) )
@@ -580,7 +585,7 @@ class GoogleSheetsMetadataBlock(Block):
title="Spreadsheet ID or URL", title="Spreadsheet ID or URL",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The metadata of the spreadsheet including sheets info", description="The metadata of the spreadsheet including sheets info",
) )
@@ -652,7 +657,7 @@ class GoogleSheetsMetadataBlock(Block):
class GoogleSheetsManageSheetBlock(Block): class GoogleSheetsManageSheetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -672,9 +677,8 @@ class GoogleSheetsManageSheetBlock(Block):
description="New sheet name for copy", default="" description="New sheet name for copy", default=""
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField(description="Operation result") result: dict = SchemaField(description="Operation result")
error: str = SchemaField(description="Error message, if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -760,7 +764,7 @@ class GoogleSheetsManageSheetBlock(Block):
class GoogleSheetsBatchOperationsBlock(Block): class GoogleSheetsBatchOperationsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -772,7 +776,7 @@ class GoogleSheetsBatchOperationsBlock(Block):
description="List of operations to perform", description="List of operations to perform",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result of the batch operations", description="The result of the batch operations",
) )
@@ -877,7 +881,7 @@ class GoogleSheetsBatchOperationsBlock(Block):
class GoogleSheetsFindReplaceBlock(Block): class GoogleSheetsFindReplaceBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -904,7 +908,7 @@ class GoogleSheetsFindReplaceBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result of the find/replace operation including number of replacements", description="The result of the find/replace operation including number of replacements",
) )
@@ -987,7 +991,7 @@ class GoogleSheetsFindReplaceBlock(Block):
class GoogleSheetsFindBlock(Block): class GoogleSheetsFindBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets.readonly"] ["https://www.googleapis.com/auth/spreadsheets.readonly"]
) )
@@ -1020,7 +1024,7 @@ class GoogleSheetsFindBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result of the find operation including locations and count", description="The result of the find operation including locations and count",
) )
@@ -1255,7 +1259,7 @@ class GoogleSheetsFindBlock(Block):
class GoogleSheetsFormatBlock(Block): class GoogleSheetsFormatBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -1270,9 +1274,8 @@ class GoogleSheetsFormatBlock(Block):
italic: bool = SchemaField(default=False) italic: bool = SchemaField(default=False)
font_size: int = SchemaField(default=10) font_size: int = SchemaField(default=10)
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField(description="API response or success flag") result: dict = SchemaField(description="API response or success flag")
error: str = SchemaField(description="Error message, if any")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1383,7 +1386,7 @@ class GoogleSheetsFormatBlock(Block):
class GoogleSheetsCreateSpreadsheetBlock(Block): class GoogleSheetsCreateSpreadsheetBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: GoogleCredentialsInput = GoogleCredentialsField( credentials: GoogleCredentialsInput = GoogleCredentialsField(
["https://www.googleapis.com/auth/spreadsheets"] ["https://www.googleapis.com/auth/spreadsheets"]
) )
@@ -1395,7 +1398,7 @@ class GoogleSheetsCreateSpreadsheetBlock(Block):
default=["Sheet1"], default=["Sheet1"],
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField( result: dict = SchemaField(
description="The result containing spreadsheet ID and URL", description="The result containing spreadsheet ID and URL",
) )

View File

@@ -3,7 +3,13 @@ from typing import Literal
import googlemaps import googlemaps
from pydantic import BaseModel, SecretStr from pydantic import BaseModel, SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -37,7 +43,7 @@ class Place(BaseModel):
class GoogleMapsSearchBlock(Block): class GoogleMapsSearchBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.GOOGLE_MAPS], Literal["api_key"] Literal[ProviderName.GOOGLE_MAPS], Literal["api_key"]
] = CredentialsField(description="Google Maps API Key") ] = CredentialsField(description="Google Maps API Key")
@@ -58,9 +64,8 @@ class GoogleMapsSearchBlock(Block):
le=60, le=60,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
place: Place = SchemaField(description="Place found") place: Place = SchemaField(description="Place found")
error: str = SchemaField(description="Error message if the search failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -8,7 +8,13 @@ from typing import Literal
import aiofiles import aiofiles
from pydantic import SecretStr from pydantic import SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
CredentialsField, CredentialsField,
CredentialsMetaInput, CredentialsMetaInput,
@@ -62,7 +68,7 @@ class HttpMethod(Enum):
class SendWebRequestBlock(Block): class SendWebRequestBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
url: str = SchemaField( url: str = SchemaField(
description="The URL to send the request to", description="The URL to send the request to",
placeholder="https://api.example.com", placeholder="https://api.example.com",
@@ -93,7 +99,7 @@ class SendWebRequestBlock(Block):
default_factory=list, default_factory=list,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
response: object = SchemaField(description="The response from the server") response: object = SchemaField(description="The response from the server")
client_error: object = SchemaField(description="Errors on 4xx status codes") client_error: object = SchemaField(description="Errors on 4xx status codes")
server_error: object = SchemaField(description="Errors on 5xx status codes") server_error: object = SchemaField(description="Errors on 5xx status codes")

View File

@@ -3,13 +3,19 @@ from backend.blocks.hubspot._auth import (
HubSpotCredentialsField, HubSpotCredentialsField,
HubSpotCredentialsInput, HubSpotCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
class HubSpotCompanyBlock(Block): class HubSpotCompanyBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: HubSpotCredentialsInput = HubSpotCredentialsField() credentials: HubSpotCredentialsInput = HubSpotCredentialsField()
operation: str = SchemaField( operation: str = SchemaField(
description="Operation to perform (create, update, get)", default="get" description="Operation to perform (create, update, get)", default="get"
@@ -22,7 +28,7 @@ class HubSpotCompanyBlock(Block):
description="Company domain for get/update operations", default="" description="Company domain for get/update operations", default=""
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
company: dict = SchemaField(description="Company information") company: dict = SchemaField(description="Company information")
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")

View File

@@ -3,13 +3,19 @@ from backend.blocks.hubspot._auth import (
HubSpotCredentialsField, HubSpotCredentialsField,
HubSpotCredentialsInput, HubSpotCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
class HubSpotContactBlock(Block): class HubSpotContactBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: HubSpotCredentialsInput = HubSpotCredentialsField() credentials: HubSpotCredentialsInput = HubSpotCredentialsField()
operation: str = SchemaField( operation: str = SchemaField(
description="Operation to perform (create, update, get)", default="get" description="Operation to perform (create, update, get)", default="get"
@@ -22,7 +28,7 @@ class HubSpotContactBlock(Block):
description="Email address for get/update operations", default="" description="Email address for get/update operations", default=""
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
contact: dict = SchemaField(description="Contact information") contact: dict = SchemaField(description="Contact information")
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")

View File

@@ -5,13 +5,19 @@ from backend.blocks.hubspot._auth import (
HubSpotCredentialsField, HubSpotCredentialsField,
HubSpotCredentialsInput, HubSpotCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
class HubSpotEngagementBlock(Block): class HubSpotEngagementBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: HubSpotCredentialsInput = HubSpotCredentialsField() credentials: HubSpotCredentialsInput = HubSpotCredentialsField()
operation: str = SchemaField( operation: str = SchemaField(
description="Operation to perform (send_email, track_engagement)", description="Operation to perform (send_email, track_engagement)",
@@ -29,7 +35,7 @@ class HubSpotEngagementBlock(Block):
default=30, default=30,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: dict = SchemaField(description="Operation result") result: dict = SchemaField(description="Operation result")
status: str = SchemaField(description="Operation status") status: str = SchemaField(description="Operation status")

View File

@@ -4,7 +4,13 @@ from typing import Any, Dict, Literal, Optional
from pydantic import SecretStr from pydantic import SecretStr
from requests.exceptions import RequestException from requests.exceptions import RequestException
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -84,7 +90,7 @@ class UpscaleOption(str, Enum):
class IdeogramModelBlock(Block): class IdeogramModelBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.IDEOGRAM], Literal["api_key"] Literal[ProviderName.IDEOGRAM], Literal["api_key"]
] = CredentialsField( ] = CredentialsField(
@@ -154,9 +160,8 @@ class IdeogramModelBlock(Block):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: str = SchemaField(description="Generated image URL") result: str = SchemaField(description="Generated image URL")
error: str = SchemaField(description="Error message if the model run failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -2,7 +2,14 @@ import copy
from datetime import date, time from datetime import date, time
from typing import Any, Optional from typing import Any, Optional
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema, BlockType from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchema,
BlockSchemaInput,
BlockType,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.file import store_media_file from backend.util.file import store_media_file
from backend.util.mock import MockObject from backend.util.mock import MockObject
@@ -22,7 +29,7 @@ class AgentInputBlock(Block):
It Outputs the value passed as input. It Outputs the value passed as input.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
name: str = SchemaField(description="The name of the input.") name: str = SchemaField(description="The name of the input.")
value: Any = SchemaField( value: Any = SchemaField(
description="The value to be passed as input.", description="The value to be passed as input.",
@@ -60,6 +67,7 @@ class AgentInputBlock(Block):
return schema return schema
class Output(BlockSchema): class Output(BlockSchema):
# Use BlockSchema to avoid automatic error field for interface definition
result: Any = SchemaField(description="The value passed as input.") result: Any = SchemaField(description="The value passed as input.")
def __init__(self, **kwargs): def __init__(self, **kwargs):
@@ -109,7 +117,7 @@ class AgentOutputBlock(Block):
If formatting fails or no `format` is provided, the raw `value` is output. If formatting fails or no `format` is provided, the raw `value` is output.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
value: Any = SchemaField( value: Any = SchemaField(
description="The value to be recorded as output.", description="The value to be recorded as output.",
default=None, default=None,
@@ -151,6 +159,7 @@ class AgentOutputBlock(Block):
return self.get_field_schema("value") return self.get_field_schema("value")
class Output(BlockSchema): class Output(BlockSchema):
# Use BlockSchema to avoid automatic error field for interface definition
output: Any = SchemaField(description="The value recorded as output.") output: Any = SchemaField(description="The value recorded as output.")
name: Any = SchemaField(description="The name of the value recorded as output.") name: Any = SchemaField(description="The name of the value recorded as output.")

View File

@@ -1,12 +1,18 @@
from typing import Any from typing import Any
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.json import loads from backend.util.json import loads
class StepThroughItemsBlock(Block): class StepThroughItemsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
items: list = SchemaField( items: list = SchemaField(
advanced=False, advanced=False,
description="The list or dictionary of items to iterate over", description="The list or dictionary of items to iterate over",
@@ -26,7 +32,7 @@ class StepThroughItemsBlock(Block):
default="", default="",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
item: Any = SchemaField(description="The current item in the iteration") item: Any = SchemaField(description="The current item in the iteration")
key: Any = SchemaField( key: Any = SchemaField(
description="The key or index of the current item in the iteration", description="The key or index of the current item in the iteration",

View File

@@ -3,13 +3,19 @@ from backend.blocks.jina._auth import (
JinaCredentialsField, JinaCredentialsField,
JinaCredentialsInput, JinaCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
class JinaChunkingBlock(Block): class JinaChunkingBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
texts: list = SchemaField(description="List of texts to chunk") texts: list = SchemaField(description="List of texts to chunk")
credentials: JinaCredentialsInput = JinaCredentialsField() credentials: JinaCredentialsInput = JinaCredentialsField()
@@ -20,7 +26,7 @@ class JinaChunkingBlock(Block):
description="Whether to return token information", default=False description="Whether to return token information", default=False
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
chunks: list = SchemaField(description="List of chunked texts") chunks: list = SchemaField(description="List of chunked texts")
tokens: list = SchemaField( tokens: list = SchemaField(
description="List of token information for each chunk", description="List of token information for each chunk",

View File

@@ -3,13 +3,19 @@ from backend.blocks.jina._auth import (
JinaCredentialsField, JinaCredentialsField,
JinaCredentialsInput, JinaCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
class JinaEmbeddingBlock(Block): class JinaEmbeddingBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
texts: list = SchemaField(description="List of texts to embed") texts: list = SchemaField(description="List of texts to embed")
credentials: JinaCredentialsInput = JinaCredentialsField() credentials: JinaCredentialsInput = JinaCredentialsField()
model: str = SchemaField( model: str = SchemaField(
@@ -17,7 +23,7 @@ class JinaEmbeddingBlock(Block):
default="jina-embeddings-v2-base-en", default="jina-embeddings-v2-base-en",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
embeddings: list = SchemaField(description="List of embeddings") embeddings: list = SchemaField(description="List of embeddings")
def __init__(self): def __init__(self):

View File

@@ -8,7 +8,13 @@ from backend.blocks.jina._auth import (
JinaCredentialsField, JinaCredentialsField,
JinaCredentialsInput, JinaCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
@@ -20,13 +26,13 @@ class Reference(TypedDict):
class FactCheckerBlock(Block): class FactCheckerBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
statement: str = SchemaField( statement: str = SchemaField(
description="The statement to check for factuality" description="The statement to check for factuality"
) )
credentials: JinaCredentialsInput = JinaCredentialsField() credentials: JinaCredentialsInput = JinaCredentialsField()
class Output(BlockSchema): class Output(BlockSchemaOutput):
factuality: float = SchemaField( factuality: float = SchemaField(
description="The factuality score of the statement" description="The factuality score of the statement"
) )
@@ -36,7 +42,6 @@ class FactCheckerBlock(Block):
description="List of references supporting or contradicting the statement", description="List of references supporting or contradicting the statement",
default=[], default=[],
) )
error: str = SchemaField(description="Error message if the check fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -8,20 +8,25 @@ from backend.blocks.jina._auth import (
JinaCredentialsInput, JinaCredentialsInput,
) )
from backend.blocks.search import GetRequest from backend.blocks.search import GetRequest
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
class SearchTheWebBlock(Block, GetRequest): class SearchTheWebBlock(Block, GetRequest):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: JinaCredentialsInput = JinaCredentialsField() credentials: JinaCredentialsInput = JinaCredentialsField()
query: str = SchemaField(description="The search query to search the web for") query: str = SchemaField(description="The search query to search the web for")
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: str = SchemaField( results: str = SchemaField(
description="The search results including content from top 5 URLs" description="The search results including content from top 5 URLs"
) )
error: str = SchemaField(description="Error message if the search fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -58,7 +63,7 @@ class SearchTheWebBlock(Block, GetRequest):
class ExtractWebsiteContentBlock(Block, GetRequest): class ExtractWebsiteContentBlock(Block, GetRequest):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: JinaCredentialsInput = JinaCredentialsField() credentials: JinaCredentialsInput = JinaCredentialsField()
url: str = SchemaField(description="The URL to scrape the content from") url: str = SchemaField(description="The URL to scrape the content from")
raw_content: bool = SchemaField( raw_content: bool = SchemaField(
@@ -68,7 +73,7 @@ class ExtractWebsiteContentBlock(Block, GetRequest):
advanced=True, advanced=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
content: str = SchemaField(description="The scraped content from the given URL") content: str = SchemaField(description="The scraped content from the given URL")
error: str = SchemaField( error: str = SchemaField(
description="Error message if the content cannot be retrieved" description="Error message if the content cannot be retrieved"

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
OAuth2Credentials, OAuth2Credentials,
SchemaField, SchemaField,
@@ -22,7 +23,7 @@ from .models import CreateCommentResponse
class LinearCreateCommentBlock(Block): class LinearCreateCommentBlock(Block):
"""Block for creating comments on Linear issues""" """Block for creating comments on Linear issues"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = linear.credentials_field( credentials: CredentialsMetaInput = linear.credentials_field(
description="Linear credentials with comment creation permissions", description="Linear credentials with comment creation permissions",
required_scopes={LinearScope.COMMENTS_CREATE}, required_scopes={LinearScope.COMMENTS_CREATE},
@@ -30,12 +31,11 @@ class LinearCreateCommentBlock(Block):
issue_id: str = SchemaField(description="ID of the issue to comment on") issue_id: str = SchemaField(description="ID of the issue to comment on")
comment: str = SchemaField(description="Comment text to add to the issue") comment: str = SchemaField(description="Comment text to add to the issue")
class Output(BlockSchema): class Output(BlockSchemaOutput):
comment_id: str = SchemaField(description="ID of the created comment") comment_id: str = SchemaField(description="ID of the created comment")
comment_body: str = SchemaField( comment_body: str = SchemaField(
description="Text content of the created comment" description="Text content of the created comment"
) )
error: str = SchemaField(description="Error message if comment creation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
OAuth2Credentials, OAuth2Credentials,
SchemaField, SchemaField,
@@ -22,7 +23,7 @@ from .models import CreateIssueResponse, Issue
class LinearCreateIssueBlock(Block): class LinearCreateIssueBlock(Block):
"""Block for creating issues on Linear""" """Block for creating issues on Linear"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = linear.credentials_field( credentials: CredentialsMetaInput = linear.credentials_field(
description="Linear credentials with issue creation permissions", description="Linear credentials with issue creation permissions",
required_scopes={LinearScope.ISSUES_CREATE}, required_scopes={LinearScope.ISSUES_CREATE},
@@ -43,10 +44,9 @@ class LinearCreateIssueBlock(Block):
default=None, default=None,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
issue_id: str = SchemaField(description="ID of the created issue") issue_id: str = SchemaField(description="ID of the created issue")
issue_title: str = SchemaField(description="Title of the created issue") issue_title: str = SchemaField(description="Title of the created issue")
error: str = SchemaField(description="Error message if issue creation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -129,14 +129,14 @@ class LinearCreateIssueBlock(Block):
class LinearSearchIssuesBlock(Block): class LinearSearchIssuesBlock(Block):
"""Block for searching issues on Linear""" """Block for searching issues on Linear"""
class Input(BlockSchema): class Input(BlockSchemaInput):
term: str = SchemaField(description="Term to search for issues") term: str = SchemaField(description="Term to search for issues")
credentials: CredentialsMetaInput = linear.credentials_field( credentials: CredentialsMetaInput = linear.credentials_field(
description="Linear credentials with read permissions", description="Linear credentials with read permissions",
required_scopes={LinearScope.READ}, required_scopes={LinearScope.READ},
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
issues: list[Issue] = SchemaField(description="List of issues") issues: list[Issue] = SchemaField(description="List of issues")
def __init__(self): def __init__(self):

View File

@@ -3,7 +3,8 @@ from backend.sdk import (
Block, Block,
BlockCategory, BlockCategory,
BlockOutput, BlockOutput,
BlockSchema, BlockSchemaInput,
BlockSchemaOutput,
CredentialsMetaInput, CredentialsMetaInput,
OAuth2Credentials, OAuth2Credentials,
SchemaField, SchemaField,
@@ -22,16 +23,15 @@ from .models import Project
class LinearSearchProjectsBlock(Block): class LinearSearchProjectsBlock(Block):
"""Block for searching projects on Linear""" """Block for searching projects on Linear"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput = linear.credentials_field( credentials: CredentialsMetaInput = linear.credentials_field(
description="Linear credentials with read permissions", description="Linear credentials with read permissions",
required_scopes={LinearScope.READ}, required_scopes={LinearScope.READ},
) )
term: str = SchemaField(description="Term to search for projects") term: str = SchemaField(description="Term to search for projects")
class Output(BlockSchema): class Output(BlockSchemaOutput):
projects: list[Project] = SchemaField(description="List of projects") projects: list[Project] = SchemaField(description="List of projects")
error: str = SchemaField(description="Error message if issue creation failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -16,7 +16,13 @@ from anthropic.types import ToolParam
from groq import AsyncGroq from groq import AsyncGroq
from pydantic import BaseModel, SecretStr from pydantic import BaseModel, SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -766,7 +772,7 @@ class AIBlockBase(Block, ABC):
class AIStructuredResponseGeneratorBlock(AIBlockBase): class AIStructuredResponseGeneratorBlock(AIBlockBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
prompt: str = SchemaField( prompt: str = SchemaField(
description="The prompt to send to the language model.", description="The prompt to send to the language model.",
placeholder="Enter your prompt here...", placeholder="Enter your prompt here...",
@@ -833,12 +839,11 @@ class AIStructuredResponseGeneratorBlock(AIBlockBase):
description="Ollama host for local models", description="Ollama host for local models",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
response: dict[str, Any] | list[dict[str, Any]] = SchemaField( response: dict[str, Any] | list[dict[str, Any]] = SchemaField(
description="The response object generated by the language model." description="The response object generated by the language model."
) )
prompt: list = SchemaField(description="The prompt sent to the language model.") prompt: list = SchemaField(description="The prompt sent to the language model.")
error: str = SchemaField(description="Error message if the API call failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1207,7 +1212,7 @@ def trim_prompt(s: str) -> str:
class AITextGeneratorBlock(AIBlockBase): class AITextGeneratorBlock(AIBlockBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
prompt: str = SchemaField( prompt: str = SchemaField(
description="The prompt to send to the language model. You can use any of the {keys} from Prompt Values to fill in the prompt with values from the prompt values dictionary by putting them in curly braces.", description="The prompt to send to the language model. You can use any of the {keys} from Prompt Values to fill in the prompt with values from the prompt values dictionary by putting them in curly braces.",
placeholder="Enter your prompt here...", placeholder="Enter your prompt here...",
@@ -1245,12 +1250,11 @@ class AITextGeneratorBlock(AIBlockBase):
description="The maximum number of tokens to generate in the chat completion.", description="The maximum number of tokens to generate in the chat completion.",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
response: str = SchemaField( response: str = SchemaField(
description="The response generated by the language model." description="The response generated by the language model."
) )
prompt: list = SchemaField(description="The prompt sent to the language model.") prompt: list = SchemaField(description="The prompt sent to the language model.")
error: str = SchemaField(description="Error message if the API call failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1304,7 +1308,7 @@ class SummaryStyle(Enum):
class AITextSummarizerBlock(AIBlockBase): class AITextSummarizerBlock(AIBlockBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
text: str = SchemaField( text: str = SchemaField(
description="The text to summarize.", description="The text to summarize.",
placeholder="Enter the text to summarize here...", placeholder="Enter the text to summarize here...",
@@ -1344,10 +1348,9 @@ class AITextSummarizerBlock(AIBlockBase):
description="Ollama host for local models", description="Ollama host for local models",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
summary: str = SchemaField(description="The final summary of the text.") summary: str = SchemaField(description="The final summary of the text.")
prompt: list = SchemaField(description="The prompt sent to the language model.") prompt: list = SchemaField(description="The prompt sent to the language model.")
error: str = SchemaField(description="Error message if the API call failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1517,7 +1520,7 @@ class AITextSummarizerBlock(AIBlockBase):
class AIConversationBlock(AIBlockBase): class AIConversationBlock(AIBlockBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
prompt: str = SchemaField( prompt: str = SchemaField(
description="The prompt to send to the language model.", description="The prompt to send to the language model.",
placeholder="Enter your prompt here...", placeholder="Enter your prompt here...",
@@ -1544,12 +1547,11 @@ class AIConversationBlock(AIBlockBase):
description="Ollama host for local models", description="Ollama host for local models",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
response: str = SchemaField( response: str = SchemaField(
description="The model's response to the conversation." description="The model's response to the conversation."
) )
prompt: list = SchemaField(description="The prompt sent to the language model.") prompt: list = SchemaField(description="The prompt sent to the language model.")
error: str = SchemaField(description="Error message if the API call failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -1616,7 +1618,7 @@ class AIConversationBlock(AIBlockBase):
class AIListGeneratorBlock(AIBlockBase): class AIListGeneratorBlock(AIBlockBase):
class Input(BlockSchema): class Input(BlockSchemaInput):
focus: str | None = SchemaField( focus: str | None = SchemaField(
description="The focus of the list to generate.", description="The focus of the list to generate.",
placeholder="The top 5 most interesting news stories in the data.", placeholder="The top 5 most interesting news stories in the data.",
@@ -1653,15 +1655,12 @@ class AIListGeneratorBlock(AIBlockBase):
description="Ollama host for local models", description="Ollama host for local models",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
generated_list: List[str] = SchemaField(description="The generated list.") generated_list: List[str] = SchemaField(description="The generated list.")
list_item: str = SchemaField( list_item: str = SchemaField(
description="Each individual item in the list.", description="Each individual item in the list.",
) )
prompt: list = SchemaField(description="The prompt sent to the language model.") prompt: list = SchemaField(description="The prompt sent to the language model.")
error: str = SchemaField(
description="Error message if the list generation failed."
)
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -2,7 +2,13 @@ import operator
from enum import Enum from enum import Enum
from typing import Any from typing import Any
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
@@ -15,7 +21,7 @@ class Operation(Enum):
class CalculatorBlock(Block): class CalculatorBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
operation: Operation = SchemaField( operation: Operation = SchemaField(
description="Choose the math operation you want to perform", description="Choose the math operation you want to perform",
placeholder="Select an operation", placeholder="Select an operation",
@@ -31,7 +37,7 @@ class CalculatorBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: float = SchemaField(description="The result of your calculation") result: float = SchemaField(description="The result of your calculation")
def __init__(self): def __init__(self):
@@ -85,13 +91,13 @@ class CalculatorBlock(Block):
class CountItemsBlock(Block): class CountItemsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
collection: Any = SchemaField( collection: Any = SchemaField(
description="Enter the collection you want to count. This can be a list, dictionary, string, or any other iterable.", description="Enter the collection you want to count. This can be a list, dictionary, string, or any other iterable.",
placeholder="For example: [1, 2, 3] or {'a': 1, 'b': 2} or 'hello'", placeholder="For example: [1, 2, 3] or {'a': 1, 'b': 2} or 'hello'",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
count: int = SchemaField(description="The number of items in the collection") count: int = SchemaField(description="The number of items in the collection")
def __init__(self): def __init__(self):

View File

@@ -6,14 +6,20 @@ from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.fx.Loop import Loop from moviepy.video.fx.Loop import Loop
from moviepy.video.io.VideoFileClip import VideoFileClip from moviepy.video.io.VideoFileClip import VideoFileClip
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.file import MediaFileType, get_exec_file_path, store_media_file from backend.util.file import MediaFileType, get_exec_file_path, store_media_file
class MediaDurationBlock(Block): class MediaDurationBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
media_in: MediaFileType = SchemaField( media_in: MediaFileType = SchemaField(
description="Media input (URL, data URI, or local path)." description="Media input (URL, data URI, or local path)."
) )
@@ -22,13 +28,10 @@ class MediaDurationBlock(Block):
default=True, default=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
duration: float = SchemaField( duration: float = SchemaField(
description="Duration of the media file (in seconds)." description="Duration of the media file (in seconds)."
) )
error: str = SchemaField(
description="Error message if something fails.", default=""
)
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -70,7 +73,7 @@ class LoopVideoBlock(Block):
Block for looping (repeating) a video clip until a given duration or number of loops. Block for looping (repeating) a video clip until a given duration or number of loops.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
video_in: MediaFileType = SchemaField( video_in: MediaFileType = SchemaField(
description="The input video (can be a URL, data URI, or local path)." description="The input video (can be a URL, data URI, or local path)."
) )
@@ -90,13 +93,10 @@ class LoopVideoBlock(Block):
default="file_path", default="file_path",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_out: str = SchemaField( video_out: str = SchemaField(
description="Looped video returned either as a relative path or a data URI." description="Looped video returned either as a relative path or a data URI."
) )
error: str = SchemaField(
description="Error message if something fails.", default=""
)
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -166,7 +166,7 @@ class AddAudioToVideoBlock(Block):
Optionally scale the volume of the new track. Optionally scale the volume of the new track.
""" """
class Input(BlockSchema): class Input(BlockSchemaInput):
video_in: MediaFileType = SchemaField( video_in: MediaFileType = SchemaField(
description="Video input (URL, data URI, or local path)." description="Video input (URL, data URI, or local path)."
) )
@@ -182,13 +182,10 @@ class AddAudioToVideoBlock(Block):
default="file_path", default="file_path",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
video_out: MediaFileType = SchemaField( video_out: MediaFileType = SchemaField(
description="Final video (with attached audio), as a path or data URI." description="Final video (with attached audio), as a path or data URI."
) )
error: str = SchemaField(
description="Error message if something fails.", default=""
)
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -3,7 +3,13 @@ from typing import List, Literal
from pydantic import SecretStr from pydantic import SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
BlockSecret, BlockSecret,
@@ -37,7 +43,7 @@ class PublishToMediumStatus(str, Enum):
class PublishToMediumBlock(Block): class PublishToMediumBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
author_id: BlockSecret = SecretField( author_id: BlockSecret = SecretField(
key="medium_author_id", key="medium_author_id",
description="""The Medium AuthorID of the user. You can get this by calling the /me endpoint of the Medium API.\n\ncurl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://api.medium.com/v1/me" the response will contain the authorId field.""", description="""The Medium AuthorID of the user. You can get this by calling the /me endpoint of the Medium API.\n\ncurl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://api.medium.com/v1/me" the response will contain the authorId field.""",
@@ -84,7 +90,7 @@ class PublishToMediumBlock(Block):
description="The Medium integration can be used with any API key with sufficient permissions for the blocks it is used on.", description="The Medium integration can be used with any API key with sufficient permissions for the blocks it is used on.",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post_id: str = SchemaField(description="The ID of the created Medium post") post_id: str = SchemaField(description="The ID of the created Medium post")
post_url: str = SchemaField(description="The URL of the created Medium post") post_url: str = SchemaField(description="The URL of the created Medium post")
published_at: int = SchemaField( published_at: int = SchemaField(

View File

@@ -3,7 +3,7 @@ from typing import Any, Literal, Optional, Union
from mem0 import MemoryClient from mem0 import MemoryClient
from pydantic import BaseModel, SecretStr from pydantic import BaseModel, SecretStr
from backend.data.block import Block, BlockOutput, BlockSchema from backend.data.block import Block, BlockOutput, BlockSchemaInput, BlockSchemaOutput
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -55,7 +55,7 @@ class AddMemoryBlock(Block, Mem0Base):
Always limited by user_id and optional graph_id and graph_exec_id""" Always limited by user_id and optional graph_id and graph_exec_id"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.MEM0], Literal["api_key"] Literal[ProviderName.MEM0], Literal["api_key"]
] = CredentialsField(description="Mem0 API key credentials") ] = CredentialsField(description="Mem0 API key credentials")
@@ -74,13 +74,12 @@ class AddMemoryBlock(Block, Mem0Base):
description="Limit the memory to the agent", default=True description="Limit the memory to the agent", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
action: str = SchemaField(description="Action of the operation") action: str = SchemaField(description="Action of the operation")
memory: str = SchemaField(description="Memory created") memory: str = SchemaField(description="Memory created")
results: list[dict[str, str]] = SchemaField( results: list[dict[str, str]] = SchemaField(
description="List of all results from the operation" description="List of all results from the operation"
) )
error: str = SchemaField(description="Error message if operation fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -172,7 +171,7 @@ class AddMemoryBlock(Block, Mem0Base):
class SearchMemoryBlock(Block, Mem0Base): class SearchMemoryBlock(Block, Mem0Base):
"""Block for searching memories in Mem0""" """Block for searching memories in Mem0"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.MEM0], Literal["api_key"] Literal[ProviderName.MEM0], Literal["api_key"]
] = CredentialsField(description="Mem0 API key credentials") ] = CredentialsField(description="Mem0 API key credentials")
@@ -201,9 +200,8 @@ class SearchMemoryBlock(Block, Mem0Base):
description="Limit the memory to the agent", default=True description="Limit the memory to the agent", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
memories: Any = SchemaField(description="List of matching memories") memories: Any = SchemaField(description="List of matching memories")
error: str = SchemaField(description="Error message if operation fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -266,7 +264,7 @@ class SearchMemoryBlock(Block, Mem0Base):
class GetAllMemoriesBlock(Block, Mem0Base): class GetAllMemoriesBlock(Block, Mem0Base):
"""Block for retrieving all memories from Mem0""" """Block for retrieving all memories from Mem0"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.MEM0], Literal["api_key"] Literal[ProviderName.MEM0], Literal["api_key"]
] = CredentialsField(description="Mem0 API key credentials") ] = CredentialsField(description="Mem0 API key credentials")
@@ -289,9 +287,8 @@ class GetAllMemoriesBlock(Block, Mem0Base):
description="Limit the memory to the agent", default=True description="Limit the memory to the agent", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
memories: Any = SchemaField(description="List of memories") memories: Any = SchemaField(description="List of memories")
error: str = SchemaField(description="Error message if operation fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(
@@ -353,7 +350,7 @@ class GetAllMemoriesBlock(Block, Mem0Base):
class GetLatestMemoryBlock(Block, Mem0Base): class GetLatestMemoryBlock(Block, Mem0Base):
"""Block for retrieving the latest memory from Mem0""" """Block for retrieving the latest memory from Mem0"""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: CredentialsMetaInput[ credentials: CredentialsMetaInput[
Literal[ProviderName.MEM0], Literal["api_key"] Literal[ProviderName.MEM0], Literal["api_key"]
] = CredentialsField(description="Mem0 API key credentials") ] = CredentialsField(description="Mem0 API key credentials")
@@ -380,12 +377,11 @@ class GetLatestMemoryBlock(Block, Mem0Base):
description="Limit the memory to the agent", default=True description="Limit the memory to the agent", default=True
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
memory: Optional[dict[str, Any]] = SchemaField( memory: Optional[dict[str, Any]] = SchemaField(
description="Latest memory if found" description="Latest memory if found"
) )
found: bool = SchemaField(description="Whether a memory was found") found: bool = SchemaField(description="Whether a memory was found")
error: str = SchemaField(description="Error message if operation fails")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -4,7 +4,13 @@ from typing import Any, Dict, List, Optional
from pydantic import model_validator from pydantic import model_validator
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import NotionClient from ._api import NotionClient
@@ -20,7 +26,7 @@ from ._auth import (
class NotionCreatePageBlock(Block): class NotionCreatePageBlock(Block):
"""Create a new page in Notion with content.""" """Create a new page in Notion with content."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NotionCredentialsInput = NotionCredentialsField() credentials: NotionCredentialsInput = NotionCredentialsField()
parent_page_id: Optional[str] = SchemaField( parent_page_id: Optional[str] = SchemaField(
description="Parent page ID to create the page under. Either this OR parent_database_id is required.", description="Parent page ID to create the page under. Either this OR parent_database_id is required.",
@@ -58,10 +64,9 @@ class NotionCreatePageBlock(Block):
) )
return self return self
class Output(BlockSchema): class Output(BlockSchemaOutput):
page_id: str = SchemaField(description="ID of the created page.") page_id: str = SchemaField(description="ID of the created page.")
page_url: str = SchemaField(description="URL of the created page.") page_url: str = SchemaField(description="URL of the created page.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -2,7 +2,13 @@ from __future__ import annotations
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import NotionClient, parse_rich_text from ._api import NotionClient, parse_rich_text
@@ -18,7 +24,7 @@ from ._auth import (
class NotionReadDatabaseBlock(Block): class NotionReadDatabaseBlock(Block):
"""Query a Notion database and retrieve entries with their properties.""" """Query a Notion database and retrieve entries with their properties."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NotionCredentialsInput = NotionCredentialsField() credentials: NotionCredentialsInput = NotionCredentialsField()
database_id: str = SchemaField( database_id: str = SchemaField(
description="Notion database ID. Must be accessible by the connected integration.", description="Notion database ID. Must be accessible by the connected integration.",
@@ -44,7 +50,7 @@ class NotionReadDatabaseBlock(Block):
le=100, le=100,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
entries: List[Dict[str, Any]] = SchemaField( entries: List[Dict[str, Any]] = SchemaField(
description="List of database entries with their properties." description="List of database entries with their properties."
) )
@@ -59,7 +65,6 @@ class NotionReadDatabaseBlock(Block):
) )
count: int = SchemaField(description="Number of entries retrieved.") count: int = SchemaField(description="Number of entries retrieved.")
database_title: str = SchemaField(description="Title of the database.") database_title: str = SchemaField(description="Title of the database.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -1,6 +1,12 @@
from __future__ import annotations from __future__ import annotations
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import NotionClient from ._api import NotionClient
@@ -16,15 +22,14 @@ from ._auth import (
class NotionReadPageBlock(Block): class NotionReadPageBlock(Block):
"""Read a Notion page by ID and return its raw JSON.""" """Read a Notion page by ID and return its raw JSON."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NotionCredentialsInput = NotionCredentialsField() credentials: NotionCredentialsInput = NotionCredentialsField()
page_id: str = SchemaField( page_id: str = SchemaField(
description="Notion page ID. Must be accessible by the connected integration. You can get this from the page URL notion.so/A-Page-586edd711467478da59fe3ce29a1ffab would be 586edd711467478da59fe35e29a1ffab", description="Notion page ID. Must be accessible by the connected integration. You can get this from the page URL notion.so/A-Page-586edd711467478da59fe3ce29a1ffab would be 586edd711467478da59fe35e29a1ffab",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
page: dict = SchemaField(description="Raw Notion page JSON.") page: dict = SchemaField(description="Raw Notion page JSON.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -1,6 +1,12 @@
from __future__ import annotations from __future__ import annotations
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import NotionClient, blocks_to_markdown, extract_page_title from ._api import NotionClient, blocks_to_markdown, extract_page_title
@@ -16,7 +22,7 @@ from ._auth import (
class NotionReadPageMarkdownBlock(Block): class NotionReadPageMarkdownBlock(Block):
"""Read a Notion page and convert it to clean Markdown format.""" """Read a Notion page and convert it to clean Markdown format."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NotionCredentialsInput = NotionCredentialsField() credentials: NotionCredentialsInput = NotionCredentialsField()
page_id: str = SchemaField( page_id: str = SchemaField(
description="Notion page ID. Must be accessible by the connected integration. You can get this from the page URL notion.so/A-Page-586edd711467478da59fe35e29a1ffab would be 586edd711467478da59fe35e29a1ffab", description="Notion page ID. Must be accessible by the connected integration. You can get this from the page URL notion.so/A-Page-586edd711467478da59fe35e29a1ffab would be 586edd711467478da59fe35e29a1ffab",
@@ -26,10 +32,9 @@ class NotionReadPageMarkdownBlock(Block):
default=True, default=True,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
markdown: str = SchemaField(description="Page content in Markdown format.") markdown: str = SchemaField(description="Page content in Markdown format.")
title: str = SchemaField(description="Page title.") title: str = SchemaField(description="Page title.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -4,7 +4,13 @@ from typing import List, Optional
from pydantic import BaseModel from pydantic import BaseModel
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import OAuth2Credentials, SchemaField from backend.data.model import OAuth2Credentials, SchemaField
from ._api import NotionClient, extract_page_title, parse_rich_text from ._api import NotionClient, extract_page_title, parse_rich_text
@@ -35,7 +41,7 @@ class NotionSearchResult(BaseModel):
class NotionSearchBlock(Block): class NotionSearchBlock(Block):
"""Search across your Notion workspace for pages and databases.""" """Search across your Notion workspace for pages and databases."""
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NotionCredentialsInput = NotionCredentialsField() credentials: NotionCredentialsInput = NotionCredentialsField()
query: str = SchemaField( query: str = SchemaField(
description="Search query text. Leave empty to get all accessible pages/databases.", description="Search query text. Leave empty to get all accessible pages/databases.",
@@ -49,7 +55,7 @@ class NotionSearchBlock(Block):
description="Maximum number of results to return", default=20, ge=1, le=100 description="Maximum number of results to return", default=20, ge=1, le=100
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: List[NotionSearchResult] = SchemaField( results: List[NotionSearchResult] = SchemaField(
description="List of search results with title, type, URL, and metadata." description="List of search results with title, type, URL, and metadata."
) )
@@ -60,7 +66,6 @@ class NotionSearchBlock(Block):
description="List of IDs from search results for batch operations." description="List of IDs from search results for batch operations."
) )
count: int = SchemaField(description="Number of results found.") count: int = SchemaField(description="Number of results found.")
error: str = SchemaField(description="Error message if the operation failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -3,14 +3,20 @@ from backend.blocks.nvidia._auth import (
NvidiaCredentialsField, NvidiaCredentialsField,
NvidiaCredentialsInput, NvidiaCredentialsInput,
) )
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.request import Requests from backend.util.request import Requests
from backend.util.type import MediaFileType from backend.util.type import MediaFileType
class NvidiaDeepfakeDetectBlock(Block): class NvidiaDeepfakeDetectBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: NvidiaCredentialsInput = NvidiaCredentialsField() credentials: NvidiaCredentialsInput = NvidiaCredentialsField()
image_base64: MediaFileType = SchemaField( image_base64: MediaFileType = SchemaField(
description="Image to analyze for deepfakes", description="Image to analyze for deepfakes",
@@ -20,7 +26,7 @@ class NvidiaDeepfakeDetectBlock(Block):
default=False, default=False,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
status: str = SchemaField( status: str = SchemaField(
description="Detection status (SUCCESS, ERROR, CONTENT_FILTERED)", description="Detection status (SUCCESS, ERROR, CONTENT_FILTERED)",
) )

View File

@@ -6,7 +6,13 @@ from typing import Any, Literal
import openai import openai
from pydantic import SecretStr from pydantic import SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -54,7 +60,7 @@ def PerplexityCredentialsField() -> PerplexityCredentials:
class PerplexityBlock(Block): class PerplexityBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
prompt: str = SchemaField( prompt: str = SchemaField(
description="The query to send to the Perplexity model.", description="The query to send to the Perplexity model.",
placeholder="Enter your query here...", placeholder="Enter your query here...",
@@ -78,14 +84,13 @@ class PerplexityBlock(Block):
description="The maximum number of tokens to generate.", description="The maximum number of tokens to generate.",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
response: str = SchemaField( response: str = SchemaField(
description="The response from the Perplexity model." description="The response from the Perplexity model."
) )
annotations: list[dict[str, Any]] = SchemaField( annotations: list[dict[str, Any]] = SchemaField(
description="List of URL citations and annotations from the response." description="List of URL citations and annotations from the response."
) )
error: str = SchemaField(description="Error message if the API call failed.")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

View File

@@ -1,7 +1,13 @@
import logging import logging
from typing import Any, Literal from typing import Any, Literal
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import SchemaField from backend.data.model import SchemaField
from backend.util.clients import get_database_manager_async_client from backend.util.clients import get_database_manager_async_client
@@ -22,7 +28,7 @@ def get_storage_key(key: str, scope: StorageScope, graph_id: str) -> str:
class PersistInformationBlock(Block): class PersistInformationBlock(Block):
"""Block for persisting key-value data for the current user with configurable scope""" """Block for persisting key-value data for the current user with configurable scope"""
class Input(BlockSchema): class Input(BlockSchemaInput):
key: str = SchemaField(description="Key to store the information under") key: str = SchemaField(description="Key to store the information under")
value: Any = SchemaField(description="Value to store") value: Any = SchemaField(description="Value to store")
scope: StorageScope = SchemaField( scope: StorageScope = SchemaField(
@@ -30,7 +36,7 @@ class PersistInformationBlock(Block):
default="within_agent", default="within_agent",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
value: Any = SchemaField(description="Value that was stored") value: Any = SchemaField(description="Value that was stored")
def __init__(self): def __init__(self):
@@ -90,7 +96,7 @@ class PersistInformationBlock(Block):
class RetrieveInformationBlock(Block): class RetrieveInformationBlock(Block):
"""Block for retrieving key-value data for the current user with configurable scope""" """Block for retrieving key-value data for the current user with configurable scope"""
class Input(BlockSchema): class Input(BlockSchemaInput):
key: str = SchemaField(description="Key to retrieve the information for") key: str = SchemaField(description="Key to retrieve the information for")
scope: StorageScope = SchemaField( scope: StorageScope = SchemaField(
description="Scope of persistence: within_agent (shared across all runs of this agent) or across_agents (shared across all agents for this user)", description="Scope of persistence: within_agent (shared across all runs of this agent) or across_agents (shared across all agents for this user)",
@@ -100,7 +106,7 @@ class RetrieveInformationBlock(Block):
description="Default value to return if key is not found", default=None description="Default value to return if key is not found", default=None
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
value: Any = SchemaField(description="Retrieved value or default value") value: Any = SchemaField(description="Retrieved value or default value")
def __init__(self): def __init__(self):

View File

@@ -3,7 +3,13 @@ from typing import Any, Literal
from pinecone import Pinecone, ServerlessSpec from pinecone import Pinecone, ServerlessSpec
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
APIKeyCredentials, APIKeyCredentials,
CredentialsField, CredentialsField,
@@ -27,7 +33,7 @@ def PineconeCredentialsField() -> PineconeCredentialsInput:
class PineconeInitBlock(Block): class PineconeInitBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: PineconeCredentialsInput = PineconeCredentialsField() credentials: PineconeCredentialsInput = PineconeCredentialsField()
index_name: str = SchemaField(description="Name of the Pinecone index") index_name: str = SchemaField(description="Name of the Pinecone index")
dimension: int = SchemaField( dimension: int = SchemaField(
@@ -43,7 +49,7 @@ class PineconeInitBlock(Block):
description="Region for serverless", default="us-east-1" description="Region for serverless", default="us-east-1"
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
index: str = SchemaField(description="Name of the initialized Pinecone index") index: str = SchemaField(description="Name of the initialized Pinecone index")
message: str = SchemaField(description="Status message") message: str = SchemaField(description="Status message")
@@ -83,7 +89,7 @@ class PineconeInitBlock(Block):
class PineconeQueryBlock(Block): class PineconeQueryBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: PineconeCredentialsInput = PineconeCredentialsField() credentials: PineconeCredentialsInput = PineconeCredentialsField()
query_vector: list = SchemaField(description="Query vector") query_vector: list = SchemaField(description="Query vector")
namespace: str = SchemaField( namespace: str = SchemaField(
@@ -102,7 +108,7 @@ class PineconeQueryBlock(Block):
host: str = SchemaField(description="Host for pinecone", default="") host: str = SchemaField(description="Host for pinecone", default="")
idx_name: str = SchemaField(description="Index name for pinecone") idx_name: str = SchemaField(description="Index name for pinecone")
class Output(BlockSchema): class Output(BlockSchemaOutput):
results: Any = SchemaField(description="Query results from Pinecone") results: Any = SchemaField(description="Query results from Pinecone")
combined_results: Any = SchemaField( combined_results: Any = SchemaField(
description="Combined results from Pinecone" description="Combined results from Pinecone"
@@ -166,7 +172,7 @@ class PineconeQueryBlock(Block):
class PineconeInsertBlock(Block): class PineconeInsertBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: PineconeCredentialsInput = PineconeCredentialsField() credentials: PineconeCredentialsInput = PineconeCredentialsField()
index: str = SchemaField(description="Initialized Pinecone index") index: str = SchemaField(description="Initialized Pinecone index")
chunks: list = SchemaField(description="List of text chunks to ingest") chunks: list = SchemaField(description="List of text chunks to ingest")
@@ -181,7 +187,7 @@ class PineconeInsertBlock(Block):
default_factory=dict, default_factory=dict,
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
upsert_response: str = SchemaField( upsert_response: str = SchemaField(
description="Response from Pinecone upsert operation" description="Response from Pinecone upsert operation"
) )

View File

@@ -4,7 +4,13 @@ from typing import Iterator, Literal
import praw import praw
from pydantic import BaseModel, SecretStr from pydantic import BaseModel, SecretStr
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import ( from backend.data.model import (
CredentialsField, CredentialsField,
CredentialsMetaInput, CredentialsMetaInput,
@@ -76,7 +82,7 @@ def get_praw(creds: RedditCredentials) -> praw.Reddit:
class GetRedditPostsBlock(Block): class GetRedditPostsBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
subreddit: str = SchemaField( subreddit: str = SchemaField(
description="Subreddit name, excluding the /r/ prefix", description="Subreddit name, excluding the /r/ prefix",
default="writingprompts", default="writingprompts",
@@ -94,7 +100,7 @@ class GetRedditPostsBlock(Block):
description="Number of posts to fetch", default=10 description="Number of posts to fetch", default=10
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
post: RedditPost = SchemaField(description="Reddit post") post: RedditPost = SchemaField(description="Reddit post")
posts: list[RedditPost] = SchemaField(description="List of all Reddit posts") posts: list[RedditPost] = SchemaField(description="List of all Reddit posts")
@@ -194,11 +200,11 @@ class GetRedditPostsBlock(Block):
class PostRedditCommentBlock(Block): class PostRedditCommentBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: RedditCredentialsInput = RedditCredentialsField() credentials: RedditCredentialsInput = RedditCredentialsField()
data: RedditComment = SchemaField(description="Reddit comment") data: RedditComment = SchemaField(description="Reddit comment")
class Output(BlockSchema): class Output(BlockSchemaOutput):
comment_id: str = SchemaField(description="Posted comment ID") comment_id: str = SchemaField(description="Posted comment ID")
def __init__(self): def __init__(self):

View File

@@ -10,7 +10,13 @@ from backend.blocks.replicate._auth import (
ReplicateCredentialsInput, ReplicateCredentialsInput,
) )
from backend.blocks.replicate._helper import ReplicateOutputs, extract_result from backend.blocks.replicate._helper import ReplicateOutputs, extract_result
from backend.data.block import Block, BlockCategory, BlockOutput, BlockSchema from backend.data.block import (
Block,
BlockCategory,
BlockOutput,
BlockSchemaInput,
BlockSchemaOutput,
)
from backend.data.model import APIKeyCredentials, CredentialsField, SchemaField from backend.data.model import APIKeyCredentials, CredentialsField, SchemaField
@@ -38,7 +44,7 @@ class ImageType(str, Enum):
class ReplicateFluxAdvancedModelBlock(Block): class ReplicateFluxAdvancedModelBlock(Block):
class Input(BlockSchema): class Input(BlockSchemaInput):
credentials: ReplicateCredentialsInput = CredentialsField( credentials: ReplicateCredentialsInput = CredentialsField(
description="The Replicate integration can be used with " description="The Replicate integration can be used with "
"any API key with sufficient permissions for the blocks it is used on.", "any API key with sufficient permissions for the blocks it is used on.",
@@ -105,9 +111,8 @@ class ReplicateFluxAdvancedModelBlock(Block):
title="Safety Tolerance", title="Safety Tolerance",
) )
class Output(BlockSchema): class Output(BlockSchemaOutput):
result: str = SchemaField(description="Generated output") result: str = SchemaField(description="Generated output")
error: str = SchemaField(description="Error message if the model run failed")
def __init__(self): def __init__(self):
super().__init__( super().__init__(

Some files were not shown because too many files have changed in this diff Show More