fix: don't use ai aggregators if we have the model ourselves (#2424)
Docker Image CI / build-and-push-image (push) Has been cancelled
Maintain Release Merge PR / update-release-pr (push) Has been cancelled
release-please / release-please (push) Has been cancelled
test / test-backend (24.x) (push) Has been cancelled
test / API tests (node env, api-test) (24.x) (push) Has been cancelled
test / puterjs (node env, vitest) (24.x) (push) Has been cancelled

* cleanup: eslint changes

* fix: don't use ai aggregators if we have the model ourselves
This commit is contained in:
Daniel Salazar
2026-02-05 16:30:45 -08:00
committed by GitHub
parent 5fdfae6087
commit fbb2080a66
6 changed files with 34 additions and 9 deletions
+7
View File
@@ -59,6 +59,13 @@ export const rules = {
'no-use-before-define': ['error', {
'functions': false,
}],
'@stylistic/array-bracket-spacing': ['error', 'never'],
'@stylistic/linebreak-style': ['error', 'unix'],
'no-sequences': [
'error', {
allowInParentheses: false,
},
],
};
const tsRules = {
@@ -566,7 +566,7 @@ export class MeteringService {
]);
const defaultSubscriptionId = defaultSubscriptionEvent.defaultSubscriptionId as unknown as (typeof SUB_POLICIES)[number]['id'] || defaultUserSubscriptionId;
const availablePolicies = [ ...availablePoliciesEvent.availablePolicies, ...SUB_POLICIES ];
const availablePolicies = [...availablePoliciesEvent.availablePolicies, ...SUB_POLICIES];
const userSubscriptionId = userSubscriptionEvent.userSubscriptionId as unknown as typeof SUB_POLICIES[number]['id'] || defaultSubscriptionId;
return availablePolicies.find(({ id }) => id === userSubscriptionId) || availablePolicies.find(({ id }) => id === defaultSubscriptionId)!;
@@ -8,6 +8,7 @@
export const ELEVENLABS_COST_MAP = {
'elevenlabs:eleven_multilingual_v2:character': 18000 * 0.9, // using scale costs per additional char * 0.9
'elevenlabs:eleven_turbo_v2_5:character': 18000 * 0.9, // using scale costs per additional char * 0.9
'elevenlabs:eleven_turbo_v2:character': 18000 * 0.9, // using scale costs per additional char * 0.9
'elevenlabs:eleven_flash_v2_5:character': 9000 * 0.9, // using scale costs per additional char * 0.9
'elevenlabs:eleven_v3:character': 18000 * 0.9, // using scale costs per additional char * 0.9
'elevenlabs:eleven_multilingual_sts_v2:second': 300000 * 0.9, // using scale costs unit * 0.9
@@ -20,6 +20,7 @@
import { createId as cuid2 } from '@paralleldrive/cuid2';
import { PassThrough } from 'stream';
import { APIError } from '../../../api/APIError.js';
import { redisClient } from '../../../clients/redis/redisSingleton.js';
import { ErrorService } from '../../../modules/core/ErrorService.js';
import { Context } from '../../../util/context.js';
import BaseService from '../../BaseService.js';
@@ -45,7 +46,6 @@ import { OpenRouterProvider } from './providers/OpenRouterProvider/OpenRouterPro
import { TogetherAIProvider } from './providers/TogetherAiProvider/TogetherAIProvider.js';
import { IChatModel, IChatProvider, ICompleteArguments } from './providers/types.js';
import { XAIProvider } from './providers/XAIProvider/XAIProvider.js';
import { redisClient } from '../../../clients/redis/redisSingleton.js';
// Maximum number of fallback attempts when a model fails, including the first attempt
const MAX_FALLBACKS = 3 + 1; // includes first attempt
@@ -150,14 +150,14 @@ export class AIChatService extends BaseService {
if ( xaiConfig && xaiConfig.apiKey ) {
this.#providers['xai'] = new XAIProvider(xaiConfig, this.meteringService);
}
const togetherConfig = this.config.providers?.['together-ai'] || this.global_config?.services?.['together-ai'];
if ( togetherConfig && togetherConfig.apiKey ) {
this.#providers['together-ai'] = new TogetherAIProvider(togetherConfig, this.meteringService);
}
const openrouterConfig = this.config.providers?.['openrouter'] || this.global_config?.services?.['openrouter'];
if ( openrouterConfig && openrouterConfig.apiKey ) {
this.#providers['openrouter'] = new OpenRouterProvider(openrouterConfig, this.meteringService);
}
const togetherConfig = this.config.providers?.['together-ai'] || this.global_config?.services?.['together-ai'];
if ( togetherConfig && togetherConfig.apiKey ) {
this.#providers['together-ai'] = new TogetherAIProvider(togetherConfig, this.meteringService);
}
// ollama if local instance detected
@@ -221,6 +221,23 @@ export class AIChatService extends BaseService {
model.aliases = [model.puterId];
}
}
let exists = false;
if ( model.aliases ) {
for ( let alias of model.aliases ) {
if ( this.#modelIdMap[alias] && this.#modelIdMap[alias] !== this.#modelIdMap[model.id] ) {
if ( providerName === 'together-ai' || providerName === 'openrouter' ) {
delete this.#modelIdMap[model.id];
exists = true;
break;
}
}
}
}
if ( exists ) {
continue;
}
if ( model.aliases ) {
for ( let alias of model.aliases ) {
alias = alias.trim().toLowerCase();
@@ -674,7 +691,7 @@ export class AIChatService extends BaseService {
if ( targetModel.id.startsWith('openrouter:') || targetModel.id.startsWith('togetherai:') ) {
[aiProvider, modelToSearch] = targetModel.id.replace('openrouter:', '').replace('togetherai:', '').toLowerCase().split('/');
} else {
[aiProvider, modelToSearch] = targetModel.provider!.toLowerCase().replace('gemini', 'google').replace('openai-completion', 'openai').replace('openai-responses', 'openai'), targetModel.id.toLowerCase();
[aiProvider, modelToSearch] = [targetModel.provider!.toLowerCase().replace('gemini', 'google').replace('openai-completion', 'openai').replace('openai-responses', 'openai'), targetModel.id.toLowerCase()];
}
const potentialMatches = models.filter(model => {
@@ -244,7 +244,7 @@ export class ClaudeProvider implements IChatProvider {
return 'container_upload';
})();
delete task.contentPart.puter_path,
delete task.contentPart.puter_path;
task.contentPart.type = contentBlockTypeForFileBasedOnMime;
task.contentPart.source = {
type: 'file',
@@ -4,7 +4,7 @@ export const CLAUDE_MODELS: IChatModel[] = [
{
puterId: 'anthropic:anthropic/claude-opus-4-6',
id: 'claude-opus-4-6',
aliases: ['claude-opus-4-6-latest', 'claude-opus-4.6', 'anthropic/claude-opus-4-6'],
aliases: ['claude-opus-4-6-latest', 'claude-opus-4.6', 'claude-opus-4-6', 'anthropic/claude-opus-4-6'],
name: 'Claude Opus 4.6',
costs_currency: 'usd-cents',
input_cost_key: 'input_tokens',