#Langgraph tool artifacts
1 messages · Page 1 of 1 (latest)
This solution has been AI generated
It looks like useRenderToolCall only exposes the tool call args, result, and status. There isn’t a separate "artifacts" field in the current LangGraph integration—so any artifacts must be returned as part of the tool’s result and rendered from there.
How useRenderToolCall exposes tool output
- Render-only hook for backend tool calls
- Provides:
status,args, andresult - No dedicated "artifacts" API; include artifacts in
resultyourself
Example: return and render artifacts from result
import { useRenderToolCall } from "@copilotkit/react-core";
useRenderToolCall({
name: "generate_artifacts",
description: "Generates assets and returns them as artifacts",
parameters: { type: "object", properties: { prompt: { type: "string" } } },
render: ({ status, args, result }) => {
if (status === "executing") return <div>Working…</div>;
if (status === "complete" && result?.artifacts) {
return (
<div>
<h3>Artifacts</h3>
<pre>{JSON.stringify(result.artifacts, null, 2)}</pre>
</div>
);
}
return null;
},
});
Catch-all renderer (any tool)
useRenderToolCall({
name: "*",
render: ({ name, status, args, result }) => (
<div>
<h4>Tool: {name}</h4>
<p>Status: {status}</p>
{result && <pre>{JSON.stringify(result, null, 2)}</pre>}
</div>
),
});
Notes
- To surface artifacts, ensure your backend tool returns them (e.g.,
{ artifacts: [...] }). - The hook supports statuses like
executingandcompletefor render logic.
References:
- useRenderToolCall Hook Reference: https://docs.copilotkit.ai/reference/hooks/useRenderToolCall
- Generative UI Guide: https://docs.copilotkit.ai/direct-to-llm/guides/generative-ui
}
**Was this helpful?**
If this solution worked for you, please click on the appropriate option below to help us improve:
Thank you for your feedback! Our team will provide additional assistance. 🔄
Hi @wraith flame, if you want artifacts to be presented in the frontend, you need to configure your backend logics to send that data. It is not supported in CopilotKit OOTB.
Any examples or hints of how to do that, @onyx pivot ? Sending everything in the result and then parsing it in the FE doesn't seem to be a nice idea - especially considering that this would basically kill the token-streaming
So if you are using langgraph, you need to update the messages array with the tool_calls array to hold this result value.
AIMessage(
content="",
tool_calls=[{
"id": "toolu_01",
"name": "add_numbers",
"args": {"a": 23, "b": 42}
}]
),
Kind of like this. You need pass the result value inside the args.
Got it! Thank you 🙏
Interesting. Suppose I want to return LLM artifacts like code and docs just like Claude Code. How do I do this?
@muted steppe, You could pass the required artifacts inside the args object.
AIMessage(
content="",
tool_calls=[{
"id": "someUUID",
"name": "llm_out",
"args": {"artifacts" : {.....}}
}]
),
Note that this is an example for langGraph. You need to change it appropriately for whatever framework you are using. By connecting this with the CPK, you can make it work. Please refer this doc for the CPK layer: https://docs.copilotkit.ai/direct-to-llm/guides/generative-ui
Learn how to embed custom UI components in the chat window.
Hi @muted steppe , @wraith flame , @onyx pivot ,@stark night ,
I’d like to share my approach for handling this. Suppose I have a report writer that generates large reports - instead of returning the entire artifact directly, I store the report as a file on the server (e.g., artifacts/reports/UUID.md) and return the UUID of the stored artifact. Later, I can either manually render it (when tool call ends and artifact generates successfully ) or expose another tool to handle the rendering (on demand, when the user explicitly demands it) using the returned UUID
@icy yacht Thanks for your explanation! I have one more question. Using this approach, how would we handle real-time streaming of the artifact as it’s being generated similar to how Claude streams long-form outputs (like reports or code) in real time?
@muted steppe well that's the downside of this approach , in langgraph for example we wait until the model generates the tool calls and then we invoke those tool calls, so you probably have to wait until the agent generates the full artifact and then you will store it once the tool got invoked.
@muted steppe
I’m not sure if this is possible (I haven’t tested it yet), but I think it’s feasible. LangGraph supports tool call streaming, and I assume CopilotKit does as well ( @onyx pivot , please confirm). The idea would be to use the arguments passed to CopilotKit TOOL_CALL event to stream the generation in real-time and render it. (the above solution)
On the other hand, in LangGraph, tools aren’t executed until the full tool calls are generated. So basically, you could stream the chunks of the tool call arguments via CopilotKit, and once the streaming is complete, the graph would execute the tool call. The result would then be stored and returned for future use.
I think this is a reasonable approach, but we need Tony to confirm exactly how CopilotKit handles this under the hood.
something like this:
TOOL CALL START -> TOOL CALL ARGS (chunk): streaming... -> TOOL CALL ARGS (chunk): streaming... -> .. -> TOOL CALL ARGS (chunk, complete): streaming + invoking ... -> TOOL CALL RESPONSE : arifact saved... -> TOOL CALL END
@fluid cloud Would you mind taking a look at this when you get a chance? Thanks!