diff --git a/server/claude-sdk.js b/server/claude-sdk.js index d1e62090..c3c56bae 100644 --- a/server/claude-sdk.js +++ b/server/claude-sdk.js @@ -24,7 +24,7 @@ import { notifyRunStopped, notifyUserIfEnabled } from './services/notification-orchestrator.js'; -import { providersService } from './modules/providers/services/providers.service.js'; +import { sessionsService } from './modules/providers/services/sessions.service.js'; import { createNormalizedMessage } from './shared/utils.js'; const activeSessions = new Map(); @@ -649,7 +649,7 @@ async function queryClaudeSDK(command, options = {}, ws) { const sid = capturedSessionId || sessionId || null; // Use adapter to normalize SDK events into NormalizedMessage[] - const normalized = providersService.normalizeMessage('claude', transformedMessage, sid); + const normalized = sessionsService.normalizeMessage('claude', transformedMessage, sid); for (const msg of normalized) { // Preserve parentToolUseId from SDK wrapper for subagent tool grouping if (transformedMessage.parentToolUseId && !msg.parentToolUseId) { diff --git a/server/cursor-cli.js b/server/cursor-cli.js index 76f643e6..36f2c2d0 100644 --- a/server/cursor-cli.js +++ b/server/cursor-cli.js @@ -1,7 +1,7 @@ import { spawn } from 'child_process'; import crossSpawn from 'cross-spawn'; import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js'; -import { providersService } from './modules/providers/services/providers.service.js'; +import { sessionsService } from './modules/providers/services/sessions.service.js'; import { createNormalizedMessage } from './shared/utils.js'; // Use cross-spawn on Windows for better command execution @@ -189,7 +189,7 @@ async function spawnCursor(command, options = {}, ws) { case 'assistant': // Accumulate assistant message chunks if (response.message && response.message.content && response.message.content.length > 0) { - const normalized = providersService.normalizeMessage('cursor', response, capturedSessionId || sessionId || null); + const normalized = sessionsService.normalizeMessage('cursor', response, capturedSessionId || sessionId || null); for (const msg of normalized) ws.send(msg); } break; @@ -219,7 +219,7 @@ async function spawnCursor(command, options = {}, ws) { } // If not JSON, send as stream delta via adapter - const normalized = providersService.normalizeMessage('cursor', line, capturedSessionId || sessionId || null); + const normalized = sessionsService.normalizeMessage('cursor', line, capturedSessionId || sessionId || null); for (const msg of normalized) ws.send(msg); } }; diff --git a/server/gemini-response-handler.js b/server/gemini-response-handler.js index b5310142..b0a17485 100644 --- a/server/gemini-response-handler.js +++ b/server/gemini-response-handler.js @@ -1,5 +1,5 @@ // Gemini Response Handler - JSON Stream processing -import { providersService } from './modules/providers/services/providers.service.js'; +import { sessionsService } from './modules/providers/services/sessions.service.js'; class GeminiResponseHandler { constructor(ws, options = {}) { @@ -56,7 +56,7 @@ class GeminiResponseHandler { } // Normalize via adapter and send all resulting messages - const normalized = providersService.normalizeMessage('gemini', event, sid); + const normalized = sessionsService.normalizeMessage('gemini', event, sid); for (const msg of normalized) { this.ws.send(msg); } diff --git a/server/modules/providers/services/providers.service.ts b/server/modules/providers/services/sessions.service.ts similarity index 71% rename from server/modules/providers/services/providers.service.ts rename to server/modules/providers/services/sessions.service.ts index 9ecfc65b..41a649ff 100644 --- a/server/modules/providers/services/providers.service.ts +++ b/server/modules/providers/services/sessions.service.ts @@ -7,17 +7,23 @@ import type { } from '@/shared/types.js'; /** - * Application service for provider message operations. + * Application service for provider-backed session message operations. * * Callers pass a provider id and this service resolves the concrete provider * class, keeping normalization/history call sites decoupled from implementation * file layout. */ -export const providersService = { +export const sessionsService = { + /** + * Lists provider ids that can load session history and normalize live messages. + */ listProviderIds(): LLMProvider[] { return providerRegistry.listProviders().map((provider) => provider.id); }, + /** + * Normalizes one provider-native event into frontend session message events. + */ normalizeMessage( providerName: string, raw: unknown, @@ -26,6 +32,9 @@ export const providersService = { return providerRegistry.resolveProvider(providerName).normalizeMessage(raw, sessionId); }, + /** + * Fetches normalized persisted session history for one provider/session pair. + */ fetchHistory( providerName: string, sessionId: string, diff --git a/server/openai-codex.js b/server/openai-codex.js index 6ea6d5ae..8c78ac36 100644 --- a/server/openai-codex.js +++ b/server/openai-codex.js @@ -15,7 +15,7 @@ import { Codex } from '@openai/codex-sdk'; import { notifyRunFailed, notifyRunStopped } from './services/notification-orchestrator.js'; -import { providersService } from './modules/providers/services/providers.service.js'; +import { sessionsService } from './modules/providers/services/sessions.service.js'; import { createNormalizedMessage } from './shared/utils.js'; // Track active sessions @@ -264,7 +264,7 @@ export async function queryCodex(command, options = {}, ws) { const transformed = transformCodexEvent(event); // Normalize the transformed event into NormalizedMessage(s) via adapter - const normalizedMsgs = providersService.normalizeMessage('codex', transformed, currentSessionId); + const normalizedMsgs = sessionsService.normalizeMessage('codex', transformed, currentSessionId); for (const msg of normalizedMsgs) { sendMessage(ws, msg); } diff --git a/server/routes/messages.js b/server/routes/messages.js index b981d8ab..81444d56 100644 --- a/server/routes/messages.js +++ b/server/routes/messages.js @@ -10,7 +10,7 @@ */ import express from 'express'; -import { providersService } from '../modules/providers/services/providers.service.js'; +import { sessionsService } from '../modules/providers/services/sessions.service.js'; const router = express.Router(); @@ -38,13 +38,13 @@ router.get('/:sessionId/messages', async (req, res) => { : null; const offset = parseInt(req.query.offset || '0', 10); - const availableProviders = providersService.listProviderIds(); + const availableProviders = sessionsService.listProviderIds(); if (!availableProviders.includes(provider)) { const available = availableProviders.join(', '); return res.status(400).json({ error: `Unknown provider: ${provider}. Available: ${available}` }); } - const result = await providersService.fetchHistory(provider, sessionId, { + const result = await sessionsService.fetchHistory(provider, sessionId, { projectName, projectPath, limit,