Render all multi artifacts correctly (#976)
This commit is contained in:
@@ -2,7 +2,7 @@ import { artifactApiClient } from "@/api/AxiosClient";
|
|||||||
import { ArtifactApiResponse } from "@/api/types";
|
import { ArtifactApiResponse } from "@/api/types";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQueries } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
// https://stackoverflow.com/a/60338028
|
// https://stackoverflow.com/a/60338028
|
||||||
@@ -27,29 +27,36 @@ function format(html: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
artifact: ArtifactApiResponse;
|
artifacts: Array<ArtifactApiResponse>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function HTMLArtifact({ artifact }: Props) {
|
function HTMLArtifact({ artifacts }: Props) {
|
||||||
const { data, isFetching, isError, error } = useQuery<string>({
|
function fetchArtifact(artifact: ArtifactApiResponse) {
|
||||||
queryKey: ["artifact", artifact.artifact_id],
|
if (artifact.uri.startsWith("file://")) {
|
||||||
queryFn: async () => {
|
return artifactApiClient
|
||||||
if (artifact.uri.startsWith("file://")) {
|
.get(`/artifact/text`, {
|
||||||
return artifactApiClient
|
params: {
|
||||||
.get(`/artifact/text`, {
|
path: artifact.uri.slice(7),
|
||||||
params: {
|
},
|
||||||
path: artifact.uri.slice(7),
|
})
|
||||||
},
|
.then((response) => response.data);
|
||||||
})
|
}
|
||||||
.then((response) => response.data);
|
if (artifact.uri.startsWith("s3://") && artifact.signed_url) {
|
||||||
}
|
return axios.get(artifact.signed_url).then((response) => response.data);
|
||||||
if (artifact.uri.startsWith("s3://") && artifact.signed_url) {
|
}
|
||||||
return axios.get(artifact.signed_url).then((response) => response.data);
|
}
|
||||||
}
|
|
||||||
},
|
const results = useQueries({
|
||||||
|
queries:
|
||||||
|
artifacts?.map((artifact) => {
|
||||||
|
return {
|
||||||
|
queryKey: ["artifact", artifact.artifact_id],
|
||||||
|
queryFn: () => fetchArtifact(artifact),
|
||||||
|
};
|
||||||
|
}) ?? [],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFetching) {
|
if (results.some((result) => result.isLoading)) {
|
||||||
return <Skeleton className="h-48 w-full" />;
|
return <Skeleton className="h-48 w-full" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +64,11 @@ function HTMLArtifact({ artifact }: Props) {
|
|||||||
<Textarea
|
<Textarea
|
||||||
className="w-full"
|
className="w-full"
|
||||||
rows={15}
|
rows={15}
|
||||||
value={isError ? JSON.stringify(error) : format(data ?? "")}
|
value={
|
||||||
|
results.some((result) => result.isError)
|
||||||
|
? JSON.stringify(results.find((result) => result.isError)?.error)
|
||||||
|
: results.map((result) => format(result.data ?? "")).join(",\n")
|
||||||
|
}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -61,12 +61,12 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
(artifact) => artifact.artifact_type === ArtifactType.LLMRequest,
|
(artifact) => artifact.artifact_type === ArtifactType.LLMRequest,
|
||||||
);
|
);
|
||||||
|
|
||||||
const visibleElementsTreeInPrompt = artifacts?.find(
|
const visibleElementsTreeInPrompt = artifacts?.filter(
|
||||||
(artifact) =>
|
(artifact) =>
|
||||||
artifact.artifact_type === ArtifactType.VisibleElementsTreeInPrompt,
|
artifact.artifact_type === ArtifactType.VisibleElementsTreeInPrompt,
|
||||||
);
|
);
|
||||||
|
|
||||||
const llmPrompt = artifacts?.find(
|
const llmPrompt = artifacts?.filter(
|
||||||
(artifact) => artifact.artifact_type === ArtifactType.LLMPrompt,
|
(artifact) => artifact.artifact_type === ArtifactType.LLMPrompt,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
(artifact) => artifact.artifact_type === ArtifactType.LLMResponseParsed,
|
(artifact) => artifact.artifact_type === ArtifactType.LLMResponseParsed,
|
||||||
);
|
);
|
||||||
|
|
||||||
const htmlRaw = artifacts?.find(
|
const htmlRaw = artifacts?.filter(
|
||||||
(artifact) => artifact.artifact_type === ArtifactType.HTMLScrape,
|
(artifact) => artifact.artifact_type === ArtifactType.HTMLScrape,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -84,8 +84,10 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
<TabsTrigger value="info">Info</TabsTrigger>
|
<TabsTrigger value="info">Info</TabsTrigger>
|
||||||
<TabsTrigger value="screenshot_llm">Annotated Screenshots</TabsTrigger>
|
<TabsTrigger value="screenshot_llm">Annotated Screenshots</TabsTrigger>
|
||||||
<TabsTrigger value="screenshot_action">Action Screenshots</TabsTrigger>
|
<TabsTrigger value="screenshot_action">Action Screenshots</TabsTrigger>
|
||||||
<TabsTrigger value="element_tree_trimmed">Element Tree</TabsTrigger>
|
<TabsTrigger value="element_tree_trimmed">
|
||||||
<TabsTrigger value="html_element_tree">HTML Element Tree</TabsTrigger>
|
HTML Element Tree
|
||||||
|
</TabsTrigger>
|
||||||
|
<TabsTrigger value="element_tree">Element Tree</TabsTrigger>
|
||||||
<TabsTrigger value="llm_prompt">Prompt</TabsTrigger>
|
<TabsTrigger value="llm_prompt">Prompt</TabsTrigger>
|
||||||
<TabsTrigger value="llm_response_parsed">Action List</TabsTrigger>
|
<TabsTrigger value="llm_response_parsed">Action List</TabsTrigger>
|
||||||
<TabsTrigger value="html_raw">HTML (Raw)</TabsTrigger>
|
<TabsTrigger value="html_raw">HTML (Raw)</TabsTrigger>
|
||||||
@@ -165,16 +167,16 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="element_tree_trimmed">
|
<TabsContent value="element_tree_trimmed">
|
||||||
{visibleElementsTreeInPrompt ? (
|
{visibleElementsTreeInPrompt ? (
|
||||||
<HTMLArtifact artifact={visibleElementsTreeInPrompt} />
|
<HTMLArtifact artifacts={visibleElementsTreeInPrompt} />
|
||||||
) : null}
|
) : null}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="html_element_tree">
|
<TabsContent value="element_tree">
|
||||||
{visibleElementsTree ? (
|
{visibleElementsTree ? (
|
||||||
<JSONArtifact artifacts={visibleElementsTree} />
|
<JSONArtifact artifacts={visibleElementsTree} />
|
||||||
) : null}
|
) : null}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="llm_prompt">
|
<TabsContent value="llm_prompt">
|
||||||
{llmPrompt ? <TextArtifact artifact={llmPrompt} /> : null}
|
{llmPrompt ? <TextArtifact artifacts={llmPrompt} /> : null}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="llm_response_parsed">
|
<TabsContent value="llm_response_parsed">
|
||||||
{llmResponseParsed ? (
|
{llmResponseParsed ? (
|
||||||
@@ -182,7 +184,7 @@ function StepArtifacts({ id, stepProps }: Props) {
|
|||||||
) : null}
|
) : null}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="html_raw">
|
<TabsContent value="html_raw">
|
||||||
{htmlRaw ? <TextArtifact artifact={htmlRaw} /> : null}
|
{htmlRaw ? <TextArtifact artifacts={htmlRaw} /> : null}
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="llm_request">
|
<TabsContent value="llm_request">
|
||||||
{llmRequest ? <JSONArtifact artifacts={llmRequest} /> : null}
|
{llmRequest ? <JSONArtifact artifacts={llmRequest} /> : null}
|
||||||
|
|||||||
@@ -2,33 +2,40 @@ import { artifactApiClient } from "@/api/AxiosClient";
|
|||||||
import { ArtifactApiResponse } from "@/api/types";
|
import { ArtifactApiResponse } from "@/api/types";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQueries } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
artifact: ArtifactApiResponse;
|
artifacts: Array<ArtifactApiResponse>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function TextArtifact({ artifact }: Props) {
|
function TextArtifact({ artifacts }: Props) {
|
||||||
const { data, isFetching, isError, error } = useQuery<string>({
|
function fetchArtifact(artifact: ArtifactApiResponse) {
|
||||||
queryKey: ["artifact", artifact.artifact_id],
|
if (artifact.uri.startsWith("file://")) {
|
||||||
queryFn: async () => {
|
return artifactApiClient
|
||||||
if (artifact.uri.startsWith("file://")) {
|
.get(`/artifact/text`, {
|
||||||
return artifactApiClient
|
params: {
|
||||||
.get(`/artifact/text`, {
|
path: artifact.uri.slice(7),
|
||||||
params: {
|
},
|
||||||
path: artifact.uri.slice(7),
|
})
|
||||||
},
|
.then((response) => response.data);
|
||||||
})
|
}
|
||||||
.then((response) => response.data);
|
if (artifact.uri.startsWith("s3://") && artifact.signed_url) {
|
||||||
}
|
return axios.get(artifact.signed_url).then((response) => response.data);
|
||||||
if (artifact.uri.startsWith("s3://") && artifact.signed_url) {
|
}
|
||||||
return axios.get(artifact.signed_url).then((response) => response.data);
|
}
|
||||||
}
|
|
||||||
},
|
const results = useQueries({
|
||||||
|
queries:
|
||||||
|
artifacts?.map((artifact) => {
|
||||||
|
return {
|
||||||
|
queryKey: ["artifact", artifact.artifact_id],
|
||||||
|
queryFn: () => fetchArtifact(artifact),
|
||||||
|
};
|
||||||
|
}) ?? [],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFetching) {
|
if (results.some((result) => result.isLoading)) {
|
||||||
return <Skeleton className="h-48 w-full" />;
|
return <Skeleton className="h-48 w-full" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +43,11 @@ function TextArtifact({ artifact }: Props) {
|
|||||||
<Textarea
|
<Textarea
|
||||||
className="w-full"
|
className="w-full"
|
||||||
rows={15}
|
rows={15}
|
||||||
value={isError ? JSON.stringify(error) : data}
|
value={
|
||||||
|
results.some((result) => result.isError)
|
||||||
|
? JSON.stringify(results.find((result) => result.isError)?.error)
|
||||||
|
: results.map((result) => result.data).join(",\n")
|
||||||
|
}
|
||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user