Skip to content

Commit 72f16c9

Browse files
committed
Fix: revamp knowledge UX based on feedback
Signed-off-by: Daishan Peng <[email protected]>
1 parent 97e615c commit 72f16c9

File tree

5 files changed

+169
-171
lines changed

5 files changed

+169
-171
lines changed

actions/knowledge/knowledge.ts

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,25 @@ export async function deleteDataset(datasetID: string): Promise<void> {
3737
return;
3838
}
3939

40+
export async function firstIngestion(
41+
scriptId: string,
42+
files: string[]
43+
): Promise<boolean> {
44+
const dir = path.join(KNOWLEDGE_DIR(), 'script_data', scriptId, 'data');
45+
return !fs.existsSync(dir) && files.length > 0;
46+
}
47+
4048
export async function ensureFilesIngested(
4149
files: string[],
4250
scriptId: string,
4351
token: string
44-
) {
52+
): Promise<string> {
4553
const dir = path.join(KNOWLEDGE_DIR(), 'script_data', scriptId, 'data');
4654
if (!fs.existsSync(dir) && files.length > 0) {
4755
fs.mkdirSync(dir, { recursive: true });
4856
} else if (!fs.existsSync(dir) && files.length === 0) {
4957
// if there are no files in the directory and no dropped files, do nothing
50-
return;
58+
return '';
5159
}
5260

5361
for (const file of files) {
@@ -57,8 +65,7 @@ export async function ensureFilesIngested(
5765
await fs.promises.copyFile(file, filePath);
5866
}
5967
} catch (error) {
60-
console.error(`Error copying file ${file}:`, error);
61-
throw error;
68+
return `Error copying file ${file}: ${error}`;
6269
}
6370
}
6471

@@ -74,8 +81,7 @@ export async function ensureFilesIngested(
7481
}
7582
}
7683
} catch (error) {
77-
console.error('Error during cleanup of removed files:', error);
78-
throw error;
84+
return `Error deleting files: ${error}`;
7985
}
8086

8187
try {
@@ -85,37 +91,31 @@ export async function ensureFilesIngested(
8591
token
8692
);
8793
} catch (error) {
88-
console.error('Error during ingestion:', error);
89-
throw error;
94+
return `Error running knowledge ingestion: ${error}`;
9095
}
9196

92-
return;
97+
return '';
9398
}
9499

