mirror of
https://github.com/langchain-ai/langgraphjs-gen-ui-examples.git
synced 2026-07-01 12:31:37 -04:00
feat: useArtifact cleanup (#26)
This commit is contained in:
@@ -168,3 +168,11 @@ The allowed actions are:
|
||||
- `Respond` - If you send a text response back, it will be used to rewrite the email in some way, then interrupt again and wait for you to take an action.
|
||||
- `Ignore` - This will send back an `ignore` response, and the graph will end without taking any actions.
|
||||
- `Mark as resolved` - If you select this, it will resume the graph, but starting at the `__end__` node, causing the graph to end without taking any actions.
|
||||
|
||||
## Writer Agent
|
||||
|
||||
This is a dummy agent used to demonstrate how you can stream generative UI components as an artifact. It should be accessed via the `writer` graph ID. It should be accessed via the `agent` graph ID, which means you'll need to go through the Supervisor agent to access it. The following prompts will trigger the writer agent:
|
||||
|
||||
- `Write me a short story about a <insert topic here>`
|
||||
|
||||
This will render a generative UI component that contains the title and content of your short story. The generative UI component will be rendered in a side panel to the right of the chat and the contents of the story will be streamed to the UI as it is generated.
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import { Message } from "@langchain/langgraph-sdk";
|
||||
import { useStreamContext, UIMessage } from "@langchain/langgraph-sdk/react-ui";
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
const NoopPreview = () => null;
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
const NoopSetOpen = () => void 0;
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
const NoopSetContext = () => void 0;
|
||||
|
||||
const NoopContext = {};
|
||||
import { useMemo } from "react";
|
||||
import type { Message } from "@langchain/langgraph-sdk";
|
||||
import {
|
||||
useStreamContext,
|
||||
type UIMessage,
|
||||
} from "@langchain/langgraph-sdk/react-ui";
|
||||
|
||||
/**
|
||||
* Hook that obtains the artifact context provided by the `LoadExternalComponent`
|
||||
* found in the `meta.artifact` field.
|
||||
*
|
||||
* @see https://github.com/langchain-ai/agent-chat-ui/blob/main/src/components/thread/messages/ai.tsx
|
||||
*/
|
||||
export function useArtifact<TContext = Record<string, unknown>>() {
|
||||
type Component = (props: {
|
||||
children: React.ReactNode;
|
||||
title?: React.ReactNode;
|
||||
}) => React.ReactNode;
|
||||
|
||||
type Context = TContext | undefined;
|
||||
|
||||
type Bag = {
|
||||
open: boolean;
|
||||
setOpen: (value: boolean | ((prev: boolean) => boolean)) => void;
|
||||
@@ -28,17 +29,23 @@ export function useArtifact<TContext = Record<string, unknown>>() {
|
||||
|
||||
const thread = useStreamContext<
|
||||
{ messages: Message[]; ui: UIMessage[] },
|
||||
{ MetaType: { artifact: { content: Component } & Bag } }
|
||||
{ MetaType: { artifact: [Component, Bag] } }
|
||||
>();
|
||||
|
||||
return [
|
||||
thread.meta?.artifact?.content ?? NoopPreview,
|
||||
{
|
||||
open: thread.meta?.artifact?.open ?? false,
|
||||
setOpen: thread.meta?.artifact?.setOpen ?? NoopSetOpen,
|
||||
const noop = useMemo(
|
||||
() =>
|
||||
[
|
||||
() => null,
|
||||
{
|
||||
open: false,
|
||||
setOpen: () => void 0,
|
||||
|
||||
context: thread.meta?.artifact?.context ?? NoopContext,
|
||||
setContext: thread.meta?.artifact?.setContext ?? NoopSetContext,
|
||||
},
|
||||
] as [Component, Bag];
|
||||
context: {} as TContext,
|
||||
setContext: () => void 0,
|
||||
},
|
||||
] as [Component, Bag],
|
||||
[],
|
||||
);
|
||||
|
||||
return thread.meta?.artifact ?? noop;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user