Compare commits

..

5 Commits

Author SHA1 Message Date
ItzCrazyKns
f18e132d1b feat(news-widget): fix loading animation 2025-10-02 17:55:56 +05:30
ItzCrazyKns
37317992b4 feat(app): lint & beautify 2025-10-02 17:17:52 +05:30
ItzCrazyKns
8b588824f2 feat(css): add line-clamp-2 class 2025-10-02 17:17:44 +05:30
ItzCrazyKns
a19cf00873 feat(lineOutputParser): return undefined on invalid tags 2025-10-02 17:17:31 +05:30
ItzCrazyKns
5cc11ac0bf feat(message-handling): fix repeated first token, think tag handling
closes #889
2025-10-02 17:15:54 +05:30
6 changed files with 40 additions and 32 deletions

View File

@@ -20,6 +20,15 @@
} }
} }
@layer utilities {
.line-clamp-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
@media screen and (-webkit-min-device-pixel-ratio: 0) { @media screen and (-webkit-min-device-pixel-ratio: 0) {
select, select,
textarea, textarea,

View File

@@ -69,9 +69,7 @@ const MessageBox = ({
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<div <div className={'w-full pt-8 break-words'}>
className={'w-full pt-8 break-words'}
>
<h2 className="text-black dark:text-white font-medium text-3xl lg:w-9/12"> <h2 className="text-black dark:text-white font-medium text-3xl lg:w-9/12">
{section.userMessage.content} {section.userMessage.content}
</h2> </h2>

View File

@@ -29,15 +29,13 @@ const NewsArticleWidget = () => {
return ( return (
<div className="bg-light-secondary dark:bg-dark-secondary rounded-2xl border border-light-200 dark:border-dark-200 shadow-sm shadow-light-200/10 dark:shadow-black/25 flex flex-row items-stretch w-full h-24 min-h-[96px] max-h-[96px] p-0 overflow-hidden"> <div className="bg-light-secondary dark:bg-dark-secondary rounded-2xl border border-light-200 dark:border-dark-200 shadow-sm shadow-light-200/10 dark:shadow-black/25 flex flex-row items-stretch w-full h-24 min-h-[96px] max-h-[96px] p-0 overflow-hidden">
{loading ? ( {loading ? (
<> <div className="animate-pulse flex flex-row items-stretch w-full h-full">
<div className="animate-pulse flex flex-row items-center w-full h-full"> <div className="w-24 min-w-24 max-w-24 h-full bg-light-200 dark:bg-dark-200" />
<div className="rounded-lg w-16 min-w-16 max-w-16 h-16 min-h-16 max-h-16 bg-light-200 dark:bg-dark-200 mr-3" /> <div className="flex flex-col justify-center flex-1 px-3 py-2 gap-2">
<div className="flex flex-col justify-center flex-1 h-full w-0 gap-2"> <div className="h-4 w-3/4 rounded bg-light-200 dark:bg-dark-200" />
<div className="h-4 w-3/4 rounded bg-light-200 dark:bg-dark-200" /> <div className="h-3 w-1/2 rounded bg-light-200 dark:bg-dark-200" />
<div className="h-3 w-1/2 rounded bg-light-200 dark:bg-dark-200" />
</div>
</div> </div>
</> </div>
) : error ? ( ) : error ? (
<div className="w-full text-xs text-red-400">Could not load news.</div> <div className="w-full text-xs text-red-400">Could not load news.</div>
) : article ? ( ) : article ? (

View File

@@ -399,6 +399,7 @@ export const ChatProvider = ({
(m, j) => (m, j) =>
j > i && j > i &&
m.role === 'source' && m.role === 'source' &&
m.sources &&
(nextUserMessageIndex === -1 || j < nextUserMessageIndex), (nextUserMessageIndex === -1 || j < nextUserMessageIndex),
) as SourceMessage | undefined; ) as SourceMessage | undefined;
@@ -417,7 +418,7 @@ export const ChatProvider = ({
const closeThinkTag = const closeThinkTag =
processedMessage.match(/<\/think>/g)?.length || 0; processedMessage.match(/<\/think>/g)?.length || 0;
if (openThinkTag > closeThinkTag) { if (openThinkTag && !closeThinkTag) {
processedMessage += '</think> <a> </a>'; processedMessage += '</think> <a> </a>';
} }
} }
@@ -426,7 +427,11 @@ export const ChatProvider = ({
thinkingEnded = true; thinkingEnded = true;
} }
if (sourceMessage && sourceMessage.sources.length > 0) { if (
sourceMessage &&
sourceMessage.sources &&
sourceMessage.sources.length > 0
) {
processedMessage = processedMessage.replace( processedMessage = processedMessage.replace(
citationRegex, citationRegex,
(_, capturedContent: string) => { (_, capturedContent: string) => {
@@ -635,23 +640,22 @@ export const ChatProvider = ({
}, },
]); ]);
added = true; added = true;
setMessageAppeared(true);
} else {
setMessages((prev) =>
prev.map((message) => {
if (
message.messageId === data.messageId &&
message.role === 'assistant'
) {
return { ...message, content: message.content + data.data };
}
return message;
}),
);
} }
setMessages((prev) =>
prev.map((message) => {
if (
message.messageId === data.messageId &&
message.role === 'assistant'
) {
return { ...message, content: message.content + data.data };
}
return message;
}),
);
recievedMessage += data.data; recievedMessage += data.data;
setMessageAppeared(true);
} }
if (data.type === 'messageEnd') { if (data.type === 'messageEnd') {

View File

@@ -4,7 +4,7 @@ interface LineOutputParserArgs {
key?: string; key?: string;
} }
class LineOutputParser extends BaseOutputParser<string> { class LineOutputParser extends BaseOutputParser<string | undefined> {
private key = 'questions'; private key = 'questions';
constructor(args?: LineOutputParserArgs) { constructor(args?: LineOutputParserArgs) {
@@ -18,7 +18,7 @@ class LineOutputParser extends BaseOutputParser<string> {
lc_namespace = ['langchain', 'output_parsers', 'line_output_parser']; lc_namespace = ['langchain', 'output_parsers', 'line_output_parser'];
async parse(text: string): Promise<string> { async parse(text: string): Promise<string | undefined> {
text = text.trim() || ''; text = text.trim() || '';
const regex = /^(\s*(-|\*|\d+\.\s|\d+\)\s|\u2022)\s*)+/; const regex = /^(\s*(-|\*|\d+\.\s|\d+\)\s|\u2022)\s*)+/;
@@ -26,7 +26,7 @@ class LineOutputParser extends BaseOutputParser<string> {
const endKeyIndex = text.indexOf(`</${this.key}>`); const endKeyIndex = text.indexOf(`</${this.key}>`);
if (startKeyIndex === -1 || endKeyIndex === -1) { if (startKeyIndex === -1 || endKeyIndex === -1) {
return ''; return undefined;
} }
const questionsStartIndex = const questionsStartIndex =

View File

@@ -453,7 +453,6 @@ class MetaSearchAgent implements MetaSearchAgentType {
event.event === 'on_chain_end' && event.event === 'on_chain_end' &&
event.name === 'FinalSourceRetriever' event.name === 'FinalSourceRetriever'
) { ) {
``;
emitter.emit( emitter.emit(
'data', 'data',
JSON.stringify({ type: 'sources', data: event.data.output }), JSON.stringify({ type: 'sources', data: event.data.output }),