Skip to content

Commit 6e8a2c1

Browse files
committed
feat: Enhance ChatService with detailed logging for message handling and streaming state
1 parent 7a3189d commit 6e8a2c1

File tree

1 file changed

+104
-15
lines changed

1 file changed

+104
-15
lines changed

packages/realtime/src/chat-service.ts

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,91 @@ export class ChatService {
3939
}
4040

4141
private handleIncomingMessage(message: SignalRMessage): void {
42-
console.log('Raw incoming message:', message);
42+
console.log('🔍 Raw incoming message:', message);
43+
console.log('🔍 Message keys:', Object.keys(message || {}));
44+
console.log('🔍 Message action:', message?.action);
45+
console.log('🔍 Message data keys:', Object.keys(message?.data || {}));
4346

44-
// Check if the message itself is streaming format
47+
// Check if this is a streaming format message
4548
if (this.isStreamingMessage(message)) {
46-
console.log('Detected streaming message');
49+
console.log('Detected as streaming format message');
4750
this.handleStreamingMessage(message);
4851
return;
4952
}
5053

51-
// Handle as regular message only if not currently streaming
54+
// Handle based on action like AngularJS code
55+
if (message?.action) {
56+
console.log('🎯 Processing action-based message:', message.action);
57+
switch (message.action) {
58+
case "NewMessage":
59+
this.handleNewMessage(message);
60+
break;
61+
case "NewStreamingMessage":
62+
this.handleNewStreamingMessage(message);
63+
break;
64+
default:
65+
console.log('⚠️ Unknown action:', message.action);
66+
}
67+
} else {
68+
console.log('📄 Processing as regular message (no action)');
69+
// Fallback for regular SignalR messages
70+
this.handleRegularMessage(message);
71+
}
72+
}
73+
74+
private handleNewMessage(message: SignalRMessage): void {
75+
console.log('📤 Handling NewMessage:', message);
76+
console.log('🔍 Current streaming state:', this.streamingState.isStreaming);
77+
78+
if (this.streamingState.isStreaming) {
79+
console.log('🏁 NewMessage received during streaming - treating as completion signal');
80+
// Use NewMessage as the completion trigger for streaming
81+
this.completeStreaming();
82+
return;
83+
}
84+
85+
if (message?.data?.response) {
86+
console.log('✅ Processing NewMessage as regular message (no streaming was active)');
87+
// Reset streaming data and add final message (like AngularJS)
88+
this.streamingState.isStreaming = false;
89+
this.streamingState.currentMessage = '';
90+
this.notifyStreamingStateChange();
91+
92+
// Emit as regular message
93+
this.emitRegularMessage({
94+
id: Date.now().toString(),
95+
content: message.data.response,
96+
role: "assistant" as const,
97+
timestamp: new Date().toISOString(),
98+
});
99+
}
100+
}
101+
102+
private handleNewStreamingMessage(message: SignalRMessage): void {
103+
console.log('🌊 Handling NewStreamingMessage:', message);
104+
105+
if (message?.data?.response) {
106+
console.log('✅ Found response data:', message.data.response);
107+
// Accumulate streaming content (like AngularJS)
108+
this.appendStreamingChunk(message.data.response);
109+
} else {
110+
console.log('❌ No response data found in streaming message');
111+
}
112+
}
113+
114+
private handleRegularMessage(message: SignalRMessage): void {
115+
console.log('📄 Handling regular message - this bypasses streaming');
116+
console.log('📄 Streaming state:', this.streamingState.isStreaming);
117+
118+
// Only process if not currently streaming
52119
if (!this.streamingState.isStreaming && message?.data?.response) {
53-
console.log('Processing as regular message');
120+
console.log('Processing regular message response:', message.data.response);
54121

55122
let content = '';
56123
if (typeof message.data.response === 'string') {
57124
content = message.data.response;
125+
console.log('📝 String content:', content);
58126
} else if (typeof message.data.response === 'object' && message.data.response !== null) {
59-
// Handle complex SignalR response structures
60127
const responseObj = message.data.response as any;
61128
if (responseObj.content) {
62129
content = responseObj.content;
@@ -65,30 +132,37 @@ export class ChatService {
65132
} else if (responseObj.message) {
66133
content = responseObj.message;
67134
} else {
68-
// Fallback - try to extract meaningful text from the object
69135
content = JSON.stringify(message.data.response, null, 2);
70136
}
137+
console.log('📝 Object content extracted:', content);
71138
} else {
72139
content = String(message.data.response);
140+
console.log('📝 Converted content:', content);
73141
}
74142

75-
// Only add if we have actual content and it's not streaming format
76143
if (content.trim() && !content.includes('"type":1') && !content.includes('"type":3')) {
77-
// Emit as regular message for the UI to handle
144+
console.log('🚀 Emitting regular message with content:', content);
78145
this.emitRegularMessage({
79146
id: Date.now().toString(),
80147
content: content,
81148
role: "assistant" as const,
82149
timestamp: new Date().toISOString(),
83150
});
151+
} else {
152+
console.log('❌ Content filtered out or contains streaming markers');
84153
}
85154
} else {
86-
console.log('Message ignored - either streaming active or no response content');
155+
console.log('❌ Regular message skipped - streaming active or no response');
87156
}
88157
}
89158

90159
private isStreamingMessage(message: any): boolean {
91-
// Check direct streaming format
160+
// Check for action-based pattern (like AngularJS)
161+
if (message?.action === 'NewStreamingMessage') {
162+
return true;
163+
}
164+
165+
// Check direct streaming format (type 1/3 pattern)
92166
if (typeof message === 'object' &&
93167
typeof message.type === 'number' &&
94168
typeof message.target === 'string' &&
@@ -101,7 +175,8 @@ export class ChatService {
101175
// Check if response contains streaming JSON pattern
102176
const response = message.data.response;
103177
return response.includes('"type":1') && response.includes('"target":"receive_message"') ||
104-
response.includes('"type":3');
178+
response.includes('"type":3') ||
179+
response.includes('"action":"NewStreamingMessage"');
105180
}
106181

107182
return false;
@@ -172,17 +247,22 @@ export class ChatService {
172247
}
173248

174249
private appendStreamingChunk(chunk: string): void {
250+
console.log('📝 Appending streaming chunk:', chunk);
251+
175252
if (!this.streamingState.isStreaming) {
253+
console.log('🚀 Starting new stream');
176254
this.streamingState.isStreaming = true;
177255
this.streamingState.currentMessage = '';
178256
this.notifyStreamingStateChange();
179257
}
180258

181259
this.streamingState.currentMessage += chunk;
260+
console.log('📄 Current streaming message:', this.streamingState.currentMessage);
182261

183262
// Notify streaming handlers
184263
this.streamingHandlers.forEach(handler => {
185264
try {
265+
console.log('🔔 Calling streaming handler with chunk:', chunk);
186266
handler(chunk, false);
187267
} catch (error) {
188268
console.error('Error in streaming handler:', error);
@@ -191,24 +271,31 @@ export class ChatService {
191271
}
192272

193273
private completeStreaming(): void {
274+
console.log('🏁 Completing streaming...');
275+
console.log('📄 Final streaming content:', this.streamingState.currentMessage);
276+
194277
if (this.streamingState.isStreaming) {
195-
// Notify completion
278+
// Notify completion to UI handlers first
279+
console.log('📢 Notifying streaming handlers of completion');
196280
this.streamingHandlers.forEach(handler => {
197281
try {
198-
handler('', true);
282+
handler('', true); // Empty chunk with isComplete = true
199283
} catch (error) {
200284
console.error('Error in streaming completion handler:', error);
201285
}
202286
});
203287

204288
// Reset streaming state
289+
console.log('🔄 Resetting streaming state');
205290
this.streamingState.isStreaming = false;
206291
const finalMessage = this.streamingState.currentMessage;
207292
this.streamingState.currentMessage = '';
208293

209294
this.notifyStreamingStateChange();
210295

211-
console.log('Streaming completed. Final message:', finalMessage);
296+
console.log('✅ Streaming completed. Final message length:', finalMessage.length);
297+
} else {
298+
console.log('⚠️ completeStreaming called but streaming was not active');
212299
}
213300
}
214301

@@ -278,7 +365,9 @@ export class ChatService {
278365
}
279366

280367
public onStreaming(handler: StreamingMessageHandler): void {
368+
console.log('📋 Registering streaming handler. Current handlers:', this.streamingHandlers.length);
281369
this.streamingHandlers.push(handler);
370+
console.log('📋 After registration, total handlers:', this.streamingHandlers.length);
282371
}
283372

284373
public offStreaming(handler: StreamingMessageHandler): void {

0 commit comments

Comments
 (0)