Open Artifacts

repository·main·Indexed 43 days ago

https://github.com/13point5/open-artifacts

An open-source implementation of Claude-like functionality that allows users to generate and interact with 'Artifacts' using their own Anthropic or OpenAI API keys. It features iterative editing through cropping and voice commands, and requires a Supabase instance for database and authentication.

Tokens
5.2K
Snippets
22
Records
27
Agent score
55%

What's inside Open Artifacts

  1. Get started with Open Artifacts

    main

    Open Artifacts is an open-source clone of Claude's functionality that allows users to generate Artifacts using their own Anthropic or OpenAI API keys. To get started, clone the repository and navigate to the project directory.

    git clone https://github.com/13point5/open-artifacts.git
    cd open-artifacts
  2. Install and run the Open Artifacts application

    main

    After configuring Supabase, follow these steps to set up the application locally:

    1. Install project dependencies:
      npm install
    2. Set the NEXT_PUBLIC_ARTIFACT_RENDERER_URL environment variable to the URL where you have deployed the Open Artifacts Renderer.
    3. Start the development server:
      npm run dev
    4. Access the application at http://localhost:3000.
    npm install
    npm run dev
  3. Configure Supabase for Open Artifacts

    main

    Open Artifacts requires a Supabase instance for database and authentication. Follow these steps to set up your backend:

    1. Install the Supabase CLI.
    2. Create a new project in the Supabase dashboard.
    3. Initialize Supabase locally in your project folder:
      supabase init
    4. Link your local environment to your remote Supabase project using your project reference:
      supabase link --project-ref <your-project-ref>
    5. Apply the database migrations:
      supabase db push
    6. Retrieve your project credentials and add them to your environment variables:
      • NEXT_PUBLIC_SUPABASE_URL
      • NEXT_PUBLIC_SUPABASE_ANON_KEY
    supabase init
    supabase link --project-ref <your-project-ref>
    supabase db push
  4. Required environment variables

    main

    The following environment variables are required for the application to function:

    Supabase Configuration

    • NEXT_PUBLIC_SUPABASE_URL: The API URL for your Supabase project.
    • NEXT_PUBLIC_SUPABASE_ANON_KEY: The public anonymous key for your Supabase project.

    Renderer Configuration

    • NEXT_PUBLIC_ARTIFACT_RENDERER_URL: The URL of your deployed Open Artifacts Renderer. This is required to view generated artifacts.
  5. Add a message to a chat with addMessage()

    main

    Use addMessage to insert a new message into an existing chat.

    Parameters:

    • supabase: The Supabase client instance.
    • chatId: The ID of the chat to which the message belongs.
    • message: An object containing role (string), content (string), and optional metadata (Record).
    • attachments: An optional array of Attachment objects.

    If no chatId is provided, the function returns the message object without performing a database insertion.

    await addMessage(supabase, chatId, {
      role: "user",
      content: "Hello world",
      metadata: { someKey: "someValue" }
    }, [attachment1, attachment2]);
  6. Merge Tailwind classes with `cn`

    main

    The cn utility function is a wrapper around clsx and tailwind-merge. It allows you to conditionally apply CSS classes and ensures that Tailwind class conflicts are resolved correctly (the last class provided wins).

    import { cn } from './lib/utils';
    
    // Example usage with conditional classes
    const className = cn(
      'px-2 py-1 bg-red-500 text-white', 
      isError && 'border-2 border-black',
      'p-4' // This will override 'px-2 py-1' due to tailwind-merge logic
    );
  7. Create a new chat with createChat()

    main

    Use createChat to initialize a new chat record in the database. You must provide a title and a valid userId. The function returns the newly created chat object.

    const newChat = await createChat(supabase, "My New Chat", userId);
  8. Retrieve messages for a specific chat with getChatMessages()

    main

    Use getChatMessages to fetch all messages belonging to a specific chat ID. The messages are returned ordered by created_at in ascending order. If no id is provided, it returns an empty array [].

    const messages = await getChatMessages(supabase, chatId);
  9. Parse LLM messages into structured parts with `parseMessage`

    main

    Use parseMessage to convert a raw string from an LLM into an array of structured MessagePart objects. This function identifies three types of content based on specific XML-like tags:

    1. Text: Standard conversational text.
    2. Thought: Content wrapped in <thinking> and </thinking> tags.
    3. Artifact: Content wrapped in <artifact> and </artifact> tags. The <artifact> tag can include attributes like identifier, type, title, and language.

    When an <artifact> tag is encountered, the parser initializes generating: true. Once the closing </artifact> tag is found, generating is set to false.

    import { parseMessage } from './lib/utils';
    
    const rawMessage = `
    Here is your code:
    <artifact identifier="code-1" type="code" title="Example" language="typescript">
    console.log("hello");
    </artifact>
    `;
    
    const parts = parseMessage(rawMessage);
    // parts will contain:
    // [ 
    //   { type: 'text', data: 'Here is your code:' },
    //   { type: 'artifact', data: { id: 'code-1', type: 'code', title: 'Example', language: 'typescript', content: 'console.log("hello");', generating: false } }
    // ]
  10. Retrieve all chats for a user with getChats()

    main

    Use getChats to fetch a list of all chat records associated with a specific user ID. The results are returned ordered by created_at in descending order. This function requires an authenticated userId and a Supabase client instance.

    const chats = await getChats(supabase, userId);
  11. Manage user settings via localStorage

    main

    User settings (API keys and selected model) are persisted in the browser's localStorage using the key openArtifacts:settings. You can retrieve the current settings using getSettings() and persist changes using updateSettings(newSettings).

    If no settings are found or if the stored data is corrupted, the system falls back to defaultSettings:

    • anthropicApiKey: empty string
    • openaiApiKey: empty string
    • model: Models.claude
    import { getSettings, updateSettings } from '@/lib/userSettings';
    
    // Retrieve current settings
    const currentSettings = getSettings();
    
    // Update settings
    updateSettings({
      ...currentSettings,
      openaiApiKey: 'sk-...',
      model: Models.gpt4o // Assuming Models is imported from @/app/types
    });