Skip to content

Commit 762f164

Browse files
committed
✨ Multi modal agent.
Add tooltips
1 parent 3674759 commit 762f164

File tree

4 files changed

+15
-223
lines changed

4 files changed

+15
-223
lines changed

backend/agents/create_agent_info.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,11 @@ async def join_minio_file_description_to_query(minio_files, query):
315315
file_descriptions = []
316316
for file in minio_files:
317317
if isinstance(file, dict) and "url" in file and file["url"] and "name" in file and file["name"]:
318-
file_descriptions.append("File S3 URL: " + "s3:/" + file["url"] + ", file name:" + file["name"])
319-
318+
file_descriptions.append(f"File name: {file['name']}, S3 URL: s3:/{file['url']}")
320319
if file_descriptions:
321-
final_query = "User provided some reference files:\n"
320+
final_query = "User uploaded files. The file information is as follows:\n"
322321
final_query += "\n".join(file_descriptions) + "\n\n"
323-
final_query += f"User wants to answer questions based on the above information: {query}"
322+
final_query += f"User wants to answer questions based on the information in the above files: {query}"
324323
return final_query
325324

326325

frontend/app/[locale]/chat/internal/chatInterface.tsx

Lines changed: 4 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -451,218 +451,23 @@ export function ChatInterface() {
451451
],
452452
}));
453453

454-
// If there are attachment files, preprocess first
454+
// If there are attachment files, skip preprocessing (no API call, no UI prompts)
455455
let finalQuery = userMessage.content;
456456
// Declare a variable to save file description information
457457
let fileDescriptionsMap: Record<string, string> = {};
458458

