diff --git a/client/src/components/Artifacts/Artifact.tsx b/client/src/components/Artifacts/Artifact.tsx
index 73faee54ca..8dad0116f0 100644
--- a/client/src/components/Artifacts/Artifact.tsx
+++ b/client/src/components/Artifacts/Artifact.tsx
@@ -1,34 +1,72 @@
+import { useEffect, useCallback } from 'react';
import { visit } from 'unist-util-visit';
-import type { Plugin } from 'unified';
-import type { Root } from 'mdast';
+import { useSetRecoilState } from 'recoil';
+import { artifactsState, artifactIdsState } from '~/store/artifacts';
+import type { Pluggable } from 'unified';
-export function artifactPlugin() {
+export const artifactPlugin: Pluggable = () => {
return (tree) => {
- visit(
- tree,
- ['textDirective', 'leafDirective', 'containerDirective'],
- (node) => {
- node.data = {
- hName: node.name,
- hProperties: node.attributes,
- ...node.data,
- };
- return node;
- },
- );
+ visit(tree, ['textDirective', 'leafDirective', 'containerDirective'], (node) => {
+ node.data = {
+ hName: node.name,
+ hProperties: node.attributes,
+ ...node.data,
+ };
+ return node;
+ });
};
-}
+};
+
+export function Artifact({ node, ...props }) {
+ const setArtifacts = useSetRecoilState(artifactsState);
+ const setArtifactIds = useSetRecoilState(artifactIdsState);
+
+ const updateArtifact = useCallback(() => {
+ const content =
+ props.children && typeof props.children === 'string'
+ ? props.children
+ : props.children?.props?.children || '';
+
+ const title = props.title || 'Untitled Artifact';
+ const type = props.type || 'unknown';
+ const identifier = props.identifier || 'no-identifier';
+ const artifactKey = `${identifier}_${type}_${title}`.replace(/\s+/g, '_').toLowerCase();
+
+ setArtifacts((prevArtifacts) => {
+ if (prevArtifacts[artifactKey] && prevArtifacts[artifactKey].content === content) {
+ return prevArtifacts;
+ }
+
+ return {
+ ...prevArtifacts,
+ [artifactKey]: {
+ id: artifactKey,
+ identifier,
+ title,
+ type,
+ content,
+ },
+ };
+ });
+
+ setArtifactIds((prevIds) => {
+ if (!prevIds.includes(artifactKey)) {
+ return [...prevIds, artifactKey];
+ }
+ return prevIds;
+ });
+ }, [props, setArtifacts, setArtifactIds]);
+
+ useEffect(() => {
+ updateArtifact();
+ }, [updateArtifact]);
-export function artifact({ node, ...props }) {
- // if (props.className === 'artifact') {
- console.dir(props, { depth: null });
return (
-
{props.dataIdentifier}
-
Type: {props.dataType}
+
{props.title || 'Untitled Artifact'}
+
Type: {props.type || 'unknown'}
+
Identifier: {props.identifier || 'No identifier'}
{props.children}
);
- // }
- // return ;
-}
\ No newline at end of file
+}
diff --git a/client/src/components/Artifacts/Artifacts.tsx b/client/src/components/Artifacts/Artifacts.tsx
index b5d7713add..ef5633965d 100644
--- a/client/src/components/Artifacts/Artifacts.tsx
+++ b/client/src/components/Artifacts/Artifacts.tsx
@@ -2,21 +2,19 @@ import React, { useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import * as Tabs from '@radix-ui/react-tabs';
import { Sandpack } from '@codesandbox/sandpack-react';
-import {
- SandpackPreview,
- SandpackProvider,
-} from '@codesandbox/sandpack-react/unstyled';
+import { SandpackPreview, SandpackProvider } from '@codesandbox/sandpack-react/unstyled';
import { mapCodeFiles, sharedOptions, sharedFiles, sharedProps } from '~/utils/artifacts';
import store from '~/store';
export function CodeViewer({ showEditor = false }: { showEditor?: boolean }) {
- const codeBlockIds = useRecoilValue(store.codeBlockIdsState);
- const codeBlocks = useRecoilValue(store.codeBlocksState);
+ const artifactIds = useRecoilValue(store.artifactIdsState);
+ const artifacts = useRecoilValue(store.artifactsState);
- const files = useMemo(() => mapCodeFiles(codeBlockIds, codeBlocks), [codeBlockIds, codeBlocks]);
+ // const files = useMemo(() => mapCodeFiles(artifactIds, artifacts), [artifactIds, artifacts]);
- console.log('CODE FILES & blocks', files, codeBlocks);
- if ((Object.keys(files)).length === 0) {
+ // console.log('CODE FILES & blocks', files, artifacts);
+ const files = {};
+ if (Object.keys(files).length === 0) {
return null;
}
@@ -55,32 +53,34 @@ export function CodeViewer({ showEditor = false }: { showEditor?: boolean }) {
export default function Artifacts() {
const [activeTab, setActiveTab] = useState('code');
- const codeBlockIds = useRecoilValue(store.codeBlockIdsState);
- const codeBlocks = useRecoilValue(store.codeBlocksState);
+ const artifactIds = useRecoilValue(store.artifactIdsState);
+ const artifacts = useRecoilValue(store.artifactsState);
- const files = useMemo(() => mapCodeFiles(codeBlockIds, codeBlocks), [codeBlockIds, codeBlocks]);
- const firstFileContent = Object.values(files)[0] || '';
+ // const files = useMemo(() => mapCodeFiles(artifactIds, artifacts), [artifactIds, artifacts]);
+ // const firstFileContent = Object.values(files)[0] || '';
+
+ const firstFileContent = '';
return (
-
-
-
+
+
+
Code
Preview
-
+
{firstFileContent}
diff --git a/client/src/components/Chat/Messages/Content/Markdown.tsx b/client/src/components/Chat/Messages/Content/Markdown.tsx
index a669ccd66e..db0083ef08 100644
--- a/client/src/components/Chat/Messages/Content/Markdown.tsx
+++ b/client/src/components/Chat/Messages/Content/Markdown.tsx
@@ -10,7 +10,7 @@ import remarkDirective from 'remark-directive';
import type { PluggableList, Pluggable } from 'unified';
import { langSubset, preprocessLaTeX, handleDoubleClick } from '~/utils';
import { CodeBlockArtifact, CodeMarkdown } from '~/components/Artifacts/Code';
-import { artifact, artifactPlugin } from '~/components/Artifacts/Artifact';
+import { Artifact as artifact, artifactPlugin } from '~/components/Artifacts/Artifact';
import CodeBlock from '~/components/Messages/Content/CodeBlock';
import { useFileDownload } from '~/data-provider';
import useLocalize from '~/hooks/useLocalize';
@@ -156,11 +156,13 @@ const Markdown = memo(({ content = '', showCursor, isLatestMessage }: TContentPr
return (
startupConfig?.interface ?? defaultInterface,
[startupConfig],
diff --git a/client/src/store/artifacts.ts b/client/src/store/artifacts.ts
index 34fa78de64..008bb208b6 100644
--- a/client/src/store/artifacts.ts
+++ b/client/src/store/artifacts.ts
@@ -1,27 +1,38 @@
-// client/src/store/artifacts.ts
import { atom } from 'recoil';
-import type { CodeBlock } from '~/common';
+import { logger } from '~/utils';
+export interface Artifact {
+ identifier?: string;
+ title: string;
+ type: string;
+ content: string;
+}
-export const codeBlocksState = atom>({
- key: 'codeBlocksState',
+export const artifactsState = atom>({
+ key: 'artifactsState',
default: {},
effects: [
({ onSet, node }) => {
onSet(async (newValue) => {
- console.log('Recoil Effect: Setting codeBlocksState', { key: node.key, newValue });
+ logger.log('artifacts', 'Recoil Effect: Setting artifactsState', {
+ key: node.key,
+ newValue,
+ });
});
},
] as const,
});
-export const codeBlockIdsState = atom({
- key: 'codeBlockIdsState',
+export const artifactIdsState = atom({
+ key: 'artifactIdsState',
default: [],
effects: [
({ onSet, node }) => {
onSet(async (newValue) => {
- console.log('Recoil Effect: Setting codeBlockIdsState', { key: node.key, newValue });
+ logger.log('artifacts', 'Recoil Effect: Setting artifactIdsState', {
+ key: node.key,
+ newValue,
+ });
});
},
] as const,
-});
\ No newline at end of file
+});