mirror of
https://github.com/HeyPuter/puter.git
synced 2026-02-05 05:19:44 -06:00
[PUT-475] fix togetherai chat being broken + deprioritize them 🐛 (#2369)
This commit is contained in:
@@ -25,7 +25,7 @@ const mandatoryRules = {
|
||||
'no-use-before-define': ['error', {
|
||||
'functions': false,
|
||||
}],
|
||||
'no-invalid-this': 'error',
|
||||
'no-invalid-this': 'warn',
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
|
||||
@@ -107,6 +107,7 @@ class AIInterfaceService extends BaseService {
|
||||
stream: { type: 'flag' },
|
||||
response: { type: 'json' },
|
||||
model: { type: 'string' },
|
||||
provider: { type: 'string', optional: true },
|
||||
temperature: { type: 'number' },
|
||||
max_tokens: { type: 'number' },
|
||||
},
|
||||
|
||||
@@ -25,7 +25,6 @@ import { Context } from '../../../util/context.js';
|
||||
import { kv } from '../../../util/kvSingleton.js';
|
||||
import BaseService from '../../BaseService.js';
|
||||
import { BaseDatabaseAccessService } from '../../database/BaseDatabaseAccessService.js';
|
||||
import { DB_WRITE } from '../../database/consts.js';
|
||||
import { DriverService } from '../../drivers/DriverService.js';
|
||||
import { TypedValue } from '../../drivers/meta/Runtime.js';
|
||||
import { EventService } from '../../EventService.js';
|
||||
@@ -35,19 +34,19 @@ import { normalize_tools_object } from '../utils/FunctionCalling.js';
|
||||
import { extract_text, normalize_messages, normalize_single_message } from '../utils/Messages.js';
|
||||
import Streaming from '../utils/Streaming.js';
|
||||
import { ClaudeProvider } from './providers/ClaudeProvider/ClaudeProvider.js';
|
||||
import { DeepSeekProvider } from './providers/DeepSeekProvider/DeepSeekProvider.js';
|
||||
import { FakeChatProvider } from './providers/FakeChatProvider.js';
|
||||
import { GeminiChatProvider } from './providers/GeminiProvider/GeminiChatProvider.js';
|
||||
import { GroqAIProvider } from './providers/GroqAiProvider/GroqAIProvider.js';
|
||||
import { MistralAIProvider } from './providers/MistralAiProvider/MistralAiProvider.js';
|
||||
import { OllamaChatProvider } from './providers/OllamaProvider.js';
|
||||
import { OpenAiChatProvider } from './providers/OpenAiProvider/OpenAiChatCompletionsProvider.js';
|
||||
import { OpenAiResponsesChatProvider } from './providers/OpenAiProvider/OpenAiChatResponsesProvider.js';
|
||||
import { OpenRouterProvider } from './providers/OpenRouterProvider/OpenRouterProvider.js';
|
||||
import { TogetherAIProvider } from './providers/TogetherAiProvider/TogetherAIProvider.js';
|
||||
import { IChatModel, IChatProvider, ICompleteArguments } from './providers/types.js';
|
||||
import { UsageLimitedChatProvider } from './providers/UsageLimitedChatProvider.js';
|
||||
import { OllamaChatProvider } from './providers/OllamaProvider.js';
|
||||
import { DeepSeekProvider } from './providers/DeepSeekProvider/DeepSeekProvider.js';
|
||||
import { XAIProvider } from './providers/XAIProvider/XAIProvider.js';
|
||||
import { TogetherAIProvider } from './providers/TogetherAiProvider/TogetherAIProvider.js';
|
||||
import { OpenRouterProvider } from './providers/OpenRouterProvider/OpenRouterProvider.js';
|
||||
|
||||
// Maximum number of fallback attempts when a model fails, including the first attempt
|
||||
const MAX_FALLBACKS = 3 + 1; // includes first attempt
|
||||
@@ -63,7 +62,7 @@ export class AIChatService extends BaseService {
|
||||
}
|
||||
|
||||
get db (): BaseDatabaseAccessService {
|
||||
return this.services.get('database').get(DB_WRITE, 'ai-service');
|
||||
return this.services.get('database').get();
|
||||
}
|
||||
|
||||
get errorService (): ErrorService {
|
||||
@@ -218,12 +217,11 @@ export class AIChatService extends BaseService {
|
||||
}
|
||||
this.#modelIdMap[model.id].push({ ...model, provider: providerName });
|
||||
if ( model.puterId ) {
|
||||
if (model.aliases) {
|
||||
if ( model.aliases ) {
|
||||
model.aliases.push(model.puterId);
|
||||
} else {
|
||||
model.aliases = [model.puterId]
|
||||
model.aliases = [model.puterId];
|
||||
}
|
||||
|
||||
}
|
||||
if ( model.aliases ) {
|
||||
for ( let alias of model.aliases ) {
|
||||
@@ -241,6 +239,14 @@ export class AIChatService extends BaseService {
|
||||
}
|
||||
}
|
||||
this.#modelIdMap[model.id].sort((a, b) => {
|
||||
// Sort togetherai provider models last
|
||||
if ( a.provider === 'together-ai' && b.provider !== 'together-ai' ) {
|
||||
return 1;
|
||||
}
|
||||
if ( b.provider === 'together-ai' && a.provider !== 'together-ai' ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( a.costs[a.input_cost_key || 'input_tokens'] === b.costs[b.input_cost_key || 'input_tokens'] ) {
|
||||
return a.id.length - b.id.length; // use shorter id since its likely the official one
|
||||
}
|
||||
@@ -279,7 +285,7 @@ export class AIChatService extends BaseService {
|
||||
let { test_mode: testMode, response_metadata: resMetadata, intended_service: legacyProviderName } = clientDriverCall as { test_mode?: boolean; response_metadata: Record<string, unknown>; intended_service?: string };
|
||||
const actor = Context.get('actor');
|
||||
|
||||
let intendedProvider = parameters.provider || legacyProviderName === AIChatService.SERVICE_NAME ? '' : legacyProviderName ; // should now all go through here
|
||||
let intendedProvider = parameters.provider || (legacyProviderName === AIChatService.SERVICE_NAME ? '' : legacyProviderName); // should now all go through here
|
||||
|
||||
if ( !parameters.model && !intendedProvider ) {
|
||||
intendedProvider = AIChatService.DEFAULT_PROVIDER;
|
||||
|
||||
@@ -57,8 +57,8 @@ export class TogetherAIProvider implements IChatProvider {
|
||||
context: model.context_length,
|
||||
description: model.display_name,
|
||||
costs_currency: 'usd-cents',
|
||||
input_cost_key: 'prompt_tokens',
|
||||
output_cost_key: 'completion_tokens',
|
||||
input_cost_key: 'input',
|
||||
output_cost_key: 'output',
|
||||
costs: {
|
||||
tokens: 1_000_000,
|
||||
...model.pricing,
|
||||
@@ -73,8 +73,8 @@ export class TogetherAIProvider implements IChatProvider {
|
||||
name: 'Model Fallback Test 1',
|
||||
context: 1000,
|
||||
costs_currency: 'usd-cents',
|
||||
input_cost_key: 'prompt_tokens',
|
||||
output_cost_key: 'completion_tokens',
|
||||
input_cost_key: 'input',
|
||||
output_cost_key: 'output',
|
||||
costs: {
|
||||
tokens: 1_000_000,
|
||||
prompt_tokens: 10,
|
||||
@@ -115,7 +115,10 @@ export class TogetherAIProvider implements IChatProvider {
|
||||
messages,
|
||||
stream,
|
||||
...(tools ? { tools } : {}),
|
||||
...(max_tokens ? { max_tokens } : {}),
|
||||
// TODO: make this better but togetherai doesn't handle max tokens properly at all
|
||||
...(max_tokens ? { max_tokens: max_tokens - messages.reduce((acc, curr) => {
|
||||
return acc + (curr.type === 'text' ? curr.text.length / 2 : 200);
|
||||
}, 0) } : {}),
|
||||
...(temperature ? { temperature } : {}),
|
||||
...(stream ? { stream_options: { include_usage: true } } : {}),
|
||||
} as Together.Chat.Completions.CompletionCreateParamsNonStreaming);
|
||||
|
||||
@@ -736,6 +736,10 @@ class AI {
|
||||
requestParams.max_tokens = userParams.max_tokens;
|
||||
}
|
||||
|
||||
if ( userParams.provider ) {
|
||||
requestParams.provider = userParams.provider;
|
||||
}
|
||||
|
||||
// convert undefined to empty string so that .startsWith works
|
||||
requestParams.model = requestParams.model ?? '';
|
||||
|
||||
@@ -745,11 +749,11 @@ class AI {
|
||||
}
|
||||
|
||||
if ( userParams.driver ) {
|
||||
driver = userParams.driver;
|
||||
requestParams.provider = requestParams.provider || userParams.driver;
|
||||
}
|
||||
|
||||
// Additional parameters to pass from userParams to requestParams
|
||||
const PARAMS_TO_PASS = ['tools', 'response', 'reasoning', 'reasoning_effort', 'text', 'verbosity'];
|
||||
const PARAMS_TO_PASS = ['tools', 'response', 'reasoning', 'reasoning_effort', 'text', 'verbosity', 'provider'];
|
||||
for ( const name of PARAMS_TO_PASS ) {
|
||||
if ( userParams[name] ) {
|
||||
requestParams[name] = userParams[name];
|
||||
|
||||
Reference in New Issue
Block a user