#Langgraph tool artifacts

1 messages · Page 1 of 1 (latest)

wraith flame
#

Hello,

I am trying to get the tool artifacts from the results of useRenderToolCall but I can receive the tool content only, any support?

primal knollBOT
#

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, and result
  • No dedicated "artifacts" API; include artifacts in result yourself

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 executing and complete for render logic.

References:

}

**Was this helpful?**

If this solution worked for you, please click on the appropriate option below to help us improve:
primal knollBOT
#

Thank you for your feedback! Our team will provide additional assistance. 🔄

primal knollBOT
#

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.

stark night
#

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

onyx pivot
#

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.

stark night
#

Got it! Thank you 🙏

muted steppe
#

Interesting. Suppose I want to return LLM artifacts like code and docs just like Claude Code. How do I do this?

primal knollBOT
#

@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

icy yacht
#

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

muted steppe
#

@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?

icy yacht
#

@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.

icy yacht
#

@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
onyx pivot
#

@fluid cloud Would you mind taking a look at this when you get a chance? Thanks!