support magic link in CUA engine (#3780)
This commit is contained in:
@@ -40,12 +40,15 @@ dependencies = [
|
|||||||
"types-toml>=0.10.8.7,<0.11",
|
"types-toml>=0.10.8.7,<0.11",
|
||||||
"httpx[socks]>=0.27.0",
|
"httpx[socks]>=0.27.0",
|
||||||
"filetype>=1.2.0,<2",
|
"filetype>=1.2.0,<2",
|
||||||
|
"redis>=5.0.3,<6",
|
||||||
"onnxruntime>=1.20.0,<1.23.0 ; python_version >= '3.12' and python_version < '3.14'",
|
"onnxruntime>=1.20.0,<1.23.0 ; python_version >= '3.12' and python_version < '3.14'",
|
||||||
"onnxruntime<1.17 ; python_version >= '3.11' and python_version < '3.12'",
|
"onnxruntime<1.17 ; python_version >= '3.11' and python_version < '3.12'",
|
||||||
"aioredlock>=0.7.3,<0.8",
|
"aioredlock>=0.7.3,<0.8",
|
||||||
|
"stripe>=9.7.0,<10",
|
||||||
"tldextract>=5.1.2,<6",
|
"tldextract>=5.1.2,<6",
|
||||||
"websockets~=12.0",
|
"websockets~=12.0",
|
||||||
"email-validator>=2.2.0,<3",
|
"email-validator>=2.2.0,<3",
|
||||||
|
"temporalio>=1.6.0,<2",
|
||||||
"requests-toolbelt>=1.0.0,<2",
|
"requests-toolbelt>=1.0.0,<2",
|
||||||
"rich[jupyter]>=13.7.0,<14",
|
"rich[jupyter]>=13.7.0,<14",
|
||||||
"posthog>=3.7.0,<4",
|
"posthog>=3.7.0,<4",
|
||||||
@@ -70,16 +73,11 @@ dependencies = [
|
|||||||
"openpyxl>=3.1.5,<4",
|
"openpyxl>=3.1.5,<4",
|
||||||
"pandas>=2.3.1,<3",
|
"pandas>=2.3.1,<3",
|
||||||
"azure-identity>=1.24.0,<2",
|
"azure-identity>=1.24.0,<2",
|
||||||
"azure-keyvault-secrets>=4.2.0,<5",
|
"azure-keyvault>=4.2.0,<5",
|
||||||
|
"dramatiq[asyncio]>=1.18.0,<2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
cloud = [
|
|
||||||
"stripe>=9.7.0,<10",
|
|
||||||
"temporalio>=1.6.0,<2",
|
|
||||||
"dramatiq[asyncio]>=1.18.0,<2",
|
|
||||||
"redis>=5.0.3,<6",
|
|
||||||
]
|
|
||||||
dev = [
|
dev = [
|
||||||
"isort>=5.13.2,<6",
|
"isort>=5.13.2,<6",
|
||||||
"mypy>=1.18.2,<2",
|
"mypy>=1.18.2,<2",
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ Help the user decide what to do next based on the assistant's message. Here's th
|
|||||||
- solve_captcha: the task is blocked by captcha and the assistant is asking the user to solve the captcha
|
- solve_captcha: the task is blocked by captcha and the assistant is asking the user to solve the captcha
|
||||||
- complete: the user goal has been achieved
|
- complete: the user goal has been achieved
|
||||||
- get_verification_code: the assistant is asking the user to provide a verification code (2FA, MFA or TOTP code). At this point, the code should have been sent to the user. If code hasn't been sent, do not return get_verification_code action.
|
- get_verification_code: the assistant is asking the user to provide a verification code (2FA, MFA or TOTP code). At this point, the code should have been sent to the user. If code hasn't been sent, do not return get_verification_code action.
|
||||||
|
- get_magic_link: the assistant is asking the user to verify the authorization by a magic link in the email. At this point, the link should have been sent to the user.
|
||||||
- other: the assistant is asking the user to do something else
|
- other: the assistant is asking the user to do something else
|
||||||
|
|
||||||
Return the action to take next in the following JSON format:
|
Return the action to take next in the following JSON format:
|
||||||
{
|
{
|
||||||
"action": str // complete, solve_captcha, get_verification_code, other
|
"action": str // complete, solve_captcha, get_verification_code, get_magic_link, other
|
||||||
"useful_information": str // If there is any useful information the assistant has provided that contributes to the user goal, put it here.
|
"useful_information": str // If there is any useful information the assistant has provided that contributes to the user goal, put it here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from skyvern.webeye.actions.actions import (
|
|||||||
CompleteAction,
|
CompleteAction,
|
||||||
DownloadFileAction,
|
DownloadFileAction,
|
||||||
DragAction,
|
DragAction,
|
||||||
|
GotoUrlAction,
|
||||||
InputOrSelectContext,
|
InputOrSelectContext,
|
||||||
InputTextAction,
|
InputTextAction,
|
||||||
KeypressAction,
|
KeypressAction,
|
||||||
@@ -799,6 +800,53 @@ async def generate_cua_fallback_actions(
|
|||||||
reasoning=reasoning,
|
reasoning=reasoning,
|
||||||
intention=reasoning,
|
intention=reasoning,
|
||||||
)
|
)
|
||||||
|
elif skyvern_action_type == "get_magic_link":
|
||||||
|
if (task.totp_verification_url or task.totp_identifier) and task.organization_id:
|
||||||
|
LOG.info(
|
||||||
|
"Getting magic link for CUA",
|
||||||
|
task_id=task.task_id,
|
||||||
|
organization_id=task.organization_id,
|
||||||
|
workflow_run_id=task.workflow_run_id,
|
||||||
|
totp_verification_url=task.totp_verification_url,
|
||||||
|
totp_identifier=task.totp_identifier,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
otp_value = await poll_otp_value(
|
||||||
|
organization_id=task.organization_id,
|
||||||
|
task_id=task.task_id,
|
||||||
|
workflow_run_id=task.workflow_run_id,
|
||||||
|
totp_verification_url=task.totp_verification_url,
|
||||||
|
totp_identifier=task.totp_identifier,
|
||||||
|
)
|
||||||
|
if not otp_value or otp_value.get_otp_type() != OTPType.MAGIC_LINK:
|
||||||
|
raise NoTOTPVerificationCodeFound()
|
||||||
|
magic_link = otp_value.value
|
||||||
|
reasoning = reasoning or "Received magic link. Navigating to the magic link URL to verify the login"
|
||||||
|
action = GotoUrlAction(
|
||||||
|
url=magic_link,
|
||||||
|
reasoning=reasoning,
|
||||||
|
intention=reasoning,
|
||||||
|
)
|
||||||
|
except NoTOTPVerificationCodeFound:
|
||||||
|
reasoning_suffix = "No magic link found"
|
||||||
|
reasoning = f"{reasoning}. {reasoning_suffix}" if reasoning else reasoning_suffix
|
||||||
|
action = TerminateAction(
|
||||||
|
reasoning=reasoning,
|
||||||
|
intention=reasoning,
|
||||||
|
)
|
||||||
|
except FailedToGetTOTPVerificationCode as e:
|
||||||
|
reasoning_suffix = f"Failed to get magic link. Reason: {e.reason}"
|
||||||
|
reasoning = f"{reasoning}. {reasoning_suffix}" if reasoning else reasoning_suffix
|
||||||
|
action = TerminateAction(
|
||||||
|
reasoning=reasoning,
|
||||||
|
intention=reasoning,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
action = TerminateAction(
|
||||||
|
reasoning=reasoning,
|
||||||
|
intention=reasoning,
|
||||||
|
)
|
||||||
|
|
||||||
elif skyvern_action_type == "get_verification_code":
|
elif skyvern_action_type == "get_verification_code":
|
||||||
if (task.totp_verification_url or task.totp_identifier) and task.organization_id:
|
if (task.totp_verification_url or task.totp_identifier) and task.organization_id:
|
||||||
LOG.info(
|
LOG.info(
|
||||||
|
|||||||
Reference in New Issue
Block a user