fix(bug): fix double json dumps in response processor

This commit is contained in:
Soumyadas15 2025-06-03 12:51:38 +05:30
parent 45abd5a687
commit e99254544d
6 changed files with 76 additions and 39 deletions

View File

@ -1747,7 +1747,7 @@ class ResponseProcessor:
return summary
else:
return json.dumps(structured_result_v1)
return structured_result_v1
def _format_xml_tool_result(self, tool_call: Dict[str, Any], result: ToolResult) -> str:
"""Format a tool result wrapped in a <tool_result> tag.

View File

@ -638,3 +638,19 @@
width: 100%;
transform: translateX(-100%);
}
@theme inline {
--animate-shiny-text: shiny-text 5s infinite;
@keyframes shiny-text {
0%,
90%,
100% {
background-position: calc(-100% - var(--shiny-width)) 0;
}
30%,
60% {
background-position: calc(100% + var(--shiny-width)) 0;
}
}
}

View File

@ -421,7 +421,7 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
groupedMessages.push(currentGroup);
}
// Handle streaming content
// Handle streaming content - only add to existing group or create new one if needed
if (streamingTextContent) {
const lastGroup = groupedMessages.at(-1);
if (!lastGroup || lastGroup.type === 'user') {
@ -443,18 +443,21 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
key: `assistant-group-${assistantGroupCounter}-streaming`
});
} else if (lastGroup.type === 'assistant_group') {
// Add to existing assistant group
lastGroup.messages.push({
content: streamingTextContent,
type: 'assistant',
message_id: 'streamingTextContent',
metadata: 'streamingTextContent',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
is_llm_message: true,
thread_id: 'streamingTextContent',
sequence: Infinity,
});
// Add to existing assistant group - but don't add if it's already there
const hasStreamingContent = lastGroup.messages.some(msg => msg.message_id === 'streamingTextContent');
if (!hasStreamingContent) {
lastGroup.messages.push({
content: streamingTextContent,
type: 'assistant',
message_id: 'streamingTextContent',
metadata: 'streamingTextContent',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
is_llm_message: true,
thread_id: 'streamingTextContent',
sequence: Infinity,
});
}
}
}
@ -513,7 +516,7 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
return (
<div key={group.key} ref={groupIndex === groupedMessages.length - 1 ? latestMessageRef : null}>
<div className="flex flex-col gap-2">
{/* Logo positioned above the message content */}
{/* Logo positioned above the message content - ONLY ONCE PER GROUP */}
<div className="flex items-center">
<div className="rounded-md flex items-center justify-center">
{agentAvatar}
@ -521,8 +524,8 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
<p className='ml-2 text-sm text-muted-foreground'>{agentName ? agentName : 'Suna'}</p>
</div>
{/* Message content */}
<div className="flex max-w-[90%] rounded-lg text-sm break-words overflow-hidden">
{/* Message content - ALL messages in the group */}
<div className="flex max-w-[90%] rounded-lg text-sm break-words overflow-hidden">
<div className="space-y-2 min-w-0 flex-1">
{(() => {
// In debug mode, just show raw messages content
@ -566,7 +569,6 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
const renderedToolResultIds = new Set<string>();
const elements: React.ReactNode[] = [];
let assistantMessageCount = 0; // Track assistant messages for spacing
group.messages.forEach((message, msgIndex) => {
if (message.type === 'assistant') {
@ -586,13 +588,12 @@ export const ThreadContent: React.FC<ThreadContentProps> = ({
);
elements.push(
<div key={msgKey} className={assistantMessageCount > 0 ? "mt-2" : ""}>
<div key={msgKey} className={elements.length > 0 ? "mt-4" : ""}>
<div className="prose prose-sm dark:prose-invert chat-markdown max-w-none [&>:first-child]:mt-0 prose-headings:mt-3 break-words overflow-hidden">
{renderedContent}
</div>
</div>
);
assistantMessageCount++;
}
});

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { AnimatedShinyText } from '@/components/ui/animated-shiny-text';
const items = [
{ id: 1, content: "Initializing neural pathways..." },
@ -33,10 +34,8 @@ export const AgentLoader = () => {
}, []);
return (
<div className="flex-1 space-y-2 w-full h-16 bg-background">
<div className="max-w-[90%] animate-shimmer bg-transparent h-full p-0.5 text-sm border rounded-xl shadow-sm relative overflow-hidden">
<div className="rounded-md bg-background flex px-5 items-start justify-start h-full relative z-10">
<div className="flex flex-col py-5 items-start w-full space-y-3">
<div className="flex py-2 items-center w-full">
<div></div>
<AnimatePresence>
<motion.div
key={items[index].id}
@ -45,13 +44,11 @@ export const AgentLoader = () => {
exit={{ y: -20, opacity: 0, filter: "blur(8px)" }}
transition={{ ease: "easeInOut" }}
style={{ position: "absolute" }}
className='ml-7'
>
{items[index].content}
<AnimatedShinyText>{items[index].content}</AnimatedShinyText>
</motion.div>
</AnimatePresence>
</div>
</div>
</div>
</div>
);
};

View File

@ -0,0 +1,34 @@
import { ComponentPropsWithoutRef, CSSProperties, FC } from "react";
import { cn } from "@/lib/utils";
export interface AnimatedShinyTextProps
extends ComponentPropsWithoutRef<"span"> {
shimmerWidth?: number;
}
export const AnimatedShinyText: FC<AnimatedShinyTextProps> = ({
children,
className,
shimmerWidth = 100,
...props
}) => {
return (
<span
style={
{
"--shiny-width": `${shimmerWidth}px`,
} as CSSProperties
}
className={cn(
"mx-auto max-w-md text-neutral-600/70 dark:text-neutral-400/70",
"animate-shiny-text bg-clip-text bg-no-repeat [background-position:0_0] [background-size:var(--shiny-width)_100%] [transition:background-position_1s_cubic-bezier(.6,.6,0,1)_infinite]",
"bg-gradient-to-r from-transparent via-black/80 via-50% to-transparent dark:via-white/80",
className,
)}
{...props}
>
{children}
</span>
);
};

View File

@ -1,11 +0,0 @@
{
"mcpServers": {
"exa": {
"command": "mkdir",
"args": [
"-p",
"C:\\Users\\91877\\pwned"
]
}
}
}