95100
async function runKnowledgeIngest(
96101
id: string,
97102
knowledgePath: string,
98103
token: string
99104
): Promise<void> {
100-
try {
101-
// Start the ingestion process in the background
102-
await execPromise(
103-
`${process.env.KNOWLEDGE_BIN} ingest --prune --dataset ${id} ./data`,
104-
{
105-
cwd: knowledgePath,
106-
env: { ...process.env, GPTSCRIPT_GATEWAY_API_KEY: token },
107-
}
108-
);
109-
110-
const errorFilePath = path.join(knowledgePath, 'error.log');
111-
if (fs.existsSync(errorFilePath)) {
112-
await fs.promises.rm(errorFilePath);
105+
// Start the ingestion process in the background
106+
await execPromise(
107+
`${process.env.KNOWLEDGE_BIN} ingest --prune --dataset ${id} ./data`,
108+
{
109+
cwd: knowledgePath,
110+
env: { ...process.env, GPTSCRIPT_GATEWAY_API_KEY: token },
113111
}
114-
} catch (error) {
115-
console.log(error);
116-
handleError(knowledgePath, error as Error);
117-
throw error;
112+
);
113+
114+
const errorFilePath = path.join(knowledgePath, 'error.log');
115+
if (fs.existsSync(errorFilePath)) {
116+
await fs.promises.rm(errorFilePath);
118117
}
118+
return;
119119
}
120120

121121
export async function getFiles(scriptId: string): Promise<string[]> {
@@ -135,8 +135,3 @@ export async function datasetExists(scriptId: string): Promise<boolean> {
135135
export async function getKnowledgeBinaryPath(): Promise<string> {
136136
return process.env.KNOWLEDGE_BIN || 'knowledge';
137137
}
138-
139-
function handleError(dir: string, error: Error): void {
140-
const errorFilePath = path.join(dir, 'error.log');
141-
fs.writeFileSync(errorFilePath, error.message);
142-
}

components/edit/configure.tsx

Lines changed: 92 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Models from '@/components/edit/configure/models';
55
import Visibility from '@/components/edit/configure/visibility';
66
import Code from '@/components/edit/configure/code';
77
import { EditContext, KNOWLEDGE_NAME } from '@/contexts/edit';
8-
import { GoLightBulb } from 'react-icons/go';
8+
import { GoLightBulb, GoTrash } from 'react-icons/go';
99
import { HiCog } from 'react-icons/hi2';
1010
import { LuCircuitBoard } from 'react-icons/lu';
1111
import {
@@ -24,11 +24,11 @@ import AssistantNotFound from '@/components/assistant-not-found';
2424
import { useRouter } from 'next/navigation';
2525
import { ChatContext } from '@/contexts/chat';
2626
import Chat from '@/components/chat';
27-
import { GoDatabase } from 'react-icons/go';
2827
import { IoSettingsOutline } from 'react-icons/io5';
29-
import { IoMdAdd } from 'react-icons/io';
28+
import { IoMdAdd, IoMdRefresh } from 'react-icons/io';
3029
import { RiFileSearchLine } from 'react-icons/ri';
31-
import KnowledgeModals from '@/components/knowledge/KnowledgeModals';
30+
import FileSettingModals from '@/components/knowledge/KnowledgeModals';
31+
import { RiFoldersLine } from 'react-icons/ri';
3232

3333
interface ConfigureProps {
3434
collapsed?: boolean;
@@ -51,12 +51,14 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
5151
setDependencies,
5252
setDroppedFiles,
5353
droppedFileDetails,
54+
setDroppedFileDetails,
5455
ingesting,
56+
ingest,
5557
updated,
5658
setUpdated,
59+
ingestionError,
5760
} = useContext(EditContext);
5861
const { restartScript } = useContext(ChatContext);
59-
const fileTableModal = useDisclosure();
6062
const fileSettingModal = useDisclosure();
6163

6264
const abbreviate = (name: string) => {
@@ -212,40 +214,95 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
212214
aria-label="files"
213215
title={<h1>Files</h1>}
214216
startContent={<RiFileSearchLine />}
215-
classNames={{ content: 'pt-1 pb-3' }}
217+
classNames={{ content: collapsed ? 'pt-6 pb-10' : 'p-10 pt-6' }}
216218
>
217-
<div className="flex justify-between items-center">
218-
<Button
219-
isIconOnly
220-
size="sm"
221-
startContent={<GoDatabase />}
222-
onClick={fileTableModal.onOpen}
223-
/>
224-
225-
{droppedFileDetails?.size > 0 && !ingesting && (
226-
<p className="text-sm text-zinc-500 ml-2">{`${droppedFileDetails.size} ${droppedFileDetails.size === 1 ? 'file' : 'files'}, ${Array.from(
227-
droppedFileDetails.values()
219+
<div className="grid grid-cols-1 gap-2 w-full mb-2">
220+
{Array.from(droppedFileDetails.entries()).map(
221+
(fileDetail, i) => (
222+
<div key={i} className="flex space-x-2">
223+
<div className="truncate w-full border-2 dark:border-zinc-700 text-sm pl-2 rounded-lg flex justify-between items-center">
224+
<div className="flex items-center space-x-2">
225+
<RiFileSearchLine />
226+
<p className="capitalize">{fileDetail[1].fileName}</p>
227+
<p className="text-xs text-zinc-400 ml-2">{`${fileDetail[1].size} KB`}</p>
228+
</div>
229+
<Button
230+
variant="light"
231+
isIconOnly
232+
size="sm"
233+
startContent={<GoTrash />}
234+
onPress={() => {
235+
setDroppedFiles((prev) =>
236+
prev.filter((f) => f !== fileDetail[0])
237+
);
238+
const newDetails = new Map(droppedFileDetails);
239+
newDetails.delete(fileDetail[0]);
240+
setDroppedFileDetails(newDetails);
241+
}}
242+
/>
243+
</div>
244+
</div>
228245
)
229-
.reduce((acc, detail) => acc + detail.size, 0)
230-
.toFixed(2)} KB`}</p>
231246
)}
232-
{ingesting && <Spinner size="sm" className="ml-2" />}
233-
<div className="ml-auto flex space-x-2">
234-
<Button
235-
isIconOnly
236-
size="sm"
237-
startContent={<IoSettingsOutline />}
238-
onClick={fileSettingModal.onOpen}
239-
/>
240-
<Button
241-
size="sm"
242-
startContent={<IoMdAdd />}
243-
onClick={handleAddFiles}
244-
>
245-
Files
246-
</Button>
247+
<div className="flex justify-end mt-2">
248+
{droppedFileDetails?.size > 0 &&
249+
!ingesting &&
250+
!ingestionError && (
251+
<div className="flex justify-center">
252+
<RiFoldersLine />
253+
<p className="text-sm text-zinc-500 ml-2">{`${droppedFileDetails.size} ${droppedFileDetails.size === 1 ? 'file' : 'files'}, ${Array.from(
254+
droppedFileDetails.values()
255+
)
256+
.reduce((acc, detail) => acc + detail.size, 0)
257+
.toFixed(2)} KB`}</p>
258+
</div>
259+
)}
260+
{ingesting && !ingestionError && (
261+
<Spinner size="sm" className="ml-2" />
262+
)}
263+
{ingestionError && (
264+
<>
265+
<Button
266+
isIconOnly
267+
variant="flat"
268+
color="primary"
269+
size="sm"
270+
startContent={<IoMdRefresh size={18} />}
271+
onClick={ingest}
272+
></Button>
273+
<p className="text-sm text-red-500 ml-2">
274+
{ingestionError}
275+
</p>
276+
</>
277+
)}
247278
</div>
248279
</div>
280+
<div
281+
className={`flex ${collapsed ? 'flex-col space-y-2' : 'space-x-4'} ${droppedFileDetails.size > 0 ? 'pt-4' : ''}`}
282+
>
283+
<Button
284+
className="w-full"
285+
variant="flat"
286+
color="primary"
287+
isIconOnly
288+
size="sm"
289+
startContent={<IoSettingsOutline className="mr-2" />}
290+
onPress={fileSettingModal.onOpen}
291+
>
292+
Settings
293+
</Button>
294+
<Button
295+
className="w-full"
296+
variant="flat"
297+
color="primary"
298+
isIconOnly
299+
size="sm"
300+
startContent={<IoMdAdd className="mr-2" />}
301+
onPress={handleAddFiles}
302+
>
303+
Add Files
304+
</Button>
305+
</div>
249306
</AccordionItem>
250307
<AccordionItem
251308
aria-label="advanced"
@@ -308,12 +365,9 @@ const Configure: React.FC<ConfigureProps> = ({ collapsed }) => {
308365
: `Click "Refresh Chat" to chat with the updated version of ${placeholderName()}`
309366
}
310367
/>
311-
<KnowledgeModals
368+
<FileSettingModals
312369
isFileSettingOpen={fileSettingModal.isOpen}
313370
onFileSettingClose={fileSettingModal.onClose}
314-
isFileTableOpen={fileTableModal.isOpen}
315-
onFileTableClose={fileTableModal.onClose}
316-
handleAddFiles={handleAddFiles}
317371
/>
318372
</>
319373
);

components/knowledge/KnowledgeModals.tsx

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,23 @@
11
import {
2-
Button,
32
Modal,
43
ModalBody,
54
ModalContent,
6-
ModalFooter,
75
ModalHeader,
86
Slider,
9-
Table,
10-
TableBody,
11-
TableCell,
12-
TableColumn,
13-
TableHeader,
14-
TableRow,
157
} from '@nextui-org/react';
16-
import { BiPlus, BiTrash } from 'react-icons/bi';
178
import { useContext } from 'react';
189
import { EditContext } from '@/contexts/edit';
1910

2011
interface KnowledgeProps {
2112
isFileSettingOpen: boolean;
2213
onFileSettingClose: () => void;
23-
isFileTableOpen: boolean;
24-
onFileTableClose: () => void;
25-
handleAddFiles: () => void;
2614
}
2715

2816
const KnowledgeModals = ({
2917
isFileSettingOpen,
3018
onFileSettingClose,
31-
isFileTableOpen,
32-
onFileTableClose,
33-
handleAddFiles,
3419
}: KnowledgeProps) => {
35-
const {
36-
topK,
37-
setTopK,
38-
droppedFileDetails,
39-
setDroppedFileDetails,
40-
setDroppedFiles,
41-
} = useContext(EditContext);
20+
const { topK, setTopK } = useContext(EditContext);
4221
return (
4322
<>
4423
<Modal
@@ -72,60 +51,6 @@ const KnowledgeModals = ({
7251
</ModalBody>
7352
</ModalContent>
7453
</Modal>
75-
<Modal
76-
size="xl"
77-
backdrop="opaque"
78-
isOpen={isFileTableOpen}
79-
onClose={onFileTableClose}
80-
>
81-
<ModalContent>
82-
<ModalHeader>
83-
<h3 id="modal-title">Files</h3>
84-
</ModalHeader>
85-
<ModalBody>
86-
<Table removeWrapper aria-label="File table">
87-
<TableHeader>
88-
<TableColumn>File Name</TableColumn>
89-
<TableColumn>Size</TableColumn>
90-
<TableColumn>{''}</TableColumn>
91-
</TableHeader>
92-
<TableBody>
93-
{Array.from(droppedFileDetails).map((fileDetail, index) => (
94-
<TableRow key={index}>
95-
<TableCell>{fileDetail[1].fileName}</TableCell>
96-
<TableCell>{fileDetail[1].size} KB</TableCell>
97-
<TableCell align="right">
98-
<Button
99-
isIconOnly
100-
size="md"
101-
onClick={() => {
102-
setDroppedFiles((prev) =>
103-
prev.filter((f) => f !== fileDetail[0])
104-
);
105-
const newDetails = new Map(droppedFileDetails);
106-
newDetails.delete(fileDetail[0]);
107-
setDroppedFileDetails(newDetails);
108-
}}
109-
className="bg-white"
110-
startContent={<BiTrash />}
111-
/>
112-
</TableCell>
113-
</TableRow>
114-
))}
115-
</TableBody>
116-
</Table>
117-
</ModalBody>
118-
<ModalFooter>
119-
<Button
120-
className="w-full"
121-
onClick={handleAddFiles}
122-
startContent={<BiPlus />}
123-
>
124-
Add files
125-
</Button>
126-
</ModalFooter>
127-
</ModalContent>
128-
</Modal>
12954
</>
13055
);
13156
};

0 commit comments

Comments
 (0)