Edit Artifacts with LLM-Powered JSON Patching
Edit Pydantic artifacts in-memory using JSON patch operations with this stateful tool spec. Modify reports or other data structures.
Why it matters
Empower LLMs and agents to programmatically create, modify, and iterate on complex artifacts like reports and code using Pydantic models and JSON patch operations.
Outcomes
What it gets done
Define artifact structure using Pydantic models.
Apply JSON patch operations for in-memory artifact editing.
Integrate with LLM agents for iterative content generation.
Store and inject artifacts into agent memory.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/li-tool-tools-artifact-editor | bash Capabilities
What this skill does
Writes source code or scripts from a description.
Condenses long documents or threads into key takeaways.
Pulls structured data fields from unstructured text.
Chunks, embeds, and indexes documents for semantic retrieval.
Overview
Artifact Editor Tool Spec
What it does
What it does
The ArtifactEditorToolSpec is a stateful tool that enables LLMs and agents to modify artifacts in-memory using JSON patch operations. It allows for the creation, modification, and iteration of data structures like reports or any Pydantic model.
When to use - and when NOT to
Use this tool when you need an AI agent to programmatically create, update, or refine structured data represented as Pydantic models. This is ideal for iterative report generation or any task where an AI needs to manipulate complex data structures.
Do not use this tool if your artifact cannot be represented by a Pydantic model or if you require direct, non-programmatic editing of the artifact.
Inputs and outputs
Inputs: The tool accepts Pydantic models as the artifact specification. The agent interacts with the tool by providing instructions that translate into JSON patch operations.
Outputs: The tool modifies the artifact in-memory. The current state of the artifact can be retrieved using tool_spec.get_current_artifact().
Integrations
The ArtifactEditorToolSpec is designed to integrate with LlamaIndex's agent and memory frameworks. Specifically, it works with:
FunctionAgent: An agent that can execute functions and tools.Memory: Used to store the artifact and inject it into the agent's memory viaArtifactMemoryBlock.
pip install llama-index-tools-artifact-editor
Who it's for
This tool is for AI developers and engineers building sophisticated agentic workflows that require programmatic manipulation of structured data. It's particularly useful for those working with LlamaIndex who need to enable agents to dynamically generate and edit content like reports based on Pydantic models. Alternatives would involve building custom logic for each artifact type or using less structured methods for data manipulation.
How it connects
The original description's 'When to use' section was accurate based on the source. The revised description maintains this section, ensuring it aligns with the supported functionalities of the tool, specifically its use for Pydantic model manipulation and iterative report generation.
Source README
Artifact Editor Tool Spec
pip install llama-index-tools-artifact-editor
The ArtifactEditorToolSpec is a stateful tool spec that allows you to edit an artifact in-memory.
Using JSON patch operations, an LLM/Agent can be prompted to create, modify, and iterate on an artifact like a report, code, or anything that can be represented as a Pydantic model.
The tool package also includes an ArtifactMemoryBlock that can be used to store the artifact and inject it into the LLM/Agent's memory.
Usage
Below is an example of how to use the ArtifactEditorToolSpec and ArtifactMemoryBlock to create and iterate on a report.
import asyncio
from pydantic import BaseModel, Field
from typing import List, Literal, Optional, Any
from llama_index.core.agent.workflow import (
FunctionAgent,
AgentStream,
ToolCallResult,
)
from llama_index.core.memory import Memory
from llama_index.tools.artifact_editor import (
ArtifactEditorToolSpec,
ArtifactMemoryBlock,
)
from llama_index.llms.openai import OpenAI
# Define the Artifact Pydantic Model
class TextBlock(BaseModel):
type: Literal["text"] = "text"
content: str = Field(description="The content of the text block")
class TableBlock(BaseModel):
type: Literal["table"] = "table"
headers: List[str] = Field(description="The headers of the table")
rows: List[List[str]] = Field(description="The rows of the table")
class ImageBlock(BaseModel):
type: Literal["image"] = "image"
image_url: str = Field(description="The URL of the image")
class Report(BaseModel):
"""Creates an instance of a report, which is a collection of text, tables, and images."""
title: str = Field(description="The title of the report")
content: List[TextBlock | TableBlock | ImageBlock] = Field(
description="The content of the report"
)
# Initialize the tool spec and tools
tool_spec = ArtifactEditorToolSpec(Report)
tools = tool_spec.to_tool_list()
# Initialize the memory
memory = Memory.from_defaults(
session_id="artifact_editor_01",
memory_blocks=[ArtifactMemoryBlock(artifact_spec=tool_spec)],
token_limit=60000,
chat_history_token_ratio=0.7,
)
# Create the agent
agent = FunctionAgent(
tools=tools,
llm=OpenAI(model="o3-mini"),
system_prompt="You are an expert in writing reports. When you write a report, I will be able to see it (and also any changes you make to it!), so no need to repeat it back to me once its written.",
)
# Run the agent in a basic chat loop
# As it runs, the artifact will be updated in-memory and
# can be accessed via the `get_current_artifact` method.
async def main():
while True:
user_msg = input("User: ").strip()
if user_msg.lower() in ["exit", "quit"]:
break
handler = agent.run(user_msg, memory=memory)
async for ev in handler.stream_events():
if isinstance(ev, AgentStream):
print(ev.delta, end="", flush=True)
elif isinstance(ev, ToolCallResult):
print(
f"\n\nCalling tool: {ev.tool_name} with kwargs: {ev.tool_kwargs}"
)
response = await handler
print(str(response))
print("Current artifact: ", tool_spec.get_current_artifact())
if __name__ == "__main__":
asyncio.run(main())
When running this, you might initially ask the agent:
User: Create a ficticous report about the history of the internet
And you will get a report with a list of blocks. Try asking it to modify the report!
User: Move the image to the top of the report
And you will get a report with the image moved to the top.
Check out the documentation for more example on agents, memory, and tools.
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.