Spaces:
Runtime error
Runtime error
File size: 3,827 Bytes
3b6afc0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import React, { useState, useCallback, memo, ReactNode } from 'react';
import { Spinner } from '~/components';
import { useRecoilValue } from 'recoil';
import CodeBlock from './Content/CodeBlock.jsx';
import { Disclosure } from '@headlessui/react';
import { ChevronDownIcon, LucideProps } from 'lucide-react';
import { cn } from '~/utils/';
import store from '~/store';
interface Input {
inputStr: string;
}
interface PluginProps {
plugin: {
plugin: string;
input: string;
thought: string;
loading?: boolean;
outputs?: string;
latest?: string;
inputs?: Input[];
};
}
type PluginsMap = {
[pluginKey: string]: string;
};
type PluginIconProps = LucideProps & {
className?: string;
};
function formatInputs(inputs: Input[]) {
let output = '';
for (let i = 0; i < inputs.length; i++) {
output += `${inputs[i].inputStr}`;
if (inputs.length > 1 && i !== inputs.length - 1) {
output += ',\n';
}
}
return output;
}
const Plugin: React.FC<PluginProps> = ({ plugin }) => {
const [loading, setLoading] = useState(plugin.loading);
const finished = plugin.outputs && plugin.outputs.length > 0;
const plugins: PluginsMap = useRecoilValue(store.plugins);
const getPluginName = useCallback(
(pluginKey: string) => {
if (!pluginKey) {
return null;
}
if (pluginKey === 'n/a' || pluginKey === 'self reflection') {
return pluginKey;
}
return plugins[pluginKey] ?? 'self reflection';
},
[plugins],
);
if (!plugin || !plugin.latest) {
return null;
}
const latestPlugin = getPluginName(plugin.latest);
if (!latestPlugin || (latestPlugin && latestPlugin === 'n/a')) {
return null;
}
if (finished && loading) {
setLoading(false);
}
const generateStatus = (): ReactNode => {
if (!loading && latestPlugin === 'self reflection') {
return 'Finished';
} else if (latestPlugin === 'self reflection') {
return 'I\'m thinking...';
} else {
return (
<>
{loading ? 'Using' : 'Used'} <b>{latestPlugin}</b>
{loading ? '...' : ''}
</>
);
}
};
return (
<div className="flex flex-col items-start">
<Disclosure>
{({ open }) => {
const iconProps: PluginIconProps = {
className: cn(open ? 'rotate-180 transform' : '', 'h-4 w-4'),
};
return (
<>
<div
className={cn(
loading ? 'bg-green-100' : 'bg-[#ECECF1]',
'flex items-center rounded p-3 text-sm text-gray-900',
)}
>
<div>
<div className="flex items-center gap-3">
<div>{generateStatus()}</div>
</div>
</div>
{loading && <Spinner className="ml-1" />}
<Disclosure.Button className="ml-12 flex items-center gap-2">
<ChevronDownIcon {...iconProps} />
</Disclosure.Button>
</div>
<Disclosure.Panel className="my-3 flex max-w-full flex-col gap-3">
<CodeBlock
lang={latestPlugin?.toUpperCase() || 'INPUTS'}
codeChildren={formatInputs(plugin.inputs ?? [])}
plugin={true}
classProp="max-h-[450px]"
/>
{finished && (
<CodeBlock
lang="OUTPUTS"
codeChildren={plugin.outputs ?? ''}
plugin={true}
classProp="max-h-[450px]"
/>
)}
</Disclosure.Panel>
</>
);
}}
</Disclosure>
</div>
);
};
export default memo(Plugin);
|