mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-28 21:00:58 +03:00
Feature/sse (#3125)
* Base changes for ServerSide Events (instead of socket.io) * lint fixes * adding of interface and separate methods for streaming events * lint * first draft, handles both internal and external prediction end points. * lint fixes * additional internal end point for streaming and associated changes * return streamresponse as true to build agent flow * 1) JSON formatting for internal events 2) other fixes * 1) convert internal event to metadata to maintain consistency with external response * fix action and metadata streaming * fix for error when agent flow is aborted * prevent subflows from streaming and other code cleanup * prevent streaming from enclosed tools * add fix for preventing chaintool streaming * update lock file * add open when hidden to sse * Streaming errors * Streaming errors * add fix for showing error message --------- Co-authored-by: Henry <hzj94@hotmail.com>
This commit is contained in:
@@ -400,3 +400,22 @@ export interface IStateWithMessages extends ICommonObject {
|
||||
messages: BaseMessage[]
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export interface IServerSideEventStreamer {
|
||||
streamEvent(chatId: string, data: string): void
|
||||
streamStartEvent(chatId: string, data: any): void
|
||||
|
||||
streamTokenEvent(chatId: string, data: string): void
|
||||
streamCustomEvent(chatId: string, eventType: string, data: any): void
|
||||
|
||||
streamSourceDocumentsEvent(chatId: string, data: any): void
|
||||
streamUsedToolsEvent(chatId: string, data: any): void
|
||||
streamFileAnnotationsEvent(chatId: string, data: any): void
|
||||
streamToolEvent(chatId: string, data: any): void
|
||||
streamAgentReasoningEvent(chatId: string, data: any): void
|
||||
streamNextAgentEvent(chatId: string, data: any): void
|
||||
streamActionEvent(chatId: string, data: any): void
|
||||
|
||||
streamAbortEvent(chatId: string): void
|
||||
streamEndEvent(chatId: string): void
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Logger } from 'winston'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { Server } from 'socket.io'
|
||||
import { Client } from 'langsmith'
|
||||
import CallbackHandler from 'langfuse-langchain'
|
||||
import lunary from 'lunary'
|
||||
@@ -15,7 +14,7 @@ import { AgentAction } from '@langchain/core/agents'
|
||||
import { LunaryHandler } from '@langchain/community/callbacks/handlers/lunary'
|
||||
|
||||
import { getCredentialData, getCredentialParam, getEnvironmentVariable } from './utils'
|
||||
import { ICommonObject, INodeData } from './Interface'
|
||||
import { ICommonObject, INodeData, IServerSideEventStreamer } from './Interface'
|
||||
import { LangWatch, LangWatchSpan, LangWatchTrace, autoconvertTypedValues } from 'langwatch'
|
||||
|
||||
interface AgentRun extends Run {
|
||||
@@ -163,16 +162,16 @@ export class ConsoleCallbackHandler extends BaseTracer {
|
||||
export class CustomChainHandler extends BaseCallbackHandler {
|
||||
name = 'custom_chain_handler'
|
||||
isLLMStarted = false
|
||||
socketIO: Server
|
||||
socketIOClientId = ''
|
||||
skipK = 0 // Skip streaming for first K numbers of handleLLMStart
|
||||
returnSourceDocuments = false
|
||||
cachedResponse = true
|
||||
chatId: string = ''
|
||||
sseStreamer: IServerSideEventStreamer | undefined
|
||||
|
||||
constructor(socketIO: Server, socketIOClientId: string, skipK?: number, returnSourceDocuments?: boolean) {
|
||||
constructor(sseStreamer: IServerSideEventStreamer | undefined, chatId: string, skipK?: number, returnSourceDocuments?: boolean) {
|
||||
super()
|
||||
this.socketIO = socketIO
|
||||
this.socketIOClientId = socketIOClientId
|
||||
this.sseStreamer = sseStreamer
|
||||
this.chatId = chatId
|
||||
this.skipK = skipK ?? this.skipK
|
||||
this.returnSourceDocuments = returnSourceDocuments ?? this.returnSourceDocuments
|
||||
}
|
||||
@@ -186,14 +185,20 @@ export class CustomChainHandler extends BaseCallbackHandler {
|
||||
if (this.skipK === 0) {
|
||||
if (!this.isLLMStarted) {
|
||||
this.isLLMStarted = true
|
||||
this.socketIO.to(this.socketIOClientId).emit('start', token)
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamStartEvent(this.chatId, token)
|
||||
}
|
||||
}
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamTokenEvent(this.chatId, token)
|
||||
}
|
||||
this.socketIO.to(this.socketIOClientId).emit('token', token)
|
||||
}
|
||||
}
|
||||
|
||||
handleLLMEnd() {
|
||||
this.socketIO.to(this.socketIOClientId).emit('end')
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamEndEvent(this.chatId)
|
||||
}
|
||||
}
|
||||
|
||||
handleChainEnd(outputs: ChainValues, _: string, parentRunId?: string): void | Promise<void> {
|
||||
@@ -208,17 +213,23 @@ export class CustomChainHandler extends BaseCallbackHandler {
|
||||
const result = cachedValue.split(/(\s+)/)
|
||||
result.forEach((token: string, index: number) => {
|
||||
if (index === 0) {
|
||||
this.socketIO.to(this.socketIOClientId).emit('start', token)
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamStartEvent(this.chatId, token)
|
||||
}
|
||||
}
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamTokenEvent(this.chatId, token)
|
||||
}
|
||||
this.socketIO.to(this.socketIOClientId).emit('token', token)
|
||||
})
|
||||
if (this.returnSourceDocuments) {
|
||||
this.socketIO.to(this.socketIOClientId).emit('sourceDocuments', outputs?.sourceDocuments)
|
||||
if (this.returnSourceDocuments && this.sseStreamer) {
|
||||
this.sseStreamer.streamSourceDocumentsEvent(this.chatId, outputs?.sourceDocuments)
|
||||
}
|
||||
if (this.sseStreamer) {
|
||||
this.sseStreamer.streamEndEvent(this.chatId)
|
||||
}
|
||||
this.socketIO.to(this.socketIOClientId).emit('end')
|
||||
} else {
|
||||
if (this.returnSourceDocuments) {
|
||||
this.socketIO.to(this.socketIOClientId).emit('sourceDocuments', outputs?.sourceDocuments)
|
||||
if (this.returnSourceDocuments && this.sseStreamer) {
|
||||
this.sseStreamer.streamSourceDocumentsEvent(this.chatId, outputs?.sourceDocuments)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user