mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-04-18 19:41:31 +00:00
Move provider-specific normalizeMessage and fetchHistory logic out of the legacy server/providers adapters and into the refactored provider classes so callers can depend on the main provider contract instead of parallel adapter plumbing. Add a providers service to resolve concrete providers through the registry and delegate message normalization/history loading from realtime handlers and the unified messages route. Add shared TypeScript message/history types and normalized message helpers so provider implementations and callers use the same contract. Remove the old adapter registry/files now that Claude, Codex, Cursor, and Gemini implement the required behavior directly.
80 lines
2.1 KiB
JavaScript
80 lines
2.1 KiB
JavaScript
// Gemini Response Handler - JSON Stream processing
|
|
import { providersService } from './modules/providers/services/providers.service.js';
|
|
|
|
class GeminiResponseHandler {
|
|
constructor(ws, options = {}) {
|
|
this.ws = ws;
|
|
this.buffer = '';
|
|
this.onContentFragment = options.onContentFragment || null;
|
|
this.onInit = options.onInit || null;
|
|
this.onToolUse = options.onToolUse || null;
|
|
this.onToolResult = options.onToolResult || null;
|
|
}
|
|
|
|
// Process incoming raw data from Gemini stream-json
|
|
processData(data) {
|
|
this.buffer += data;
|
|
|
|
// Split by newline
|
|
const lines = this.buffer.split('\n');
|
|
|
|
// Keep the last incomplete line in the buffer
|
|
this.buffer = lines.pop() || '';
|
|
|
|
for (const line of lines) {
|
|
if (!line.trim()) continue;
|
|
|
|
try {
|
|
const event = JSON.parse(line);
|
|
this.handleEvent(event);
|
|
} catch (err) {
|
|
// Not a JSON line, probably debug output or CLI warnings
|
|
}
|
|
}
|
|
}
|
|
|
|
handleEvent(event) {
|
|
const sid = typeof this.ws.getSessionId === 'function' ? this.ws.getSessionId() : null;
|
|
|
|
if (event.type === 'init') {
|
|
if (this.onInit) {
|
|
this.onInit(event);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Invoke per-type callbacks for session tracking
|
|
if (event.type === 'message' && event.role === 'assistant') {
|
|
const content = event.content || '';
|
|
if (this.onContentFragment && content) {
|
|
this.onContentFragment(content);
|
|
}
|
|
} else if (event.type === 'tool_use' && this.onToolUse) {
|
|
this.onToolUse(event);
|
|
} else if (event.type === 'tool_result' && this.onToolResult) {
|
|
this.onToolResult(event);
|
|
}
|
|
|
|
// Normalize via adapter and send all resulting messages
|
|
const normalized = providersService.normalizeMessage('gemini', event, sid);
|
|
for (const msg of normalized) {
|
|
this.ws.send(msg);
|
|
}
|
|
}
|
|
|
|
forceFlush() {
|
|
if (this.buffer.trim()) {
|
|
try {
|
|
const event = JSON.parse(this.buffer);
|
|
this.handleEvent(event);
|
|
} catch (err) { }
|
|
}
|
|
}
|
|
|
|
destroy() {
|
|
this.buffer = '';
|
|
}
|
|
}
|
|
|
|
export default GeminiResponseHandler;
|