Merge branch 'dynamic_field' into feature/store
This commit is contained in:
commit
42bd345162
7 changed files with 118 additions and 18 deletions
|
|
@ -14,6 +14,7 @@ from langflow.api.v1.schemas import (
|
|||
)
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
from langflow.interface.custom.directory_reader import DirectoryReader
|
||||
from langflow.interface.types import build_langchain_template_custom_component, create_and_validate_component
|
||||
from langflow.processing.process import process_graph_cached, process_tweaks
|
||||
from langflow.services.auth.utils import api_key_security, get_current_active_user
|
||||
from langflow.services.cache.utils import save_uploaded_file
|
||||
|
|
@ -208,9 +209,7 @@ async def custom_component(
|
|||
raw_code: CustomComponentCode,
|
||||
user: User = Depends(get_current_active_user),
|
||||
):
|
||||
from langflow.interface.types import (
|
||||
build_langchain_template_custom_component,
|
||||
)
|
||||
component = create_and_validate_component(raw_code.code)
|
||||
|
||||
extractor = CustomComponent(code=raw_code.code)
|
||||
extractor.validate()
|
||||
|
|
@ -235,3 +234,15 @@ async def reload_custom_component(path: str):
|
|||
return build_langchain_template_custom_component(extractor, user_id=user.id)
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
|
||||
|
||||
@router.post("/custom_component/update", status_code=HTTPStatus.OK)
|
||||
async def custom_component_update(
|
||||
raw_code: CustomComponentCode,
|
||||
user: User = Depends(get_current_active_user),
|
||||
):
|
||||
component = create_and_validate_component(raw_code.code)
|
||||
|
||||
component_node = build_langchain_template_custom_component(component, user_id=user.id, update_field=raw_code.field)
|
||||
# Update the field
|
||||
return component_node
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ from enum import Enum
|
|||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from uuid import UUID
|
||||
from langflow.services.database.models.api_key.model import ApiKeyRead
|
||||
from langflow.services.database.models.flow import FlowCreate, FlowRead
|
||||
from langflow.services.database.models.user import UserRead
|
||||
from langflow.services.database.models.base import orjson_dumps
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
from langflow.services.database.models.api_key.model import ApiKeyRead
|
||||
from langflow.services.database.models.base import orjson_dumps
|
||||
from langflow.services.database.models.flow import FlowCreate, FlowRead
|
||||
from langflow.services.database.models.user import UserRead
|
||||
|
||||
|
||||
class BuildStatus(Enum):
|
||||
"""Status of the build."""
|
||||
|
|
@ -156,6 +157,7 @@ class StreamData(BaseModel):
|
|||
|
||||
class CustomComponentCode(BaseModel):
|
||||
code: str
|
||||
field: Optional[str] = None
|
||||
|
||||
|
||||
class CustomComponentResponseError(BaseModel):
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import contextlib
|
|||
import re
|
||||
import traceback
|
||||
import warnings
|
||||
from typing import Any, List, Optional, Union
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from uuid import UUID
|
||||
|
||||
from cachetools import LRUCache, cached
|
||||
|
|
@ -201,7 +201,9 @@ def update_attributes(frontend_node, template_config):
|
|||
frontend_node[attribute] = template_config[attribute]
|
||||
|
||||
|
||||
def build_field_config(custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None):
|
||||
def build_field_config(
|
||||
custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None, update_field=None
|
||||
):
|
||||
"""Build the field configuration for a custom component"""
|
||||
|
||||
try:
|
||||
|
|
@ -222,7 +224,22 @@ def build_field_config(custom_component: CustomComponent, user_id: Optional[Unio
|
|||
) from exc
|
||||
|
||||
try:
|
||||
return custom_class(user_id=user_id).build_config()
|
||||
build_config: Dict = custom_class(user_id=user_id).build_config()
|
||||
|
||||
if update_field is not None:
|
||||
try:
|
||||
field_dict = build_config.get(update_field, {})
|
||||
update_field_dict(field_dict)
|
||||
build_config[update_field] = field_dict
|
||||
except Exception as exc:
|
||||
logger.error(f"Error while getting build_config: {str(exc)}")
|
||||
else:
|
||||
for field_name, field_dict in build_config.items():
|
||||
update_field_dict(field_dict)
|
||||
build_config[field_name] = field_dict
|
||||
|
||||
return build_config
|
||||
|
||||
except Exception as exc:
|
||||
logger.error(f"Error while building field config: {str(exc)}")
|
||||
raise HTTPException(
|
||||
|
|
@ -234,6 +251,17 @@ def build_field_config(custom_component: CustomComponent, user_id: Optional[Unio
|
|||
) from exc
|
||||
|
||||
|
||||
def update_field_dict(field_dict):
|
||||
"""Update the field dictionary by calling options() or value() if they are callable"""
|
||||
if "options" in field_dict and callable(field_dict["options"]):
|
||||
field_dict["options"] = field_dict["options"]()
|
||||
# Also update the "refresh" key
|
||||
field_dict["refresh"] = True
|
||||
elif "value" in field_dict and callable(field_dict["value"]):
|
||||
field_dict["value"] = field_dict["value"]()
|
||||
field_dict["refresh"] = True
|
||||
|
||||
|
||||
def add_extra_fields(frontend_node, field_config, function_args):
|
||||
"""Add extra fields to the frontend node"""
|
||||
if not function_args:
|
||||
|
|
@ -314,7 +342,9 @@ def add_output_types(frontend_node, return_types: List[str]):
|
|||
|
||||
|
||||
def build_langchain_template_custom_component(
|
||||
custom_component: CustomComponent, user_id: Optional[Union[str, UUID]] = None
|
||||
custom_component: CustomComponent,
|
||||
user_id: Optional[Union[str, UUID]] = None,
|
||||
update_field: Optional[str] = None,
|
||||
):
|
||||
"""Build a custom component template for the langchain"""
|
||||
try:
|
||||
|
|
@ -328,7 +358,7 @@ def build_langchain_template_custom_component(
|
|||
|
||||
update_attributes(frontend_node, template_config)
|
||||
logger.debug("Updated attributes")
|
||||
field_config = build_field_config(custom_component, user_id=user_id)
|
||||
field_config = build_field_config(custom_component, user_id=user_id, update_field=update_field)
|
||||
logger.debug("Built field config")
|
||||
entrypoint_args = custom_component.get_function_entrypoint_args
|
||||
|
||||
|
|
@ -514,3 +544,9 @@ def merge_nested_dicts(dict1, dict2):
|
|||
else:
|
||||
dict1[key] = value
|
||||
return dict1
|
||||
|
||||
|
||||
def create_and_validate_component(code: str) -> CustomComponent:
|
||||
component = CustomComponent(code=code)
|
||||
component.is_check_valid()
|
||||
return component
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ class TemplateFieldCreator(BaseModel, ABC):
|
|||
info: Optional[str] = ""
|
||||
"""Additional information about the field to be shown in the tooltip. Defaults to an empty string."""
|
||||
|
||||
refresh: bool = False
|
||||
"""Specifies if the field should be refreshed. Defaults to False."""
|
||||
|
||||
def to_dict(self):
|
||||
result = self.model_dump()
|
||||
# Remove key if it is None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue