fix input text action with no text in GET steps API (#421)

This commit is contained in:
Kerem Yilmaz
2024-06-05 13:18:35 -07:00
committed by GitHub
parent cf3fb71012
commit 3f3fbbc63d
7 changed files with 53 additions and 70 deletions

View File

@@ -1,6 +1,5 @@
import abc
from enum import StrEnum
from typing import Any, Dict, List
from typing import Any, Dict
import structlog
from deprecation import deprecated
@@ -27,17 +26,6 @@ class ActionType(StrEnum):
SOLVE_CAPTCHA = "solve_captcha"
TERMINATE = "terminate"
COMPLETE = "complete"
# Note: Remember to update ActionTypeUnion with new actions
class Action(BaseModel):
action_type: ActionType
description: str | None = None
reasoning: str | None = None
class WebAction(Action, abc.ABC):
element_id: str
class UserDefinedError(BaseModel):
@@ -46,8 +34,41 @@ class UserDefinedError(BaseModel):
confidence_float: float = Field(..., ge=0, le=1)
class DecisiveAction(Action, abc.ABC):
errors: List[UserDefinedError] = []
class SelectOption(BaseModel):
label: str | None
value: str | None
index: int | None
def __repr__(self) -> str:
return f"SelectOption(label={self.label}, value={self.value}, index={self.index})"
class Action(BaseModel):
action_type: ActionType
description: str | None = None
reasoning: str | None = None
element_id: str | None = None
# DecisiveAction (CompleteAction, TerminateAction) fields
errors: list[UserDefinedError] | None = None
data_extraction_goal: str | None = None
# WebAction fields
file_name: str | None = None
file_url: str | None = None
download: bool | None = None
is_upload_file_tag: bool | None = None
text: str | None = None
option: SelectOption | None = None
is_checked: bool | None = None
class WebAction(Action):
element_id: str
class DecisiveAction(Action):
errors: list[UserDefinedError] = []
class ClickAction(WebAction):
@@ -55,6 +76,9 @@ class ClickAction(WebAction):
file_url: str | None = None
download: bool = False
def __repr__(self) -> str:
return f"ClickAction(element_id={self.element_id}, file_url={self.file_url}, download={self.download})"
class InputTextAction(WebAction):
action_type: ActionType = ActionType.INPUT_TEXT
@@ -90,15 +114,6 @@ class SolveCaptchaAction(Action):
action_type: ActionType = ActionType.SOLVE_CAPTCHA
class SelectOption(BaseModel):
label: str | None
value: str | None
index: int | None
def __repr__(self) -> str:
return f"SelectOption(label={self.label}, value={self.value}, index={self.index})"
class SelectOptionAction(WebAction):
action_type: ActionType = ActionType.SELECT_OPTION
option: SelectOption
@@ -221,8 +236,8 @@ def parse_action(action: Dict[str, Any], data_extraction_goal: str | None = None
raise UnsupportedActionType(action_type=action_type)
def parse_actions(task: Task, json_response: List[Dict[str, Any]]) -> List[Action]:
actions: List[Action] = []
def parse_actions(task: Task, json_response: list[Dict[str, Any]]) -> list[Action]:
actions: list[Action] = []
for action in json_response:
try:
action_instance = parse_action(action=action, data_extraction_goal=task.data_extraction_goal)
@@ -257,7 +272,6 @@ def parse_actions(task: Task, json_response: List[Dict[str, Any]]) -> List[Actio
raw_action=action,
exc_info=True,
)
return actions
@@ -268,20 +282,3 @@ class ScrapeResult(BaseModel):
"""
scraped_data: dict[str, Any] | list[dict[str, Any]]
# https://blog.devgenius.io/deserialize-child-classes-with-pydantic-that-gonna-work-784230e1cf83
ActionTypeUnion = (
ClickAction
| InputTextAction
| UploadFileAction
# Deprecated
# | DownloadFileAction
| SelectOptionAction
| CheckboxAction
| WaitAction
| NullAction
| SolveCaptchaAction
| TerminateAction
| CompleteAction
)

View File

@@ -5,7 +5,7 @@ from typing import Any
from pydantic import BaseModel
from skyvern.forge.sdk.settings_manager import SettingsManager
from skyvern.webeye.actions.actions import Action, ActionTypeUnion, DecisiveAction, UserDefinedError
from skyvern.webeye.actions.actions import Action, DecisiveAction, UserDefinedError
from skyvern.webeye.actions.responses import ActionResult
from skyvern.webeye.scraper.scraper import ScrapedPage
@@ -18,7 +18,7 @@ class AgentStepOutput(BaseModel):
# Will be deprecated once we move to the new format below
action_results: list[ActionResult] | None = None
# Nullable for backwards compatibility, once backfill is done, this won't be nullable anymore
actions_and_results: list[tuple[ActionTypeUnion, list[ActionResult]]] | None = None
actions_and_results: list[tuple[Action, list[ActionResult]]] | None = None
errors: list[UserDefinedError] = []
def __repr__(self) -> str:
@@ -38,7 +38,7 @@ class DetailedAgentStepOutput(BaseModel):
llm_response: dict[str, Any] | None
actions: list[Action] | None
action_results: list[ActionResult] | None
actions_and_results: list[tuple[ActionTypeUnion, list[ActionResult]]] | None
actions_and_results: list[tuple[Action, list[ActionResult]]] | None
class Config:
exclude = ["scraped_page", "extract_action_prompt"]