459459
if (attachments.length > 0) {
460-
// Attachment preprocessing step, as independent step in assistant steps
461-
setSessionMessages((prev) => ({
462-
...prev,
463-
[currentConversationId]: [
464-
...(prev[currentConversationId] || []),
465-
{
466-
id: uuidv4(),
467-
role: ROLE_ASSISTANT,
468-
content: "",
469-
timestamp: new Date(),
470-
isComplete: false,
471-
steps: [
472-
{
473-
id: `preprocess-${Date.now()}`,
474-
title: t("chatInterface.filePreprocessing"),
475-
content: "",
476-
expanded: true,
477-
metrics: "",
478-
thinking: { content: "", expanded: false },
479-
code: { content: "", expanded: false },
480-
output: { content: "", expanded: false },
481-
contents: [
482-
{
483-
id: `preprocess-content-${Date.now()}`,
484-
type: chatConfig.contentTypes.PREPROCESS,
485-
content: t("chatInterface.parsingFile"),
486-
expanded: false,
487-
timestamp: Date.now(),
488-
},
489-
],
490-
},
491-
],
492-
},
493-
],
494-
}));
495-
496-
// Buffer for truncation messages with deduplication
497-
const truncationBuffer: any[] = [];
498-
const processedTruncationIds = new Set<string>(); // Track processed truncation messages to avoid duplicates
499-
500-
// Use extracted preprocessing function to process attachments
460+
// Skip preprocessing - directly use original content
461+
// No preprocessing UI will be shown
501462
const result = await preprocessAttachments(
502463
userMessage.content,
503464
attachments,
504465
currentController.signal,
505-
(jsonData) => {
506-
setSessionMessages((prev) => {
507-
const newMessages = { ...prev };
508-
const lastMsg =
509-
newMessages[currentConversationId]?.[
510-
newMessages[currentConversationId].length - 1
511-
];
512-
if (lastMsg && lastMsg.role === ROLE_ASSISTANT) {
513-
if (!lastMsg.steps) lastMsg.steps = [];
514-
// Find the latest preprocessing step
515-
let step = lastMsg.steps.find(
516-
(s) => s.title === t("chatInterface.filePreprocessing")
517-
);
518-
if (!step) {
519-
step = {
520-
id: `preprocess-${Date.now()}`,
521-
title: t("chatInterface.filePreprocessing"),
522-
content: "",
523-
expanded: true,
524-
metrics: "",
525-
thinking: { content: "", expanded: false },
526-
code: { content: "", expanded: false },
527-
output: { content: "", expanded: false },
528-
contents: [
529-
{
530-
id: `preprocess-content-${Date.now()}`,
531-
type: chatConfig.contentTypes.PREPROCESS,
532-
content: t("chatInterface.parsingFile"),
533-
expanded: false,
534-
timestamp: Date.now(),
535-
},
536-
],
537-
};
538-
lastMsg.steps.push(step);
539-
}
540-
541-
// Handle truncation messages - buffer them instead of updating immediately
542-
if (jsonData.type === "truncation") {
543-
// Create a unique ID for this truncation message to avoid duplicates
544-
const truncationId = `${jsonData.filename || "unknown"}_${
545-
jsonData.message || ""
546-
}`;
547-
548-
// Only add if not already processed
549-
if (!processedTruncationIds.has(truncationId)) {
550-
truncationBuffer.push(jsonData);
551-
processedTruncationIds.add(truncationId);
552-
}
553-
return newMessages; // Don't update stepContent for truncation
554-
}
555-
556-
let stepContent = "";
557-
switch (jsonData.type) {
558-
case "progress":
559-
if (jsonData.message_data) {
560-
const i18nKey = getI18nKeyByType(jsonData.type);
561-
stepContent = String(
562-
t(i18nKey, jsonData.message_data.params)
563-
);
564-
} else {
565-
stepContent = jsonData.message || "";
566-
}
567-
break;
568-
case "error":
569-
stepContent = t("chatInterface.parseFileFailed", {
570-
filename: jsonData.filename,
571-
message: jsonData.message,
572-
});
573-
break;
574-
case "file_processed":
575-
stepContent = t("chatInterface.fileParsed", {
576-
filename: jsonData.filename,
577-
});
578-
break;
579-
case "complete":
580-
// When complete, process all buffered truncation messages
581-
if (truncationBuffer.length > 0) {
582-
// Process truncation messages using internationalization
583-
const truncationInfo = truncationBuffer
584-
.map((truncation) => {
585-
if (truncation.message_data) {
586-
const i18nKey = getI18nKeyByType(truncation.type);
587-
return String(
588-
t(i18nKey, truncation.message_data.params)
589-
);
590-
} else {
591-
return truncation.message;
592-
}
593-
})
594-
.join(String(t("chatInterface.truncationSeparator")));
595-
596-
stepContent = t(
597-
"chatInterface.fileParsingCompleteWithTruncation",
598-
{
599-
truncationInfo: truncationInfo,
600-
}
601-
);
602-
} else {
603-
stepContent = t("chatInterface.fileParsingComplete");
604-
}
605-
break;
606-
default:
607-
stepContent = jsonData.message || "";
608-
}
609-
// Only update the first content, don't add new ones
610-
if (step && step.contents && step.contents.length > 0) {
611-
step.contents[0].content = stepContent;
612-
step.contents[0].timestamp = Date.now();
613-
}
614-
}
615-
return newMessages;
616-
});
617-
},
466+
() => {}, // Empty progress callback - won't be called
618467
t,
619468
currentConversationId
620469
);
621470

622-
// Handle preprocessing result
623-
if (!result.success) {
624-
// Reset button states immediately when preprocessing fails
625-
setIsLoading(false);
626-
setIsStreaming(false);
627-
628-
// Remove from streaming conversations (both new and existing conversations)
629-
if (currentConversationId) {
630-
setStreamingConversations((prev) => {
631-
const newSet = new Set(prev);
632-
newSet.delete(currentConversationId);
633-
return newSet;
634-
});
635-
}
636-
637-
setSessionMessages((prev) => {
638-
const newMessages = { ...prev };
639-
const lastMsg =
640-
newMessages[currentConversationId]?.[
641-
newMessages[currentConversationId].length - 1
642-
];
643-
644-
if (lastMsg && lastMsg.role === ROLE_ASSISTANT) {
645-
// Handle error codes with internationalization
646-
let errorMessage;
647-
if (result.error === 'REQUEST_ENTITY_TOO_LARGE') {
648-
errorMessage = t("chatInterface.fileSizeExceeded");
649-
} else if (result.error === 'FILE_PARSING_FAILED') {
650-
errorMessage = t("chatInterface.fileParsingFailed");
651-
} else {
652-
// For any other error, show a simple message
653-
errorMessage = t("chatInterface.fileProcessingStopped");
654-
}
655-
656-
lastMsg.content = errorMessage;
657-
lastMsg.isComplete = true;
658-
}
659-
660-
return newMessages;
661-
});
662-
shouldResetButtonStates = false; // Don't reset again in finally block
663-
return;
664-
}
665-
666471
finalQuery = result.finalQuery;
667472
fileDescriptionsMap = result.fileDescriptions || {};
668473
}
@@ -1433,25 +1238,6 @@ export function ChatInterface() {
14331238
if (lastMsg && lastMsg.role === ROLE_ASSISTANT) {
14341239
lastMsg.isComplete = true;
14351240
lastMsg.thinking = undefined; // Explicitly clear thinking state
1436-
1437-
// If this was a preprocess step, mark it as stopped
1438-
if (lastMsg.steps && lastMsg.steps.length > 0) {
1439-
const preprocessStep = lastMsg.steps.find(
1440-
(step) => step.title === t("chatInterface.filePreprocessing")
1441-
);
1442-
if (preprocessStep) {
1443-
const stoppedMessage =
1444-
(t("chatInterface.fileProcessingStopped") as string) ||
1445-
"File preprocessing stopped";
1446-
preprocessStep.content = stoppedMessage;
1447-
if (
1448-
preprocessStep.contents &&
1449-
preprocessStep.contents.length > 0
1450-
) {
1451-
preprocessStep.contents[0].content = stoppedMessage;
1452-
}
1453-
}
1454-
}
14551241
}
14561242
return newMessages;
14571243
});

frontend/app/[locale]/chat/internal/chatPreprocess.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ export const preprocessAttachments = async (
8282
return { finalQuery: content, success: true };
8383
}
8484

85+
// Skip preprocessing API call - return original content directly
86+
// If you want to re-enable preprocessing, uncomment the code below
87+
return { finalQuery: content, success: true };
88+
89+
/*
90+
// Original preprocessing code (disabled)
8591
try {
8692
// Call file preprocessing interface
8793
const preProcessReader = await conversationService.preprocessFiles(
@@ -152,6 +158,7 @@ export const preprocessAttachments = async (
152158
error: error instanceof Error ? (error as Error).message : String(error),
153159
};
154160
}
161+
*/
155162
};
156163

157164
/**

test/backend/agents/test_create_agent_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,7 @@ async def test_join_minio_file_description_to_query_with_files(self):
12541254

12551255
result = await join_minio_file_description_to_query(minio_files, query)
12561256

1257-
expected = "User provided some reference files:\nFile S3 URL: s3://nexent/1.pdf, file name:1.pdf\nFile S3 URL: s3://nexent/2.pdf, file name:2.pdf\n\nUser wants to answer questions based on the above information: test query"
1257+
expected = "User uploaded files. The file information is as follows:\nFile name: 1.pdf, S3 URL: s3://nexent/1.pdf\nFile name: 2.pdf, S3 URL: s3://nexent/2.pdf\n\nUser wants to answer questions based on the information in the above files: test query"
12581258
assert result == expected
12591259

12601260
@pytest.mark.asyncio

0 commit comments

Comments
 (0)