feat: improve prompt, add ability to abort streaming, improve message parser

This commit is contained in:
Dominic Elm
2024-07-18 11:10:12 +02:00
parent 637ad2b870
commit 012b5bae80
12 changed files with 633 additions and 160 deletions

View File

@@ -1,8 +1,9 @@
import { useStore } from '@nanostores/react';
import { AnimatePresence, motion } from 'framer-motion';
import { computed } from 'nanostores';
import { useState } from 'react';
import { memo, useEffect, useRef, useState } from 'react';
import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki';
import { chatStore } from '../../lib/stores/chat';
import { getArtifactKey, workbenchStore, type ActionState } from '../../lib/stores/workbench';
import { classNames } from '../../utils/classNames';
import { cubicEasingFn } from '../../utils/easings';
@@ -25,9 +26,11 @@ interface ArtifactProps {
messageId: string;
}
export function Artifact({ artifactId, messageId }: ArtifactProps) {
export const Artifact = memo(({ artifactId, messageId }: ArtifactProps) => {
const userToggledActions = useRef(false);
const [showActions, setShowActions] = useState(false);
const chat = useStore(chatStore);
const artifacts = useStore(workbenchStore.artifacts);
const artifact = artifacts[getArtifactKey(artifactId, messageId)];
@@ -37,6 +40,17 @@ export function Artifact({ artifactId, messageId }: ArtifactProps) {
}),
);
const toggleActions = () => {
userToggledActions.current = true;
setShowActions(!showActions);
};
useEffect(() => {
if (actions.length && !showActions && !userToggledActions.current) {
setShowActions(true);
}
}, [actions]);
return (
<div className="flex flex-col overflow-hidden border rounded-lg w-full">
<div className="flex">
@@ -48,7 +62,7 @@ export function Artifact({ artifactId, messageId }: ArtifactProps) {
}}
>
<div className="flex items-center px-6 bg-gray-100/50">
{!artifact?.closed ? (
{!artifact?.closed && !chat.aborted ? (
<div className="i-svg-spinners:90-ring-with-bg scale-130"></div>
) : (
<div className="i-ph:code-bold scale-130 text-gray-600"></div>
@@ -67,7 +81,7 @@ export function Artifact({ artifactId, messageId }: ArtifactProps) {
exit={{ width: 0 }}
transition={{ duration: 0.15, ease: cubicEasingFn }}
className="hover:bg-gray-200"
onClick={() => setShowActions(!showActions)}
onClick={toggleActions}
>
<div className="p-4">
<div className={showActions ? 'i-ph:caret-up-bold' : 'i-ph:caret-down-bold'}></div>
@@ -98,9 +112,9 @@ export function Artifact({ artifactId, messageId }: ArtifactProps) {
const { status, type, content, abort } = action;
return (
<li key={index} className={classNames(getTextColor(action.status))}>
<li key={index}>
<div className="flex items-center gap-1.5">
<div className="text-lg">
<div className={classNames('text-lg', getTextColor(action.status))}>
{status === 'running' ? (
<div className="i-svg-spinners:90-ring-with-bg"></div>
) : status === 'pending' ? (
@@ -136,7 +150,7 @@ export function Artifact({ artifactId, messageId }: ArtifactProps) {
</AnimatePresence>
</div>
);
}
});
function getTextColor(status: ActionState['status']) {
switch (status) {