165 lines
6.1 KiB
TypeScript
165 lines
6.1 KiB
TypeScript
// services/provider-router.service.ts
|
|
import {Injectable} from '@nestjs/common';
|
|
import {ContentStyle} from '../enum/style.enum';
|
|
import {ProviderName} from '../providers/ai-provider.factory';
|
|
import {Language} from "../../../common/interfaces/language.prompt.interface";
|
|
import {ContentTone, isEdgyTone} from "../enum/tone.enum";
|
|
import {AngleEnum} from "../enum/angle.enum";
|
|
import {getRandomElement} from "../../../shared/helper";
|
|
|
|
interface ProviderPair {
|
|
writer: ProviderName;
|
|
reviewer: ProviderName;
|
|
}
|
|
export type ContentType = 'post' | 'comment' | 'translation';
|
|
interface RoutingDecision {
|
|
writer: ProviderName;
|
|
reviewer: ProviderName;
|
|
useXEnrichment: boolean;
|
|
reason: string;
|
|
}
|
|
|
|
@Injectable()
|
|
export class ProviderRouterService {
|
|
/**
|
|
* Chọn cặp provider tối ưu theo style.
|
|
* Logic: style cần creativity -> GPT viết
|
|
* style cần accuracy -> DeepSeek viết
|
|
*/
|
|
// routev0(style: ContentStyle): ProviderPair {
|
|
// const map: Record<ContentStyle, ProviderPair> = {
|
|
// // Cần hook mạnh, emotion -> GPT viết
|
|
// [ContentStyle.BREAKING_NEWS]: { writer: 'openai', reviewer: 'deepseek' },
|
|
// [ContentStyle.MEME]: { writer: 'openai', reviewer: 'deepseek' },
|
|
// [ContentStyle.LIFESTYLE]: { writer: 'openai', reviewer: 'deepseek' },
|
|
// [ContentStyle.CRYPTO]: { writer: 'openai', reviewer: 'deepseek' },
|
|
//
|
|
// // Cần accuracy, logic -> DeepSeek viết
|
|
// [ContentStyle.TECH]: { writer: 'deepseek', reviewer: 'openai' },
|
|
// [ContentStyle.FINANCE]: { writer: 'deepseek', reviewer: 'openai' },
|
|
// [ContentStyle.EDUCATIONAL]: { writer: 'deepseek', reviewer: 'openai' },
|
|
//
|
|
// // Neutral -> cheapest
|
|
// [ContentStyle.GENERAL]: { writer: 'deepseek', reviewer: 'deepseek' },
|
|
// };
|
|
// return map[style];
|
|
// }
|
|
|
|
/**
|
|
* Core routing logic: dựa vào language + contentType + style.
|
|
*/
|
|
route(params: {
|
|
language: Language;
|
|
contentType: ContentType;
|
|
style?: ContentStyle;
|
|
tone?: ContentTone;
|
|
}): RoutingDecision {
|
|
const { language, contentType, style, tone } = params;
|
|
|
|
if(contentType ==='translation') {
|
|
if (language === 'cn') {
|
|
// Default EN
|
|
return {
|
|
writer: 'deepseek',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: 'CN default: GPT reliable',
|
|
};
|
|
}
|
|
return {
|
|
writer: getRandomElement([ 'openai',]),
|
|
reviewer: 'openai',
|
|
useXEnrichment: false,
|
|
reason: 'EN default: GPT reliable',
|
|
};
|
|
}
|
|
|
|
if (tone === ContentTone.EMPATHETIC) {
|
|
return {
|
|
writer: 'openai', // warmest voice, less "AI-ish"
|
|
reviewer: 'openai',
|
|
useXEnrichment: false,
|
|
reason: 'Empathy context: GPT for warmer human-like tone',
|
|
};
|
|
}
|
|
|
|
// 🔥 EDGY TONES: route mạnh sang Grok (EN) hoặc DeepSeek (others)
|
|
// GPT thường refuse hoặc water down → tránh
|
|
if (tone && isEdgyTone(tone)) {
|
|
if (language === 'en') {
|
|
return {
|
|
writer: getRandomElement(['openai', 'google', 'grok']),
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: `Edgy tone (${tone}) EN: Grok (handles edge best)`,
|
|
};
|
|
}
|
|
if (tone === ContentTone.SPICY) {
|
|
return {
|
|
writer: getRandomElement(['deepseek', 'google', 'openai',]),
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: `Edgy tone (${tone}) EN: Grok (handles edge best)`,
|
|
};
|
|
}
|
|
return {
|
|
writer: getRandomElement(['deepseek', 'google',]),
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: `Edgy tone (${tone}) ${language}: DeepSeek (less refusal)`,
|
|
};
|
|
}
|
|
|
|
// === ENGLISH ===
|
|
if (language === 'en') {
|
|
// Breaking news EN -> Grok (real-time + X-native)
|
|
if (style === ContentStyle.BREAKING_NEWS) {
|
|
return {
|
|
writer: 'google',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: 'EN breaking news: Grok has real-time X context',
|
|
};
|
|
}
|
|
|
|
// Comment EN casual/witty -> Grok
|
|
if (contentType === 'comment' && tone !== 'professional') {
|
|
return {
|
|
writer: 'google',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: 'EN casual comment: Grok sounds most human on X',
|
|
};
|
|
}
|
|
|
|
// Comment EN professional/analyst -> GPT
|
|
if (contentType === 'comment' && tone === 'professional') {
|
|
return {
|
|
writer: 'openai',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: 'EN professional comment: GPT more consistent',
|
|
};
|
|
}
|
|
|
|
// Default EN
|
|
return {
|
|
writer: 'openai',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: false,
|
|
reason: 'EN default: GPT reliable',
|
|
};
|
|
}
|
|
|
|
// === JP / KR / VI ===
|
|
// GPT thắng áp đảo với non-English
|
|
// @ts-ignore
|
|
return {
|
|
writer: 'openai',
|
|
reviewer: 'deepseek',
|
|
useXEnrichment: [ContentStyle.BREAKING_NEWS].includes(style!), // breaking news cần phải dùng X tìm cho hay
|
|
reason: `${language.toUpperCase()}: GPT superior for non-English`,
|
|
};
|
|
}
|
|
}
|