backend changes extracted from codex/jon/SKY-5016 (#2508)

This commit is contained in:
Shuchang Zheng 2025-05-29 06:15:04 -07:00 committed by GitHub
parent 4ad65b579c
commit 08bf2bc428
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 122 additions and 9 deletions

View file

@ -46,7 +46,7 @@ from skyvern.forge.sdk.api.files import (
download_from_s3,
get_path_for_workflow_download_directory,
)
from skyvern.forge.sdk.api.llm.api_handler_factory import LLMAPIHandlerFactory
from skyvern.forge.sdk.api.llm.api_handler_factory import LLMAPIHandlerFactory, LLMCaller
from skyvern.forge.sdk.artifact.models import ArtifactType
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.db.enums import TaskType
@ -126,6 +126,7 @@ class Block(BaseModel, abc.ABC):
block_type: BlockType
output_parameter: OutputParameter
continue_on_failure: bool = False
model: dict[str, Any] | None = None
async def record_output_parameter_value(
self,
@ -618,6 +619,9 @@ class BaseTaskBlock(Block):
try:
current_context = skyvern_context.ensure_context()
current_context.task_id = task.task_id
llm_key = workflow.determine_llm_key(block=self)
llm_caller = None if not llm_key else LLMCaller(llm_key=llm_key)
await app.agent.execute_step(
organization=organization,
task=task,
@ -627,6 +631,7 @@ class BaseTaskBlock(Block):
close_browser_on_completion=browser_session_id is None,
complete_verification=self.complete_verification,
engine=self.engine,
llm_caller=llm_caller,
)
except Exception as e:
# Make sure the task is marked as failed in the database before raising the exception

View file

@ -5,10 +5,11 @@ from typing import Any, List
from pydantic import BaseModel, field_validator
from typing_extensions import deprecated
from skyvern.config import settings
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.task_v2 import TaskV2
from skyvern.forge.sdk.workflow.exceptions import WorkflowDefinitionHasDuplicateBlockLabels
from skyvern.forge.sdk.workflow.models.block import BlockTypeVar
from skyvern.forge.sdk.workflow.models.block import Block, BlockTypeVar
from skyvern.forge.sdk.workflow.models.parameter import PARAMETER_TYPE
from skyvern.schemas.runs import ProxyLocation
from skyvern.utils.url_validators import validate_url
@ -74,12 +75,41 @@ class Workflow(BaseModel):
totp_verification_url: str | None = None
totp_identifier: str | None = None
persist_browser_session: bool = False
model: dict[str, Any] | None = None
status: WorkflowStatus = WorkflowStatus.published
created_at: datetime
modified_at: datetime
deleted_at: datetime | None = None
def determine_llm_key(self, *, block: Block | None = None) -> str | None:
"""
Determine the LLM key override to use for a block, if it has one.
It has one if:
- it defines one, or
- the workflow it is a part of (if applicable) defines one
"""
mapping = settings.get_model_name_to_llm_key()
if block:
model_name = (block.model or {}).get("model")
if model_name:
llm_key = mapping.get(model_name)
if llm_key:
return llm_key
workflow_model_name = (self.model or {}).get("model")
if workflow_model_name:
llm_key = mapping.get(workflow_model_name)
if llm_key:
return llm_key
return None
class WorkflowRunStatus(StrEnum):
created = "created"

View file

@ -117,6 +117,7 @@ class BlockYAML(BaseModel, abc.ABC):
block_type: BlockType
label: str
continue_on_failure: bool = False
model: dict[str, Any] | None = None
class TaskBlockYAML(BlockYAML):
@ -413,6 +414,7 @@ class WorkflowCreateYAMLRequest(BaseModel):
totp_verification_url: str | None = None
totp_identifier: str | None = None
persist_browser_session: bool = False
model: dict[str, Any] | None = None
workflow_definition: WorkflowDefinitionYAML
is_saved_task: bool = False
status: WorkflowStatus = WorkflowStatus.published

View file

@ -180,7 +180,7 @@ class WorkflowService:
else:
raise MissingValueForParameter(
parameter_key=workflow_parameter.key,
workflow_id=workflow.workflow_permanent_id,
workflow_id=workflow.workflow_id,
workflow_run_id=workflow_run.workflow_run_id,
)
except Exception as e:
@ -336,6 +336,7 @@ class WorkflowService:
block_idx=block_idx,
block_type_var=block.block_type,
block_label=block.label,
model=block.model,
)
block_result = await block.execute_safe(
workflow_run_id=workflow_run_id,
@ -550,6 +551,7 @@ class WorkflowService:
totp_verification_url: str | None = None,
totp_identifier: str | None = None,
persist_browser_session: bool = False,
model: dict[str, Any] | None = None,
workflow_permanent_id: str | None = None,
version: int | None = None,
is_saved_task: bool = False,
@ -565,6 +567,7 @@ class WorkflowService:
totp_verification_url=totp_verification_url,
totp_identifier=totp_identifier,
persist_browser_session=persist_browser_session,
model=model,
workflow_permanent_id=workflow_permanent_id,
version=version,
is_saved_task=is_saved_task,
@ -592,6 +595,7 @@ class WorkflowService:
)
if not workflow:
raise WorkflowNotFound(workflow_permanent_id=workflow_permanent_id, version=version)
return workflow
async def get_workflows_by_permanent_ids(
@ -1403,6 +1407,7 @@ class WorkflowService:
totp_verification_url=request.totp_verification_url,
totp_identifier=request.totp_identifier,
persist_browser_session=request.persist_browser_session,
model=request.model,
workflow_permanent_id=workflow_permanent_id,
version=existing_version + 1,
is_saved_task=request.is_saved_task,
@ -1419,6 +1424,7 @@ class WorkflowService:
totp_verification_url=request.totp_verification_url,
totp_identifier=request.totp_identifier,
persist_browser_session=request.persist_browser_session,
model=request.model,
is_saved_task=request.is_saved_task,
status=request.status,
)
@ -1657,6 +1663,7 @@ class WorkflowService:
error_code_mapping=block_yaml.error_code_mapping,
max_steps_per_run=block_yaml.max_steps_per_run,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
complete_on_download=block_yaml.complete_on_download,
download_suffix=block_yaml.download_suffix,
continue_on_failure=block_yaml.continue_on_failure,
@ -1724,6 +1731,7 @@ class WorkflowService:
json_schema=block_yaml.json_schema,
output_parameter=output_parameter,
continue_on_failure=block_yaml.continue_on_failure,
model=block_yaml.model,
)
elif block_yaml.block_type == BlockType.DOWNLOAD_TO_S3:
return DownloadToS3Block(
@ -1781,6 +1789,7 @@ class WorkflowService:
file_url=block_yaml.file_url,
json_schema=block_yaml.json_schema,
continue_on_failure=block_yaml.continue_on_failure,
model=block_yaml.model,
)
elif block_yaml.block_type == BlockType.VALIDATION:
validation_block_parameters = (
@ -1803,6 +1812,7 @@ class WorkflowService:
continue_on_failure=block_yaml.continue_on_failure,
# only need one step for validation block
max_steps_per_run=1,
model=block_yaml.model,
)
elif block_yaml.block_type == BlockType.ACTION:
@ -1826,6 +1836,7 @@ class WorkflowService:
navigation_goal=block_yaml.navigation_goal,
error_code_mapping=block_yaml.error_code_mapping,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
complete_on_download=block_yaml.complete_on_download,
download_suffix=block_yaml.download_suffix,
continue_on_failure=block_yaml.continue_on_failure,
@ -1854,6 +1865,7 @@ class WorkflowService:
error_code_mapping=block_yaml.error_code_mapping,
max_steps_per_run=block_yaml.max_steps_per_run,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
complete_on_download=block_yaml.complete_on_download,
download_suffix=block_yaml.download_suffix,
continue_on_failure=block_yaml.continue_on_failure,
@ -1883,6 +1895,7 @@ class WorkflowService:
data_schema=block_yaml.data_schema,
max_steps_per_run=block_yaml.max_steps_per_run,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
continue_on_failure=block_yaml.continue_on_failure,
cache_actions=block_yaml.cache_actions,
complete_verification=False,
@ -1905,6 +1918,7 @@ class WorkflowService:
error_code_mapping=block_yaml.error_code_mapping,
max_steps_per_run=block_yaml.max_steps_per_run,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
continue_on_failure=block_yaml.continue_on_failure,
totp_verification_url=block_yaml.totp_verification_url,
totp_identifier=block_yaml.totp_identifier,
@ -1942,6 +1956,7 @@ class WorkflowService:
error_code_mapping=block_yaml.error_code_mapping,
max_steps_per_run=block_yaml.max_steps_per_run,
max_retries=block_yaml.max_retries,
model=block_yaml.model,
download_suffix=block_yaml.download_suffix,
continue_on_failure=block_yaml.continue_on_failure,
totp_verification_url=block_yaml.totp_verification_url,
@ -1959,6 +1974,7 @@ class WorkflowService:
totp_identifier=block_yaml.totp_identifier,
max_iterations=block_yaml.max_iterations,
max_steps=block_yaml.max_steps,
model=block_yaml.model,
output_parameter=output_parameter,
)
elif block_yaml.block_type == BlockType.GOTO_URL: