All Projects
cat ~/projects/sanity-content-copilot/README.md
active

>Sanity Content Copilot

Active
Started: April 27, 2025Completed: May 18, 2025Company: Sanity

An AI assistant that transforms content creation in Sanity Studio through natural conversation. The Content Copilot integrates directly into the Studio interface as a side-by-side component, allowing users to discuss their projects while the AI automatically populates structured fields based on the conversation.

>Problem & Solution

Problem

Documenting projects in Sanity Studio requires manually filling out numerous structured fields, which creates friction in the content creation process. This is especially challenging when trying to showcase AI engineering skills through multiple projects, as the technical storytelling gets lost in the tedious form-filling experience.

Solution

Created a custom AI assistant integrated directly into Sanity Studio as a side-by-side view component. The solution uses a custom React component embedded in the Sanity Studio structure, leveraging the Vercel AI SDK for the chat interface, Supabase for message persistence, and Claude 3.5 Sonnet as the LLM. The assistant uses specialized tool calls to interact with the Sanity API, allowing it to update document fields in real-time based on natural conversation.

>Challenges

Side-by-side View Integration

Implementing automatic side-by-side view mode for the Content Copilot required a creative workaround. Created an 'AutoPreviewPane' component and added a temporary field to the Sanity schema to gain direct access from the schema itself, enabling automatic split pane view.

Tool Call Architecture

Designing the primitive operations needed for the AI to manipulate any part of the Sanity document structure. Created a system of Write, Delete, Array, and Query tools that could handle all necessary data operations while interfacing directly with the Sanity API.

>Approach

Progressive Conversation Design

Designed a three-phase conversation flow (story, background updates, refinement) that prioritizes natural interaction while gradually populating structured fields, creating a more human experience compared to traditional form interfaces.

Primitive Operations Architecture

Identified the core primitive operations needed (Write, Delete, Array, Query) to manipulate any part of the Sanity document structure, creating a flexible system that could handle all necessary data operations through direct API calls.

Custom Sanity Studio Integration

Researched Sanity Studio's architecture to identify integration points, ultimately creating a custom React component that could be embedded as a side-by-side view within the Studio interface.

>Technical Insights

Progressive Conversation UX

Implemented a three-phase conversation approach (story, transition, field-focused) that prioritizes natural interaction while gradually filling in structured data. This creates a more human experience compared to traditional form interfaces.

Sanity API Integration

Created a system of primitive operations (Write, Delete, Array, Query) that allows the AI to manipulate any part of the Sanity document structure through direct API calls, providing complete flexibility without requiring hardcoded field mappings.

Conversation Management

Leveraged the Vercel AI SDK for conversation management with a simple but effective memory system. Stored conversations in a Supabase table using JSONB fields, allowing for persistent context across sessions while maintaining a lightweight architecture.

Schema Serialization for LLMs

Developed custom serialization logic to handle circular references in Sanity's schema types. Created a TypeScript function that transforms complex schema objects with circular dependencies into LLM-friendly JSON structures, enabling the AI to understand document structure without running into reference errors.

export function serializeSchemaType(schemaType: SchemaType): SerializableSchemaType {
  const baseInfo: SerializableSchemaType = {
    type: schemaType.jsonType,
    title: schemaType.title
  };

  // If it's an object type with fields, process them
  if (isObjectSchemaType(schemaType) && schemaType.fields) {
    baseInfo.fields = schemaType.fields.map(serializeField);
  }

  return baseInfo;
}

>Technologies

Sanity
Next.js
React
Vercel AI SDK
Claude 3.5 Sonnet
Supabase
Sanity

>Results

  • Reduced project documentation time from hours to minutes through natural conversation
  • Created a more enjoyable content creation experience that encourages more thorough documentation
  • Successfully documented multiple projects using the Content Copilot, including this project itself in a meta-demonstration
  • Enabled richer, more detailed project descriptions by removing the friction of manual form-filling
  • Created a working prototype that predates Sanity's official AI features, demonstrating forward-thinking in content management workflows

>Key Metrics

Projects Documented17
Content Creation Efficiency Increase50 %

>Key Learnings

  • Gained deep understanding of Sanity's GROQ query language and API authentication
  • Developed techniques for translating TypeScript schema types into LLM-friendly formats
  • Created methods to provide both schema information and live document state to the AI assistant
  • Designed a progressive conversation UX that prioritizes natural interaction over form-filling
$cd ~/projects
will@diamond:~