|
1 | 1 | "use client";
|
2 | 2 |
|
| 3 | +import { |
| 4 | + getCustomAnnotation, |
| 5 | + useChatMessage, |
| 6 | + useChatUI, |
| 7 | +} from "@llamaindex/chat-ui"; |
3 | 8 | import { Check, ChevronDown, Code, Copy, Loader2 } from "lucide-react";
|
4 |
| -import { useEffect, useRef, useState } from "react"; |
| 9 | +import { useEffect, useMemo, useRef, useState } from "react"; |
| 10 | +import { z } from "zod"; |
5 | 11 | import { Button, buttonVariants } from "../../button";
|
6 | 12 | import {
|
7 | 13 | Collapsible,
|
@@ -386,3 +392,59 @@ function closePanel() {
|
386 | 392 | panel.classList.add("hidden");
|
387 | 393 | });
|
388 | 394 | }
|
| 395 | + |
| 396 | +const ArtifactToolSchema = z.object({ |
| 397 | + tool_name: z.literal("artifact"), |
| 398 | + tool_kwargs: z.object({ |
| 399 | + query: z.string(), |
| 400 | + }), |
| 401 | + tool_id: z.string(), |
| 402 | + tool_output: z.object({ |
| 403 | + content: z.string(), |
| 404 | + tool_name: z.string(), |
| 405 | + raw_input: z.object({ |
| 406 | + args: z.array(z.unknown()), |
| 407 | + kwargs: z.object({ |
| 408 | + query: z.string(), |
| 409 | + }), |
| 410 | + }), |
| 411 | + raw_output: z.custom<CodeArtifact>(), |
| 412 | + is_error: z.boolean(), |
| 413 | + }), |
| 414 | + return_direct: z.boolean().optional(), |
| 415 | +}); |
| 416 | + |
| 417 | +type ArtifactTool = z.infer<typeof ArtifactToolSchema>; |
| 418 | + |
| 419 | +export function ArtifactToolComponent() { |
| 420 | + const { message } = useChatMessage(); |
| 421 | + const { messages } = useChatUI(); |
| 422 | + |
| 423 | + const artifactOutputEvent = getCustomAnnotation<ArtifactTool>( |
| 424 | + message.annotations, |
| 425 | + (annotation: unknown) => { |
| 426 | + const result = ArtifactToolSchema.safeParse(annotation); |
| 427 | + return result.success; |
| 428 | + }, |
| 429 | + ).at(0); |
| 430 | + |
| 431 | + const artifactVersion = useMemo(() => { |
| 432 | + const artifactToolCalls = messages.filter((m) => |
| 433 | + m.annotations?.some( |
| 434 | + (a: unknown) => (a as ArtifactTool).tool_name === "artifact", |
| 435 | + ), |
| 436 | + ); |
| 437 | + return artifactToolCalls.length; |
| 438 | + }, [messages]); |
| 439 | + |
| 440 | + return ( |
| 441 | + <div className="flex flex-col gap-4"> |
| 442 | + {artifactOutputEvent && ( |
| 443 | + <Artifact |
| 444 | + artifact={artifactOutputEvent.tool_output.raw_output} |
| 445 | + version={artifactVersion} |
| 446 | + /> |
| 447 | + )} |
| 448 | + </div> |
| 449 | + ); |
| 450 | +} |
0 commit comments