mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-17 17:35:01 +00:00
refactor: remove session model and thinking mode management from providers and related services
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { AppError } from '@/shared/utils/app-error.js';
|
||||
import type {
|
||||
IProvider,
|
||||
MutableProviderSession,
|
||||
@@ -11,11 +10,6 @@ import type {
|
||||
} from '@/modules/llm/providers/provider.interface.js';
|
||||
import type { LLMProvider } from '@/shared/types/app.js';
|
||||
|
||||
type SessionPreference = {
|
||||
model?: string;
|
||||
thinkingMode?: string;
|
||||
};
|
||||
|
||||
const MAX_EVENT_BUFFER_SIZE = 2_000;
|
||||
|
||||
/**
|
||||
@@ -27,7 +21,6 @@ export abstract class AbstractProvider implements IProvider {
|
||||
readonly capabilities: ProviderCapabilities;
|
||||
|
||||
protected readonly sessions = new Map<string, MutableProviderSession>();
|
||||
protected readonly sessionPreferences = new Map<string, SessionPreference>();
|
||||
|
||||
protected constructor(
|
||||
id: LLMProvider,
|
||||
@@ -90,98 +83,6 @@ export abstract class AbstractProvider implements IProvider {
|
||||
return stopped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates/supports model switching and updates both live and persisted state.
|
||||
*/
|
||||
async setSessionModel(sessionId: string, model: string): Promise<void> {
|
||||
if (!this.capabilities.supportsModelSwitching) {
|
||||
throw new AppError(`Provider "${this.id}" does not support model switching.`, {
|
||||
code: 'MODEL_SWITCH_NOT_SUPPORTED',
|
||||
statusCode: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const trimmedModel = model.trim();
|
||||
if (!trimmedModel) {
|
||||
throw new AppError('Model cannot be empty.', {
|
||||
code: 'INVALID_MODEL',
|
||||
statusCode: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (session?.setModel) {
|
||||
await session.setModel(trimmedModel);
|
||||
}
|
||||
|
||||
const currentPreference = this.sessionPreferences.get(sessionId) ?? {};
|
||||
this.sessionPreferences.set(sessionId, { ...currentPreference, model: trimmedModel });
|
||||
|
||||
if (session) {
|
||||
session.model = trimmedModel;
|
||||
this.appendEvent(session, {
|
||||
timestamp: new Date().toISOString(),
|
||||
channel: 'system',
|
||||
message: `Model updated to "${trimmedModel}".`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates/supports thinking mode updates and applies them to live/persisted state.
|
||||
*/
|
||||
async setSessionThinkingMode(sessionId: string, thinkingMode: string): Promise<void> {
|
||||
if (!this.capabilities.supportsThinkingModeControl) {
|
||||
throw new AppError(`Provider "${this.id}" does not support thinking mode control.`, {
|
||||
code: 'THINKING_MODE_NOT_SUPPORTED',
|
||||
statusCode: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const trimmedMode = thinkingMode.trim();
|
||||
if (!trimmedMode) {
|
||||
throw new AppError('Thinking mode cannot be empty.', {
|
||||
code: 'INVALID_THINKING_MODE',
|
||||
statusCode: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const session = this.sessions.get(sessionId);
|
||||
if (session?.setThinkingMode) {
|
||||
await session.setThinkingMode(trimmedMode);
|
||||
}
|
||||
|
||||
const currentPreference = this.sessionPreferences.get(sessionId) ?? {};
|
||||
this.sessionPreferences.set(sessionId, { ...currentPreference, thinkingMode: trimmedMode });
|
||||
|
||||
if (session) {
|
||||
session.thinkingMode = trimmedMode;
|
||||
this.appendEvent(session, {
|
||||
timestamp: new Date().toISOString(),
|
||||
channel: 'system',
|
||||
message: `Thinking mode updated to "${trimmedMode}".`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads saved preferences for resumed sessions.
|
||||
*/
|
||||
protected getSessionPreference(sessionId: string): SessionPreference {
|
||||
return this.sessionPreferences.get(sessionId) ?? {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores session preferences for subsequent resume/start operations.
|
||||
*/
|
||||
protected rememberSessionPreference(sessionId: string, preference: SessionPreference): void {
|
||||
const currentPreference = this.sessionPreferences.get(sessionId) ?? {};
|
||||
this.sessionPreferences.set(sessionId, {
|
||||
...currentPreference,
|
||||
...preference,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates mutable internal session state and registers it in memory.
|
||||
*/
|
||||
@@ -206,10 +107,6 @@ export abstract class AbstractProvider implements IProvider {
|
||||
};
|
||||
|
||||
this.sessions.set(sessionId, session);
|
||||
this.rememberSessionPreference(sessionId, {
|
||||
model: input.model,
|
||||
thinkingMode: input.thinkingMode,
|
||||
});
|
||||
|
||||
this.appendEvent(session, {
|
||||
timestamp: session.startedAt,
|
||||
|
||||
@@ -133,20 +133,12 @@ export abstract class BaseCliProvider extends AbstractProvider {
|
||||
* Boots one CLI child process and wires stream handlers to the session buffer.
|
||||
*/
|
||||
private async startSessionInternal(input: CreateCliInvocationInput): Promise<ProviderSessionSnapshot> {
|
||||
const preferred = this.getSessionPreference(input.sessionId);
|
||||
const effectiveModel = input.model ?? preferred.model;
|
||||
const effectiveThinking = input.thinkingMode ?? preferred.thinkingMode;
|
||||
|
||||
const session = this.createSessionRecord(input.sessionId, {
|
||||
model: effectiveModel,
|
||||
thinkingMode: effectiveThinking,
|
||||
model: input.model,
|
||||
thinkingMode: input.thinkingMode,
|
||||
});
|
||||
|
||||
const invocation = this.createCliInvocation({
|
||||
...input,
|
||||
model: effectiveModel,
|
||||
thinkingMode: effectiveThinking,
|
||||
});
|
||||
const invocation = this.createCliInvocation(input);
|
||||
|
||||
const child = spawn(invocation.command, invocation.args, {
|
||||
cwd: invocation.cwd ?? input.workspacePath ?? process.cwd(),
|
||||
|
||||
@@ -19,8 +19,6 @@ type CreateSdkExecutionInput = StartSessionInput & {
|
||||
type SdkExecution = {
|
||||
stream: AsyncIterable<unknown>;
|
||||
stop: () => Promise<boolean>;
|
||||
setModel?: (model: string) => Promise<void>;
|
||||
setThinkingMode?: (thinkingMode: string) => Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,21 +70,15 @@ export abstract class BaseSdkProvider extends AbstractProvider {
|
||||
* Initializes one SDK execution and wires it to the internal session record.
|
||||
*/
|
||||
private async startSessionInternal(input: CreateSdkExecutionInput): Promise<ProviderSessionSnapshot> {
|
||||
const preferred = this.getSessionPreference(input.sessionId);
|
||||
const effectiveModel = input.model ?? preferred.model;
|
||||
const effectiveThinking = input.thinkingMode ?? preferred.thinkingMode;
|
||||
|
||||
const session = this.createSessionRecord(input.sessionId, {
|
||||
model: effectiveModel,
|
||||
thinkingMode: effectiveThinking,
|
||||
model: input.model,
|
||||
thinkingMode: input.thinkingMode,
|
||||
});
|
||||
|
||||
let execution: SdkExecution;
|
||||
try {
|
||||
execution = await this.createSdkExecution({
|
||||
...input,
|
||||
model: effectiveModel,
|
||||
thinkingMode: effectiveThinking,
|
||||
emitEvent: (event) => {
|
||||
this.appendEvent(session, event);
|
||||
},
|
||||
@@ -103,8 +95,6 @@ export abstract class BaseSdkProvider extends AbstractProvider {
|
||||
}
|
||||
|
||||
session.stop = execution.stop;
|
||||
session.setModel = execution.setModel;
|
||||
session.setThinkingMode = execution.setThinkingMode;
|
||||
|
||||
session.completion = this.consumeStream(session, execution.stream);
|
||||
return this.toSnapshot(session);
|
||||
|
||||
@@ -104,7 +104,6 @@ export class ClaudeProvider extends BaseSdkProvider {
|
||||
protected async createSdkExecution(input: ClaudeExecutionInput): Promise<{
|
||||
stream: AsyncIterable<unknown>;
|
||||
stop: () => Promise<boolean>;
|
||||
setModel: (model: string) => Promise<void>;
|
||||
}> {
|
||||
const options: Options = {
|
||||
cwd: input.workspacePath,
|
||||
@@ -131,9 +130,6 @@ export class ClaudeProvider extends BaseSdkProvider {
|
||||
await queryInstance.interrupt();
|
||||
return true;
|
||||
},
|
||||
setModel: async (model: string) => {
|
||||
await queryInstance.setModel(model);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,6 @@ export interface IProvider {
|
||||
resumeSession(input: StartSessionInput & { sessionId: string }): Promise<ProviderSessionSnapshot>;
|
||||
|
||||
stopSession(sessionId: string): Promise<boolean>;
|
||||
setSessionModel(sessionId: string, model: string): Promise<void>;
|
||||
setSessionThinkingMode(sessionId: string, thinkingMode: string): Promise<void>;
|
||||
|
||||
getSession(sessionId: string): ProviderSessionSnapshot | null;
|
||||
listSessions(): ProviderSessionSnapshot[];
|
||||
@@ -98,6 +96,4 @@ export type MutableProviderSession = Omit<ProviderSessionSnapshot, 'events'> & {
|
||||
events: ProviderSessionEvent[];
|
||||
completion: Promise<void>;
|
||||
stop: () => Promise<boolean>;
|
||||
setModel?: (model: string) => Promise<void>;
|
||||
setThinkingMode?: (thinkingMode: string) => Promise<void>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user