|
|
@@ -2,6 +2,328 @@ import i18next from 'i18next';
|
|
|
import { Modal, Tag, Typography } from '@douyinfe/semi-ui';
|
|
|
import { copy, isMobile, showSuccess } from './utils';
|
|
|
import { visit } from 'unist-util-visit';
|
|
|
+import {
|
|
|
+ OpenAI,
|
|
|
+ Claude,
|
|
|
+ Gemini,
|
|
|
+ Moonshot,
|
|
|
+ Zhipu,
|
|
|
+ Qwen,
|
|
|
+ DeepSeek,
|
|
|
+ Minimax,
|
|
|
+ Wenxin,
|
|
|
+ Spark,
|
|
|
+ Midjourney,
|
|
|
+ Hunyuan,
|
|
|
+ Cohere,
|
|
|
+ Cloudflare,
|
|
|
+ Ai360,
|
|
|
+ Yi,
|
|
|
+ Jina,
|
|
|
+ Mistral,
|
|
|
+ XAI,
|
|
|
+ Ollama,
|
|
|
+ Doubao,
|
|
|
+} from '@lobehub/icons';
|
|
|
+
|
|
|
+// 获取模型分类
|
|
|
+export const getModelCategories = (() => {
|
|
|
+ let categoriesCache = null;
|
|
|
+ let lastLocale = null;
|
|
|
+
|
|
|
+ return (t) => {
|
|
|
+ const currentLocale = i18next.language;
|
|
|
+ if (categoriesCache && lastLocale === currentLocale) {
|
|
|
+ return categoriesCache;
|
|
|
+ }
|
|
|
+
|
|
|
+ categoriesCache = {
|
|
|
+ all: {
|
|
|
+ label: t('全部模型'),
|
|
|
+ icon: null,
|
|
|
+ filter: () => true
|
|
|
+ },
|
|
|
+ openai: {
|
|
|
+ label: 'OpenAI',
|
|
|
+ icon: <OpenAI />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('gpt') ||
|
|
|
+ model.model_name.toLowerCase().includes('dall-e') ||
|
|
|
+ model.model_name.toLowerCase().includes('whisper') ||
|
|
|
+ model.model_name.toLowerCase().includes('tts') ||
|
|
|
+ model.model_name.toLowerCase().includes('text-') ||
|
|
|
+ model.model_name.toLowerCase().includes('babbage') ||
|
|
|
+ model.model_name.toLowerCase().includes('davinci') ||
|
|
|
+ model.model_name.toLowerCase().includes('curie') ||
|
|
|
+ model.model_name.toLowerCase().includes('ada')
|
|
|
+ },
|
|
|
+ anthropic: {
|
|
|
+ label: 'Anthropic',
|
|
|
+ icon: <Claude.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('claude')
|
|
|
+ },
|
|
|
+ gemini: {
|
|
|
+ label: 'Gemini',
|
|
|
+ icon: <Gemini.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('gemini')
|
|
|
+ },
|
|
|
+ moonshot: {
|
|
|
+ label: 'Moonshot',
|
|
|
+ icon: <Moonshot />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('moonshot')
|
|
|
+ },
|
|
|
+ zhipu: {
|
|
|
+ label: t('智谱'),
|
|
|
+ icon: <Zhipu.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('chatglm') ||
|
|
|
+ model.model_name.toLowerCase().includes('glm-')
|
|
|
+ },
|
|
|
+ qwen: {
|
|
|
+ label: t('通义千问'),
|
|
|
+ icon: <Qwen.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('qwen')
|
|
|
+ },
|
|
|
+ deepseek: {
|
|
|
+ label: 'DeepSeek',
|
|
|
+ icon: <DeepSeek.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('deepseek')
|
|
|
+ },
|
|
|
+ minimax: {
|
|
|
+ label: 'MiniMax',
|
|
|
+ icon: <Minimax.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('abab')
|
|
|
+ },
|
|
|
+ baidu: {
|
|
|
+ label: t('文心一言'),
|
|
|
+ icon: <Wenxin.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('ernie')
|
|
|
+ },
|
|
|
+ xunfei: {
|
|
|
+ label: t('讯飞星火'),
|
|
|
+ icon: <Spark.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('spark')
|
|
|
+ },
|
|
|
+ midjourney: {
|
|
|
+ label: 'Midjourney',
|
|
|
+ icon: <Midjourney />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('mj_')
|
|
|
+ },
|
|
|
+ tencent: {
|
|
|
+ label: t('腾讯混元'),
|
|
|
+ icon: <Hunyuan.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('hunyuan')
|
|
|
+ },
|
|
|
+ cohere: {
|
|
|
+ label: 'Cohere',
|
|
|
+ icon: <Cohere.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('command')
|
|
|
+ },
|
|
|
+ cloudflare: {
|
|
|
+ label: 'Cloudflare',
|
|
|
+ icon: <Cloudflare.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('@cf/')
|
|
|
+ },
|
|
|
+ ai360: {
|
|
|
+ label: t('360智脑'),
|
|
|
+ icon: <Ai360.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('360')
|
|
|
+ },
|
|
|
+ yi: {
|
|
|
+ label: t('零一万物'),
|
|
|
+ icon: <Yi.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('yi')
|
|
|
+ },
|
|
|
+ jina: {
|
|
|
+ label: 'Jina',
|
|
|
+ icon: <Jina />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('jina')
|
|
|
+ },
|
|
|
+ mistral: {
|
|
|
+ label: 'Mistral AI',
|
|
|
+ icon: <Mistral.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('mistral')
|
|
|
+ },
|
|
|
+ xai: {
|
|
|
+ label: 'xAI',
|
|
|
+ icon: <XAI />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('grok')
|
|
|
+ },
|
|
|
+ llama: {
|
|
|
+ label: 'Llama',
|
|
|
+ icon: <Ollama />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('llama')
|
|
|
+ },
|
|
|
+ doubao: {
|
|
|
+ label: t('豆包'),
|
|
|
+ icon: <Doubao.Color />,
|
|
|
+ filter: (model) => model.model_name.toLowerCase().includes('doubao')
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ lastLocale = currentLocale;
|
|
|
+ return categoriesCache;
|
|
|
+ };
|
|
|
+})();
|
|
|
+
|
|
|
+// 颜色列表
|
|
|
+const colors = [
|
|
|
+ 'amber',
|
|
|
+ 'blue',
|
|
|
+ 'cyan',
|
|
|
+ 'green',
|
|
|
+ 'grey',
|
|
|
+ 'indigo',
|
|
|
+ 'light-blue',
|
|
|
+ 'lime',
|
|
|
+ 'orange',
|
|
|
+ 'pink',
|
|
|
+ 'purple',
|
|
|
+ 'red',
|
|
|
+ 'teal',
|
|
|
+ 'violet',
|
|
|
+ 'yellow',
|
|
|
+];
|
|
|
+
|
|
|
+// 基础10色色板 (N ≤ 10)
|
|
|
+const baseColors = [
|
|
|
+ '#1664FF', // 主色
|
|
|
+ '#1AC6FF',
|
|
|
+ '#FF8A00',
|
|
|
+ '#3CC780',
|
|
|
+ '#7442D4',
|
|
|
+ '#FFC400',
|
|
|
+ '#304D77',
|
|
|
+ '#B48DEB',
|
|
|
+ '#009488',
|
|
|
+ '#FF7DDA',
|
|
|
+];
|
|
|
+
|
|
|
+// 扩展20色色板 (10 < N ≤ 20)
|
|
|
+const extendedColors = [
|
|
|
+ '#1664FF',
|
|
|
+ '#B2CFFF',
|
|
|
+ '#1AC6FF',
|
|
|
+ '#94EFFF',
|
|
|
+ '#FF8A00',
|
|
|
+ '#FFCE7A',
|
|
|
+ '#3CC780',
|
|
|
+ '#B9EDCD',
|
|
|
+ '#7442D4',
|
|
|
+ '#DDC5FA',
|
|
|
+ '#FFC400',
|
|
|
+ '#FAE878',
|
|
|
+ '#304D77',
|
|
|
+ '#8B959E',
|
|
|
+ '#B48DEB',
|
|
|
+ '#EFE3FF',
|
|
|
+ '#009488',
|
|
|
+ '#59BAA8',
|
|
|
+ '#FF7DDA',
|
|
|
+ '#FFCFEE',
|
|
|
+];
|
|
|
+
|
|
|
+// 模型颜色映射
|
|
|
+export const modelColorMap = {
|
|
|
+ 'dall-e': 'rgb(147,112,219)', // 深紫色
|
|
|
+ // 'dall-e-2': 'rgb(147,112,219)', // 介于紫色和蓝色之间的色调
|
|
|
+ 'dall-e-3': 'rgb(153,50,204)', // 介于紫罗兰和洋红之间的色调
|
|
|
+ 'gpt-3.5-turbo': 'rgb(184,227,167)', // 浅绿色
|
|
|
+ // 'gpt-3.5-turbo-0301': 'rgb(131,220,131)', // 亮绿色
|
|
|
+ 'gpt-3.5-turbo-0613': 'rgb(60,179,113)', // 海洋绿
|
|
|
+ 'gpt-3.5-turbo-1106': 'rgb(32,178,170)', // 浅海洋绿
|
|
|
+ 'gpt-3.5-turbo-16k': 'rgb(149,252,206)', // 淡橙色
|
|
|
+ 'gpt-3.5-turbo-16k-0613': 'rgb(119,255,214)', // 淡桃
|
|
|
+ 'gpt-3.5-turbo-instruct': 'rgb(175,238,238)', // 粉蓝色
|
|
|
+ 'gpt-4': 'rgb(135,206,235)', // 天蓝色
|
|
|
+ // 'gpt-4-0314': 'rgb(70,130,180)', // 钢蓝色
|
|
|
+ 'gpt-4-0613': 'rgb(100,149,237)', // 矢车菊蓝
|
|
|
+ 'gpt-4-1106-preview': 'rgb(30,144,255)', // 道奇蓝
|
|
|
+ 'gpt-4-0125-preview': 'rgb(2,177,236)', // 深天蓝
|
|
|
+ 'gpt-4-turbo-preview': 'rgb(2,177,255)', // 深天蓝
|
|
|
+ 'gpt-4-32k': 'rgb(104,111,238)', // 中紫色
|
|
|
+ // 'gpt-4-32k-0314': 'rgb(90,105,205)', // 暗灰蓝色
|
|
|
+ 'gpt-4-32k-0613': 'rgb(61,71,139)', // 暗蓝灰色
|
|
|
+ 'gpt-4-all': 'rgb(65,105,225)', // 皇家蓝
|
|
|
+ 'gpt-4-gizmo-*': 'rgb(0,0,255)', // 纯蓝色
|
|
|
+ 'gpt-4-vision-preview': 'rgb(25,25,112)', // 午夜蓝
|
|
|
+ 'text-ada-001': 'rgb(255,192,203)', // 粉红色
|
|
|
+ 'text-babbage-001': 'rgb(255,160,122)', // 浅珊瑚色
|
|
|
+ 'text-curie-001': 'rgb(219,112,147)', // 苍紫罗兰色
|
|
|
+ // 'text-davinci-002': 'rgb(199,21,133)', // 中紫罗兰红色
|
|
|
+ 'text-davinci-003': 'rgb(219,112,147)', // 苍紫罗兰色(与Curie相同,表示同一个系列)
|
|
|
+ 'text-davinci-edit-001': 'rgb(255,105,180)', // 热粉色
|
|
|
+ 'text-embedding-ada-002': 'rgb(255,182,193)', // 浅粉红
|
|
|
+ 'text-embedding-v1': 'rgb(255,174,185)', // 浅粉红色(略有区别)
|
|
|
+ 'text-moderation-latest': 'rgb(255,130,171)', // 强粉色
|
|
|
+ 'text-moderation-stable': 'rgb(255,160,122)', // 浅珊瑚色(与Babbage相同,表示同一类功能)
|
|
|
+ 'tts-1': 'rgb(255,140,0)', // 深橙色
|
|
|
+ 'tts-1-1106': 'rgb(255,165,0)', // 橙色
|
|
|
+ 'tts-1-hd': 'rgb(255,215,0)', // 金色
|
|
|
+ 'tts-1-hd-1106': 'rgb(255,223,0)', // 金黄色(略有区别)
|
|
|
+ 'whisper-1': 'rgb(245,245,220)', // 米色
|
|
|
+ 'claude-3-opus-20240229': 'rgb(255,132,31)', // 橙红色
|
|
|
+ 'claude-3-sonnet-20240229': 'rgb(253,135,93)', // 橙色
|
|
|
+ 'claude-3-haiku-20240307': 'rgb(255,175,146)', // 浅橙色
|
|
|
+ 'claude-2.1': 'rgb(255,209,190)', // 浅橙色(略有区别)
|
|
|
+};
|
|
|
+
|
|
|
+export function modelToColor(modelName) {
|
|
|
+ // 1. 如果模型在预定义的 modelColorMap 中,使用预定义颜色
|
|
|
+ if (modelColorMap[modelName]) {
|
|
|
+ return modelColorMap[modelName];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 生成一个稳定的数字作为索引
|
|
|
+ let hash = 0;
|
|
|
+ for (let i = 0; i < modelName.length; i++) {
|
|
|
+ hash = (hash << 5) - hash + modelName.charCodeAt(i);
|
|
|
+ hash = hash & hash; // Convert to 32-bit integer
|
|
|
+ }
|
|
|
+ hash = Math.abs(hash);
|
|
|
+
|
|
|
+ // 3. 根据模型名称长度选择不同的色板
|
|
|
+ const colorPalette = modelName.length > 10 ? extendedColors : baseColors;
|
|
|
+
|
|
|
+ // 4. 使用hash值选择颜色
|
|
|
+ const index = hash % colorPalette.length;
|
|
|
+ return colorPalette[index];
|
|
|
+}
|
|
|
+
|
|
|
+export function stringToColor(str) {
|
|
|
+ let sum = 0;
|
|
|
+ for (let i = 0; i < str.length; i++) {
|
|
|
+ sum += str.charCodeAt(i);
|
|
|
+ }
|
|
|
+ let i = sum % colors.length;
|
|
|
+ return colors[i];
|
|
|
+}
|
|
|
+
|
|
|
+// 渲染带有模型图标的标签
|
|
|
+export function renderModelTag(modelName, options = {}) {
|
|
|
+ const { color, size = 'large', shape = 'circle', onClick, suffixIcon } = options;
|
|
|
+
|
|
|
+ const categories = getModelCategories(i18next.t);
|
|
|
+ let icon = null;
|
|
|
+
|
|
|
+ for (const [key, category] of Object.entries(categories)) {
|
|
|
+ if (key !== 'all' && category.filter({ model_name: modelName })) {
|
|
|
+ icon = category.icon;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Tag
|
|
|
+ color={color || modelToColor(modelName)}
|
|
|
+ prefixIcon={icon}
|
|
|
+ suffixIcon={suffixIcon}
|
|
|
+ size={size}
|
|
|
+ shape={shape}
|
|
|
+ onClick={onClick}
|
|
|
+ >
|
|
|
+ {modelName}
|
|
|
+ </Tag>
|
|
|
+ );
|
|
|
+}
|
|
|
|
|
|
export function renderText(text, limit) {
|
|
|
if (text.length > limit) {
|
|
|
@@ -800,137 +1122,6 @@ export function renderQuotaWithPrompt(quota, digits) {
|
|
|
return '';
|
|
|
}
|
|
|
|
|
|
-const colors = [
|
|
|
- 'amber',
|
|
|
- 'blue',
|
|
|
- 'cyan',
|
|
|
- 'green',
|
|
|
- 'grey',
|
|
|
- 'indigo',
|
|
|
- 'light-blue',
|
|
|
- 'lime',
|
|
|
- 'orange',
|
|
|
- 'pink',
|
|
|
- 'purple',
|
|
|
- 'red',
|
|
|
- 'teal',
|
|
|
- 'violet',
|
|
|
- 'yellow',
|
|
|
-];
|
|
|
-
|
|
|
-// 基础10色色板 (N ≤ 10)
|
|
|
-const baseColors = [
|
|
|
- '#1664FF', // 主色
|
|
|
- '#1AC6FF',
|
|
|
- '#FF8A00',
|
|
|
- '#3CC780',
|
|
|
- '#7442D4',
|
|
|
- '#FFC400',
|
|
|
- '#304D77',
|
|
|
- '#B48DEB',
|
|
|
- '#009488',
|
|
|
- '#FF7DDA',
|
|
|
-];
|
|
|
-
|
|
|
-// 扩展20色色板 (10 < N ≤ 20)
|
|
|
-const extendedColors = [
|
|
|
- '#1664FF',
|
|
|
- '#B2CFFF',
|
|
|
- '#1AC6FF',
|
|
|
- '#94EFFF',
|
|
|
- '#FF8A00',
|
|
|
- '#FFCE7A',
|
|
|
- '#3CC780',
|
|
|
- '#B9EDCD',
|
|
|
- '#7442D4',
|
|
|
- '#DDC5FA',
|
|
|
- '#FFC400',
|
|
|
- '#FAE878',
|
|
|
- '#304D77',
|
|
|
- '#8B959E',
|
|
|
- '#B48DEB',
|
|
|
- '#EFE3FF',
|
|
|
- '#009488',
|
|
|
- '#59BAA8',
|
|
|
- '#FF7DDA',
|
|
|
- '#FFCFEE',
|
|
|
-];
|
|
|
-
|
|
|
-export const modelColorMap = {
|
|
|
- 'dall-e': 'rgb(147,112,219)', // 深紫色
|
|
|
- // 'dall-e-2': 'rgb(147,112,219)', // 介于紫色和蓝色之间的色调
|
|
|
- 'dall-e-3': 'rgb(153,50,204)', // 介于紫罗兰和洋红之间的色调
|
|
|
- 'gpt-3.5-turbo': 'rgb(184,227,167)', // 浅绿色
|
|
|
- // 'gpt-3.5-turbo-0301': 'rgb(131,220,131)', // 亮绿色
|
|
|
- 'gpt-3.5-turbo-0613': 'rgb(60,179,113)', // 海洋绿
|
|
|
- 'gpt-3.5-turbo-1106': 'rgb(32,178,170)', // 浅海洋绿
|
|
|
- 'gpt-3.5-turbo-16k': 'rgb(149,252,206)', // 淡橙色
|
|
|
- 'gpt-3.5-turbo-16k-0613': 'rgb(119,255,214)', // 淡桃
|
|
|
- 'gpt-3.5-turbo-instruct': 'rgb(175,238,238)', // 粉蓝色
|
|
|
- 'gpt-4': 'rgb(135,206,235)', // 天蓝色
|
|
|
- // 'gpt-4-0314': 'rgb(70,130,180)', // 钢蓝色
|
|
|
- 'gpt-4-0613': 'rgb(100,149,237)', // 矢车菊蓝
|
|
|
- 'gpt-4-1106-preview': 'rgb(30,144,255)', // 道奇蓝
|
|
|
- 'gpt-4-0125-preview': 'rgb(2,177,236)', // 深天蓝
|
|
|
- 'gpt-4-turbo-preview': 'rgb(2,177,255)', // 深天蓝
|
|
|
- 'gpt-4-32k': 'rgb(104,111,238)', // 中紫色
|
|
|
- // 'gpt-4-32k-0314': 'rgb(90,105,205)', // 暗灰蓝色
|
|
|
- 'gpt-4-32k-0613': 'rgb(61,71,139)', // 暗蓝灰色
|
|
|
- 'gpt-4-all': 'rgb(65,105,225)', // 皇家蓝
|
|
|
- 'gpt-4-gizmo-*': 'rgb(0,0,255)', // 纯蓝色
|
|
|
- 'gpt-4-vision-preview': 'rgb(25,25,112)', // 午夜蓝
|
|
|
- 'text-ada-001': 'rgb(255,192,203)', // 粉红色
|
|
|
- 'text-babbage-001': 'rgb(255,160,122)', // 浅珊瑚色
|
|
|
- 'text-curie-001': 'rgb(219,112,147)', // 苍紫罗兰色
|
|
|
- // 'text-davinci-002': 'rgb(199,21,133)', // 中紫罗兰红色
|
|
|
- 'text-davinci-003': 'rgb(219,112,147)', // 苍紫罗兰色(与Curie相同,表示同一个系列)
|
|
|
- 'text-davinci-edit-001': 'rgb(255,105,180)', // 热粉色
|
|
|
- 'text-embedding-ada-002': 'rgb(255,182,193)', // 浅粉红
|
|
|
- 'text-embedding-v1': 'rgb(255,174,185)', // 浅粉红色(略有区别)
|
|
|
- 'text-moderation-latest': 'rgb(255,130,171)', // 强粉色
|
|
|
- 'text-moderation-stable': 'rgb(255,160,122)', // 浅珊瑚色(与Babbage相同,表示同一类功能)
|
|
|
- 'tts-1': 'rgb(255,140,0)', // 深橙色
|
|
|
- 'tts-1-1106': 'rgb(255,165,0)', // 橙色
|
|
|
- 'tts-1-hd': 'rgb(255,215,0)', // 金色
|
|
|
- 'tts-1-hd-1106': 'rgb(255,223,0)', // 金黄色(略有区别)
|
|
|
- 'whisper-1': 'rgb(245,245,220)', // 米色
|
|
|
- 'claude-3-opus-20240229': 'rgb(255,132,31)', // 橙红色
|
|
|
- 'claude-3-sonnet-20240229': 'rgb(253,135,93)', // 橙色
|
|
|
- 'claude-3-haiku-20240307': 'rgb(255,175,146)', // 浅橙色
|
|
|
- 'claude-2.1': 'rgb(255,209,190)', // 浅橙色(略有区别)
|
|
|
-};
|
|
|
-
|
|
|
-export function modelToColor(modelName) {
|
|
|
- // 1. 如果模型在预定义的 modelColorMap 中,使用预定义颜色
|
|
|
- if (modelColorMap[modelName]) {
|
|
|
- return modelColorMap[modelName];
|
|
|
- }
|
|
|
-
|
|
|
- // 2. 生成一个稳定的数字作为索引
|
|
|
- let hash = 0;
|
|
|
- for (let i = 0; i < modelName.length; i++) {
|
|
|
- hash = (hash << 5) - hash + modelName.charCodeAt(i);
|
|
|
- hash = hash & hash; // Convert to 32-bit integer
|
|
|
- }
|
|
|
- hash = Math.abs(hash);
|
|
|
-
|
|
|
- // 3. 根据模型名称长度选择不同的色板
|
|
|
- const colorPalette = modelName.length > 10 ? extendedColors : baseColors;
|
|
|
-
|
|
|
- // 4. 使用hash值选择颜色
|
|
|
- const index = hash % colorPalette.length;
|
|
|
- return colorPalette[index];
|
|
|
-}
|
|
|
-
|
|
|
-export function stringToColor(str) {
|
|
|
- let sum = 0;
|
|
|
- for (let i = 0; i < str.length; i++) {
|
|
|
- sum += str.charCodeAt(i);
|
|
|
- }
|
|
|
- let i = sum % colors.length;
|
|
|
- return colors[i];
|
|
|
-}
|
|
|
-
|
|
|
export function renderClaudeModelPrice(
|
|
|
inputTokens,
|
|
|
completionTokens,
|