[SKY-8863] Address spillover (#5457)
Some checks are pending
Run tests and pre-commit / Run tests and pre-commit hooks (push) Waiting to run
Run tests and pre-commit / Frontend Lint and Build (push) Waiting to run
Publish Fern Docs / run (push) Waiting to run

This commit is contained in:
Aaron Perez 2026-04-10 13:34:25 -05:00 committed by GitHub
parent 8c13eca7ee
commit 9c945ee480
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 77 additions and 39 deletions

View file

@ -58,7 +58,7 @@ tabs:
demo: demo:
display-name: Book a demo display-name: Book a demo
icon: calendar icon: calendar
href: https://meetings.hubspot.com/skyvern/demo href: https://www.skyvern.com/contact
navigation: navigation:
- tab: home - tab: home
layout: layout:

View file

@ -63,7 +63,7 @@ To read about specific blocks, check out [the block documentation](/workflows/wo
## Managing Credentials and Sensitive Information ## Managing Credentials and Sensitive Information
This is something the Skyvern team will need to set you up with today. If you're interested, please [book a call with Suchintan](https://meetings.hubspot.com/skyvern/demo) This is something the Skyvern team will need to set you up with today. If you're interested, please [book a call with Suchintan](https://www.skyvern.com/contact)
## Common concepts ## Common concepts

View file

@ -42,7 +42,7 @@ Inputs:
6. **Max Retries *(optional):*** the number of times a step can be retried if it fails 6. **Max Retries *(optional):*** the number of times a step can be retried if it fails
7. **Complete on Download *(optional):*** Allows Skyvern to complete the task after a file has been downloaded 7. **Complete on Download *(optional):*** Allows Skyvern to complete the task after a file has been downloaded
8. **File Suffix *(optional):*** an identifier attached to the downloaded file 8. **File Suffix *(optional):*** an identifier attached to the downloaded file
9. **TOTP URL and TOTP Identifier *(optional):*** if you have an internal system where you can store the 2FA TOTP code, this URL calls on this storage space. The identifier allows you to link the code to the task, this is critical if you are running multiple tasks concurrently. [Contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) if you would like to set up 2FA retreival in your workflows. 9. **TOTP URL and TOTP Identifier *(optional):*** if you have an internal system where you can store the 2FA TOTP code, this URL calls on this storage space. The identifier allows you to link the code to the task, this is critical if you are running multiple tasks concurrently. [Contact us](https://www.skyvern.com/contact)
10. **Parameters *(optional):*** parameters are self-defined placeholders that are specified run-to-run. They can either be workflow parameters, passed in via an API call, or output parameters, extracted from a previous task block. If specified, they are used by Skyvern to assist in the navigation, to fill out forms or further influence what actions to take on a website. 10. **Parameters *(optional):*** parameters are self-defined placeholders that are specified run-to-run. They can either be workflow parameters, passed in via an API call, or output parameters, extracted from a previous task block. If specified, they are used by Skyvern to assist in the navigation, to fill out forms or further influence what actions to take on a website.
@ -78,7 +78,7 @@ Iterate over something such as a CSV or the output of a previous block. The bloc
Inputs: Inputs:
1. **Loop Value *(required):*** This is the value that the loop will iterate over. For instance, if you have for every invoice ID, do X, invoice ID would be the value for this input. 1. **Loop Value *(required):*** This is the value that the loop will iterate over. For instance, if you have for every invoice ID, do X, invoice ID would be the value for this input.
* Please [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) if you would like to add a loop block. Since were in beta, the loop value needs to be parameterized from the backend. * Please [contact us](https://www.skyvern.com/contact)
2. **Another block nested within the loop (required)** 2. **Another block nested within the loop (required)**
@ -222,7 +222,7 @@ Inputs:
1. **Recipients *(required):*** a list of people who will receive the email separated by commas 1. **Recipients *(required):*** a list of people who will receive the email separated by commas
2. **Subject/Body *(optional):*** the header and body of an email 2. **Subject/Body *(optional):*** the header and body of an email
3. **File attachments *(optional):*** since were still in beta, you will need to [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) to upload attachments to the email 3. **File attachments *(optional):*** since were still in beta, you will need to [contact us](https://www.skyvern.com/contact)
## FileParserBlock ## FileParserBlock
@ -240,4 +240,4 @@ Downloads and parses a file to be used within other workflow blocks.
Inputs: Inputs:
1. **File URL *(required):*** This block allows you to use CSV, TSV, Excel, and PDF files within your workflow. 1. **File URL *(required):*** This block allows you to use CSV, TSV, Excel, and PDF files within your workflow.
* Since were still in beta, you will need to [contact us](https://meetings.hubspot.com/skyvern/demo?uuid=7c83865f-1a92-4c44-9e52-1ba0dbc04f7a) to load a value into this block * Since were still in beta, you will need to [contact us](https://www.skyvern.com/contact)

View file

@ -360,7 +360,7 @@ function PasswordCredentialContent({
</div> </div>
<p className="text-sm text-slate-400"> <p className="text-sm text-slate-400">
<Link <Link
to="https://meetings.hubspot.com/skyvern/demo" to="https://www.skyvern.com/contact"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="underline underline-offset-2" className="underline underline-offset-2"

View file

@ -556,10 +556,10 @@ function WorkflowRun() {
</div> </div>
)} )}
<div className="flex h-[42rem] gap-6"> <div className="flex h-[42rem] gap-6">
<div className="w-2/3"> <div className="min-w-0 flex-[2]">
<Outlet /> <Outlet />
</div> </div>
<div className="w-1/3 min-w-0 overflow-hidden"> <div className="min-w-0 flex-1 overflow-hidden">
<WorkflowRunTimeline <WorkflowRunTimeline
activeItem={selection} activeItem={selection}
onActionItemSelected={(item) => { onActionItemSelected={(item) => {

View file

@ -22,7 +22,7 @@ function WorkflowsBetaAlertCard() {
</Button> </Button>
<Button asChild> <Button asChild>
<a <a
href="https://meetings.hubspot.com/skyvern/demo" href="https://www.skyvern.com/contact"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >

View file

@ -72,7 +72,9 @@ function ActionCard({ action, onClick, active, index, cardClassName }: Props) {
)} )}
</div> </div>
</div> </div>
<div className="text-xs text-slate-400">{action.reasoning}</div> <div className="break-words text-xs text-slate-400">
{action.reasoning}
</div>
{action.action_type === ActionTypes.InputText && ( {action.action_type === ActionTypes.InputText && (
<> <>
<Separator /> <Separator />

View file

@ -31,7 +31,7 @@ function ThoughtCard({ thought, onClick, active, cardClassName }: Props) {
</StatusPill> </StatusPill>
</div> </div>
{(thought.answer || thought.thought) && ( {(thought.answer || thought.thought) && (
<div className="text-xs text-slate-400"> <div className="break-words text-xs text-slate-400">
{thought.answer || thought.thought} {thought.answer || thought.thought}
</div> </div>
)} )}

View file

@ -91,7 +91,7 @@ function WorkflowRunTimeline({
</div> </div>
</div> </div>
<ScrollArea> <ScrollArea>
<ScrollAreaViewport className="h-[37rem] max-h-[37rem] [&>div]:!overflow-x-hidden"> <ScrollAreaViewport className="h-[37rem] max-h-[37rem] [&>div]:!block [&>div]:!overflow-x-hidden">
<div className="space-y-4 p-1"> <div className="space-y-4 p-1">
{workflowRunIsNotFinalized && ( {workflowRunIsNotFinalized && (
<div <div

View file

@ -7,7 +7,7 @@ import {
ExternalLinkIcon, ExternalLinkIcon,
ReloadIcon, ReloadIcon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
import { useCallback, useEffect, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { useShimmerText } from "./useShimmerText"; import { useShimmerText } from "./useShimmerText";
@ -117,6 +117,51 @@ function truncateValue(value: string, maxLength = 120): string {
return `${collapsed.slice(0, maxLength - 3)}...`; return `${collapsed.slice(0, maxLength - 3)}...`;
} }
/**
* Renders a loop value with line-clamp-2. Shows a tooltip with the full
* value only when the CSS clamp actually truncates the visible text.
*/
function LoopValueCode({
collapsed,
fullValue,
}: {
collapsed: string;
fullValue: string;
}) {
const codeRef = useRef<HTMLElement>(null);
const [isClamped, setIsClamped] = useState(false);
useEffect(() => {
const el = codeRef.current;
if (el) {
setIsClamped(el.scrollHeight > el.clientHeight + 1);
}
}, [collapsed]);
return (
<TooltipProvider delayDuration={300}>
<Tooltip open={isClamped ? undefined : false}>
<TooltipTrigger asChild>
<code
ref={codeRef}
className="line-clamp-2 block min-w-0 break-all rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-300"
>
{collapsed}
</code>
</TooltipTrigger>
{isClamped && (
<TooltipContent
side="top"
className="max-w-xs break-all font-mono text-[11px]"
>
{fullValue}
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
);
}
function getLoopIterationGroups( function getLoopIterationGroups(
items: Array<WorkflowRunTimelineItem>, items: Array<WorkflowRunTimelineItem>,
): Array<LoopIterationGroup> { ): Array<LoopIterationGroup> {
@ -440,7 +485,7 @@ function WorkflowRunTimelineBlockItem({
}} }}
ref={refCallback} ref={refCallback}
> >
<div className="min-w-0 space-y-4 overflow-hidden p-4"> <div className="min-w-0 space-y-4 p-4">
<div className="space-y-2"> <div className="space-y-2">
<div className="flex justify-between"> <div className="flex justify-between">
<div className="flex gap-3"> <div className="flex gap-3">
@ -512,10 +557,12 @@ function WorkflowRunTimelineBlockItem({
</div> </div>
</div> </div>
{block.description ? ( {block.description ? (
<div className="text-xs text-slate-400">{block.description}</div> <div className="break-words text-xs text-slate-400">
{block.description}
</div>
) : null} ) : null}
{isLoopBlock && ( {isLoopBlock && (
<div className="min-w-0 space-y-2 overflow-hidden rounded bg-slate-elevation5 px-3 py-2 text-xs"> <div className="min-w-0 space-y-2 rounded bg-slate-elevation5 px-3 py-2 text-xs">
<div className="text-slate-300"> <div className="text-slate-300">
Iterable values:{" "} Iterable values:{" "}
<span className="font-medium text-slate-200"> <span className="font-medium text-slate-200">
@ -530,26 +577,15 @@ function WorkflowRunTimelineBlockItem({
return ( return (
<div <div
key={index} key={index}
className="flex min-w-0 text-slate-400" className="flex min-w-0 break-words text-slate-400"
> >
<span className="mr-1 shrink-0 text-slate-500"> <span className="mr-1 shrink-0 text-slate-500">
[{index}] [{index}]
</span> </span>
<TooltipProvider delayDuration={300}> <LoopValueCode
<Tooltip> collapsed={collapsed}
<TooltipTrigger asChild> fullValue={fullValue}
<code className="block min-w-0 truncate rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-300"> />
{collapsed}
</code>
</TooltipTrigger>
<TooltipContent
side="top"
className="max-w-xs break-all font-mono text-[11px]"
>
{fullValue}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div> </div>
); );
})} })}
@ -584,7 +620,7 @@ function WorkflowRunTimelineBlockItem({
) : ( ) : (
<div className="space-y-1"> <div className="space-y-1">
<div className="text-slate-400"> <div className="text-slate-400">
<code className="rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-300"> <code className="break-all rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-300">
{evaluation.original_expression} {evaluation.original_expression}
</code> </code>
</div> </div>
@ -593,7 +629,7 @@ function WorkflowRunTimelineBlockItem({
evaluation.original_expression && ( evaluation.original_expression && (
<div className="text-slate-400"> <div className="text-slate-400">
rendered to{" "} rendered to{" "}
<code className="rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-200"> <code className="break-all rounded bg-slate-elevation1 px-1 py-0.5 font-mono text-slate-200">
{evaluation.rendered_expression} {evaluation.rendered_expression}
</code> </code>
</div> </div>
@ -637,7 +673,7 @@ function WorkflowRunTimelineBlockItem({
block.executed_branch_expression !== undefined ? ( block.executed_branch_expression !== undefined ? (
<div className="text-slate-300"> <div className="text-slate-300">
Condition{" "} Condition{" "}
<code className="rounded bg-slate-elevation3 px-1.5 py-0.5 font-mono text-slate-200"> <code className="break-all rounded bg-slate-elevation3 px-1.5 py-0.5 font-mono text-slate-200">
{block.executed_branch_expression} {block.executed_branch_expression}
</code>{" "} </code>{" "}
evaluated to{" "} evaluated to{" "}
@ -739,7 +775,7 @@ function WorkflowRunTimelineBlockItem({
<TooltipProvider delayDuration={300}> <TooltipProvider delayDuration={300}>
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<code className="max-w-[70%] truncate rounded bg-slate-elevation1 px-1 py-0.5 text-[11px] text-slate-300"> <code className="min-w-0 truncate rounded bg-slate-elevation1 px-1 py-0.5 text-[11px] text-slate-300">
current_value: {currentValuePreview} current_value: {currentValuePreview}
</code> </code>
</TooltipTrigger> </TooltipTrigger>
@ -752,14 +788,14 @@ function WorkflowRunTimelineBlockItem({
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
) : ( ) : (
<code className="max-w-[70%] truncate rounded bg-slate-elevation1 px-1 py-0.5 text-[11px] text-slate-300"> <code className="min-w-0 truncate rounded bg-slate-elevation1 px-1 py-0.5 text-[11px] text-slate-300">
current_value: {currentValuePreview} current_value: {currentValuePreview}
</code> </code>
)} )}
</button> </button>
</CollapsibleTrigger> </CollapsibleTrigger>
</div> </div>
<CollapsibleContent className="min-w-0 overflow-hidden px-2 pb-2 pt-2"> <CollapsibleContent className="min-w-0 px-2 pb-2 pt-2">
<TimelineSubItems <TimelineSubItems
items={group.items} items={group.items}
activeItem={activeItem} activeItem={activeItem}