| | import { memo } from 'react'; |
| |
|
| | import type { ArtifactKind } from './artifact'; |
| | import { FileIcon, LoaderIcon, MessageIcon, PencilEditIcon } from './icons'; |
| | import { toast } from 'sonner'; |
| | import { useArtifact } from '@/hooks/use-artifact'; |
| |
|
| | const getActionText = ( |
| | type: 'create' | 'update' | 'request-suggestions', |
| | tense: 'present' | 'past', |
| | ) => { |
| | switch (type) { |
| | case 'create': |
| | return tense === 'present' ? 'Creating' : 'Created'; |
| | case 'update': |
| | return tense === 'present' ? 'Updating' : 'Updated'; |
| | case 'request-suggestions': |
| | return tense === 'present' |
| | ? 'Adding suggestions' |
| | : 'Added suggestions to'; |
| | default: |
| | return null; |
| | } |
| | }; |
| |
|
| | interface DocumentToolResultProps { |
| | type: 'create' | 'update' | 'request-suggestions'; |
| | result: { id: string; title: string; kind: ArtifactKind }; |
| | isReadonly: boolean; |
| | } |
| |
|
| | function PureDocumentToolResult({ |
| | type, |
| | result, |
| | isReadonly, |
| | }: DocumentToolResultProps) { |
| | const { setArtifact } = useArtifact(); |
| |
|
| | return ( |
| | <button |
| | type="button" |
| | className="bg-background cursor-pointer border py-2 px-3 rounded-xl w-fit flex flex-row gap-3 items-start" |
| | onClick={(event) => { |
| | if (isReadonly) { |
| | toast.error( |
| | 'Viewing files in shared chats is currently not supported.', |
| | ); |
| | return; |
| | } |
| | |
| | const rect = event.currentTarget.getBoundingClientRect(); |
| | |
| | const boundingBox = { |
| | top: rect.top, |
| | left: rect.left, |
| | width: rect.width, |
| | height: rect.height, |
| | }; |
| | |
| | setArtifact({ |
| | documentId: result.id, |
| | kind: result.kind, |
| | content: '', |
| | title: result.title, |
| | isVisible: true, |
| | status: 'idle', |
| | boundingBox, |
| | }); |
| | }} |
| | > |
| | <div className="text-muted-foreground mt-1"> |
| | {type === 'create' ? ( |
| | <FileIcon /> |
| | ) : type === 'update' ? ( |
| | <PencilEditIcon /> |
| | ) : type === 'request-suggestions' ? ( |
| | <MessageIcon /> |
| | ) : null} |
| | </div> |
| | <div className="text-left"> |
| | {`${getActionText(type, 'past')} "${result.title}"`} |
| | </div> |
| | </button> |
| | ); |
| | } |
| |
|
| | export const DocumentToolResult = memo(PureDocumentToolResult, () => true); |
| |
|
| | interface DocumentToolCallProps { |
| | type: 'create' | 'update' | 'request-suggestions'; |
| | args: |
| | | { title: string; kind: ArtifactKind } |
| | | { id: string; description: string } |
| | | { documentId: string }; |
| | isReadonly: boolean; |
| | } |
| |
|
| | function PureDocumentToolCall({ |
| | type, |
| | args, |
| | isReadonly, |
| | }: DocumentToolCallProps) { |
| | const { setArtifact } = useArtifact(); |
| |
|
| | return ( |
| | <button |
| | type="button" |
| | className="cursor pointer w-fit border py-2 px-3 rounded-xl flex flex-row items-start justify-between gap-3" |
| | onClick={(event) => { |
| | if (isReadonly) { |
| | toast.error( |
| | 'Viewing files in shared chats is currently not supported.', |
| | ); |
| | return; |
| | } |
| | |
| | const rect = event.currentTarget.getBoundingClientRect(); |
| | |
| | const boundingBox = { |
| | top: rect.top, |
| | left: rect.left, |
| | width: rect.width, |
| | height: rect.height, |
| | }; |
| | |
| | setArtifact((currentArtifact) => ({ |
| | ...currentArtifact, |
| | isVisible: true, |
| | boundingBox, |
| | })); |
| | }} |
| | > |
| | <div className="flex flex-row gap-3 items-start"> |
| | <div className="text-zinc-500 mt-1"> |
| | {type === 'create' ? ( |
| | <FileIcon /> |
| | ) : type === 'update' ? ( |
| | <PencilEditIcon /> |
| | ) : type === 'request-suggestions' ? ( |
| | <MessageIcon /> |
| | ) : null} |
| | </div> |
| | |
| | <div className="text-left"> |
| | {`${getActionText(type, 'present')} ${ |
| | type === 'create' && 'title' in args && args.title |
| | ? `"${args.title}"` |
| | : type === 'update' && 'description' in args |
| | ? `"${args.description}"` |
| | : type === 'request-suggestions' |
| | ? 'for document' |
| | : '' |
| | }`} |
| | </div> |
| | </div> |
| | |
| | <div className="animate-spin mt-1">{<LoaderIcon />}</div> |
| | </button> |
| | ); |
| | } |
| |
|
| | export const DocumentToolCall = memo(PureDocumentToolCall, () => true); |
| |
|