mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-09 07:05:51 +08:00
Fix/use fallback models for claude (#806)
* fix: remove the hide cursor on windows logic * feat(cursor): update fallback models * fix(claude): force fallback models and disable supportedModels lookup
This commit is contained in:
@@ -1,14 +1,10 @@
|
|||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
|
|
||||||
import { query, type ModelInfo, type Options } from '@anthropic-ai/claude-agent-sdk';
|
|
||||||
|
|
||||||
import { sessionsDb } from '@/modules/database/index.js';
|
import { sessionsDb } from '@/modules/database/index.js';
|
||||||
import { resolveClaudeCodeExecutablePath } from '@/shared/claude-cli-path.js';
|
|
||||||
import type { IProviderModels } from '@/shared/interfaces.js';
|
import type { IProviderModels } from '@/shared/interfaces.js';
|
||||||
import type {
|
import type {
|
||||||
ProviderChangeActiveModelInput,
|
ProviderChangeActiveModelInput,
|
||||||
ProviderCurrentActiveModel,
|
ProviderCurrentActiveModel,
|
||||||
ProviderModelOption,
|
|
||||||
ProviderModelsDefinition,
|
ProviderModelsDefinition,
|
||||||
ProviderSessionActiveModelChange,
|
ProviderSessionActiveModelChange,
|
||||||
} from '@/shared/types.js';
|
} from '@/shared/types.js';
|
||||||
@@ -19,17 +15,29 @@ import {
|
|||||||
|
|
||||||
export const CLAUDE_FALLBACK_MODELS: ProviderModelsDefinition = {
|
export const CLAUDE_FALLBACK_MODELS: ProviderModelsDefinition = {
|
||||||
OPTIONS: [
|
OPTIONS: [
|
||||||
{ value: 'default', label: 'Default (recommended)' },
|
{
|
||||||
{ value: 'sonnet[1m]', label: 'Sonnet (1M context)' },
|
value: 'default',
|
||||||
{ value: 'opus', label: 'Opus' },
|
label: 'Default (recommended)',
|
||||||
{ value: 'opus[1m]', label: 'Opus (1M context)' },
|
description: 'Use the default model (currently Opus 4.7 (1M context)) · $5/$25 per Mtok',
|
||||||
{ value: 'haiku', label: 'Haiku' },
|
},
|
||||||
{ value: 'sonnet', label: 'sonnet' },
|
{
|
||||||
|
value: 'sonnet',
|
||||||
|
label: 'Sonnet',
|
||||||
|
description: 'Sonnet 4.6 · Best for everyday tasks · $3/$15 per Mtok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'sonnet[1m]',
|
||||||
|
label: 'Sonnet (1M context)',
|
||||||
|
description: 'Sonnet 4.6 for long sessions · $3/$15 per Mtok',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'haiku',
|
||||||
|
label: 'Haiku',
|
||||||
|
description: 'Haiku 4.5 · Fastest for quick answers · $1/$5 per Mtok',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
DEFAULT: 'default',
|
DEFAULT: 'default',
|
||||||
};
|
};
|
||||||
|
|
||||||
type ClaudeModelQueryOptions = Pick<Options, 'env' | 'pathToClaudeCodeExecutable' | 'permissionMode'>;
|
|
||||||
type ClaudeInitEvent = {
|
type ClaudeInitEvent = {
|
||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
session_id?: string;
|
session_id?: string;
|
||||||
@@ -49,46 +57,6 @@ const ANSI_PATTERN = new RegExp(
|
|||||||
'g',
|
'g',
|
||||||
);
|
);
|
||||||
|
|
||||||
const buildClaudeQueryOptions = (): ClaudeModelQueryOptions => ({
|
|
||||||
env: { ...process.env },
|
|
||||||
pathToClaudeCodeExecutable: resolveClaudeCodeExecutablePath(process.env.CLAUDE_CLI_PATH),
|
|
||||||
permissionMode: 'default',
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapClaudeModel = (model: ModelInfo): ProviderModelOption => ({
|
|
||||||
value: model.value,
|
|
||||||
label: model.displayName || model.value,
|
|
||||||
description: model.description || undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
const buildClaudeModelsDefinition = (models: ModelInfo[]): ProviderModelsDefinition => {
|
|
||||||
const options: ProviderModelOption[] = [];
|
|
||||||
const seenValues = new Set<string>();
|
|
||||||
|
|
||||||
for (const model of models) {
|
|
||||||
const mappedModel = mapClaudeModel(model);
|
|
||||||
if (seenValues.has(mappedModel.value)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
seenValues.add(mappedModel.value);
|
|
||||||
options.push(mappedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.length === 0) {
|
|
||||||
return CLAUDE_FALLBACK_MODELS;
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultValue = options.find((option) => option.value === 'default')?.value
|
|
||||||
?? options[0]?.value
|
|
||||||
?? CLAUDE_FALLBACK_MODELS.DEFAULT;
|
|
||||||
|
|
||||||
return {
|
|
||||||
OPTIONS: options,
|
|
||||||
DEFAULT: defaultValue,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const extractClaudeEventModel = (event: ClaudeInitEvent, sessionId: string): string | null => {
|
const extractClaudeEventModel = (event: ClaudeInitEvent, sessionId: string): string | null => {
|
||||||
const eventSessionId = event.sessionId ?? event.session_id;
|
const eventSessionId = event.sessionId ?? event.session_id;
|
||||||
if (eventSessionId && eventSessionId !== sessionId) {
|
if (eventSessionId && eventSessionId !== sessionId) {
|
||||||
@@ -181,25 +149,18 @@ const readClaudeSessionModelFromJsonl = async (
|
|||||||
|
|
||||||
export class ClaudeProviderModels implements IProviderModels {
|
export class ClaudeProviderModels implements IProviderModels {
|
||||||
async getSupportedModels(): Promise<ProviderModelsDefinition> {
|
async getSupportedModels(): Promise<ProviderModelsDefinition> {
|
||||||
let queryInstance: ReturnType<typeof query> | null = null;
|
// claude creates a new jsonl file as a separate session for this request.
|
||||||
|
// As a result, it lists the workspace where this is invoked when it shouldn't.
|
||||||
try {
|
//
|
||||||
// The SDK exposes its runtime model catalog on the initialized query
|
// Disabled for now:
|
||||||
// instance, so we create a lightweight query and immediately close it
|
// const queryInstance = query({
|
||||||
// after reading the control-plane metadata.
|
// prompt: 'Get supported models',
|
||||||
queryInstance = query({
|
// options: buildClaudeQueryOptions(),
|
||||||
prompt: 'Get supported models',
|
// });
|
||||||
options: buildClaudeQueryOptions(),
|
// const supportedModels = await queryInstance.supportedModels();
|
||||||
});
|
// queryInstance.close();
|
||||||
|
// return buildClaudeModelsDefinition(supportedModels);
|
||||||
const supportedModels = await queryInstance.supportedModels();
|
return CLAUDE_FALLBACK_MODELS;
|
||||||
|
|
||||||
return buildClaudeModelsDefinition(supportedModels);
|
|
||||||
} catch {
|
|
||||||
return CLAUDE_FALLBACK_MODELS;
|
|
||||||
} finally {
|
|
||||||
queryInstance?.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCurrentActiveModel(sessionId?: string): Promise<ProviderCurrentActiveModel> {
|
async getCurrentActiveModel(sessionId?: string): Promise<ProviderCurrentActiveModel> {
|
||||||
|
|||||||
Reference in New Issue
Block a user