Add instruction for running generated code locally (#3739)

This commit is contained in:
Jonathan Dobson
2025-10-16 08:03:24 -04:00
committed by GitHub
parent 9d27bb0f65
commit 881396389e
2 changed files with 71 additions and 7 deletions

View File

@@ -13,6 +13,7 @@ import {
ChevronLeftIcon, ChevronLeftIcon,
CopyIcon, CopyIcon,
GlobeIcon, GlobeIcon,
PlayIcon,
ReloadIcon, ReloadIcon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
import { useParams, useSearchParams } from "react-router-dom"; import { useParams, useSearchParams } from "react-router-dom";
@@ -40,12 +41,13 @@ import {
import { Splitter } from "@/components/Splitter"; import { Splitter } from "@/components/Splitter";
import { import {
Dialog, Dialog,
DialogClose,
DialogContent, DialogContent,
DialogDescription, DialogDescription,
DialogFooter, DialogFooter,
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
DialogClose, DialogTrigger,
} from "@/components/ui/dialog"; } from "@/components/ui/dialog";
import { toast } from "@/components/ui/use-toast"; import { toast } from "@/components/ui/use-toast";
import { BrowserStream } from "@/components/BrowserStream"; import { BrowserStream } from "@/components/BrowserStream";
@@ -108,6 +110,65 @@ interface Dom {
splitLeft: MutableRefObject<HTMLInputElement | null>; splitLeft: MutableRefObject<HTMLInputElement | null>;
} }
function bash(text: string, alternateText?: string) {
return (
<div className="flex items-center justify-start gap-1">
<CopyText className="min-w-[2.25rem]" text={alternateText ?? text} />
<code className="text-xs text-[lightblue]">{text}</code>
</div>
);
}
function CopyAndExplainCode({ code }: { code: string }) {
const [isOpen, setIsOpen] = useState(false);
const numCodeLines = code.split("\n").length;
return (
<div className="flex items-center justify-end">
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger asChild>
<Button variant="tertiary" size="sm">
<div className="flex items-center justify-center gap-2">
<div>Run Locally</div>
<PlayIcon />
</div>
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Run This Code</DialogTitle>
<DialogDescription>
Set up skyvern in your environment and run the code on your own.
</DialogDescription>
</DialogHeader>
<div>
<div>1. Install skyvern: {bash("pip install skyvern")}</div>
<div>2. Set up skyvern: {bash("skyvern quickstart")}</div>
<div>
3. Copy-paste the code and save it in a file, for example{" "}
<code>main.py</code>{" "}
{bash(`copy code [${numCodeLines} line(s)]`, code)}
</div>
<div>
4. Run the code:{" "}
{bash(
'skyvern run code --params \'{"param1": "val1", "param2": "val2"}\' main.py',
)}
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsOpen(false)}>
Ok
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<CopyText text={code} />
</div>
);
}
function CopyText({ className, text }: { className?: string; text: string }) { function CopyText({ className, text }: { className?: string; text: string }) {
const [wasCopied, setWasCopied] = useState(false); const [wasCopied, setWasCopied] = useState(false);
@@ -132,8 +193,6 @@ function CopyText({ className, text }: { className?: string; text: string }) {
); );
} }
export { CopyText };
function Workspace({ function Workspace({
initialNodes, initialNodes,
initialEdges, initialEdges,
@@ -1209,8 +1268,8 @@ function Workspace({
})} })}
> >
<div className="relative mt-[8.5rem] w-full p-6 pr-5 pt-0"> <div className="relative mt-[8.5rem] w-full p-6 pr-5 pt-0">
<div className="absolute right-[1.25rem] top-0 z-20"> <div className="absolute right-[2rem] top-[0.75rem] z-20">
<CopyText text={code} /> <CopyAndExplainCode code={code} />
</div> </div>
<CodeEditor <CodeEditor
className={cn("w-full overflow-y-scroll", { className={cn("w-full overflow-y-scroll", {
@@ -1428,4 +1487,4 @@ function Workspace({
); );
} }
export { Workspace }; export { CopyText, CopyAndExplainCode, Workspace };

View File

@@ -21,6 +21,8 @@ import { constructCacheKeyValue } from "@/routes/workflows/editor/utils";
import { getCode, getOrderedBlockLabels } from "@/routes/workflows/utils"; import { getCode, getOrderedBlockLabels } from "@/routes/workflows/utils";
import { cn } from "@/util/utils"; import { cn } from "@/util/utils";
import { CopyAndExplainCode } from "../editor/Workspace";
interface Props { interface Props {
showCacheKeyValueSelector?: boolean; showCacheKeyValueSelector?: boolean;
} }
@@ -152,7 +154,7 @@ function WorkflowRunCode(props?: Props) {
} }
return ( return (
<div className="flex h-full w-full flex-col items-end justify-center gap-2"> <div className="relative flex h-full w-full flex-col items-end justify-center gap-2">
{cacheKeyValueSet.size > 0 ? ( {cacheKeyValueSet.size > 0 ? (
<div className="flex w-full justify-end gap-4"> <div className="flex w-full justify-end gap-4">
<div className="flex items-center justify-around gap-2"> <div className="flex items-center justify-around gap-2">
@@ -209,6 +211,9 @@ function WorkflowRunCode(props?: Props) {
readOnly readOnly
fontSize={10} fontSize={10}
/> />
<div className="absolute right-[0.75rem] top-[3.5rem] flex items-center justify-end">
<CopyAndExplainCode code={code} />
</div>
</div> </div>
); );
} }