Skip to content

Commit 8239776

Browse files
authored
feat: useArtifact cleanup (#26)
2 parents a938b78 + 2b5b9f5 commit 8239776

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,11 @@ The allowed actions are:
168168
- `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.
169169
- `Ignore` - This will send back an `ignore` response, and the graph will end without taking any actions.
170170
- `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.
171+
172+
## Writer Agent
173+
174+
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:
175+
176+
- `Write me a short story about a <insert topic here>`
177+
178+
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.
Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
import { Message } from "@langchain/langgraph-sdk";
2-
import { useStreamContext, UIMessage } from "@langchain/langgraph-sdk/react-ui";
3-
4-
// eslint-disable-next-line react-refresh/only-export-components
5-
const NoopPreview = () => null;
6-
7-
// eslint-disable-next-line react-refresh/only-export-components
8-
const NoopSetOpen = () => void 0;
9-
10-
// eslint-disable-next-line react-refresh/only-export-components
11-
const NoopSetContext = () => void 0;
12-
13-
const NoopContext = {};
14-
1+
import { useMemo } from "react";
2+
import type { Message } from "@langchain/langgraph-sdk";
3+
import {
4+
useStreamContext,
5+
type UIMessage,
6+
} from "@langchain/langgraph-sdk/react-ui";
7+
8+
/**
9+
* Hook that obtains the artifact context provided by the `LoadExternalComponent`
10+
* found in the `meta.artifact` field.
11+
*
12+
* @see https://github.com/langchain-ai/agent-chat-ui/blob/main/src/components/thread/messages/ai.tsx
13+
*/
1514
export function useArtifact<TContext = Record<string, unknown>>() {
1615
type Component = (props: {
1716
children: React.ReactNode;
1817
title?: React.ReactNode;
1918
}) => React.ReactNode;
19+
2020
type Context = TContext | undefined;
21+
2122
type Bag = {
2223
open: boolean;
2324
setOpen: (value: boolean | ((prev: boolean) => boolean)) => void;
@@ -28,17 +29,23 @@ export function useArtifact<TContext = Record<string, unknown>>() {
2829

2930
const thread = useStreamContext<
3031
{ messages: Message[]; ui: UIMessage[] },
31-
{ MetaType: { artifact: { content: Component } & Bag } }
32+
{ MetaType: { artifact: [Component, Bag] } }
3233
>();
3334

34-
return [
35-
thread.meta?.artifact?.content ?? NoopPreview,
36-
{
37-
open: thread.meta?.artifact?.open ?? false,
38-
setOpen: thread.meta?.artifact?.setOpen ?? NoopSetOpen,
39-
40-
context: thread.meta?.artifact?.context ?? NoopContext,
41-
setContext: thread.meta?.artifact?.setContext ?? NoopSetContext,
42-
},
43-
] as [Component, Bag];
35+
const noop = useMemo(
36+
() =>
37+
[
38+
() => null,
39+
{
40+
open: false,
41+
setOpen: () => void 0,
42+
43+
context: {} as TContext,
44+
setContext: () => void 0,
45+
},
46+
] as [Component, Bag],
47+
[],
48+
);
49+
50+
return thread.meta?.artifact ?? noop;
4451
}

0 commit comments

Comments
 (0)