Skip to content

Commit 98e16f6

Browse files
committed
fix qa comments set 3
1 parent 71a523d commit 98e16f6

File tree

14 files changed

+461
-44
lines changed

14 files changed

+461
-44
lines changed

backend/onyx/server/features/projects/api.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,44 @@ def get_chat_session_project_token_count(
505505
return TokenCountResponse(total_tokens=int(total_tokens))
506506

507507

508+
@router.get("/session/{chat_session_id}/files")
509+
def get_chat_session_project_files(
510+
chat_session_id: str,
511+
user: User | None = Depends(current_user),
512+
db_session: Session = Depends(get_session),
513+
) -> list[UserFileSnapshot]:
514+
"""Return user files for the project linked to the given chat session.
515+
516+
If the chat session has no project, returns an empty list.
517+
Only returns files owned by the current user and not FAILED.
518+
"""
519+
user_id = user.id if user is not None else None
520+
521+
chat_session = (
522+
db_session.query(ChatSession)
523+
.filter(ChatSession.id == chat_session_id, ChatSession.user_id == user_id)
524+
.one_or_none()
525+
)
526+
if chat_session is None:
527+
raise HTTPException(status_code=404, detail="Chat session not found")
528+
529+
if chat_session.project_id is None:
530+
return []
531+
532+
user_files = (
533+
db_session.query(UserFile)
534+
.filter(
535+
UserFile.projects.any(id=chat_session.project_id),
536+
UserFile.user_id == user_id,
537+
UserFile.status != UserFileStatus.FAILED,
538+
)
539+
.order_by(UserFile.created_at.desc())
540+
.all()
541+
)
542+
543+
return [UserFileSnapshot.from_model(user_file) for user_file in user_files]
544+
545+
508546
@router.get("/{project_id}/token-count", response_model=TokenCountResponse)
509547
def get_project_token_count(
510548
project_id: int,

web/src/app/admin/assistants/AssistantEditor.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ import useSWR from "swr";
9090
import { errorHandlingFetcher } from "@/lib/fetcher";
9191
import { ConfirmEntityModal } from "@/components/modals/ConfirmEntityModal";
9292

93-
import { FilePickerModal } from "@/app/chat/my-documents/components/FilePicker";
94-
import { useDocumentsContext } from "@/app/chat/my-documents/DocumentsContext";
95-
9693
import {
9794
IMAGE_GENERATION_TOOL_ID,
9895
SEARCH_TOOL_ID,
@@ -173,7 +170,6 @@ export function AssistantEditor({
173170

174171
const [presentingDocument, setPresentingDocument] =
175172
useState<MinimalOnyxDocument | null>(null);
176-
const [filePickerModalOpen, setFilePickerModalOpen] = useState(false);
177173
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
178174
const [showAllUserFiles, setShowAllUserFiles] = useState(false);
179175

@@ -1109,6 +1105,12 @@ export function AssistantEditor({
11091105
showTriggerLabel
11101106
triggerLabel="Add User Files"
11111107
recentFiles={recentFiles}
1108+
onFileClick={(file: ProjectFile) => {
1109+
setPresentingDocument({
1110+
document_id: `project_file__${file.file_id}`,
1111+
semantic_identifier: file.name,
1112+
});
1113+
}}
11121114
onPickRecent={(file: ProjectFile) => {
11131115
if (!values.user_file_ids.includes(file.id)) {
11141116
setFieldValue("user_file_ids", [

web/src/app/chat/components/ChatPage.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ export function ChatPage({
524524
setSelectedAssistantFromId,
525525
});
526526

527-
const { onMessageSelection, currentSessionFileTokenCount } =
527+
const { onMessageSelection, currentSessionFileTokenCount, projectFiles } =
528528
useChatSessionController({
529529
existingChatSessionId,
530530
searchParams,
@@ -906,6 +906,7 @@ export function ChatPage({
906906
maxTokens={maxTokens}
907907
initialWidth={400}
908908
isOpen={true}
909+
projectFiles={projectFiles}
909910
/>
910911
</Modal>
911912
</div>
@@ -1059,6 +1060,7 @@ export function ChatPage({
10591060
maxTokens={maxTokens}
10601061
initialWidth={400}
10611062
isOpen={documentSidebarVisible && !settings?.isMobile}
1063+
projectFiles={projectFiles}
10621064
/>
10631065
</div>
10641066

@@ -1159,6 +1161,7 @@ export function ChatPage({
11591161
llmManager={llmManager}
11601162
deepResearchEnabled={deepResearchEnabled}
11611163
currentMessageFiles={currentMessageFiles}
1164+
projectFiles={projectFiles}
11621165
setPresentingDocument={setPresentingDocument}
11631166
setCurrentFeedback={setCurrentFeedback}
11641167
onSubmit={onSubmit}
@@ -1223,6 +1226,9 @@ export function ChatPage({
12231226
availableContextTokens={
12241227
availableContextTokens
12251228
}
1229+
setPresentingDocument={
1230+
setPresentingDocument
1231+
}
12261232
/>
12271233
)}
12281234
<ChatInputBar
@@ -1253,6 +1259,7 @@ export function ChatPage({
12531259
handleMessageSpecificFileUpload
12541260
}
12551261
textAreaRef={textAreaRef}
1262+
setPresentingDocument={setPresentingDocument}
12561263
/>
12571264
</div>
12581265

web/src/app/chat/components/MessagesDisplay.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface MessagesDisplayProps {
1818
llmManager: { currentLlm: LlmDescriptor | null };
1919
deepResearchEnabled: boolean;
2020
currentMessageFiles: ProjectFile[];
21+
projectFiles: ProjectFile[];
2122
setPresentingDocument: (doc: MinimalOnyxDocument | null) => void;
2223
setCurrentFeedback: (feedback: [FeedbackType, number] | null) => void;
2324
onSubmit: (args: {
@@ -58,6 +59,7 @@ export const MessagesDisplay: React.FC<MessagesDisplayProps> = ({
5859
llmManager,
5960
deepResearchEnabled,
6061
currentMessageFiles,
62+
projectFiles,
6163
setPresentingDocument,
6264
setCurrentFeedback,
6365
onSubmit,
@@ -204,6 +206,7 @@ export const MessagesDisplay: React.FC<MessagesDisplayProps> = ({
204206
parentMessage?.childrenNodeIds ?? emptyChildrenIds
205207
}
206208
onMessageSelection={onMessageSelection}
209+
projectFiles={projectFiles}
207210
/>
208211
</div>
209212
);

web/src/app/chat/components/documentSidebar/DocumentResults.tsx

Lines changed: 125 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { MinimalOnyxDocument, OnyxDocument } from "@/lib/search/interfaces";
22
import { ChatDocumentDisplay } from "./ChatDocumentDisplay";
33
import { removeDuplicateDocs } from "@/lib/documentUtils";
4-
import { ChatFileType } from "@/app/chat/interfaces";
54
import {
65
Dispatch,
76
ForwardedRef,
@@ -16,6 +15,31 @@ import {
1615
useCurrentMessageTree,
1716
useSelectedNodeForDocDisplay,
1817
} from "../../stores/useChatSessionStore";
18+
import type { ProjectFile } from "@/app/chat/projects/projectsService";
19+
20+
// Build an OnyxDocument from basic file info
21+
const buildOnyxDocumentFromFile = (
22+
id: string,
23+
name?: string | null,
24+
appendProjectPrefix?: boolean
25+
): OnyxDocument => {
26+
const document_id = appendProjectPrefix ? `project_file__${id}` : id;
27+
return {
28+
document_id,
29+
semantic_identifier: name || id,
30+
link: "",
31+
source_type: "file" as any,
32+
blurb: "",
33+
boost: 0,
34+
hidden: false,
35+
score: 1,
36+
chunk_ind: 0,
37+
match_highlights: [],
38+
metadata: {},
39+
updated_at: null,
40+
is_internet: false,
41+
} as any;
42+
};
1943

2044
interface DocumentResultsProps {
2145
closeSidebar: () => void;
@@ -29,6 +53,7 @@ interface DocumentResultsProps {
2953
isSharedChat?: boolean;
3054
modal: boolean;
3155
setPresentingDocument: Dispatch<SetStateAction<MinimalOnyxDocument | null>>;
56+
projectFiles?: ProjectFile[];
3257
}
3358

3459
const DocumentResultsComponent = (
@@ -44,6 +69,7 @@ const DocumentResultsComponent = (
4469
isSharedChat,
4570
isOpen,
4671
setPresentingDocument,
72+
projectFiles = [],
4773
}: DocumentResultsProps,
4874
ref: ForwardedRef<HTMLDivElement>
4975
) => {
@@ -80,7 +106,7 @@ const DocumentResultsComponent = (
80106
: null;
81107

82108
const humanFileDescriptors = humanMessage?.files.filter(
83-
(file) => file.type == ChatFileType.USER_KNOWLEDGE
109+
(file) => file.user_file_id !== null
84110
);
85111
const selectedDocumentIds =
86112
selectedDocuments?.map((document) => document.document_id) || [];
@@ -103,6 +129,15 @@ const DocumentResultsComponent = (
103129
!citedDocumentIds.has(doc.document_id)
104130
);
105131

132+
const hasDocs = dedupedDocuments.length > 0;
133+
const hasCited = citedDocuments.length > 0;
134+
const hasOther = otherDocuments.length > 0;
135+
const hasHumanFiles = (humanFileDescriptors?.length || 0) > 0;
136+
const hasProjectFiles = (projectFiles?.length || 0) > 0;
137+
const showCloseInUserFiles = !hasCited && !hasOther && hasHumanFiles;
138+
const showCloseInProjectFiles =
139+
!hasCited && !hasOther && !hasHumanFiles && hasProjectFiles;
140+
106141
return (
107142
<>
108143
<div
@@ -127,10 +162,11 @@ const DocumentResultsComponent = (
127162
>
128163
<div className="flex flex-col h-full">
129164
<div className="overflow-y-auto h-fit mb-8 pb-8 sm:mx-0 flex-grow gap-y-0 default-scrollbar dark-scrollbar flex flex-col">
130-
{dedupedDocuments.length > 0 ? (
165+
{/* Documents Sections */}
166+
{hasDocs && (
131167
<>
132168
{/* Cited Documents Section */}
133-
{citedDocuments.length > 0 && (
169+
{hasCited && (
134170
<div className="mt-4">
135171
<div className="px-4 pb-3 pt-2 flex justify-between border-b border-border">
136172
<h3 className="text-base font-semibold text-text-700">
@@ -175,7 +211,7 @@ const DocumentResultsComponent = (
175211
)}
176212

177213
{/* Other Documents Section */}
178-
{otherDocuments.length > 0 && (
214+
{hasOther && (
179215
<div className="mt-4">
180216
<>
181217
<div className="px-4 pb-3 pt-2 border-b border-border">
@@ -215,7 +251,90 @@ const DocumentResultsComponent = (
215251
</div>
216252
)}
217253
</>
218-
) : null}
254+
)}
255+
256+
{/* Human Files Section */}
257+
{humanFileDescriptors && humanFileDescriptors.length > 0 && (
258+
<div className="mt-4">
259+
<div className="px-4 pb-3 pt-2 flex justify-between border-b border-border">
260+
<h3 className="text-base font-semibold text-text-700">
261+
User Files
262+
</h3>
263+
{showCloseInUserFiles && (
264+
<button
265+
aria-label="Close sidebar"
266+
title="Close"
267+
className="my-auto p-1 rounded transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-700"
268+
onClick={closeSidebar}
269+
>
270+
<XIcon size={16} />
271+
</button>
272+
)}
273+
</div>
274+
{humanFileDescriptors.map((f) => (
275+
<div key={f.id} className={`desktop:px-2 w-full mb-2`}>
276+
<ChatDocumentDisplay
277+
setPresentingDocument={setPresentingDocument}
278+
closeSidebar={closeSidebar}
279+
modal={modal}
280+
document={buildOnyxDocumentFromFile(
281+
f.id,
282+
f.name,
283+
false
284+
)}
285+
isSelected={false}
286+
handleSelect={() => {}}
287+
hideSelection={true}
288+
tokenLimitReached={false}
289+
/>
290+
</div>
291+
))}
292+
</div>
293+
)}
294+
295+
{/* Project Files Section */}
296+
{projectFiles && projectFiles.length > 0 && (
297+
<div className="mt-4">
298+
<div className="px-4 pb-3 pt-2 flex justify-between border-b border-border">
299+
<h3 className="text-base font-semibold text-text-700">
300+
Project Files
301+
</h3>
302+
{showCloseInProjectFiles && (
303+
<button
304+
aria-label="Close sidebar"
305+
title="Close"
306+
className="my-auto p-1 rounded transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-700"
307+
onClick={closeSidebar}
308+
>
309+
<XIcon size={16} />
310+
</button>
311+
)}
312+
</div>
313+
{projectFiles.slice(0, 20).map((f) => (
314+
<div key={f.id} className={`desktop:px-2 w-full mb-2`}>
315+
<ChatDocumentDisplay
316+
setPresentingDocument={setPresentingDocument}
317+
closeSidebar={closeSidebar}
318+
modal={modal}
319+
document={buildOnyxDocumentFromFile(
320+
f.file_id,
321+
f.name,
322+
true
323+
)}
324+
isSelected={false}
325+
handleSelect={() => {}}
326+
hideSelection={true}
327+
tokenLimitReached={false}
328+
/>
329+
</div>
330+
))}
331+
{projectFiles.length > 20 && (
332+
<div className="text-text-500 px-4 py-2 text-xs">
333+
+{projectFiles.length - 20} more
334+
</div>
335+
)}
336+
</div>
337+
)}
219338
</div>
220339
</div>
221340
</div>

0 commit comments

Comments
 (0)